feat(quality): add anti-inert gate registry

This commit is contained in:
2026-08-01 09:58:46 -05:00
parent f4fd5967fc
commit 0b4aa4751a
18 changed files with 3247 additions and 3 deletions
+3
View File
@@ -0,0 +1,3 @@
# Administrator Guide
- [Gate registry operations](quality-gate-registry.md)
+33
View File
@@ -0,0 +1,33 @@
# Gate Registry Operations
## Routine verification
Run `pnpm gate:verify` from a dependency-installed checkout. Exit zero means registry observations matched their declared `actual` values; it does **not** assert required-behavior conformance while deltas remain. Open `DEFECT` records are checked descriptions of current behavior with tracked owners, never successful gate outcomes.
Investigate any of these immediately:
- `GATE VERIFY FAILED` — registry structure, observed behavior, provenance, claim binding, source/deployment identity, or negative-control detection changed.
- `unregistered gate` — an executable appeared under a declared gate root without a registry entry.
- `no negative control` — a gate has no must-fail case.
- `DEPLOYED IDENTITY UNAVAILABLE` — the runner cannot reach the installed enforcing copy. The pinned observation is checked, but live equality is not asserted.
- `PROVIDER EVIDENCE ... ABSENT` — retained external history was unavailable; do not infer merge-time success.
## Updating a gate
1. Add or change the criterion and exact case.
2. Observe the case fail for its own stated reason.
3. Declare an exact inerting mutation and observe the verifier detect it.
4. If required and actual behavior differ, add a tracked remediation owner and justification.
5. If meaning changed, append provenance; never replace the original silently.
6. For an installed counterpart, verify live byte identity and update the observed digest only from measured evidence.
7. Run focused verifier tests, `pnpm gate:verify`, and the repository baseline gates.
Do not add an ownerless exception or describe an open delta as pass/green/OK.
## CI behavior
Woodpecker runs `gate-verify` on every pull request and protected-main push without path filtering. This is deliberate: changes outside gate files can make a gate inert.
Provider evidence input is an optional JSON array of normalized pipeline records containing `commit`, unique integer pipeline `number`, pipeline `status`, and a `gate-verify` step status. The highest numbered rerun is authoritative; ambiguous duplicates fail. Its retention window is provider-controlled and is not overstated by this repository.
Prior commit replay performs a frozen offline install from each commit's own lockfile before running that commit's verifier. Bubblewrap clears the environment, hides operator-home credentials, and disables networking for historical lifecycle and verifier code. A missing cached dependency or unavailable sandbox fails replay; current dependencies are never substituted.
+3
View File
@@ -0,0 +1,3 @@
# Developer Guide
- [Gate registry and negative controls](quality-gate-registry.md)
@@ -0,0 +1,41 @@
# Gate Registry and Negative Controls
`gates/gates.manifest.json` is the machine-readable registry for the initial RM-02 gate slice. Run:
```bash
pnpm gate:verify
```
## Registered slice
The registry covers root typecheck, lint, and format checks; RM-01 checkout preflight; the Mosaic CI queue guard; and root Husky pre-commit/pre-push hooks. It does not imply repository-wide coverage. Framework scripts, package-local build/test scripts, templates, and deployment/release scripts remain assigned to RM-54.
Every gate declares exact invocations, observed and required outcomes, criterion bindings, and a single exact inerting mutation. Every must-fail case requires a non-empty reason diagnostic. The verifier rejects a stale, ambiguous, crashing, or ineffective mutation. Fixture and mutation writes reject path traversal and final-component symlinks. This proves detection of the **declared** inerting mutation, not every possible semantic weakening.
## Required versus actual
A case may record different `required` and `actual` outcomes only with a tracked owner. The verifier checks current reality against `actual`, prints each difference as `DEFECT (owner: ...)`, and fails when behavior changes without a matching registry update. A defect is never described as passing, green, or OK.
The queue guard currently has RM-03-owned deltas. In particular, its stdin/heredoc classifier does not consume piped status JSON, so terminal-success, no-status, and terminal-failure payloads become `unknown`; unknown and malformed states exit zero; push purpose defaults to `main`. RM-02 records these observations and does not edit the guard.
## Criteria, prose, and compatibility
Each criterion must bind to a must-fail case. Designated governing prose uses `GATE-CLAIM:<id>` markers; an unbound marker or registered-but-missing marker fails. Orchestrator-owned claims from `TASKS.md` are bound through `docs/remediation/GATE-CLAIMS.md`, which records source headings and anchored text without changing task tracking. Marker completeness still requires RM-54 review because arbitrary English claims cannot be inferred safely.
Compatibility checks detect direct contradictions in declared finite constructions. The verifier combines referenced case fixtures and environments in one isolated tree, rejects conflicting fixture/environment values, executes the construction's exact invocation, and checks its exact outcome. They do not prove semantic consistency of arbitrary natural language.
Restatements preserve original text, current text, reason, finding/task, and date.
## Source and deployed identity
A gate with an external installed counterpart declares it explicitly. When the installed queue guard is reachable, its bytes must equal repository source and an internal drift control is observed red. In CI the operator-home installation may be outside the container; the verifier checks the pinned observed source digest, reports `DEPLOYED IDENTITY UNAVAILABLE (owner: RM-04)`, and does not infer live equality.
## Commit and provider boundary
The current checkout is evaluated directly. On feature branches and main, each prior prospective commit is archived from Git, receives a frozen offline install from that commit's lockfile, and runs that commit's own verifier and manifest. Missing cached dependencies or an unrunnable historical verifier fail loudly rather than borrowing current-tree dependencies.
Historical install scripts and verifiers execute inside Bubblewrap with network, PID, IPC, and UTS namespaces isolated; a cleared/allowlisted environment; an isolated home; a writable replay tree; read-only system files; and a read-only pnpm store. Current CI secrets, sibling runner processes, and the operator home are not visible inside that boundary. Because lifecycle scripts are required for faithful installs, the verifier snapshots every archived file before install and fails if any authoritative file changes, disappears, or changes type/mode before replay. Replay fails when this sandbox or integrity check cannot be established.
Retained provider evidence can assert terminal-success for prior commits when supplied through `GATE_PROVIDER_EVIDENCE_FILE`. Each normalized record contains `commit`, unique integer pipeline `number`, pipeline `status`, and step statuses; the highest-numbered rerun is authoritative. Ambiguous duplicates fail. Absent, expired, or currently-running evidence is reported explicitly and never inferred as success.
Repository replay proves tree reproducibility under the selected commit's locked dependency graph. It does not prove that CI blocked a merge at the time or resist an actor who can rewrite the verifier, registry, and gate consistently. RM-25/RM-59 own that external authority and trust anchor.
+43
View File
@@ -14,6 +14,49 @@
---
## RM-02 Gate Registry and Negative-Control Verifier (#1029)
### Problem and objective
Existing deterministic gates can return success without enforcing their stated property. RM-02 introduces a machine-readable registry and an unconditional CI verifier that distinguishes required behavior from observed behavior, proves every registered negative control can detect its own failure reason, and makes source/deployment drift visible.
### Scope
**In scope:** root typecheck, lint, and format gates; RM-01 checkout preflight; the Mosaic CI queue guard; root Husky pre-commit and pre-push hooks; criterion bindings; modeled compatibility; meaning-change provenance; security/integrity prose claim markers; source-versus-deployed identity; prospective per-commit tree replay; retained provider CI evidence where available.
**Out of scope:** fixing the queue guard (RM-03); exhaustive registration of every repository executable (RM-54); semantic proof that arbitrary English criteria are mutually satisfiable (RM-54/RM-55); a same-authority trust anchor for repository-authored evidence (RM-25/RM-59).
### Normative requirements
1. `RM02-REQ-01`: The JSON registry SHALL give every gate and criterion a stable ID and SHALL declare exact invocation, input classes, cases, exact observed and required exit codes, reason diagnostics, and criterion bindings.
2. `RM02-REQ-02`: Every gate SHALL have at least one observed-red must-fail case. The verifier SHALL reject missing, stale, ambiguous, or ineffective declared inert mutations and SHALL name an externally inerted gate.
3. `RM02-REQ-03`: Every acceptance criterion SHALL bind to a case that can fail for that criterion's stated reason. Security/integrity prose claims in the designated governing documents SHALL carry bound `GATE-CLAIM:<id>` markers.
4. `RM02-REQ-04`: Declared finite compatibility scenarios SHALL execute together and direct modeled contradictions SHALL fail. This does not claim semantic consistency of arbitrary English.
5. `RM02-REQ-05`: Restated criteria SHALL retain original text, current text, reason, finding/task, and dated meaning-change history.
6. `RM02-REQ-06`: An observed behavior differing from required behavior SHALL be reported as `DEFECT` with a tracked owner; an ownerless delta SHALL fail verification. Such a gate SHALL never be described as passing, green, or OK.
7. `RM02-REQ-07`: Executables under declared gate roots SHALL fail with `unregistered gate` when absent from the registry. The initial coverage boundary SHALL explicitly list exclusions and bind the broader inventory to RM-54.
8. `RM02-REQ-08`: Every gate with a deployed counterpart SHALL register source/deployed byte identity and a must-fail drift control. Gates without a deployed counterpart SHALL say so explicitly.
9. `RM02-REQ-09`: CI SHALL run `pnpm gate:verify` on every pull request without path filtering and on protected-main pushes.
10. `RM02-REQ-10`: Verification SHALL replay prospective first-parent commits from the activation boundary against each commit's own tree. It SHALL distinguish reproducibility replay from retained external provider evidence and SHALL state when provider history is absent, expired, or still running.
### Acceptance criteria
1. `RM02-AC-01`: A healthy current tree returns zero while prominently reporting the queue guard's required-versus-actual `DEFECT (owner: RM-03)` delta.
2. `RM02-AC-02`: Externally mutate any registered gate at its declared inerting point so its failure path succeeds; verification returns nonzero and names that gate. The verifier's internal meta-control is observed red before its healthy result is trusted.
3. `RM02-AC-03`: An executable added under a declared gate root without an entry returns nonzero and includes `unregistered gate`.
4. `RM02-AC-04`: A gate with zero must-fail cases returns nonzero and includes `no negative control`.
5. `RM02-AC-05`: Unbound criteria, unbound governing prose markers, ownerless behavior deltas, stale mutations, source/deployed drift, and modeled compatibility conflicts each return nonzero with the responsible stable ID.
6. `RM02-AC-06`: CI configuration invokes the verifier unconditionally on every pull request.
7. `RM02-AC-07`: Per-commit replay uses the selected commit's manifest and tree rather than current main, while external CI evidence is asserted only for the provider-retained window and never inferred when unavailable.
### Risks, dependencies, and verification boundary
- The repository verifier proves declared controls, modeled scenarios, source/deployed equality at execution time, and prospective tree reproducibility. It does **not** defend against an actor able to rewrite the gate, registry, and verifier consistently.
- External branch protection and provider CI history supply merge-time evidence where retained. RM-25/RM-59 track the authority/trust anchor outside the worktree.
- `ASSUMPTION:` RM-54 is the owner for expanding registration and prose-marker coverage beyond this approved seven-gate slice; rationale: the remediation task graph already assigns the fleet-wide inert-gate audit there.
---
## Problem Statement
Jarvis (v0.2.0) is a self-hosted AI assistant with a Python FastAPI backend and Next.js frontend. It handles chat, projects, tasks, and LLM routing but lacks orchestration depth, agent coordination, shared memory, and remote access. The Mosaic framework (`~/.config/mosaic`) provides agent guides, shell-based orchestration tools, and quality rails — but these are loose scripts, not an integrated platform. The `@mosaicstack/*` packages in mosaic-mono-v0 began consolidating these into TypeScript packages (brain, queue, coord, cli, prdy, quality-rails) but have no UI, no auth, and no agent runtime integration.
+6
View File
@@ -1,5 +1,11 @@
# Documentation Sitemap
## Gate verification
- [Developer gate registry guide](DEVELOPER-GUIDE/quality-gate-registry.md) — manifest schema, negative controls, defect deltas, modeled boundaries, and commit/provider evidence.
- [Gate registry operations](ADMIN-GUIDE/quality-gate-registry.md) — routine verification, failure interpretation, registry updates, and unconditional CI behavior.
- [RM-02 governing claim index](remediation/GATE-CLAIMS.md) — marker bindings for orchestrator-owned remediation claims without modifying task tracking.
## Compaction refresh lease broker
- [Internal broker protocol](architecture/lease-broker-protocol.md) — kernel identity, ancestry and generation invariants, framed requests, responses, and persisted cycle bindings.
@@ -0,0 +1,94 @@
# RM-02 Gate Registry Implementation Plan
> **For Pi:** Use test-driven development and execute each task RED → GREEN → refactor.
**Goal:** Build a machine-readable seven-gate registry and an unconditional CI verifier that detects inert gates, binds criteria to observed negative controls, records defects honestly, and replays prospective commits against their own trees.
**Architecture:** A dependency-free Node CLI reads `gates/gates.manifest.json`, validates its closed schema and references, then runs typed cases in isolated main-disk fixtures. Gate-specific fixture setup remains declarative; exact invocations and exact observed/required exits stay in JSON. A separate history module selects each first-parent commit's own tree/manifest and reports retained external CI evidence without inferring missing evidence.
**Tech Stack:** Node.js ESM, `node:test`, JSON, shell gates, pnpm, Woodpecker CI.
---
### Task 1: Meta-negative-control kernel
**Files:**
- Create: `scripts/gate-verify.test.mjs`
- Create: `scripts/gate-verify.mjs`
1. Write a black-box fixture whose gate failure branch has already been changed to success.
2. Run `node --test scripts/gate-verify.test.mjs`; require failure because the absent verifier does not name the inert gate.
3. Implement manifest loading, exact process execution, and named mismatch reporting only.
4. Re-run and require the external inert mutation to produce verifier nonzero while the test passes.
5. Add an internally applied declared mutation and require a healthy fixture to report its negative control armed.
### Task 2: Registry structural clauses
**Files:**
- Modify: `scripts/gate-verify.test.mjs`
- Modify: `scripts/gate-verify.mjs`
Add failing tests, one behavior at a time, for: `unregistered gate`; `no negative control`; unbound criterion; unbound `GATE-CLAIM`; ownerless required/actual delta; stale/ambiguous/ineffective mutation; direct modeled conflict; missing meaning-change provenance. Implement the minimum validator after each observed RED.
### Task 3: Gate fixtures and seven-gate manifest
**Files:**
- Create: `gates/gates.manifest.json`
- Create: `gates/fixtures/quality-case.mjs`
- Create: `gates/fixtures/preflight-case.mjs`
- Create: `gates/fixtures/queue-case.sh`
- Create: `gates/fixtures/hook-case.sh`
- Modify: `scripts/gate-verify.test.mjs`
Register typecheck, lint, format, RM-01 preflight, queue guard, pre-commit, and pre-push. For each, first run its known-bad case against an intentionally inert fixture and observe verifier RED; then restore the real gate behavior and require its exact observed exit/reason. Record queue defects as required/actual deltas owned by RM-03, never as pass/green/OK.
### Task 4: Source-versus-deployed identity
**Files:**
- Modify: `gates/gates.manifest.json`
- Modify: `scripts/gate-verify.test.mjs`
- Modify: `scripts/gate-verify.mjs`
Write and observe a failing test with a byte-mutated deployed counterpart. Implement byte equality and internal drift mutation controls. Declare `none` explicitly for gates without deployed counterparts.
### Task 5: Prose claims and compatibility constructions
**Files:**
- Modify: `docs/remediation/MISSION.md`
- Modify: `docs/remediation/TASKS.md` only if coordinator authorization overrides the worker prohibition; otherwise place markers in an RM-02 claim index that references immutable source anchors.
- Modify: `gates/gates.manifest.json`
- Modify: verifier tests/implementation.
Enumerate current security/integrity claims, bind each marker/id to a negative case, and reject unbound markers. Execute finite compatibility scenarios and clearly document that arbitrary English consistency is outside the model.
### Task 6: Prospective per-commit replay and provider evidence
**Files:**
- Create: `scripts/gate-history.mjs`
- Create: `scripts/gate-history.test.mjs`
- Modify: `scripts/gate-verify.mjs`
- Modify: `gates/gates.manifest.json`
Test with a synthetic git repository containing two commits whose manifests differ; prove replay reads each selected commit's tree. Add bounded Gitea/Woodpecker status lookup for prior commits when credentials/history are available. Missing, expired, and currently-running evidence must be explicit states, never inferred success.
### Task 7: CI and documentation
**Files:**
- Modify: `package.json`
- Modify: `.woodpecker/ci.yml`
- Create/update: `docs/DEVELOPER-GUIDE/quality-gate-registry.md`
- Create/update: `docs/ADMIN-GUIDE/quality-gate-registry.md`
- Modify: `docs/SITEMAP.md`
Add `gate:verify`; run it in an unconditional PR/main CI step. Document invocation, defect semantics, coverage/exclusions, marker syntax, replay/provider boundaries, and source/deployed identity.
### Task 8: Verification and delivery
Run focused tests, `pnpm gate:verify`, checkout tests, typecheck, lint, format, and applicable integration tests. Run Codex code and security review; remediate and re-review. Verify authorship, commit, execute queue guard before push, push, create PR via Mosaic wrapper, and send exact-head review request to rev-974 through the coordinator. Do not merge without coordinator authorization.
+24
View File
@@ -0,0 +1,24 @@
# RM-02 Governing Claim Index
This index binds remediation claims that live in orchestrator-owned `TASKS.md` without modifying that file. The source heading and quoted text are the reviewable anchor; `gate:verify` enforces each marker-to-criterion binding. Marker completeness beyond this approved slice remains RM-54.
## Prose is an enforceable claim
<!-- GATE-CLAIM:PROSE-IS-A-CLAIM -->
- Source: `docs/remediation/TASKS.md`, heading `D-20 — the orchestrator's own documentation overclaimed, and a reviewer disproved it empirically`.
- Anchored text: “The defect was not in the code — it was in this file.”
## Generated-state verification scope
<!-- GATE-CLAIM:GENERATED-STATE-SCOPE -->
- Source: `docs/remediation/TASKS.md`, heading `D-19 — an integrity property that cannot exist at the layer it was specified`.
- Anchored text: “a verifier that cannot detect the attack is not a verifier.”
## Criterion restatement provenance
<!-- GATE-CLAIM:CRITERION-RESTATEMENT -->
- Source: `docs/remediation/TASKS.md`, heading `D-18 — two pre-registered criteria were mutually unsatisfiable, discoverable only at implementation`.
- Anchored text: “Both criteria were pre-registered. They cannot both be satisfied.”
+8
View File
@@ -12,6 +12,8 @@ gate/program; the LLM handles only genuine judgment.
### First-class principle — observe the property, not the exit code
<!-- GATE-CLAIM:OBSERVE-PROPERTY -->
> **No write is done until the requested PROPERTY is observed. A success exit code is not evidence.**
>
> **Success output is designed to be believed.** That is the whole reason the inert-gate class exists
@@ -30,6 +32,8 @@ gate/program; the LLM handles only genuine judgment.
### First-class principle — pre-registration prevents retrofitting, and nothing else
<!-- GATE-CLAIM:PREREGISTRATION-BOUNDARY -->
> **A pre-registered check set can fail in three distinct ways:**
>
> | mode | the set is… | found as |
@@ -56,6 +60,8 @@ gate/program; the LLM handles only genuine judgment.
### Corollary — never ship an integrity claim dressed as a property
<!-- GATE-CLAIM:ARTIFACT-INTEGRITY-BOUNDARY -->
> A verification artifact that can be forged by whoever it is meant to catch verifies nothing. If a
> manifest, marker, ledger, or receipt is writable by the same actor whose behaviour it certifies, it
> **certifies the attack.** Such an artifact must sit inside the integrity envelope it belongs to,
@@ -68,6 +74,8 @@ gate/program; the LLM handles only genuine judgment.
### First-class principle — when a property cannot exist at the layer it was specified
<!-- GATE-CLAIM:IMPOSSIBLE-LAYER-BOUNDARY -->
> Some required properties are **impossible at the layer that asked for them** — not hard, impossible.
> A local check cannot defend against an actor who can rewrite the check itself. When that happens,
> there are exactly three honest moves, and all three are mandatory:
@@ -0,0 +1,73 @@
# RM-02 Gate Registry Scratchpad (#1029)
## Objective
Deliver the seven-gate registry and RED-first anti-inert verifier on `feat/rm-02-gate-registry`, preserving required-versus-actual defects without laundering them as success.
## Constraints and boundaries
- Do not modify `ci-queue-wait.sh`; RM-03 owns that fix.
- Do not modify `docs/remediation/TASKS.md`; workers cannot edit orchestrator tracking.
- Every declared behavior must be observed, not inferred from an exit code.
- Repository-local evidence does not establish same-authority tamper resistance; RM-25/RM-59 own the external trust anchor.
- Coverage is seven logical gates; broader inventory is RM-54.
- Budget assumption: no explicit token ceiling was supplied. Keep implementation dependency-free (stock Node), avoid repeated full monorepo installs, and keep generated test artifacts under the worktree/main disk.
## Plan
1. Update PRD and tracking references.
2. Write black-box meta-negative-control first and observe it fail for the missing verifier behavior.
3. Implement minimal manifest parser/case runner/mutation detector; observe meta-control succeed.
4. Add schema, coverage, provenance, prose marker, compatibility, discovery, deployment identity, and defect-delta tests RED-first.
5. Register seven gates with exact cases and run each case.
6. Add prospective per-commit replay and bounded provider-evidence reporting.
7. Wire unconditional Woodpecker CI and update developer/admin documentation.
8. Run situational and baseline verification, independent Codex review, remediate, commit, queue guard, push, PR, coordinator/reviewer handoff.
## Progress
- 2026-08-01: Design approved by `mos-remediation`; rulings A-E and source/deployed identity addition incorporated.
- 2026-08-01: Isolated worktree created from `origin/main` f65e9ea6; RM-01 f58b3699 verified as ancestor.
- 2026-08-01: Git author set to `f10-coder <[email protected]>`; provider issue #1029 created with `MOSAIC_GIT_IDENTITY=f10-coder`.
- 2026-08-01: Source/deployed queue-guard SHA-256 observed equal (`19cda2f...`); this observation is not yet an enforced property.
## Tests and RED-first evidence
- Meta-negative RED first: `node --test scripts/gate-verify.test.mjs` failed because the absent verifier did not name externally inerted `meta-fixture`.
- Structural RED: nine tests failed before implementation for internal mutation, unregistered executable, missing negative control, ownerless delta, unbound criterion/claim, modeled conflict, missing provenance, and deployment drift.
- Clause hardening RED: positive-only security criterion and missing registered claim marker both passed incorrectly before validation was added.
- CI wiring RED: package script and unconditional Woodpecker step tests both failed before wiring.
- History RED: history test failed with missing module before own-tree manifest selection/provider classification was implemented.
- `pnpm gate:verify`: exit 0; seven gates each reported `META-NEGATIVE-CONTROL ... observed red`; queue source/deployed drift control observed red; six queue behavior deltas printed as `DEFECT (owner: RM-03)`.
- Focused Node tests: 33/33 pass after review hardening (23 verifier/wiring plus 10 history/provider tests).
- `pnpm typecheck`: pass (45/45 Turbo tasks).
- `pnpm lint`: pass (25/25 Turbo tasks).
- `pnpm format:check`: pass.
- `pnpm test`: repository suites reached 45/46 Turbo tasks; all application/package tests shown passed, then the known host-specific wake assertion aborted exit 97 (`BASH_LINENO convention violated`, #973/D-16). No test was edited or bypassed. CI remains the authoritative full-suite environment.
## Self-surfaced defect
The queue guard's `get_state_from_status_json` runs `python3 - <<'PY'` while provider JSON is piped to the shell function. The heredoc owns stdin, so Python never reads provider JSON. Terminal success, no-status, terminal failure, and malformed payloads all classify as `unknown`; the associated fail-open outcomes are recorded under RM-03. No queue-guard source was modified.
## Independent review remediation
- Final pre-commit Codex code review found three blockers: a tautological deployment drift control, independently observed rather than combined compatibility cases, and unauthorized edits to orchestrator-owned `TASKS.md`.
- Deployment identity now uses one shared file comparator for both live equality and a temporary drifted deployed copy; a test makes that comparator inert and proves the meta-control fails.
- Compatibility scenarios now merge referenced fixtures/environments into one isolated construction and execute an exact scenario invocation; a test proves two independently valid fixtures coexist in the combined run.
- `TASKS.md` changes were reverted. `docs/remediation/GATE-CLAIMS.md` binds source headings and anchored text without editing orchestrator tracking.
- Codex security review found the Bubblewrap replay shared the runner PID namespace. Replay now unshares PID, IPC, and UTS namespaces, and an abuse-case test proves a sibling runner PID is invisible.
- Second review found empty reason diagnostics, final-symlink fixture writes, and lifecycle-script mutation of authoritative history files. Must-fail cases now require a reason pattern; writes use no-follow semantics; and replay snapshots every archived file before install and rejects any changed, deleted, or type/mode-shifted source before executing the verifier. Dedicated negative tests cover all three.
- Third code review found ambiguous duplicate provider steps and order-sensitive JSON outcome comparison. Provider evidence now requires exactly one `gate-verify` step in the authoritative rerun, and structural equality normalizes object keys. Both regressions have RED-first tests. Third security review reported no findings.
## Documentation checklist
- PRD, developer guide, admin guide, governing claim index, sitemap, plan, and scratchpad updated.
- User/API documentation not applicable: no user workflow or API changed.
- Independent review documentation check pending rev-974.
- Canonical documentation remains in-repository; no external publication requested.
## Risks/blockers
- Current queue guard intentionally has required-versus-actual deltas owned by RM-03.
- Provider CI cannot report the currently executing pipeline as terminal success; current-commit evidence must be labeled pending and becomes historical evidence only after provider completion.
- CI containers may not expose the operator-home deployed queue guard. In that layer the verifier checks the pinned observed digest and reports live identity unavailable under RM-04; it does not infer live equality.