ArghDA M3: Flying-Logic reasoning graph — demote-only verdict propagation#33
Merged
Merged
Conversation
…tion The headline capability of the epic. A new `src/reason/` layer that *wraps* (does not replace) the DAG: the `DagDocument` is embedded verbatim, and on top go a per-node `Verdict`, `And`/`Or` edge juncts, and a memoised, cycle-safe, DEMOTE-ONLY propagation fold. The honesty invariant, enforced end-to-end: a node's effective verdict can only be LOWERED by its dependencies, never manufactured. Lint-clean + no typecheck = `Unknown`, never green. Only `Proven` is green; `Admitted`/`Postulated` are amber. And because the fold is demote-only over `And` import edges, structural amber INFECTS downstream — anything that transitively imports a `postulate` (or `missing-safe`/escape-hatch) module is itself capped, visible before any prover runs. `Or` groups are forgiving (one green route keeps a goal up). Import cycles degrade to `Error` and terminate. Staleness (closure-hash-changed proven → `Unknown`) is applied pre-fold so it propagates. `wired` marks the CRT-root-reachable cone. - `src/reason/mod.rs`: `Junct`, `ReasonNode` (self_verdict/effective/ verdict_evidence/soundness/wired), `ReasonEdge`, `ReasonDocument` (version "0.1", embedded `dag`, `crt_roots`); rank/demote/promote lattice; lint→verdict caps; the propagation fold. - `arghda reason <path> [--check]`: `--check` runs the backend per node for REAL exit-code verdicts (honest); default is structure+lint derived. - Tests: 9 unit (demote, downstream amber infection, Or forgiveness, cycle termination, wiring, clean-but-unchecked→Unknown) + 6 integration. Total suite 81 green; clippy -D warnings, fmt, SPDX clean. - Dogfood caught + fixed a real wiring bug: the CLI's `discover_roots` yields include-root-relative paths, which a stray `include_root.join` double-prefixed, leaving every node unwired. Fixed (match the orphan-module rule's convention) + regression-tested; the earlier tests missed it because they passed absolute paths. - STATE.a2ml records M3 = 100%. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MpYSh6Wy8YMBH2E3qVyT7
hyperpolymath
marked this pull request as ready for review
July 1, 2026 07:53
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
The headline capability of the "Flying Logic for provers/solvers" epic, built on the M1
Backendtrait (merged #32). A newsrc/reason/layer wraps (does not replace) the DAG: theDagDocumentis embedded verbatim, and on top go a per-nodeVerdict,And/Oredge juncts, and a memoised, cycle-safe, demote-only propagation fold.The honesty invariant (enforced end-to-end)
A node's effective verdict can only be lowered by its dependencies, never manufactured:
Unknown, never green. Only a real prover exit-0 makesProven.Provenis green;Admitted/Postulatedare amber.Andimport edges, structural amber infects downstream — anything that transitively imports apostulate(ormissing-safe/ escape-hatch) module is itself capped. Visible before any prover runs.Orgroups are forgiving (one green route keeps a goal up). Import cycles degrade toErrorand terminate. Staleness (closure-hash-changedProven→Unknown) is applied pre-fold so it propagates.wiredmarks the CRT-root-reachable cone.Changes
src/reason/mod.rs:Junct,ReasonNode(self_verdict/effective/verdict_evidence/soundness/wired),ReasonEdge,ReasonDocument(version:"0.1", embeddeddag,crt_roots); the rank/demote/promote lattice; lint→verdict caps; the propagation fold.arghda reason <path> [--check]:--checkruns the backend per node for real exit-code verdicts; default is structure+lint-derived (allunknownon a clean tree, honestly).STATE.a2mlrecords M3 = 100%.Verified (ran, not inferred)
cargo test→ 81 passing, 0 failed (61 lib + 20 integration; +9 reason unit tests covering demote / downstream-amber-infection / Or-forgiveness / cycle-termination / wiring / clean-but-unchecked→Unknown, +6 reason integration).cargo clippy -D warningsclean ·cargo fmt --checkclean ·check-spdx.shOK.arghda reason tests/fixtures/wellformed --checkran realagdatypechecks → the whole coneproven+wired.A bug dogfooding caught (and I fixed)
The first
--checkdogfood showed every nodewired=falsewithcrt_roots=['tests.fixtures.wellformed.All']. The CLI'sdiscover_rootsyields include-root-relative paths, which a strayinclude_root.joindouble-prefixed — so the CRT-root ids never matched the node ids. The unit/integration tests missed it because they passed absolute roots (where the join is a silent no-op). Fixed to match the orphan-module rule's convention (paths go straight tomodule_name_of), plus a regression test that exercises thediscover_rootspath. Re-dogfooded green.Next (all unblocked by the stable trait)
M4 Idris2 · M5 SMT (Z3/CVC5) · M2 Cubical-Agda · M3 follow-on (feed real verdicts + staleness from a workspace
proven/state soreasonlights the cone without--check).Generated by Claude Code