gugen (具現)
English | 日本語
Explainable materials synthesis and process planning, in Rust.
Given a target inorganic composition (and optionally a target structure), gugen returns candidate precursor sets, balanced reactions, and solid-state process plans — each with its evidence, assumptions, and unresolved conditions kept explicit and machine-readable. It does not predict experimental success.
Status: v0.8.0 pending publication (bug-check-and-refactoring sweep; one breaking validation-bypass fix -- see CHANGELOG.md). crates.io / docs.rs. v0.8.0 closes a validation-bypass gap in
SolidThermodynamicEntry(private fields, matching theBalancedReaction/ReactionSpeciesprecedent), fixes a grammar-guard bug in the experimentalHydroxideToOxideGrammar, and movesprocess.rs's condition-conflict-resolution code into its own file (no public API change). SeeCHANGELOG.mdfor the full breaking-change list and migration notes.
Try it in your browser
Explore real, cited inorganic synthesis examples in the gugen Playground.
It runs entirely in your browser via WebAssembly. No account, server, external API, or uploaded data is required. The playground shows accepted plans, rejected candidates, and unresolved conditions; it does not predict experimental success.
What gugen does and doesn't guarantee
gugen's output is a set of candidate plans, not a validated SOP. It does
not guarantee: experimental success, target-phase formation, a single
phase product, reaction completion at a stated temperature, high yield,
safe executability, patentability, or industrial scalability. A ranking
score is an ordinal, explainable measure for sorting candidates against
each other — never a success probability. See
docs/scientific_scope.md for the full list
of what's in and out of scope for v0.1, and
docs/evidence_model.md for how evidence,
assumptions, and unresolved conditions are kept separate.
What works today
Reaction balancing
Exact-rational Gauss-Jordan elimination over the element × species
matrix — never floating-point approximation (see
docs/architecture.md). The full runnable source
for this example is examples/balance_batio3.rs.
use ;
let ba = new?;
let ti = new?;
let o = new?;
let bao = new?;
let tio2 = new?;
let batio3 = new?;
let reactions = balance?;
Output (cargo run --example balance_batio3):
1 Ba:1, O:1 + 1 O:2, Ti:1 -> 1 Ba:1, O:3, Ti:1
Bounded precursor-set search
search_precursor_sets runs a deterministic, budget-bounded search over
a precursor catalog, returning both accepted precursor sets (each with
its balanced reaction) and every rejected candidate with a reason code —
never just the winners. See src/precursor.rs's
tests for worked examples.
Multi-step synthesis routes
search_two_step_routes chains two search_precursor_sets calls into a
stoichiometrically connected route (precursors → intermediate → target)
for targets a single step can't reach within budget. It is a
primitive, not an accuracy improvement: intermediate_candidates is
always caller-supplied (gugen never proposes or fetches them itself),
every route is validated for connectivity only (each stage's reactants
are explained by a base precursor or an earlier stage's product) — not
for whether it matches any real synthesis procedure — and Planner
never calls this automatically. Measured against a real 408-row
literature holdout, of the 294 targets confirmed genuinely unreachable
in one step this recovered 12 net-new (4.08%); see
docs/phase31_pr2_two_step_arity_recall.md
for the full methodology and honest limitations. The full runnable
source is in search_two_step_routes's own
rustdoc example.
use ;
// Target needs 5 elements at once -- more than a tight one-step budget
// (max_precursors_per_plan = 4) allows, so it's only reachable by first
// combining three of them into an intermediate.
let target = new?;
let base = vec!;
let intermediate = new?;
let budget = SearchBudget ;
let routes = search_two_step_routes?;
// routes[0].stages() has exactly 2 stages; the last stage's products
// include `target`.
An optional, separate experimental_grammar feature (default off) adds
a small set of hand-written decomposition grammars
(src/transformation_grammar.rs) that propose candidate intermediate
compositions from stoichiometry alone (e.g. MCO3 -> MO + CO2). It is
explicitly experimental: measured against the same holdout, it did not
recover any target beyond what a plain corpus-frequency prior already
reaches (see
docs/phase31_pr3_transformation_grammar_audit.md),
its API may change in any 0.x release, and it is not wired into
Planner.
The gugen Playground does not currently visualize multi-step routes — only single-step plans.
Solid-state process templates
conventional_solid_state_template turns an accepted precursor set into a
weigh/mix/grind/form/heat/cool/characterize step sequence, each step marked
Required/Recommended/Optional/Unresolved. It does not apply the same
template to every material: a route that releases a byproduct (e.g. a
carbonate route releasing CO₂) gets an extra calcination step that an
oxide-only route to the same target does not. Temperature, duration, ramp
rate, and atmosphere are left unresolved (None) rather than guessed —
this worked example uses Planner::offline_minimal, which wires in no
provider at all. A caller can configure a ProcessEvidenceProvider (e.g.
InMemoryLiteratureConditionProvider) to resolve some of these fields from
cited literature; see docs/integration.md.
Plan scoring and confidence
score_plan computes a PlanScoreBreakdown and a ConfidenceAssessment
per plan — never a single collapsed number. Missing thermodynamic data is
excluded from the score rather than treated as failure; a plan with no
evidence scores lower than one with evidence. total_ranking_score is an
ordinal, explainable score for comparing candidates, never a success
probability — thermodynamic_support stays None regardless of whether a
ThermodynamicProvider is configured (a resolved reaction energy becomes
evidence, never a numeric score — AGENTS.md §4.3), so total_ranking_score
is honestly driven by only one real signal (process_simplicity, now
computed per-route-family since Phase 12 added a second route family — see
below); see
PlanScoreBreakdown's doc comment for the full breakdown
of what's currently constant versus load-bearing. Every plan currently sets manual_review_required: true, since gugen has no hazard/safety data source wired in yet.
Commercial Precursor Catalog
Optional, off-by-default commercial_catalog feature: matches an existing
SynthesisPlan's precursors against a caller-supplied catalog of
commercial offers (price, purity, package size, supplier), as a
post-planning stage that never touches the plan's score, confidence,
reaction, or process steps. Matches on a canonical, scale-invariant
composition ratio via exact rational arithmetic (Fe2O3 matches Fe4O6;
hydrate vs. anhydrous and different compounds stay distinct; no alias or
substitute-precursor inference); CSV/JSON catalog import with a
structured accepted/rejected load report; stoichiometric quantity
calculation, purity-adjusted purchase mass, package-count rounding,
currency-safe checked-arithmetic cost totals; a bounded search over
complete purchasing combinations. See
docs/commercial_precursor_catalog.md
for the full CSV/JSON schema, exact-match policy, and quantity-calculation
rules, and examples/commercial_catalog_assessment.rs for a runnable
worked example (cargo run --example commercial_catalog_assessment --features commercial_catalog). No real catalog data ships with gugen;
gugen does not certify commercial data (prices/availability are supplied
estimates, not guarantees).
CLI
$ gugen balance reaction.json
reaction.json:
Output (serde_json::to_string_pretty, one field per line):
The gugen binary itself requires the serde and clap features
([[bin]] in Cargo.toml) — cargo install gugen with no --features
flag builds no binary at all (default features are []), it only
installs the library. To get the CLI:
cargo install gugen --features serde,clap
or, from a checkout, cargo build --features serde,clap --bin gugen.
Subcommands (AGENTS.md §19):
gugen balance reaction.json
gugen plan target.json --catalog precursors.json [--output report.json] [--format json|markdown]
gugen explain report.json --plan plan-001
gugen validate-target target.json
gugen doctor
gugen batch input.json --catalog precursors.json [--output out.json]
target.json/precursors.json/input.json reuse gugen's own public JSON
shapes (TargetSpecification, a JSON array of PrecursorCandidate, and a
JSON array of TargetSpecification respectively) rather than a separate
CLI-specific format. gugen batch plans every target independently — one
target's failure doesn't abort the rest.
commercial-plan (Commercial Precursor Catalog, matching a target's
plans against a commercial-offers catalog for price/purity/lead-time)
additionally needs the commercial_catalog feature:
cargo install gugen --features serde,clap,commercial_catalog
gugen commercial-plan target.json --catalog precursors.json \
--commercial-catalog offers.csv \
[--commercial-catalog-column-map column_map.json] \
[--ranking-policy balanced|cost-first|lead-time-first|purity-first|minimum-unresolved-data|pareto] \
[--min-purity 0.99] [--max-lead-time-days 30] [--max-total-cost 50000 --currency USD] \
[--format json|markdown|csv]
Without commercial_catalog enabled, commercial-plan doesn't exist as
a subcommand at all (not a runtime error — the binary is built without
it). See docs/commercial_precursor_catalog.md for the full option
list and --commercial-catalog-column-map's declarative CSV
column-name mapping for real-world supplier exports with non-standard
headers.
Worked example: a full synthesis plan
$ gugen plan target.json --catalog precursors.json --format markdown
target.json (BaTiO3) and precursors.json (the standard BaCO3 + TiO2
solid-state route to it):
Output (real, unedited gugen plan output; this is also
tests/fixtures/batio3_report.md's golden snapshot, minus its score-
breakdown/confidence/assumptions/unresolved-conditions sections and
rejected-candidate section for length — all are in the full file):
**Target:** Ba:1, O:3, Ti:1
**Applicability:** PartiallyInDomain -- formula-only target, no structure provided (AGENTS.md §16's own example for this level)
- ----
- --------
- --
- -
- ----
- -----
- -
- -
Note the two plans: since Phase 12, every accepted precursor set is offered under every applicable route family (currently 2), not just one — gugen has no route-suitability classifier to prefer one for a given target, so both are always shown, ranked independently (AGENTS.md §13). Note also the calcination/regrind step in the first plan: it's there because the balanced reaction releases CO2 (see the Evidence entry), not because every plan gets the same template — a carbonate-free route to the same target wouldn't have it, and the mechanochemical plan's own post-milling anneal is conditioned the same way. The full report also carries a per-plan score breakdown, confidence assessment (five independent sub-scores, not one blended number), assumptions list, and every rejected single-precursor candidate with its reason code.
Ecosystem
chematic-crystal
periodic structure foundation
│
┌────────────┴────────────┐
│ │
mikiwame gugen
explainable diagnostics synthesis/process planning
gugen depends on chematic-crystal for periodic structure types once
that crate is published (not yet, as of 2026-08-14 — see
docs/integration.md); until then it builds
against a minimal trait boundary it owns itself. mikiwame is published
and integrated as an optional, off-by-default mikiwame feature
(cargo build --features mikiwame) that maps its structural diagnostics
onto gugen's own warnings/confidence — not yet wired into Planner::plan,
since that still needs chematic-crystal-shaped structure data gugen
doesn't have. gugen never depends on renkin (molecular retrosynthesis)
and does not reuse its algorithms — gugen is a materials-domain sibling,
not a port.
Development
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-features
cargo test --workspace --no-default-features
cargo test --no-default-features --features mikiwame
cargo test --no-default-features --features commercial_catalog
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps
cargo build --features serde,clap --bin gugen
cargo check --target wasm32-unknown-unknown
cargo check --target wasm32-unknown-unknown --features mikiwame
cargo audit
Architecture and design decisions: docs/.
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
日本語版: README_ja.md