feat(verification): executable merge gate — PR evidence manifests, validator with negative controls, merge sweep - #26
Conversation
…lidator with negative controls, merge sweep
|
CI green on the exact head
Author-side local verification at the same SHA (uncached): turbo typecheck/test/build 15/15, Next per contract: independent review against this SHA, then the |
Independent review result — recorded per contract rule 2–3Verdict: pass-with-notes · Tested SHA Reviewer: independent read-only review thread (obvious task Reviewer's own uncached results at that SHA (worktree, frozen lockfile): Findings: no false-accept path (every skipped sub-check guarded by a shape check that itself adds Non-blocking hardening notes (6): (1) Full reviewer report: obvious task |
{
"manifestVersion": 1,
"pr": 26,
"prUrl": "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/OCPdev25/obv-hackaton/pull/26",
"testedHeadSha": "f590ddfcba15f7bb7f75788466660fc151abe1e5",
"classification": "backend-only",
"classificationJustification": "Executable merge-gate tooling (CLI + pure validator + test fixtures + CI workflow + docs); no user-facing UI surfaces, no docs-only scope — behavior evidence below.",
"review": {
"result": "pass-with-notes",
"reviewer": "independent read-only review thread (obvious task todo_1Grlbg06 / thread th_PLlJY7qr); recorded on this PR with attribution",
"reviewedHeadSha": "f590ddfcba15f7bb7f75788466660fc151abe1e5",
"date": "2026-09-17",
"url": "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/OCPdev25/obv-hackaton/pull/26#issuecomment-5719690104"
},
"checks": [
{ "name": "CI (Typecheck, test, build)", "status": "green", "headSha": "f590ddfcba15f7bb7f75788466660fc151abe1e5", "url": "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/OCPdev25/obv-hackaton/actions/runs/35261065858" },
{ "name": "Verification (security + evaluation + negative control + validator tests)", "status": "green", "headSha": "f590ddfcba15f7bb7f75788466660fc151abe1e5", "url": "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/OCPdev25/obv-hackaton/actions/runs/35261065872" }
],
"evidence": [
{ "kind": "behavior-run", "name": "CLI smoke: check positive-backend fixture -> merge (exit 0); nc1-stale-sha -> refuse [stale_head_sha] (exit 1), author-side at tested HEAD, independently reproduced by reviewer", "headSha": "f590ddfcba15f7bb7f75788466660fc151abe1e5", "result": "pass", "url": "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/OCPdev25/obv-hackaton/pull/26#issuecomment-5719690104" },
{ "kind": "test-run", "name": "Validator tests: 25 pass / 52 assertions (2 positive + 9 negative controls + inline mutations + extraction), author-side and reviewer-side at tested HEAD", "headSha": "f590ddfcba15f7bb7f75788466660fc151abe1e5", "result": "pass", "url": "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/OCPdev25/obv-hackaton/actions/runs/35261065872" },
{ "kind": "suite-run", "name": "Security suite: 17 fail-closed access cases, 0 fail (author-side and reviewer-side at tested HEAD)", "headSha": "f590ddfcba15f7bb7f75788466660fc151abe1e5", "result": "pass", "url": "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/OCPdev25/obv-hackaton/actions/runs/35261065872" },
{ "kind": "suite-run", "name": "Evaluation harness: 6/6 fixtures; broken-adapter negative control fails as expected (exit 0) — author-side and reviewer-side at tested HEAD", "headSha": "f590ddfcba15f7bb7f75788466660fc151abe1e5", "result": "pass", "url": "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/OCPdev25/obv-hackaton/actions/runs/35261065872" }
],
"suites": {
"security": { "ran": true, "result": "pass", "headSha": "f590ddfcba15f7bb7f75788466660fc151abe1e5", "url": "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/OCPdev25/obv-hackaton/actions/runs/35261065872" },
"evaluation": { "ran": true, "result": "pass", "headSha": "f590ddfcba15f7bb7f75788466660fc151abe1e5", "negativeControl": "fail-as-expected", "url": "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/OCPdev25/obv-hackaton/actions/runs/35261065872" }
},
"notes": "Author-side local verification table also run uncached at tested HEAD: turbo typecheck/test/build 15/15. Non-blocking hardening notes (6) tracked for a follow-up PR."
} |
Evidence receipt (verification gate) |
Evidence receipt (verification gate) — COMPLETEDNote: the sweep's auto-posted receipt above rendered |
Acceptance criteria
.obvious/obvious.md(review → repair → merge workflow) has a stable refusal code, and each is pinned by a test: 2 positive controls + 9 negative-control fixtures + inline mutations + extraction tests (cd verification && bun test ./test— 25 tests, 52 assertions). Negative controls pin the exact refusal-code set, so the gate must fire on its own term and stay silent otherwise.<!-- verification-manifest:v1 -->block (body or comment). The latest block across body + comments wins; a later malformed block fails loudly instead of falling back.sweepchecks, in order: open PR → not draft → basemaster→ not an arena candidate → live checks green on the exact head SHA (queried live, not from the manifest) → manifest parses → validator merge → thengh pr merge --squash+ evidence receipt.--dry-runprints the receipt without merging;--smokere-runs the full local verification table on the merge commit from a temp worktree.verification.ymlworkflow runs the security suite, evaluation harness, broken-adapter negative control, and the validator tests on every PR/push tomaster(these are not pnpm workspace members, so the turbo pipeline never covered them).verification/README.md(manifest format, refusal-code table, CLI usage, factual limits — single-page comment/check reads,gh-auth trust) and.obvious/obvious.md(layout entry + "Verification gate" section).What's included
verification/src/— types (manifest schema, reason codes), pure validator (I/O-free; live state is injected viaVerificationContext), manifest extraction,ghwrappers, CLI (check/validate-pr/sweep)verification/fixtures/— 2 positive + 9 negative controls, each internally consistent except one defectverification/test/validate.test.ts— 25 tests pinning every rule.github/workflows/verification.yml— standalone-suite CI.obvious/obvious.mdupdatesKnown limits (stated, not hidden): the gate validates what is recorded and observed — it can detect contradiction between the manifest, the live diff, and live checks, but cannot verify intent. Fabricated-but-self-consistent evidence passes; what holds it accountable is that every field carries a URL + reviewer + date, live state is re-observed at sweep time, and the receipt records everything.
validate-pris advisory when no manifest exists yet (CI mode); strict with--require.Author-side verification (exact HEAD:
f590ddfcba15f7bb7f75788466660fc151abe1e5)corepack pnpm turbo run typecheck test build --force— 15/15 successful, 0 cachedbun test ./security— 17 tests, 0 failcd evaluation && bun src/run.ts— 6/6 fixturesbun src/run.ts --adapter=./src/example/broken-adapter.ts --expect-failure— negative control behaves (exit 0)bun test ./verification/test— 25 tests, 52 assertions, 0 failcheckon positive-backend →merge(exit 0); on nc1-stale-sha →refuse: [stale_head_sha](exit 1)Review / merge path
This PR follows the repo contract: independent review against the exact HEAD, then the merge owner records the
verification-manifest:v1block on this PR and runsbun verification/src/cli.ts sweep --pr=<n> --owner=<name>(dry-run first). Arena holds, stale SHAs, and invalid manifests all refuse loudly.