From d73f8da92a1f5bb6fa0010798e66d8ad1180de0d Mon Sep 17 00:00:00 2001 From: Doll Date: Tue, 28 Jul 2026 23:08:47 -0500 Subject: [PATCH 1/2] =?UTF-8?q?forge:=20check=20=E2=80=94=20weave=20the=20?= =?UTF-8?q?ADTs=20reachable=20through=20woven=20spec=20fns=20(closes=20#92?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No file declaring more than one ADT had ever certified. The per-item ADT weave seeded `reachable_adt_deps` with `[item] + fn_deps`, while every arm of `item_subprogram` weaves `item_spec_items` as well — the referrer set was a strict subset of what the sub-program contained, so an ADT reachable only through a woven spec fn was omitted from the emitted Verus and the run failed closed on an unresolvable type. Three surfaces of the one defect: 1. a checked `struct`/`enum`: `collect_item_adt_refs` is inert on an ADT decl (field types are followed by the type-graph fixed point instead), so `adt_deps` came out empty for EVERY ADT item while the arm wove the file's whole `spec_items`. A spec fn naming a second ADT dangled -> L0 on E0425 -> `project assurance: FAILED`. 2. a checked `fn` naming no ADT that a woven spec fn takes: the solver-vacuity harness failed to elaborate, which `vacuity_solver::interpret_summary` refuses as undetermined -> a `ForgeError` aborting the run. 3. a checked `spec fn`: already correct, which is why the single-ADT corpus never exercised the gap. A single ADT masks all of it: the only ADT is the checked item, which the ADT arm pushes itself, so the decl is present by construction. Same under-approximated-closure class as the `reachable_spec_fn_deps` body-only omission recorded in proof-backends.md's increment-(i) note. The seed now extends with `item_spec_items` for every item kind (replaced, not extended, for `Item::SpecFn` — #71's distinct per-spec-fn sub-program), and the ADT arm drops the checked item from `adt_deps` before pushing it so a spec fn naming that ADT cannot produce a duplicate definition (E0428). DESIGN SOURCES THIS ITERATION: - .design/forge/check.md (REQ-1 per-item pipeline, REQ-5 L3 iff 0 errors) - .design/basis/09-option-result.md, .design/basis/11-ergonomics.md, .design/basis/12-mutual-recursion.md, .design/lower/boundary-composition.md, .design/verified/proof-backends.md (the six docs routing check.rs) - thermite-design.md §5.3 (the isolated per-item sub-program), §6 (the ladder) - reference: conformance/sum.th, conformance/composition/cases.json REQ STATUS: - REQ-1 (pipeline orchestration) SHIPPED — unchanged; this corrects its input. - REQ-5 (level determination) SHIPPED — unchanged; L3 iff verus reports 0 errors. The ADT items were never un-provable, only un-emitted. R-HONEST-4: the correction is recorded as an Amendment in .design/forge/check.md. VERIFICATION: cargo test -p forge: 807 passed, 2 failed — both pre-existing and environmental (strat_differential needs the Lean spine built locally; it fails identically on unmodified check.rs and does not reference it). new pin forge/tests/divergence_multi_adt_subprogram.rs: 4 passed. Confirmed a real pin — 3 of the 4 FAIL on pre-fix code (two assertion failures + the ForgeError abort); the 4th is the R-CHAR-3 oracle (a spare decl cannot change what is provable about its siblings, so every shared item's level must equal the single-ADT twin's) and holds on both sides by construction. conformance: multi_adt.th — pre-fix `Role`/`Action` both L0/E0425 and project FAILED; post-fix all five items L3, matching the hand-derived multi_adt.cert.json oracle subset. cargo clippy -p forge --all-targets -- -D warnings: PASS cargo fmt --all --check: PASS doc-drift: PASS (six check.rs-governing docs re-pinned) req-status / req-registry / control-plane: PASS verus 0.2026.05.24.ecee80a (the ci.yml pin) Closes #92 Co-Authored-By: Claude Opus 5 (1M context) --- .design/basis/09-option-result.md | 2 +- .design/basis/11-ergonomics.md | 2 +- .design/basis/12-mutual-recursion.md | 2 +- .design/forge/check.md | 25 +- .design/lower/boundary-composition.md | 2 +- .design/verified/proof-backends.md | 2 +- conformance/multi_adt.cert.json | 11 + conformance/multi_adt.th | 25 ++ forge/src/check.rs | 48 ++- .../tests/divergence_multi_adt_subprogram.rs | 274 ++++++++++++++++++ 10 files changed, 378 insertions(+), 15 deletions(-) create mode 100644 conformance/multi_adt.cert.json create mode 100644 conformance/multi_adt.th create mode 100644 forge/tests/divergence_multi_adt_subprogram.rs diff --git a/.design/basis/09-option-result.md b/.design/basis/09-option-result.md index f14a151e0..bee6b123d 100644 --- a/.design/basis/09-option-result.md +++ b/.design/basis/09-option-result.md @@ -2,7 +2,7 @@