[PR #7178] feat(ledger)!: require failing negative control before verifier closes obligation #7697

Open
opened 2026-11-03 13:39:43 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/7178
Author: @hannesstrydom664-hash
Created: 10/25/2026
Status: 🔄 Open

Base: main ← Head: feat/reconstruction-negative-control-4396


📝 Commits (4)

  • 059e397 feat(ledger): require failing negative control before verifier closes obligation (#4396)
  • 6f403b4 fix(ledger): address verifier negative control review feedback (#4396)
  • ffe5ca9 feat(ledger)!: mark negative-control closure requirement as breaking (#4396)
  • a1f55c0 fix(ledger): reject negative controls that reuse the positive subject

📊 Changes

10 files changed (+1027 additions, -43 deletions)

View changed files

📝 docs/reconstruction-obligation-ledgers.md (+58 -10)
📝 src/application/ReconstructionObligationAuthority.ts (+8 -1)
📝 src/application/ReconstructionObligationLedger.authority.test.ts (+53 -25)
📝 src/application/ReconstructionObligationLedger.closure.test.ts (+664 -0)
📝 src/application/ReconstructionObligationLedger.fixture.ts (+56 -2)
📝 src/application/ReconstructionObligationLedgerEvaluation.ts (+140 -0)
📝 src/application/ReconstructionObligationLedgerProjection.ts (+6 -1)
📝 src/domain/reconstructionObligationLedgerIntegrity.ts (+10 -1)
📝 src/domain/reconstructionObligationLedgerSchemas.ts (+25 -0)
📝 tests/fixtures/reconstructionProofApplicability.ts (+7 -3)

📄 Description

Summary

Fixes #4396

Prevents vacuous ("always-pass") reconstruction verifiers from closing obligations in ReconstructionObligationLedger by requiring a verifier binding to demonstrate at least one failing negative control before an obligation transitions to verified.

Problem and expected behavior

  • Smallest trigger: Evaluate a ReconstructionObligationLedger where an obligation has a passing verifier binding (status: "pass") and passing fixture results, but either has no verifier.controls or has a negative control whose proof record passed (passed: true / status: "pass").
  • Violated invariant: A verifier that passes on a known-bad or mutated candidate (or has never been challenged against a negative control) does not establish behavioral equivalence and must not close an obligation as verified.
  • Expected behavior:
    • When verifier.controls is omitted or empty, evaluation emits diagnostic "missing-verifier-control", sets verifier_control_status: "unchallenged", and keeps the obligation open (status: "implemented").
    • When any negative control reports status: "pass" or its proof record reports passed: true, evaluation emits diagnostic "vacuous-verifier", sets verifier_control_status: "vacuous", keeps the obligation open, and escalates required open obligations with "vacuous-verifier" to ledger status "failed".
    • When all negative controls fail against their known-bad candidates with qualified negative-control proof records (expectedPassed: false) and positive verifier + fixtures pass, verifier_control_status is "challenged" and the obligation closes as verified.

Change and scope

Follow the contribution scope.
Scoped enhancement implementing issue #4396 (feat(ledger): require failing negative control before verifier closes obligation).

  • src/domain/reconstructionObligationLedgerSchemas.ts: Add verifierNegativeControlSchema (control_id, optional candidate_id and candidate_sha256, defect, status, and result_evidence_id), optional controls on verifierBindingSchema, verifierControlStatusSchema ("challenged" | "unchallenged" | "vacuous" | "missing-control-result" | "inapplicable-control-proof" | "control-unavailable"), optional verifier_control_status on reconstructionObligationSchema, and diagnostics "vacuous-verifier", "missing-verifier-control", "missing-verifier-control-result", "inapplicable-verifier-control-proof", and "verifier-control-unavailable".
  • src/domain/reconstructionObligationLedgerIntegrity.ts & src/application/ReconstructionObligationLedgerProjection.ts: Include negative control result_evidence_id references in reconstructionObligationEvidenceIds and obligationLedgerEvidenceLinks, and escalate required open obligations with "vacuous-verifier" diagnostics to ledger status "failed".
  • src/application/ReconstructionObligationAuthority.ts & src/application/ReconstructionObligationLedgerEvaluation.ts: Support expectedPassed: false in qualifyReconstructionProof (returning "passed-negative-control" if the proof record reports passed: true) and evaluate verifier.controls before permitting obligation closure.
  • Tests (src/application/ReconstructionObligationLedger.closure.test.ts, src/application/ReconstructionObligationLedger.authority.test.ts, src/domain/reconstructionObligationLedgerSchemas.test.ts, tests/conformance/readiness/report/reconstructionReadiness.test.ts): Update closure/conformance fixtures with failing negative controls and add regression tests for unchallenged, vacuous, missing-evidence, unavailable, and inapplicable negative controls.

Contract and boundary impact

  • Semantic owner and earliest changed stage: src/domain/reconstructionObligationLedgerSchemas.ts, src/application/ReconstructionObligationAuthority.ts, and src/application/ReconstructionObligationLedgerEvaluation.ts.
  • Contribution scope fit and linked maintainer decision: Implements #4396 (feat(ledger): require failing negative control before verifier closes obligation).
  • CLI and MCP/tool-catalog contract: Extends ReconstructionObligationLedger schema with optional verifier.controls and optional verifier_control_status so existing serialized ledgers without controls remain parseable while new closure evaluations enforce negative controls.
  • Provider, bridge, target-format, or platform compatibility: None.
  • Evidence, artifact, provenance, or reconstruction contract: Requires retained negative-control proof Evidence (expectedPassed: false) and links negative-control result_evidence_id into ledger Evidence integrity and projection links.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): Verifier negative-control proof records are checked for subject/candidate authority when candidate_id / candidate_sha256 are supplied on the control.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact: None.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated:
    • src/application/ReconstructionObligationLedger.closure.test.ts
    • src/application/ReconstructionObligationLedger.authority.test.ts
    • src/domain/reconstructionObligationLedgerSchemas.test.ts
    • tests/conformance/readiness/report/reconstructionReadiness.test.ts
  • Base reproduction or other evidence:
    • Executed: Verified that a verifier without controls stays open (status: "implemented", verifier_control_status: "unchallenged", diagnostic "missing-verifier-control"), a verifier whose negative control passes is flagged (verifier_control_status: "vacuous", diagnostic "vacuous-verifier", ledger status "failed"), and a verifier with a qualified failing negative control closes the obligation (status: "verified", verifier_control_status: "challenged").
  • User-visible CLI/MCP output (if applicable):
    • Evaluated obligations include verifier_control_status ("challenged", "unchallenged", "vacuous", "missing-control-result", "inapplicable-control-proof", or "control-unavailable") and corresponding diagnostics when negative-control requirements are not met.
  • Remaining proof gaps: None.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • npx vitest run src/application/ReconstructionObligationLedger.closure.test.ts src/application/ReconstructionObligationLedger.authority.test.ts src/domain/reconstructionObligationLedgerSchemas.test.ts tests/conformance/readiness/report/reconstructionReadiness.test.ts tests/boundary/cli/reconstructionObligationLedgerCli.test.ts — 5 test files passed, 82 tests passed.
  • npm run typecheck — passed (tsc --noEmit, 0 errors).
  • npm run format:check — passed (oxfmt --check .).
  • npm run lint — passed (oxlint 0 warnings/0 errors; verify:module-boundaries passed).
  • npm run verify:test-discovery — passed.
  • npm run verify:architecture-guards — passed.
  • npm run scan:todos — passed.
  • npm run jscpd — passed.

Compatibility, safety, and release

  • Breaking changes or migration steps: Existing stored ledgers without verifier.controls continue to parse cleanly (controls and verifier_control_status are optional on the wire); re-evaluating an obligation for verified closure now requires at least one failing negative control on verifier.controls.
  • Real Hopper/Ghidra, browser, or OS coverage: Not applicable (pure domain/application obligation ledger evaluation and conformance suite).
  • Package or release metadata impact: None.
  • Security, privacy, process, or containment review: Strengthens verification integrity by rejecting vacuous verifiers.

Author readiness

Human owner: @hannesstrydom664-hash

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/7178 **Author:** [@hannesstrydom664-hash](https://github.com/hannesstrydom664-hash) **Created:** 10/25/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feat/reconstruction-negative-control-4396` --- ### 📝 Commits (4) - [`059e397`](https://github.com/morluto/rea/commit/059e3979009bd20723adaac62db1db1f721c907a) feat(ledger): require failing negative control before verifier closes obligation (#4396) - [`6f403b4`](https://github.com/morluto/rea/commit/6f403b4e4a92343d2794b19e4d668176c280586a) fix(ledger): address verifier negative control review feedback (#4396) - [`ffe5ca9`](https://github.com/morluto/rea/commit/ffe5ca9eb799d6a01db3a7feb03bfcef9c386083) feat(ledger)!: mark negative-control closure requirement as breaking (#4396) - [`a1f55c0`](https://github.com/morluto/rea/commit/a1f55c0214f0837b7194a6424cf8f6ce43270c70) fix(ledger): reject negative controls that reuse the positive subject ### 📊 Changes **10 files changed** (+1027 additions, -43 deletions) <details> <summary>View changed files</summary> 📝 `docs/reconstruction-obligation-ledgers.md` (+58 -10) 📝 `src/application/ReconstructionObligationAuthority.ts` (+8 -1) 📝 `src/application/ReconstructionObligationLedger.authority.test.ts` (+53 -25) 📝 `src/application/ReconstructionObligationLedger.closure.test.ts` (+664 -0) 📝 `src/application/ReconstructionObligationLedger.fixture.ts` (+56 -2) 📝 `src/application/ReconstructionObligationLedgerEvaluation.ts` (+140 -0) 📝 `src/application/ReconstructionObligationLedgerProjection.ts` (+6 -1) 📝 `src/domain/reconstructionObligationLedgerIntegrity.ts` (+10 -1) 📝 `src/domain/reconstructionObligationLedgerSchemas.ts` (+25 -0) 📝 `tests/fixtures/reconstructionProofApplicability.ts` (+7 -3) </details> ### 📄 Description ## Summary Fixes #4396 Prevents vacuous ("always-pass") reconstruction verifiers from closing obligations in `ReconstructionObligationLedger` by requiring a verifier binding to demonstrate at least one failing negative control before an obligation transitions to `verified`. ## Problem and expected behavior - **Smallest trigger:** Evaluate a `ReconstructionObligationLedger` where an obligation has a passing `verifier` binding (`status: "pass"`) and passing fixture results, but either has no `verifier.controls` or has a negative control whose proof record passed (`passed: true` / `status: "pass"`). - **Violated invariant:** A verifier that passes on a known-bad or mutated candidate (or has never been challenged against a negative control) does not establish behavioral equivalence and must not close an obligation as `verified`. - **Expected behavior:** - When `verifier.controls` is omitted or empty, evaluation emits diagnostic `"missing-verifier-control"`, sets `verifier_control_status: "unchallenged"`, and keeps the obligation open (`status: "implemented"`). - When any negative control reports `status: "pass"` or its proof record reports `passed: true`, evaluation emits diagnostic `"vacuous-verifier"`, sets `verifier_control_status: "vacuous"`, keeps the obligation open, and escalates required open obligations with `"vacuous-verifier"` to ledger status `"failed"`. - When all negative controls fail against their known-bad candidates with qualified negative-control proof records (`expectedPassed: false`) and positive verifier + fixtures pass, `verifier_control_status` is `"challenged"` and the obligation closes as `verified`. ## Change and scope Follow the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope). Scoped enhancement implementing issue #4396 (`feat(ledger): require failing negative control before verifier closes obligation`). - `src/domain/reconstructionObligationLedgerSchemas.ts`: Add `verifierNegativeControlSchema` (`control_id`, optional `candidate_id` and `candidate_sha256`, `defect`, `status`, and `result_evidence_id`), optional `controls` on `verifierBindingSchema`, `verifierControlStatusSchema` (`"challenged" | "unchallenged" | "vacuous" | "missing-control-result" | "inapplicable-control-proof" | "control-unavailable"`), optional `verifier_control_status` on `reconstructionObligationSchema`, and diagnostics `"vacuous-verifier"`, `"missing-verifier-control"`, `"missing-verifier-control-result"`, `"inapplicable-verifier-control-proof"`, and `"verifier-control-unavailable"`. - `src/domain/reconstructionObligationLedgerIntegrity.ts` & `src/application/ReconstructionObligationLedgerProjection.ts`: Include negative control `result_evidence_id` references in `reconstructionObligationEvidenceIds` and `obligationLedgerEvidenceLinks`, and escalate required open obligations with `"vacuous-verifier"` diagnostics to ledger status `"failed"`. - `src/application/ReconstructionObligationAuthority.ts` & `src/application/ReconstructionObligationLedgerEvaluation.ts`: Support `expectedPassed: false` in `qualifyReconstructionProof` (returning `"passed-negative-control"` if the proof record reports `passed: true`) and evaluate `verifier.controls` before permitting obligation closure. - Tests (`src/application/ReconstructionObligationLedger.closure.test.ts`, `src/application/ReconstructionObligationLedger.authority.test.ts`, `src/domain/reconstructionObligationLedgerSchemas.test.ts`, `tests/conformance/readiness/report/reconstructionReadiness.test.ts`): Update closure/conformance fixtures with failing negative controls and add regression tests for unchallenged, vacuous, missing-evidence, unavailable, and inapplicable negative controls. ## Contract and boundary impact - Semantic owner and earliest changed stage: `src/domain/reconstructionObligationLedgerSchemas.ts`, `src/application/ReconstructionObligationAuthority.ts`, and `src/application/ReconstructionObligationLedgerEvaluation.ts`. - Contribution scope fit and linked maintainer decision: Implements #4396 (`feat(ledger): require failing negative control before verifier closes obligation`). - CLI and MCP/tool-catalog contract: Extends `ReconstructionObligationLedger` schema with optional `verifier.controls` and optional `verifier_control_status` so existing serialized ledgers without `controls` remain parseable while new closure evaluations enforce negative controls. - Provider, bridge, target-format, or platform compatibility: None. - Evidence, artifact, provenance, or reconstruction contract: Requires retained negative-control proof Evidence (`expectedPassed: false`) and links negative-control `result_evidence_id` into ledger Evidence integrity and projection links. - Target selection, authority, upstream behavior, and cleanup details (if applicable): Verifier negative-control proof records are checked for subject/candidate authority when `candidate_id` / `candidate_sha256` are supplied on the control. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: None. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: - `src/application/ReconstructionObligationLedger.closure.test.ts` - `src/application/ReconstructionObligationLedger.authority.test.ts` - `src/domain/reconstructionObligationLedgerSchemas.test.ts` - `tests/conformance/readiness/report/reconstructionReadiness.test.ts` - Base reproduction or other evidence: - Executed: Verified that a verifier without `controls` stays open (`status: "implemented"`, `verifier_control_status: "unchallenged"`, diagnostic `"missing-verifier-control"`), a verifier whose negative control passes is flagged (`verifier_control_status: "vacuous"`, diagnostic `"vacuous-verifier"`, ledger status `"failed"`), and a verifier with a qualified failing negative control closes the obligation (`status: "verified"`, `verifier_control_status: "challenged"`). - User-visible CLI/MCP output (if applicable): - Evaluated obligations include `verifier_control_status` (`"challenged"`, `"unchallenged"`, `"vacuous"`, `"missing-control-result"`, `"inapplicable-control-proof"`, or `"control-unavailable"`) and corresponding diagnostics when negative-control requirements are not met. - Remaining proof gaps: None. For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - `npx vitest run src/application/ReconstructionObligationLedger.closure.test.ts src/application/ReconstructionObligationLedger.authority.test.ts src/domain/reconstructionObligationLedgerSchemas.test.ts tests/conformance/readiness/report/reconstructionReadiness.test.ts tests/boundary/cli/reconstructionObligationLedgerCli.test.ts` — 5 test files passed, 82 tests passed. - `npm run typecheck` — passed (`tsc --noEmit`, 0 errors). - `npm run format:check` — passed (`oxfmt --check .`). - `npm run lint` — passed (`oxlint` 0 warnings/0 errors; `verify:module-boundaries` passed). - `npm run verify:test-discovery` — passed. - `npm run verify:architecture-guards` — passed. - `npm run scan:todos` — passed. - `npm run jscpd` — passed. ## Compatibility, safety, and release - Breaking changes or migration steps: Existing stored ledgers without `verifier.controls` continue to parse cleanly (`controls` and `verifier_control_status` are optional on the wire); re-evaluating an obligation for `verified` closure now requires at least one failing negative control on `verifier.controls`. - Real Hopper/Ghidra, browser, or OS coverage: Not applicable (pure domain/application obligation ledger evaluation and conformance suite). - Package or release metadata impact: None. - Security, privacy, process, or containment review: Strengthens verification integrity by rejecting vacuous verifiers. ## Author readiness Human owner: @hannesstrydom664-hash - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#7697
No description provided.