Files
stack/docs/plans/2026-08-01-rm-02-gate-registry.md
T

5.5 KiB

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 verifies the current PR tree unprivileged and fail-closed.

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 checks activation/manifest provenance and retained external current-tree CI evidence without inferring missing evidence. Isolated own-tree execution remains fail-closed code for RM-60's future protected authority; repository-controlled PR CI does not invoke it.

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: Current-tree boundary, deferred 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. PR verification must state adjacent DOES/DOES NOT boundaries and must not execute the intermediate commit's verifier. Preserve isolated replay as a direct fail-closed primitive for RM-60's future protected pre-execution authority; sandbox failure remains nonzero. Add bounded Gitea/Woodpecker current-tree status lookup for prior commits when credentials/history are available. Missing, expired, and currently-running evidence must be explicit states, never inferred success. Protected post-merge replay is detection with quarantine/revert, never pre-merge prevention.

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.