Phase 0 — Foundations
Goal: a working multi-crate workspace with the rules enforced by tooling, CI on three operating systems, a documentation site, verified decisions on the symmetry backend and on every Python dependency that must be replaced, a concrete reuse plan for sci-form code, the binding architecture for the four surfaces, and a golden-data oracle produced by Crystal-Builder.
Exit criteria:
cargo test --workspacepasses (the workspace may be almost empty).- CI is green on Linux, macOS and Windows for Rust, Python, WASM, docs and rules.
npm run docs:buildworks and the site is deployed.- The hello-world slice (Task 0.5.7) works in all four surfaces.
- The reports of Tasks 0.3, 0.4 and 0.10 are written in
docs/algorithms/. - Golden data for the Phase 1 features exist in
tests/golden/.
Nothing is published to crates.io, PyPI or npm in this phase except the name reservations of Task 0.6.5.
Task 0.1 — Repository and workspace skeleton
- [x] 0.1.1 Create the Cargo workspace Root
Cargo.tomlwith[workspace],resolver = "3", and[workspace.package]:version = "0.0.0",edition = "2024",rust-version = "1.89",license,repository,homepage,documentation,authors,keywords,categories. Shared versions in[workspace.dependencies]:nalgebra = { version = "0.35", default-features = false, features = ["std"] },serde(derive),serde_json,thiserror = "2",rayon(optional everywhere),moyo = "0.22",flate2. Create only the crates needed by Phases 0 and 1:xtalforge-core,xtalforge-symmetry,xtalforge-io, the facadextalforge,xtalforge-cli,xtalforge-python,xtalforge-wasm. Each usesversion.workspace = trueand the workspace lints. Acceptance:cargo check --workspaceandcargo test --workspacepass on a clean checkout. - [x] 0.1.2 Toolchain, formatting and lints
rust-toolchain.tomlpinned to stable withrustfmt,clippyand thewasm32-unknown-unknowntarget.rustfmt.toml(max_width = 100,edition = "2024").[workspace.lints]:unsafe_code = "forbid"(binding crates may relax it locally with a comment explaining why),missing_docs = "warn"(raised todenyin Task 8.7.1), clippyunwrap_used,expect_used,panic,indexing_slicingaswarnin library crates andallowin tests. Note:unsafe_codeisdeny, notforbid, so the pyo3 binding crate can relax it locally with a comment as the roadmap allows; it is the only exception. - [x] 0.1.3 Repository hygiene and license
.gitignore(done),.editorconfig,LICENSE,THIRD_PARTY.md(draft exists),deny.tomlforcargo-deny: allowed licenses (MIT, Apache-2.0, BSD-2/3, ISC, Unicode-3.0, Zlib), advisories, bans on duplicate major versions ofnalgebra, and a ban on crates that build C code in default features (ccreachable only through optional features). License:MIT OR Apache-2.0, confirmed by the maintainer on 2026-11-08 and recorded inAGENTS.mdsection 6; the texts areLICENSE-MITandLICENSE-APACHE. - [x] 0.1.4 Facade crate
crates/xtalforgere-exports sub-crates under stable module names (xtalforge::core,::symmetry,::io, later::ff,::analysis, …) and aprelude. Feature flags:parallel(default, enables rayon in all crates),sci-form(quantum methods, Task 4.10),ml(Task 8.4),external(subprocess engines, Task 4.9),mof-data(embedded MOF bundle, Task 6.11.3). Document every feature in the crate docs and indocs/guide/features.md. Note:parallelis wired to optional Rayon in the domain crates; the four heavy features are declared and documented as reserved until their tasks land. - [x] 0.1.5 Contributor guide
docs/guide/contributing.md: the hard rules fromAGENTS.md, the roadmap workflow, how to run every check locally, how to add a format, a command, a calculator, a binding, and how to write an algorithm page.
Task 0.2 — Rule enforcement tooling
- [x] 0.2.1 Harden
scripts/check-rules.shThe script fails on code files over 500 lines and on Rust warning suppression attributes. Add a self-test:scripts/tests/rules/with sample files that must pass (ordinary documentation, an exactly 500-line file) and must fail (a 501-line file,#[allow(dead_code)],#[expect(unused_variables)]), and a runnerscripts/tests/run-rules-selftest.sh. Note (2026-11-08): the language check was retired by the maintainer; its helper, allow list and Spanish fixtures were removed. Rule 2 is now the warning-suppression check. Negative fixtures use the.fixturesuffix so the normal repository scan does not read them; the runner copies them to a temporary tree with their real extensions. - [x] 0.2.2 Git hooks
scripts/install-hooks.shinstalls a pre-commit hook runningcheck-rules.sh,cargo fmt --check, andcargo clippyon changed crates. Documented in the contributor guide; never mandatory for CI. Note: the language-specific commit-msg hook was removed with the language rule. A new commit-msg hook enforces thefeat/refsubject and the task list fromAGENTS.mdsection 2.1; the pre-commit hook rejects commits that span more than one directory. - [x] 0.2.3 Large-data policy and loader Convention: any table with more than ~100 rows, any parameter set copied from a paper, and every database (RCSR, PORMAKE, fragments, fullerene isomers) lives in
data/as JSON, compressed JSON (.json.gz) or a compact binary. Providextalforge_core::data: a loader for embedded compressed blobs (flate2, pure Rust backendminiz_oxide), parsed once withstd::sync::OnceLock, with a SHA-256 checksum test per bundle so a corrupt or edited bundle is caught. Also support lazily loaded external bundles (needed for WASM and for large MOF data, Task 6.11.3). Note: implemented asEmbeddedBundle,JsonBundle,load_external_gzipandload_external_jsoninxtalforge_core::data, with a gzip fixture and checksum, digest, corruption and JSON tests. The policy is indocs/guide/data.md; embedded files live inside the owning crate for packaging, the workspacedata/holds canonical and external bundles. - [x] 0.2.4 CI job for rules A CI job that runs
check-rules.shand the self-test on every push and pull request; it is a required status check. Note: the workflow was removed by maintainer decision (2026-11-08) together with the rest of CI; runscripts/check-rules.shlocally.
Task 0.3 — moyo capability audit (decision gate)
Decision already taken: use moyo if it lets us do everything required. This task produces the evidence and the plan for every gap.
[x] 0.3.1 Requirements matrix Read
Crystal-Builder/xtal/core/{spacegroup,symmetry,subgroups}.py, the point-group part ofcore/molecule.py, andanalysis/kpath.py, and list every symmetry function they use (they rely on gemmi tables and spglib). For each, record the moyo 0.22 API that covers it. Already verified on 2026-11-08 by reading the moyo 0.22.0 sources:Need moyo 0.22 Status Space group detection with tolerance MoyoDataset::new(cell, symprec, angle_tolerance, setting, rotate_basis)public Number, Hall number, H-M symbol, Pearson symbol MoyoDatasetfieldspublic Operations, orbits, Wyckoff letters, site symmetry symbols MoyoDatasetfieldspublic Standardized and primitive standardized cells, transformations, origin shift, rotation std_cell,std_linear,std_origin_shift,std_rotation_matrix,prim_std_*,mapping_std_primpublic Wyckoff tables per Hall number data::iter_wyckoff_positions_from_hall_numberpublic Hall symbol database, settings, centering, arithmetic crystal class data::*public Group identification from operations identifymodulepublic Translationengleiche and klassengleiche subgroups subgroup::enumerate_*public Euclidean normalizer MoyoDataset::euclidean_normalizerpublic Layer groups, magnetic space groups MoyoLayerDataset, magnetic datasetspublic Niggli, Delaunay, Minkowski reduction math::{niggli,delaunay,minkowski}crate-private ( pub(super))Symmetrization / standardization internals symmetrizemoduleprivate, only reachable through the dataset Brillouin zone, k-path — absent Point groups of molecules (non-periodic) — verify; likely absent [x] 0.3.2 Gap decisions For every gap, write the decision: (a) open an upstream issue/PR to make the reductions public; (b) meanwhile port Niggli/Delaunay into
xtalforge-symmetrywith attribution (Task 2.6); (c) implement the Brillouin zone and k-path ourselves (Task 2.10), because Crystal-Builder gets them from ASECell.bandpath; (d) implement molecular point groups ourselves (Task 2.8.3). Verify also: whetherstd_cellpositions are idealized (symmetrized) or only transformed, how partial occupancy must be encoded as atom types, and the behaviour for non-standard input settings. Note:std_cellrefines both lattice and positions to the detected symmetry, not only transforms them; partial occupancy must be encoded as distinct species/atom types because moyo takes atomic numbers, not occupancies;Setting::Spglibreproduces spglib Hall numbers, while origin choice still changes some Wyckoff letters. Details indocs/algorithms/symmetry-backend.md.[x] 0.3.3 Behavioural comparison against spglib With the golden data of Task 0.9 (produced by spglib through Crystal-Builder), run moyo on the whole corpus and compare: space group number, Hall number, Wyckoff letters, number of operations, standardized lattice parameters. Repeat for
symprecin {1e-5, 1e-3, 1e-2, 0.1}. Record every disagreement and its cause in the report. Note:tests/golden/moyo-audit.jsonholds eight structures x four symprec values; number, Hall number and operation count agree withSetting::Spglib. Si Wyckoff letters and four standardized-lattice cases are recorded as known origin/setting differences in the report.[x] 0.3.4 Build, target and size check Confirm that moyo compiles for
wasm32-unknown-unknown(upstream shipsmoyo-wasm, so this is expected) and inside a pyo3 extension; confirm it pulls no native code; measure the compile time and the.wasmsize it adds; check that its dependency versions (nalgebra0.35,serde,strum0.28,itertools) do not duplicate ours. Note: wasm32 and pyo3 builds pass; nalgebra 0.35 is shared; release compile about 45 s; the hello-world WASM was 41 KiB because the unused moyo code is tree-shaken, and the Phase 1 element table brings it to about 190 KiB.[x] 0.3.5 Decision report
docs/algorithms/symmetry-backend.md: verdict (adopt / adopt with gaps / reject), the matrix above with final statuses, the gap plan, links to upstream issues, and the isolation design:xtalforge-symmetryexposes our own types (SpaceGroup,SymOp,SymmetryDataset,WyckoffSite) so moyo never appears in the public API and could be replaced.
Task 0.4 — sci-form reuse audit and port plan
Decision taken: reuse what we need from sci-form, because it is tested and in production. Method: port (copy into our crates with attribution, adapted to our types, the 500-line rule and our error policy) the crystal-related code; depend on the sci-form crate itself, behind the optional sci-form feature, only for heavy quantum chemistry (xTB, EHT, PM3), which is not worth duplicating.
[x] 0.4.1 Inventory with sizes and split plan Verify each row by reading the code, not just the file names; record the public functions, their tests, and how well they match the Crystal-Builder behaviour.
Source in sci-form/srcLines Plan materials/cif.rs708 Port into xtalforge-io::cif; split into tokenizer, loop/table parser, item resolver, writermaterials/cell.rs1048 Contains lattice, supercell, PXRD, symmetry expansion and porosity: split into five modules across core,analysis,symmetrymaterials/space_group_table.rs6750 Do not port; replaced by moyo materials/space_groups.rs273 Do not port; replaced by moyo; keep its tests as extra checks materials/scattering_factors.rs396 Port into xtalforge-analysis::pxrd; coefficients todata/materials/assembly.rs829 Study for the MOF builder (Task 6.12.5); the Crystal-Builder PORMAKE path is the reference materials/sbu.rs,topology_data.rs257 / 734 Study; data to data/if usedmaterials/geometry_opt.rs,variable_cell.rs661 / 501 Port into xtalforge-ff::optimize; splitforcefield/uff.rs,params.rs,atom_typer.rs,minimizer.rs513+ Compare with Crystal-Builder ff/uff/; port the better-tested parts; parameters todata/charges_eeq/*~2800 Port EEQ as an extra charge method; eeqbc_data.rs(1673) becomes a data filesmiles.rs,graph.rs,stereo.rs875 / 627 / 1121 Port into xtalforge-build::smiles; split eachrings/sssr.rs,rings/aromaticity.rs568 / 219 Port into xtalforge-core::rings(make periodic-aware); splitsssr.rsperiodic.rs399 Port into xtalforge-core::elements; data todata/surface/sasa.rs335 Port into xtalforge-analysis(accessible surface helpers)eht/marching_cubes.rs— Not used for periodic isosurfaces: Crystal-Builder deliberately uses marching tetrahedra (Task 5.4.1) kmesh.rs1094 Study for k-point meshes (phonon DOS, Task 4.8.3) fd_gradient.rs86 Port as the finite-difference gradient checker used in tests xtb/,eht/,pm3/,conformer.rs,etkdg.rslarge Not ported; used through the optional sci-formfeature[x] 0.4.2 Quality gate for every ported file Checklist applied to each port and recorded in the pull request: read the file fully; remove
unwrap/expect/panics on input; adapt to our types; translate any non-English text (none found in a first scan on 2026-11-08; accented author names such as Rappé are allowed); split under 500 lines; keep or recreate its tests; add the origin comment and theTHIRD_PARTY.mdentry.[x] 0.4.3 Overlap analysis with Crystal-Builder Where both projects implement the same thing (UFF, CIF, PXRD, porosity, rings, MOF assembly), compare behaviour on the corpus and decide which one is the reference for golden tests. Crystal-Builder is the default reference because xtalforge must reproduce it; sci-form wins only where it is proven more accurate, and the choice is documented.
[x] 0.4.4 Policy for the
sci-formfeature Decide the version requirement (crates.iosci-form = "1", not a path dependency, so published crates build), how its types are converted to ours, how the feature appears in Python wheels and in the CLI, and confirm it stays out of the default WASM build (size). Note: the audit, inventory, quality gate, overlap table and feature policy are recorded indocs/algorithms/sci-form-reuse.md.
Task 0.5 — Binding architecture (Rust, CLI, Python, WASM at parity)
- [x] 0.5.1 Boundary design Every public operation is a function over
serde-serializable data types defined once in Rust. Small values (cell parameters, options, results) cross the boundary as plain data; large objects (Structure,Document, trajectories, grids) are opaque handles with accessor methods, so data is not copied on every call. Arrays of coordinates cross as NumPy arrays (Python) andFloat64Array(WASM). Write the design indocs/api/bindings.md. - [x] 0.5.2 Error mapping Each crate's
Errorexposescode()(stable snake_case string),message(), and optional details (line number, atom indices). Mapped to a Python exception hierarchy rooted atxtalforge.XtalforgeErrorwith one subclass per domain, to JSErrorobjects with acodeproperty, and to CLI exit codes (2 usage, 3 input, 4 computation, 5 limits, 6 engine missing) plus a JSON error object under--json. - [x] 0.5.3 CLI skeleton (
xtalforge-cli)clap(derive) with subcommands grouped by domain. Global flags:--json,--quiet,--threads N,--limits {standard,generous,warn-only}. Reads a path or-for stdin, writes a path or stdout. Subcommands are added in each phase. Mirror the Crystal-Builder CLI verbs where they exist (info,symmetry,convert,bonds,types,formats,modules,engines,run,capabilities,mcp) so its users find the same names; record the mapping in the migration guide (Task 8.7.4). - [x] 0.5.4 Python skeleton (
xtalforge-python) pyo3 + maturin, abi3 wheels with minimum Python 3.9, no Python runtime dependencies except NumPy. Type stubs (.pyi) checked bymypy --strictin CI,py.typed. Module layout mirrors the Rust facade (xtalforge.core,xtalforge.symmetry,xtalforge.io, …). Optional pure-Python helpers converting to and from ASEAtomsand pymatgenStructurewhen those packages are installed (never required). Note: interop helpers are deferred to Phase 1, when the publicStructuretype they convert exists; the pyo3 module, stubs,py.typed, wheel and pytest suite are in place. - [x] 0.5.5 WASM skeleton (
xtalforge-wasm) wasm-bindgen withwasm-packbuilds forweb,nodejsandbundler; generated TypeScript definitions; no threads by default; an optional threaded build withwasm-bindgen-rayondocumented;console_error_panic_hookonly in debug builds. Size budget recorded and checked in CI. Note: web, nodejs and bundler builds work; the panic hook is debug-only; the threaded build is documented as a reserved opt-in; the 200 KiB budget andscripts/check-wasm-size.share in place. - [x] 0.5.6 Parity matrix and shared test vectors
docs/api/parity.mdlists every public capability with four columns and a status.scripts/check-parity.shcompares the matrix with the actual exported symbols (rustdoc JSON, the Python module'sdir(), the generated.d.ts,xtalforge --help) and fails on undocumented gaps. Shared JSON test vectors intests/vectors/<capability>/*.json(input, options, expected output, tolerance) are executed by Rust tests,pytest, the WASM node tests and a CLI test runner; all four must agree. - [x] 0.5.7 Hello-world slice Implement
version()andcell_volume(a, b, c, alpha, beta, gamma)end to end in the four surfaces, with test vectors, API pages and parity entries, to prove the whole pipeline (build, test, docs, CI) before real features land.
Task 0.6 — Versioning, release automation and agent memory
- [x] 0.6.1
scripts/sync-version.shReads[workspace.package].version; updates the=X.Y.Zpins between internal crates,docs/package.jsonand README install snippets; verifies that the maturin metadata and the generatedpackage.jsonreport the same version.--checkmode only reports and exits non-zero on drift. Kept under 500 lines; covered by a self-test. - [x] 0.6.2 Changelog policy
CHANGELOG.mdfollows Keep a Changelog with sections Added, Changed, Deprecated, Removed, Fixed, Security, andBreakingduring0.0.x.docs/changelog.mdincludes the root file with VitePress<!--@include: ../CHANGELOG.md-->so there is a single source. Every pull request adds anUnreleasedentry. - [x] 0.6.3 Release workflow Triggered by a tag
vX.Y.Z: checks version sync and changelog; runs the full test matrix; publishes crates in dependency order (cargo publishwith retries for index propagation); builds and uploads wheels (maturin-action, trusted publishing); publishes the npm package (provenance enabled); creates the GitHub release with notes from the changelog; deploys the docs. Aworkflow_dispatchdry-run mode must succeed beforev0.0.1. Note: releasedv0.0.1on 2026-11-09. The maintainer removed the test matrix and Trusted Publishing from the workflow (tests run in the local gate; PyPI usesPYPI_API_TOKENwith twine), and the crates publisher now waits on the crates.io 429 retry time.workflow_dispatchbuilds the CLIs and runs the version check without publishing. - [x] 0.6.4 Agent memory discipline CI check: the version in
AGENTS.mdsection 6 equals the workspace version on tagged commits. Pull request template with the checklist: roadmap ticked, parity matrix, docs, changelog, rules script. - [x] 0.6.5 Name reservation Reserve
xtalforgeon crates.io (publish0.0.0placeholder only if the maintainer agrees), PyPI and npm (xtalforge-wasm, optionally the@xtalforgescope). All were free on 2026-11-08. Note: the0.0.1publication on 2026-11-09 reservedxtalforgeand its eleven companion crates on crates.io,xtalforgeon PyPI andxtalforge-wasmon npm. No placeholder was needed. The@xtalforgenpm scope was not claimed.
Task 0.7 — Documentation site (VitePress)
- [x] 0.7.1 Site scaffold
docs/already contains the VitePress configuration and the section stubs (Guide, API, Algorithms, Demos, Roadmap, Changelog). Runnpm install, commitpackage-lock.json, verifynpm run docs:devanddocs:build, enable local search, edit-on-GitHub links, last-updated dates, and the repository link once the remote exists. Note: lockfile committed, search/edit/last-updated/repository links enabled,npm run docs:buildpasses. - [x] 0.7.2 API reference generation One page per domain, each showing the same operation in the four surfaces with VitePress code groups (tabs). Sources: rustdoc comments (summaries extracted from
cargo +nightly rustdoc -- --output-format json, or hand-written pages checked against it), the.pyistubs, the generated.d.ts, andxtalforge <cmd> --helpcaptured by a script. A CI step fails when a public item has no page. Note: hand-written pages underdocs/api/;scripts/check-api-docs.shchecks every public core item andscripts/check-parity.shchecks every matrix capability. - [x] 0.7.3 Algorithms section Template for every algorithm page: problem, formulation (KaTeX math via
markdown-it-mathjax3), references, pseudocode, complexity, numerical caveats, validation data and tolerances, differences from Crystal-Builder. Note: the template is documented indocs/algorithms/index.md; the Phase 0 pages are the moyo, sci-form, dependency, golden-data and validation reports. - [x] 0.7.4 Demos section Interactive demos importing the WASM package built from the workspace (Vite alias in dev, the npm package in production builds). A small shared demo component library (file input, structure summary table, a minimal 3D preview with plain WebGL or three.js, plot canvas). Demos must work offline after load. Note:
docs/demos/cell-volume.mdruns the WASM package in the browser; the VitePress build bundles the.wasmasset and the page works offline. - [x] 0.7.5 Deployment GitHub Pages workflow building on push to
mainand on tags; versioned documentation per MINOR release fromv0.1.0; link checking. Note: thedocsjob of.github/workflows/release.ymlbuilds and deploys to Pages on a version tag, after the package publication and reusing the built WASM artifact. The maintainer changed the policy to tag-only deployment (nomaindeployment), and thegithub-pagesenvironment must allow thev*tag pattern.v0.0.1deployed successfully on 2026-11-09; versioned docs remain for the first MINOR release.
Task 0.8 — Continuous integration
- [ ] 0.8.1 Rust matrix Linux, macOS (arm64), Windows; stable and MSRV 1.89;
fmt,clippy -D warnings, tests with and without default features, doc tests,cargo-deny,cargo hack --each-featureon the facade crate. - [ ] 0.8.2 Python CI maturin wheel build,
pyteston Python 3.9 and the latest release,mypy --stricton the stubs, shared test vectors. - [ ] 0.8.3 WASM CI
wasm-pack test --nodeand a headless browser run;.wasmsize budget check; TypeScript type check of the generated definitions. - [ ] 0.8.4 Docs CI VitePress build, dead-link check, rules script, parity script. Note: the CI workflow was removed by maintainer decision (2026-11-08). The tag deployment lives in
release.ymland reuses thewasmartifact. - [ ] 0.8.5 Speed
Swatinem/rust-cache, sharing build artifacts between jobs, path filters so documentation-only changes skip the heavy jobs; target under 15 minutes. Note: the CI workflow was removed by maintainer decision (2026-11-08);release.ymlkeeps the Rust caches and builds the CLI/package/docs jobs in parallel where possible. This task stays open because no CI matrix runs.
Task 0.9 — Golden-data oracle from Crystal-Builder
Crystal-Builder is the behavioural reference; its sample structures and test data become our oracle.
- [x] 0.9.1 Corpus selection and licensing Copy into
tests/corpus/a curated set fromCrystal-Builder/resources/samples/:simple/(small inorganic cells),cod/(21 MOF CIFs from the COD, CC0: Al-soc-MOF-1, Co-BDP, HKUST-1, MIL-100, MIL-101, MIL-53, MIL-88B, MOF-5, MOF-74, MOF-808, Mn-BTT, NU-1000, PCN-222, PCN-224, SIFSIX-1-Cu, SIFSIX-3-Ni, UiO-66, UiO-67, ZIF-8, cubic-EuHOTP, pbz-MOF-1),prepared/,polymer/, and the top-level CIFs. Read itsPROVENANCE.mdfor every file and copy the provenance and license into ourtests/corpus/PROVENANCE.md; skip any file whose license does not allow redistribution. Add hand-made edge cases: partial occupancy, disorder groups, special positions, a triclinic cell, a hexagonal setting, malformed CIFs. - [x] 0.9.2 Golden-data generator
scripts/golden/(Python, each file under 500 lines): runs in a virtual environment with Crystal-Builder installed (pip install -e Crystal-Builder[dev], plus the extras each feature needs:ase,buildfor RDKit, phonopy where used). For each corpus entry and each feature it dumps JSON: cell parameters, P1 atoms, supercells, slabs, bonds, rings, functional groups, space group dataset, Wyckoff letters, k-path, PXRD pattern, UFF energy/forces/stress, charges, porosity numbers, topology. Each file records the Crystal-Builder commit hash, the versions of numpy, scipy, gemmi and spglib, and the options used. Output goes totests/golden/<feature>/<structure>.json; features are generated phase by phase, Phase 1 first. - [x] 0.9.3 Reuse of Crystal-Builder test data Inventory
Crystal-Builder/tests/data/(blocks,dftbrecorded outputs,eqeq,rcsr,systre,zeopp_reference.json, rod.xyzfiles,pormake_upstream.json) and map each item to the subtask that will use it. Copy only what is used, with provenance. - [x] 0.9.4 Comparison library Rust test helpers in a
xtalforge-testkitdev crate: float comparison with absolute and relative tolerances; atom-set equality up to lattice translation and permutation; bond-set equality; pattern comparison for PXRD (peak positions and normalized intensities); readable diff output. Tolerances per feature recorded indocs/algorithms/validation.md. - [x] 0.9.5 Regeneration policy Golden data is regenerated only deliberately, with the reason in the commit message, and reviewed as a diff. CI never regenerates it.
Task 0.10 — Dependency replacement map
Crystal-Builder leans on Python libraries. Each needs a pure Rust replacement or an explicit decision before its phase starts. Write docs/algorithms/dependency-map.md with one section per dependency.
[x] 0.10.1 Survey the usages
grepCrystal-Builder for imports of gemmi, spglib, scipy, ase, phonopy, rdkit, rietx, matplotlib, and list every function used, in which module, and for what.[x] 0.10.2 Decide each replacement Starting proposal to confirm or change:
Python dependency Used for Rust plan gemmi CIF parsing, space group tables own CIF parser (sci-form port), moyo tables spglib symmetry detection, standardization moyo numpy arrays nalgebra, plainVec<[f64; 3]>,ndarrayonly if neededscipy cKDTreeneighbor search own cell list; kiddok-d tree if neededscipy optimizeL-BFGS, minimizers, least squares own L-BFGS/FIRE (sci-form port); Levenberg-Marquardt for Phase 7 scipy spatial.VoronoiBrillouin zone own Wigner-Seitz construction (half-space intersection) scipy sparse,ndimagegrids, labelling own periodic flood fill / union-find ASE band paths, reading foreign trajectories, ML calculators own k-path (Task 2.10); own readers; ML via Task 8.4 phonopy displacements, force constants, phonon DOS, thermal properties own implementation (Task 4.8), validated against phonopy outputs RDKit SMILES, embedding, sketcher chemistry sci-form SMILES port; embedding via the sci-formfeaturerietx peaks, indexing, Pawley, Rietveld study then port natively (Phase 7) matplotlib colormaps (sampled), plots colormap tables as data; plots left to consumers [x] 0.10.3 License check of every algorithm source For every replacement that ports code (moyo internals, rietx, phonopy algorithms, PORMAKE), record the license and the attribution requirements in
THIRD_PARTY.mdbefore porting. Reimplementing from papers is preferred where the license is unclear.