Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Fidelity Index

Test depth per invariant. All phases (0–5) are implemented, plus post-implementation improvements (anchor resolution, build provenance, .git/ materialization, proptest, conflict detection, continuous dogfooding, INV-15 artifact format).

Test counts: 344 (default), 351 (with fjall-backend). 92% line coverage workspace-wide. fmt clean, clippy clean.

Invariants

INVDescriptionDepthNotes
INV-01Status changed by appending, not modifyingMOCKelench-store: store_blob/tree/claim idempotent (memory + fjall)
INV-02Prior status remains visibleMOCKelench-claim: compute_status reads entire log
INV-03Claim identity stable across status changesMOCKelench-claim: ClaimId immutable
INV-04Status computed by folding, not storedMOCKelench-claim: compute_status pure fn
INV-05origin.kind required and structurally distinctMOCKelench-claim: type system enforces
INV-06Agents cannot emit harness-observedMOCKelench-claim: validate_claim cross-checks signer
INV-07Only harness emits verificationMOCKelench-claim: validate_claim cross-checks signer
INV-08Predicate requires executable expressionMOCKelench-claim: validate_claim calls elench-predicate::parse
INV-09Annotations never read by policyMOCKelench-gate: evaluate filters on form=predicate
INV-10dependsOn populated with premisesREMOVEDDowngraded to guideline; empty dependsOn is a warning, not a rejection
INV-11Failure recorded only when status changedMOCKelench-claim: validate_claim checks target status in log
INV-12Agents cannot emit residue-acceptanceMOCKelench-claim: validate_claim cross-checks signer
INV-13Gate evaluable without build capabilityMOCKelench-gate: evaluate takes &[Claim], no build
INV-14Artifact acceptability is live evaluationMOCKelench-gate: evaluate called on demand, no cache
INV-15Artifact carries (tree, policy), not verdictMOCKelench-gate: Artifact struct with version field; schema/artifact.schema.json; 6 tests
INV-16unevaluated is first-class statusMOCKelench-claim: ClaimStatus::Unevaluated
INV-17Policies permit bounded unevaluated residueMOCKelench-gate: condition 2, residue-acceptance
INV-18elench owns content-addressed storeMOCKelench-store: no git dependency, owns storage; both backends pure-Rust
INV-19Git projection is read-onlyMOCKelench-projection: synthesize takes &dyn StoreBackend, no writes
INV-20Git synthesis is deterministic (BC4)PROPERTYelench-projection: proptest_inv_20_synthesis_deterministic + order_independent
INV-21Git projection produces no side effectsMOCKelench-projection: scenario_inv19_projection_does_not_write_to_store
INV-22Agent claims and provenance share DSSE/in-totoMOCKelench-envelope: sign/verify, PREDICATE_TYPE_AGENT, Ed25519 (A1)
INV-23Predicate expressions executable/deterministic/sandboxableMOCKelench-predicate: 4 primitives, not Turing-complete
INV-24AGENTS.md rules enforced by validatorMOCKelench-claim: validate_claim (Phase 0)
INV-25Content addressing (SHA-256)PROPERTYelench-claim: ClaimId::from_content; elench-store: Oid::from_blob_data/from_tree_entries + deserialize_tree_bytes round-trip + FjallStore::read_tree (feature tier)
INV-26Store is sole source of truthMOCKelench-store: all views derive from store; selectable at runtime via `–store memory
INV-27Git projection is lossy, not authoritativeMOCKelench-projection: scenario_inv27_projection_is_lossy
INV-28Claim OID is content hashPROPERTYelench-claim: ClaimId::from_content (SHA-256 of canonical JSON); proptest_inv_28
INV-29dependsOn acyclicPROPERTYelench-claim: validate_claim DFS cycle detection; proptest_inv_29

28 active invariants (24 original minus INV-10 removed, plus INV-25/26/27/28/29 added). 28 ENFORCED (was 27 + INV-15 future; INV-15 now MOCK with 6 tests). 0 future.

Features

FeatureScenariosDepthNotes
claim-emission7MOCKelench-claim: validate_claim + types. 1 scenario untested (empty dependsOn warning — dead code)
claim-revocation7MOCKelench-claim: compute_status + blast_radius + dependsOn propagation. All 7 covered.
origin-typing6MOCKelench-claim: validate_claim cross-checks. 2 scenarios untested (query-by-origin.kind not implemented)
release-gate9MOCKelench-gate: evaluate, 4 conditions. 1 scenario untested (contradictory predicates — FM-P2-02 known limitation)
anchor-resolution11MOCKelench-anchor: resolve_path_range/symbol/content_digest, reconcile CLI. 1 scenario untested (wrong-resolution — dead code)
unevaluated-residue6MOCKelench-claim: ClaimStatus::Unevaluated. 1 scenario untested (corrupt cascade — no corrupt status)
git-projection4MOCKelench-projection: synthesize, git_log_oneline/full, materialize, git blame, write-through rejected. All 4 covered.
store-backend5MOCKelench-store: –store flag, FjallStore::read_tree round-trip. All 5 covered.
build-provenance4SHALLOWelench: –artifact flag, SHA-256 of build output. CLI output checks, not in-process claim verification.
proptest-property5PROPERTYproptest: INV-25/20/13/29/28 (256 cases each). All 5 covered.
dogfooding7NONEShell scripts (run.sh, emit-continuous.sh) with no assertions. 6 of 7 scenarios have no Rust test.

71 scenarios total. 59 tested, 12 untested (see per-feature notes). 346 tests (default), 353 (with fjall-backend). 92% line coverage.

Untested scenarios (12)

FeatureScenarioReason
anchor-resolutionWrong-resolution is reported distinctly from failureStrategyOutcome::Wrong is dead code (#[allow(dead_code)])
claim-emissionA claim with empty dependsOn is accepted with a warningValidationError::EmptyDependsOn is defined but never returned
dogfooding (×6)Dogfooding claims emitted/stored, gate, log stats, git projection, continuous emission, CI nightlyShell scripts with || true, no assertions
origin-typing (×2)Harness-observed and agent-asserted claims are distinct; human-asserted distinct from agentNo query-by-origin.kind function exists
release-gateTwo contradictory predicates: gate passes (known limitation)FM-P2-02 not tested
unevaluated-residueA corrupt claim cascades to unevaluated dependentsNo “corrupt” status distinction; compute_status returns Err(ClaimNotFound)

Experiments

ExperimentGatesStatusResult
E0 — Predicate ratioBC1PASSED0.72 (threshold >= 0.30). PROCEED AS DESIGNED.
E1 — Anchor survivalBC2PASSEDAll strategies USABLE (correct >= 85%, wrong <= 2%). Proceed with multi.
E2 — Build reproducibilityBC3PASSEDSame-triple divergences all cheap-to-fix. K-of-N available.

Implementation status

All phases (0–5) are implemented, plus elench-anchor, store-backend selection, build provenance, .git/ materialization, proptest, conflict detection, continuous dogfooding, and INV-15 artifact format.

  • Phase 0: elench-predicate (64 tests) + elench-claim (40 tests)
  • Phase 1: elench-store (34 tests default; 40 with fjall-backend)
  • Phase 2: elench-envelope (12 tests)
  • Phase 3: elench-gate (23 tests)
  • Phase 4: elench-projection (14 tests)
  • Phase 5: elench binary (9 unit + 65 cli + 9 integration tests; 10 integration with fjall-backend)
  • elench-anchor (23 tests)

Store backend: in-memory (default), fjall (optional feature, ADR-0008). --store memory|fjall <path> selects the backend at the CLI; synthesize takes &dyn StoreBackend so any command can target either. materialize writes real zlib-compressed git objects to .git/objects/.

Dogfooding: dogfooding/claims.json (10 claims about elench’s own invariants), make dogfood runs the full pipeline (emit, gate, log, review, conflicts, git projection, materialize, verify). Continuous dogfooding (dogfooding/emit-continuous.sh) emits 4 harness-observed claims per CI run.