Every incumbent sells compute that emits numbers. FrankenSim sells the thing the numbers were always a proxy for — justified belief at minimum cost. A result is not a float; it is a claim that arrives with its warrant attached.
“A false certificate is worse than an ordinary wrong answer — a wrong answer wearing a badge.”
The entire type system exists to make that sentence impossible to violate by accident.
Every quantity FrankenSim produces is stained one of three colors. The color is not a comment — it is part of the type, checked at every composition, and impossible to upgrade by wishful thinking.
- verifiedinterval-certified — bounds proven
- validatedanchored to data within a regime
- estimatedbest-effort surrogate — no proof
| A\B | veri | vali | esti |
|---|---|---|---|
| veri | |||
| vali | |||
| esti |
Proven, not promised.
Bounds established by interval-certified numerics — outward-rounded intervals, exact geometric predicates, equilibrated-flux accept tests. The interval is guaranteed to contain the truth. This is the badge you can bet a bridge on.
fs-ivl · Newton–Krawczyk · Prager–Synge
Reality signed off.
Anchored to experimental data inside a stated regime — a Buckingham-π envelope where the measurement was actually taken. Trusted because it matched the world, but only where the world was asked.
fs-regime · benchmark anchors · fidelity ladder
Useful, unproven.
Best-effort: a surrogate, a coarse solve, an ML proposal. Frequently excellent — but it has shown no proof and matched no experiment. It must wear amber until something certifies or validates it.
surrogates · coarse solves · proposers
The composition rule: the weakest link wins.
Color composes like a lattice meet. Feed an estimate into a proof and you get an estimate — never the reverse. There is no operator anywhere in the 54 crates that returns a color stronger than its weakest input. That is how FrankenSim makes laundering an estimate into a certificate a type error rather than a temptation.
Auto-demotion. A validated value silently reverts to estimated the instant it is evaluated outside the regime it was validated in. The badge is bound to its envelope; step past the boundary and the badge falls off by itself.
The color is the headline; the evidence is the dossier. Every result is an Evidence<T> — a value plus four uncertainty slices, a provenance hash, and an adjoint hook, all composed conservatively. Certified<T> is its refinement, reachable only through proof.
Discretization, rounding, and truncation error — the gap between the equation you solved and the one you meant. Bounded by interval and a-posteriori estimators.
Monte-Carlo and sampling variance carried as an anytime-valid confidence sequence, so peeking never inflates the claim.
The uncertainty of the model itself — the physics you left out. The honest, humbling slice most tools pretend does not exist.
How the answer moves as inputs move — supplied for free by the adjoint hook riding inside the value.
A content address of exactly how the value was made. explain(artifact) can always reconstruct the derivation — the result knows its own history.
A gradient rides inside the value, computed through the implicit function theorem — so sensitivity is a property of the answer, not a second pipeline.
01 fs_evidence::{Evidence, ProvenanceHash};02 03 provenance = ProvenanceHash::of_bytes(b"laplacian kernel output");04 05// A value that knows how it was made — and proves its own bound.06 drag = Evidence::exact(12.47, provenance)07 .certified() // interval-certified numerics08 .expect("exact pure-math evidence is certifiable");09 10assert_eq!(drag.value, 12.47);11// drag carries: value + interval bound + provenance + adjoint hook + cancel scopeHow do you get the speed of a guess and the trust of a proof? You let anything propose, and let only mathematics accept.
Machine learning proposes; certified numerics disposes.
A surrogate, a coarse solver, or an untrusted ML model produces a candidate in microseconds. It arrives estimated and unloved. Then a cheap, independent verifier — an equilibrated-flux Prager–Synge a-posteriori accept test — checks whether the candidate actually satisfies the governing equations to tolerance. If it passes, it is stamped verified. If it does not, it is rejected.
Untrusted, fast, plural. ML, surrogates, coarse solves — race them all.
One cheap certified test decides. The verifier is the only thing that must be right.
No accept, no answer. A rejected speculation never leaks out wearing a badge.
Certificates are only as good as the thing that issues them. The Gauntlet is six graded tiers that every merge must survive — and the discipline of certifying the certifiers so the judge is never above the law.
Adjointness, symmetry, conservation, d∘d = 0 — the invariants a correct kernel can never violate.
The build fails if the observed convergence slope drifts more than 0.2 from the theoretical order. Silent accuracy loss is a red build.
Lid-driven cavity, Taylor–Green, NAFEMS — the problems the field already agreed on the answers to.
Relations that must hold even when the exact answer is unknown: refine, rotate, rescale, and check the invariant.
Inject cancellation mid-solve, starve budgets, race speculators — correctness must survive the storm, resources must never leak.
Bit-identical across runs, thread counts, and instruction sets. Any divergence is a diff, not a shrug.
Certifying the certifiers. Every verifier and error estimator is itself tested against manufactured solutions with known bounds — a certificate is trusted only after the thing issuing it has passed its own Gauntlet. The Goodhart guard treats each optimizer endpoint as an adversarial example and re-checks it out of band, because a measure that becomes a target stops being a good measure.
Geometry gluing is not eyeballed. Watertightness is defined as an algebraic fact — the vanishing of an interface cocycle — so a surface either provably seals or names exactly why it cannot.
Watertight ≡ H¹ = 0
Model the surface as a cellular sheaf: each patch carries local data, each shared edge carries a compatibility constraint. Watertightness is precisely the vanishing of the first cohomology — the interface cocycle is zero. No gaps, no double walls, no self-lies. A seal is now a theorem you can check, not a rendering you squint at.
Conflicts classify themselves
When a merge fails, the cocycle tells you which kind of failure it is. A coboundary conflict is a bookkeeping mismatch — mechanically auto-fixable. A harmonic conflict is structural — a genuine topological disagreement no amount of retopo can paper over. The math sorts the fixable from the fundamental for you.
The most epistemically honest thing a system can do is decline — and the most useful thing it can do while declining is explain. When a request is infeasible, FrankenSim does not fail with a stack trace; it returns a structured, ranked set of ways forward.
01{02 "error": "BudgetInfeasible",03 "stage": "flux.lbm",04 "need": { "wall": "5.1h" },05 "have": { "wall": "2h" },06 "fixes": [07 { "action": "relax qoi-rel-error to 4e-2", "est_wall": "1.7h", "est_qoi_impact": "+1.8e-2" },08 { "action": "surrogate screen, certify top-4 only", "est_wall": "1.9h" }09 ]10}“A refusal that teaches is worth ten silent successes.”
A BudgetInfeasible is not a dead end — it is a conversation. It states exactly what the plan needed, exactly what it was given, and a ranked list of concrete fixes, each with an estimated wall-clock cost and its impact on the quantity of interest. An agent swarm reads this and re-plans; a human reads it and understands the trade in seconds. The system refuses to guess, and refuses to hide why.
None of the above is a bolt-on. The three colors, the evidence, the refusals — all of it falls out of ten non-negotiable principles and five things that are never, ever left implicit.
One language, Franken-constellation dependencies only. Unsafe lives only in audited leaf capsules under 300 lines, each behind a safe façade.
Bit-identical across runs, thread counts, and (best-effort) ISAs — via fixed-shape reduction trees, counter-based RNG keyed by logical identity, and compensated summation.
Every operator is differentiable, certifiable, or ideally both. Gradients are checked at the merge gate; error bounds are first-class.
Every operation takes an accuracy / time / memory budget. The Error Ledger and Time Ledger compose them end-to-end and attribute every digit and every second.
Exact discrete de Rham (d∘d = 0), symplectic integrators, power-conserving ports. Preserve the math instead of resolving it away.
Kernels ship their arithmetic-intensity analysis against machine peak. No dense assembly where a matrix-free apply will do.
Cancellation is a numerical primitive. Bounded latency-to-cancel of ≤ 200 µs; speculative races kill their losers mid-solve.
Complexes and cochains, everywhere. Geometry, fields, and operators share a single typed algebra instead of six incompatible schemas.
Content-addressed artifacts, event-sourced operations, and explain(artifact): a result always knows how it was made.
The Five Explicits — units, seeds, budgets, versions, and capabilities — are never implicit, ever. Built for the swarm, compatible with humans.
Dimensional quantities are compile-time typed. A meter never silently becomes a second.
Counter-based RNG keyed by logical identity. Every random draw is reproducible by construction.
Accuracy, time, and memory ceilings travel with every call and compose across the whole plan.
The constellation is locked by hash. The kernels that produced a result are always recoverable.
The Cx context grants exactly what an operation may touch — arena, cancel token, ledger, budget.
You cannot add evidence to a value that was never designed to carry it. Composition, error bounds, provenance, and the three colors are load-bearing structure, not a reporting layer — which is exactly why they cannot be sprinkled onto a stack of six tools that only speak floats to each other.
| Capability | COMSOL | OpenFOAM + FEniCS | SciPy + Dakota | |
|---|---|---|---|---|
| ✓One safe Rust | C / Java GUI | C++ | Python + C/Fortran | |
| ✓Certified<T> | ✕No | ✕No | ✕No | |
| ✓Composed ledger | ✕Per-solver | ✕Manual | ✕None | |
| ✓Content-addressed | Project file | Case dir | ✕Ad hoc | |
| ✓Bit-identical | ✕Best-effort | ✕MPI-dependent | ✕BLAS-dependent | |
| ✓≤ 200 µs, structured | ✕Kill process | ✕Kill process | ✕Kill process | |
| ✓CutFEM on SDF | Mesh required | Mesh required | ✕External | |
| ✓Adjoint-native | ✕Add-on | adjoint solver | autograd (external) | |
| ✓e-processes | ✕No | ✕No | ✕Fixed-sample | |
| ✓Optional | ✕Required | ✕Required | ✕n/a | |
| ✓FrankenScript IR | GUI / Java | dict files | Python | |
| ✓Franken-only | Proprietary | MPI stack | NumPy / SciPy stack |
See how seven acyclic layers turn these epistemics into running Rust — or watch them earn their keep in the three flagship pipelines.