renkin 0.60.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,7 +47,7 @@ npm install renkin # JavaScript (browser / bundler -- see docs/api/wasm
47
47
 
48
48
  Auditing Syntheseus routes needs one more, optional package:
49
49
  `pip install renkin[syntheseus]` (verified against Syntheseus `0.7.2` and
50
- `0.8.0` — see the [compatibility spike](https://github.com/kent-tokyo/renkin/blob/master/docs/design/syntheseus-0.8-compatibility-spike.md)).
50
+ `0.8.0`).
51
51
 
52
52
  ---
53
53
 
@@ -73,6 +73,11 @@ report = json.loads(
73
73
  print(report["summary"])
74
74
  ```
75
75
 
76
+ For an evidence-boundary report, add `--chemical-review` to
77
+ `renkin audit-route ... --output json`. The optional report is deterministic;
78
+ missing conditions, selectivity, and substrate-scope evidence remain
79
+ `not_evaluable`. See the [chemical review rubric](https://kent-tokyo.github.io/renkin/guides/chemical-review-rubric/).
80
+
76
81
  **Syntheseus** (`pip install renkin[syntheseus]`)
77
82
 
78
83
  ```python
@@ -409,7 +414,7 @@ for the full acceptance criteria and licensing split.
409
414
  | **Route scoring** | `confidence`, `step_confidence`, `success_probability` (Retro-prob style), `convergency`, `atom_economy`, `route_cost` (`Σ BB cost + steps×0.5`, or actual prices via `--bb-prices`/`--stock`) per step/route — see caveat below the table |
410
415
  | **Step metadata provenance** | Each step reports `metadata_source`/`metadata_scope` so it's machine-readable whether `conditions`/`reaction_family` came from a rule-author default vs. something more grounded; absent (not fabricated) for extracted templates |
411
416
  | **Pareto multi-objective search** | `--format pareto` returns a Pareto front across `route_cost`/`success_probability`/`steps`; objectives configurable via `--objectives` |
412
- | **Constraint DSL** | `--constraints constraints.json` — element filters, step limits, confidence thresholds, preferred reaction families; enables LLM → RENKIN pipelines |
417
+ | **Constraint DSL** | `--constraints constraints.json` — element/building-block filters, step/cost limits, confidence thresholds, required/avoided/preferred reaction families; enables LLM → RENKIN pipelines |
413
418
  | **Output formats & diagnostics** | `--format json\|tree\|mermaid\|explain\|compare\|compare-json\|pareto`; zero-route JSON includes a `diagnostics` block with `likely_causes`/`suggestions` |
414
419
  | **`renkin-forward` toolkit** | `predict` (rank forward products), `enumerate` (bounded products from one reactant + partner library), `hints` (partner-free retrieval hints, no concrete product), `validate` (forward-verify each retro step) — see the [Forward guides](docs/guides/forward-retrieval-hints.md#predict--enumerate--hints-at-a-glance) |
415
420
  | **`renkin-bench`** | USPTO-50k/PaRoutes evaluation with `--plausibility` (forward-validated composite score), `--failure-taxonomy`, atom-balance checks (`target_MW > Σ precursor_MW`), and multi-stage `cascade` re-runs on unsolved targets — see [Benchmark](#benchmark) |
@@ -560,7 +565,7 @@ The JSON output includes `avg_nodes_expanded`, `avg_confidence`, `avg_convergenc
560
565
  | `validate_route` | Forward-validate a retrosynthetic route |
561
566
  | `explain_route` | Human-readable strengths/weaknesses per route |
562
567
  | `find_pareto_routes` | Pareto-front multi-objective route search |
563
- | `plan_with_constraints` | Constraint-DSL planning (element filters, step limits, confidence thresholds) |
568
+ | `plan_with_constraints` | Constraint-DSL planning (element/building-block filters, step/cost limits, confidence thresholds, required/avoided/preferred reaction families) |
564
569
  | `estimate_diversity` | Route diversity and coverage metrics |
565
570
 
566
571
  `find_routes` also accepts `search_mode: "coverage"` with a required
@@ -568,7 +573,7 @@ The JSON output includes `avg_nodes_expanded`, `avg_confidence`, `avg_convergenc
568
573
  to Stage 2 only when Stage 1 finds no route; the response reports the selected
569
574
  stage, timeout status, and per-stage elapsed time.
570
575
 
571
- The server auto-detects `data/building_blocks.smi` and `data/templates_extracted_5000.smi` in the working directory. Falls back to the embedded `DEFAULT_BUILDING_BLOCKS` / `default_rules()` defaults if not found (152 unique building blocks per `ChemEnv::bb_count()`, 21 handcrafted rules — verified 2026-08-29, after `heck_retro`'s removal (ring-fusion connectivity-collapse defect on internal alkenes fused to the same aromatic ring the leaving-group Br attaches to, confirmed by direct `apply_retro` reproduction on indene) dropped the count from 22, which itself followed `negishi_retro`'s and `grignard_addition_retro`'s removal (v0.36.0 rule-safety census: same ring-fused-atom-duplication defect as `aryl_amine_retro`/`buchwald_hartwig_retro`) dropping it from 24; a "509-BB / 20-rule" figure was previously documented here without verification).
576
+ The server auto-detects `data/building_blocks.smi` and `data/templates_extracted_5000.smi` in the working directory. Falls back to the embedded `DEFAULT_BUILDING_BLOCKS` / `default_rules()` defaults if not found (152 unique building blocks per `ChemEnv::bb_count()`, 22 handcrafted rules, including the new graph-based `carbamate_cleavage` rule).
572
577
 
573
578
  ```bash
574
579
  cargo build --release
@@ -670,7 +675,7 @@ renkin/ ← Cargo workspace root
670
675
  ├── scripts/
671
676
  │ ├── extract_templates.py # rdchiral template extraction pipeline
672
677
  │ ├── run_benchmark_chunks.sh # resumable chunked benchmark runner
673
- │ ├── train_reranker.py # candidate reranker training/evaluation (dev tool, offline only — see docs/guides/reranker-candidate-pools.md)
678
+ │ ├── train_reranker.py # candidate reranker training/evaluation (dev tool, offline only)
674
679
  │ └── tests/ # unittest suite for train_reranker.py
675
680
  ├── docs/ # MkDocs source → kent-tokyo.github.io/renkin/
676
681
  └── mkdocs.yml
@@ -695,7 +700,7 @@ see "Earlier milestones" below for older shipped work.
695
700
  - [x] Coverage mode (`--search-mode coverage`, [#101](https://github.com/kent-tokyo/renkin/issues/101), shipped v0.24.0) — opt-in Stage-1/Stage-2 template-count escalation, addressing the candidate-generation coverage gap below. Confirmed by a one-shot 500-target formal-TEST (`data/coverage_mode_formal_test/protocol_v2.md`): coverage +6.0pp, net gain +30, zero regressions, zero reranker failures, Stage-2 timeout rate 0.25% — all against pre-registered thresholds. See the Key Features table above for the shipped surface
696
701
  - [x] Reranker made actually usable: Python exposure (`find_routes()`'s `reranker_model_path`/`reranker_freq_table_path`) and batteries-included model distribution (`scripts/fetch_reranker_model.py`, SHA-256-verified fetch from the v0.22.0 GitHub Release's canonical assets) ([#101](https://github.com/kent-tokyo/renkin/issues/101), shipped v0.23.0) — v0.22.0 proved the reranker works; v0.23.0 is the usability/distribution unlock, not a new accuracy claim
697
702
  - [x] LightGBM candidate reranker, trained/gated offline and wired into route search ([#101](https://github.com/kent-tokyo/renkin/issues/101) Task 35, CLI shipped v0.22.0) — LambdaMART model trained on real USPTO-50k labels, passed its VAL screening gate (top1 +11.7pp, MRR +11.3pp, top10 +9.3pp, bootstrap-CI-confirmed) and a formal 4,903-target TEST evaluation against the frozen model exactly once (top1 +12.7pp, MRR +11.9pp, top10 +9.1pp — consistent magnitude with VAL, no overfitting signal), then wired into `find_routes` as an ordering-only rank bonus and confirmed with a paired 100-target route-search gate: `route_to_configured_stock` 16→20/100 (+4/-0). See the Key Features table above
698
- - [x] Formal 500-target RENKIN vs AiZynthFinder comparison ([#66](https://github.com/kent-tokyo/renkin/issues/66)) — under a fixed 500-target sample, shared 393-compound stock, and each tool's configured policy/budget, RENKIN Conservative's `route_to_shared_stock` outcome was 9.8 percentage points higher than AiZynthFinder's (73/500 vs 24/500, 95% CI [7.0, 12.8], exact McNemar p≈1.9e-11) — a statistically significant paired difference under this protocol, not a general search-capability superiority claim. Native-mode configurations (each tool's own stock) diverge in the opposite direction, dominated by unmatched conditions including a large stock-size gap. See the [comparison guide](docs/guides/open-source-retrosynthesis-comparison.md) for the full, deliberately scoped interpretation.
703
+ - [x] Formal 500-target RENKIN vs AiZynthFinder comparison ([#66](https://github.com/kent-tokyo/renkin/issues/66)) — under a fixed 500-target sample, shared 393-compound stock, and each tool's configured policy/budget, RENKIN Conservative's `route_to_shared_stock` outcome was 9.8 percentage points higher than AiZynthFinder's (73/500 vs 24/500). This is a protocol-specific paired result, not a general search-capability superiority claim; native-mode configurations use unmatched stocks and are not directly comparable.
699
704
  - [x] Ring-context safety guard for extracted templates ([#72](https://github.com/kent-tokyo/renkin/issues/72)/[#242](https://github.com/kent-tokyo/renkin/pull/242)) — opt-in `--ring-context-policy`/`--ring-context-sidecar`, catches extracted templates silently misapplying a ring-opening/closing disconnection their training data never saw; default remains `disabled` (unchanged legacy behavior)
700
705
  - [x] `atom_economy` no longer silently clamped to 100% when a route's represented precursor set can't account for the target's full mass ([#79](https://github.com/kent-tokyo/renkin/issues/79)) — a new `atom_economy_status` field (`normal`/`above_expected_range`/`not_evaluable`) reports this explicitly instead
701
706
 
@@ -707,8 +712,16 @@ see "Earlier milestones" below for older shipped work.
707
712
 
708
713
  ### Next
709
714
 
710
- - [ ] Graph rule expansion — sulfonamide / carbamate / urea cleavage (one PR per family, each with benchmark delta)
715
+ - [x] Graph rule expansion — sulfonamide and carbamate cleavage (one PR per family, with structural and atom-accounting gates; carbamate shipped v0.61.0)
716
+ - [x] Urea cleavage — validated atom-balanced disconnection to isocyanate + amine; implemented locally as the next-version candidate (not published)
711
717
  - [ ] Stock-aware planning (price / hazard / availability re-ranking)
718
+ - [x] Deterministic policy-aware vendor-offer selection (price, lead time,
719
+ availability) for exact private-stock matches
720
+ - [x] Optional local hazard labels and blocked-hazard policy decisions
721
+ - [x] Route-level stock score and deterministic multi-route ranking metadata
722
+ - [x] Constraint DSL route-cost cap (`max_route_cost`) with explicit route-cost semantics
723
+ - [x] Exact canonical building-block exclusion (`avoid_building_blocks`) for private/constrained stock policies
724
+ - [x] Exact canonical building-block requirement (`require_building_blocks`) for house-stock policies
712
725
 
713
726
  <details>
714
727
  <summary>Earlier milestones</summary>
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "kent-tokyo <kent-tokyo@users.noreply.github.com>"
6
6
  ],
7
7
  "description": "Ultra-fast retrosynthesis engine for computer-aided synthesis planning (CASP) — pure Rust, WASM-ready, Python bindings via PyO3",
8
- "version": "0.60.0",
8
+ "version": "1.0.0",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
package/renkin.d.ts CHANGED
@@ -138,6 +138,16 @@ export function find_routes_v4(target: string, depth: number, max_routes: number
138
138
  */
139
139
  export function find_routes_v5(target: string, depth: number, max_routes: number, beam_width: number, avoid_elements: string, require_elements: string, spectator_bond_policy: string, element_accounting_policy: string, beam_diversity_policy: string, beam_diversity_slots: number): string;
140
140
 
141
+ /**
142
+ * Same as [`find_routes_v5`], plus bounded candidate-level diagnostics.
143
+ * `candidate_trace_limit` is an explicit collection cap; `0` collects no
144
+ * records while still returning the aggregate `search_diagnostics` block.
145
+ * The diagnostics are read-only and do not affect route selection. A new
146
+ * export preserves the fail-loud compatibility behavior of the earlier
147
+ * versioned WASM functions.
148
+ */
149
+ export function find_routes_v6(target: string, depth: number, max_routes: number, beam_width: number, avoid_elements: string, require_elements: string, spectator_bond_policy: string, element_accounting_policy: string, beam_diversity_policy: string, beam_diversity_slots: number, candidate_trace_limit: number): string;
150
+
141
151
  /**
142
152
  * Return the crate version string.
143
153
  */
@@ -155,6 +165,7 @@ export interface InitOutput {
155
165
  readonly find_routes_v3: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => [number, number];
156
166
  readonly find_routes_v4: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number) => [number, number];
157
167
  readonly find_routes_v5: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number) => [number, number];
168
+ readonly find_routes_v6: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number) => [number, number];
158
169
  readonly version: () => [number, number];
159
170
  readonly __wbindgen_externrefs: WebAssembly.Table;
160
171
  readonly __wbindgen_malloc: (a: number, b: number) => number;
package/renkin.js CHANGED
@@ -328,6 +328,51 @@ export function find_routes_v5(target, depth, max_routes, beam_width, avoid_elem
328
328
  }
329
329
  }
330
330
 
331
+ /**
332
+ * Same as [`find_routes_v5`], plus bounded candidate-level diagnostics.
333
+ * `candidate_trace_limit` is an explicit collection cap; `0` collects no
334
+ * records while still returning the aggregate `search_diagnostics` block.
335
+ * The diagnostics are read-only and do not affect route selection. A new
336
+ * export preserves the fail-loud compatibility behavior of the earlier
337
+ * versioned WASM functions.
338
+ * @param {string} target
339
+ * @param {number} depth
340
+ * @param {number} max_routes
341
+ * @param {number} beam_width
342
+ * @param {string} avoid_elements
343
+ * @param {string} require_elements
344
+ * @param {string} spectator_bond_policy
345
+ * @param {string} element_accounting_policy
346
+ * @param {string} beam_diversity_policy
347
+ * @param {number} beam_diversity_slots
348
+ * @param {number} candidate_trace_limit
349
+ * @returns {string}
350
+ */
351
+ export function find_routes_v6(target, depth, max_routes, beam_width, avoid_elements, require_elements, spectator_bond_policy, element_accounting_policy, beam_diversity_policy, beam_diversity_slots, candidate_trace_limit) {
352
+ let deferred7_0;
353
+ let deferred7_1;
354
+ try {
355
+ const ptr0 = passStringToWasm0(target, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
356
+ const len0 = WASM_VECTOR_LEN;
357
+ const ptr1 = passStringToWasm0(avoid_elements, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
358
+ const len1 = WASM_VECTOR_LEN;
359
+ const ptr2 = passStringToWasm0(require_elements, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
360
+ const len2 = WASM_VECTOR_LEN;
361
+ const ptr3 = passStringToWasm0(spectator_bond_policy, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
362
+ const len3 = WASM_VECTOR_LEN;
363
+ const ptr4 = passStringToWasm0(element_accounting_policy, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
364
+ const len4 = WASM_VECTOR_LEN;
365
+ const ptr5 = passStringToWasm0(beam_diversity_policy, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
366
+ const len5 = WASM_VECTOR_LEN;
367
+ const ret = wasm.find_routes_v6(ptr0, len0, depth, max_routes, beam_width, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5, beam_diversity_slots, candidate_trace_limit);
368
+ deferred7_0 = ret[0];
369
+ deferred7_1 = ret[1];
370
+ return getStringFromWasm0(ret[0], ret[1]);
371
+ } finally {
372
+ wasm.__wbindgen_free(deferred7_0, deferred7_1, 1);
373
+ }
374
+ }
375
+
331
376
  /**
332
377
  * Return the crate version string.
333
378
  * @returns {string}
package/renkin_bg.wasm CHANGED
Binary file