-
Notifications
You must be signed in to change notification settings - Fork 0
JEOD Invariant Workflow
CLAUDE.md carries the one-paragraph rule: every JEOD invariant we encounter
goes in docs/JEOD_invariants.md, every enforcement site carries a
// JEOD_INV: XX.YY source tag, and tests/invariant_coverage.rs enforces
the bidirectional consistency. This page documents the full process,
including the negative-test convention and the section conventions.
-
Catalog (
docs/JEOD_invariants.md): one row per invariant with aSection.TagID (e.g.,GV.04), description, JEOD enforcement mechanism, and our status (enforced,partial,deferred,n/a,structural). -
Source tags: every enforcement site in our Rust code has a comment like
// JEOD_INV: GV.04 — degree <= source degree. The tag text should accurately describe what the code does and note any divergence from JEOD. -
CI coverage (
tests/invariant_coverage.rs, at the workspace root): bidirectional test — everyenforced/partial/structuralinvariant in the catalog must have at least one source tag, and every source tag must reference a catalog entry. -
Negative-test coverage (same file,
enforced_rows_have_negative_tests_or_warn): everyenforcedcatalog row should have a#[should_panic(expected = "…")]test that drives the misconfiguration and pins the panic message. Recognised by a// JEOD_INV: XX.YYtag inside the test function or in the few lines immediately above the#[should_panic]attribute. The bidirectional tag-↔-catalog check only proves the panic site exists — the negative test proves it actually fires; without it a future refactor could neuter anassert!to a silentif … returnand CI would stay green. The gate is informational (warning report, exit 0) in this round and is promoted to a hard assertion in a follow-up PR once the catalog body of negative tests lands per section (DB / RF / IG / GV / TM / …). To add one: write#[should_panic(expected = "<substring>")]near the enforcement site, drive the failure with a minimal misconfiguration, and tag the test with// JEOD_INV: XX.YY.
When reading JEOD source and you find a MessageHandler::fail(),
MessageHandler::error(), assert, or structural guarantee that is not
already in the catalog:
-
Add a row to
docs/JEOD_invariants.mdwith the next available tag in the appropriate section (e.g.,DB.28,GV.19). -
Add
// JEOD_INV: XX.YYat our enforcement site (or notedeferred/n/ain the catalog if we don't enforce it yet). -
Run
cargo test --test invariant_coverageto verify consistency.
If our code enforces a JEOD invariant but the enforcement site lacks a
// JEOD_INV tag, add the tag. If the invariant isn't in the catalog yet,
add it there too.
Tags must describe what the code actually does, not what JEOD does. When
our implementation diverges from JEOD (e.g., we divide by mass at runtime
instead of precomputing inverse_mass), the tag should note the divergence.
Never copy JEOD's description verbatim if our code works differently.