Rust-first layout
Goal
This page is for contributors changing internals. The design goal is a Rust-first, tests-first library where Rust is the source of truth for runtime behavior and Python provides the public façade plus RDKit bridge code.
Ownership
- Rust owns:
- prepared molecule storage after RDKit preparation
- prepared-graph runtime shape
- prepared molecule byte encoding
- exact-support algorithms
- next-token walkers
- runtime invariants and schema evolution
- Python owns:
- the thin public wrapper over
_core - RDKit interop at the
PrepareMolboundary - dataset-backed test tooling
- oracle/reference checks
- the thin public wrapper over
Implications
- Performance work should happen in Rust first.
- Bug fixes for runtime walkers should land in Rust first.
- Python parity tests should validate Rust, not define behavior independently.
- RDKit-backed checks remain valuable, but as oracle coverage rather than as the main implementation path.
Public and internal boundaries
grimaceis the only supported public Python API.grimace._coreis required and remains hidden implementation detail.grimace._runtimeis internal bridge code.grimace._referenceis internal oracle/reference code.PrepareMolmay use RDKit; runtime consumption ofPreparedMolshould not.
Test authority
The intended order of authority is:
- Rust-native tests for prepared-graph validation and walker/enumerator behavior.
- Python contract and integration tests for the public API and transport boundary.
- Python parity tests as a cross-language regression net on curated and representative slices.
- RDKit-backed reference tests as oracle coverage.
When coverage overlaps, prefer strengthening items earlier in this list instead of expanding later ones.
Change rules
- New runtime behavior should land in Rust first.
- Avoid adding dual implementations unless there is a concrete oracle or test need.
- Public API changes should happen in
grimace, not in internal modules.