Trusted route operations
Released in v1.0.9, this extends the evidence chain shipped in v1.0.8. It does not add a planner, OCR model, second chemistry parser, or route schema. It makes two existing boundaries explicit: where an audit finding occurred, and what a caller may safely ask a public surface to do.
Binding inventory
| Surface | Route audit | Input and resource boundary | Cancellation / network |
|---|---|---|---|
| CLI | renkin audit-route reads a local plain or gzip JSON file |
bounded audit input reader; optional local stock and O7 sidecars | process owner may interrupt; audit initiates no network access |
| Python | renkin.audit_route(content, ...) accepts decoded in-memory text |
shared text, stock-line, nesting, and token limits | synchronous call; no cooperative cancellation; no network |
| WASM | audit_route_v2(content, format, stock, policy) |
same shared audit limits; plain in-memory JSON only | no core cooperative cancellation; playground terminates and respawns its Worker; no network |
| MCP | generated-route tools only; it does not expose arbitrary external route import/audit | each public tool validates its declared input schema | stdio request has no cancellation contract; no network contract is inferred from MCP itself |
An audit verdict is shared by CLI, Python, and WASM only for the common in-memory content/format/policy contract. Filesystem gzip support, O7 sidecars, process cancellation, and MCP tool availability are not silently claimed to be cross-binding features.
Finding location and reason v2
AuditFinding keeps the existing code, severity, and optional node.
It also carries optional location fields:
{
"code": "forward_validation_not_evaluable",
"severity": "informational",
"node": "CCO",
"occurrence_path": [1, 0],
"step_index": 2,
"reason": "missing_atom_mapping"
}
occurrence_pathis the zero-based child-index path from the normalized route root. It identifies one occurrence even when the same canonical SMILES appears multiple times.step_indexis the preorder index inAuditReport.stepsfor a decomposing node. It is absent for leaf-only findings.- Both are absent for a route-wide finding or a parse failure with no trusted normalized tree. A missing location is therefore not guessed from an external tool's node ID.
reasonis present only forforward_validation_not_evaluable. It repeats the matching step's forward-validation reason so flat finding consumers can distinguish missing evidence from unsupported input without joiningAuditReport.steps.- Every serialized
AuditedStephas a requiredoccurrence_path; unlike a finding, it is derived only after a normalized decomposing occurrence exists.
Each AuditedStep also has an atom_mapping receipt. Its
valid/invalid/not_evaluable result is a separate evidence axis, not a
new route verdict. It reports duplicate labels within either reaction side and
product-only labels as supplied-record defects. For each non-root step, the
optional producer_consumer receipt compares its mapped forward product with
the matching mapped reactant of its normalized parent step. Map labels are not
compared across unrelated steps, and missing/unsupported source evidence is
reported as not_evaluable, never reconstructed.
The path identifies a normalized occurrence, not a source atom-map or an
experimental reaction identity. Atom-map labels from external planner exports
can be local to one reaction. target_element_accounting_status remains a
directional heavy-element check, not a mass/charge balance or proof of
reaction feasibility.
External planner fixtures
The committed tests/fixtures/synplanner/v1.6.0/ captures real
write_routes_json output with provenance, source artifact metadata, and
hashes. It is the supported SynPlanner fixture baseline. The adapter preserves
confirmed source route/tree identifiers where available and records loss in
canonical interchange; it does not invent mapping, missing species, or
conditions.
SynPlanner v1.7.0 route-tree JSON compatibility is verified against upstream
route 58 from the release's own 18-route test file. Its intake identity is
fixed: release v1.7.0 (2026-08-25), annotated tag
c581c67143a09c0dbffd3c5d019412ac54766e75, commit
c46c84e7b3688a0175d87e7ba7e0302d139171a9, and MIT license file
c9ce472807ae4d1e009d4e8ab2399802f32eb1ff. The fixture preserves the upstream
blob and extracted-route hashes plus the MIT text. Both reaction steps parse,
normalize, and forward-replay successfully. The release has no attached model
export artifact, so this does not establish compatibility with every model,
route, or the separate CLI wrapper/bundle format. The still-open
protecting-group revision PR is experimental upstream work and is not a
RENKIN supported input contract.
Browser operation contract
The playground has one WASM Worker. A search and an audit never run concurrently. For either operation, Cancel or an elapsed browser budget rejects the pending request, terminates that Worker, loads a fresh module, and only then re-enables the next request. This is termination-based cancellation, not cooperative WASM cancellation. A reply from the terminated worker cannot be applied to a later request.
The release-candidate browser check cancels a 100,000-route audit, waits for the fresh Worker, then completes the normal failing example. The cancelled reply did not replace the later result, and the browser console contained no route-input log entry. This verifies the playground orchestration; it does not turn the synchronous WASM audit function into a cooperatively cancellable API.
The exported WASM capabilities() JSON is the machine-readable source for
the WASM module's accepted formats, policies, limits, network stance, and
cancellation limitation. It describes the module, not the native CLI/Python
or MCP surfaces. The CI Node/WASM quickstart derives over-limit calls from
that payload, so a changed number cannot silently drift from the export that
enforces it.
The installed Python extension exposes its own renkin.capabilities() payload.
It uses the native search limits rather than the tighter browser limits and
also describes forward prediction, caller-selected local-path access, and the
coverage Stage-2-only timeout. It does not imply cooperative cancellation for
ordinary synchronous Python search or audit calls.
The root CLI exposes the corresponding contract with:
Its payload includes CLI-only gzip audit input and interchange support. It
does not claim that every CLI subcommand is read-only: commands which create
stock or other artifacts remain explicitly command-specific. The separate MCP
server advertises callable tools through the standard tools/list discovery;
it does not accept arbitrary external route import as an MCP tool.