Skip to content

P3 verification round — Part A re-evidenced against merged `main` `71195501`


rank: decision outranks: [] doc_id: PTV-DEC-0024 title: PTV-SCF-0001 P3 verification round — re-evidenced against 71195501; still nine FAIL, three moved date: 2026-08-27 status: open — awaiting human countersign owner: petrova-codes scaffold: PTV-SCF-0001 phase: P3 supersedes: none amends: docs/decisions/2026-08-25-ptv-scf-0001-p3-verification-round.md depends_on: docs/decisions/2026-08-25-ptv-scf-0001-p3-verification-round.md

Section titled “rank: decision outranks: [] doc_id: PTV-DEC-0024 title: PTV-SCF-0001 P3 verification round — re-evidenced against 71195501; still nine FAIL, three moved date: 2026-08-27 status: open — awaiting human countersign owner: petrova-codes scaffold: PTV-SCF-0001 phase: P3 supersedes: none amends: docs/decisions/2026-08-25-ptv-scf-0001-p3-verification-round.md depends_on: docs/decisions/2026-08-25-ptv-scf-0001-p3-verification-round.md”

P3 verification round — Part A re-evidenced against merged main 71195501

Section titled “P3 verification round — Part A re-evidenced against merged main 71195501”

Date: 2026-08-27 Amends: PTV-DEC-0021 (2026-08-25 round), Part A only.

It is a re-measurement of the nine FAIL verdicts in PTV-DEC-0021 against merged main at 71195501, because that record measured against b71930ea and the tree has moved underneath it.

It is not a discharge of anything. PTV-DEC-0021 is C7 act one and its human countersign is unticked; this record inherits that state rather than resolving it. Until both are countersigned, the standing verdicts are PTV-DEC-0021’s. “Nine gates re-measured against current main” and “the round now says nine were re-measured” are different objects, and only the second closes anything.

Part B/C (the twelve friction items F-45…F-56) is not re-run here. Two new items are added at the end because re-evidencing surfaced them.

factvalue
round’s stated baseb71930ea
merged main at this measurement71195501 (origin/main)
commits between93 (43 substantive: non-merge, non-sweep)
files changed124 — 85 outside state/, 39 inside

G-P3-2, G-P3-6 and G-P3-9 all have code and artefacts merged in that window that did not exist when the round was written.


G-P3-2 — probe asserts every A2 hop, three green runs, run IDs cited

Section titled “G-P3-2 — probe asserts every A2 hop, three green runs, run IDs cited”

FAIL. Materially moved; the failing clause is a different one.

Merged since the round: cli/src/verbs/probe_run.ts (the caller that never existed), cli/src/probes/write-probe/record.ts (append-only campaign writer), schemas/probe-run.v1.json, scripts/check-probe-run-evidence.mjs, .github/workflows/probe-run-evidence.yml, docs/evidence/README.md.

Still failing, on evidence rather than absence of machinery:

  • docs/evidence/g-p3-2-probe-runs.jsonl is 0 bytes. Zero runs recorded, so zero green runs and no identifiers to cite.
  • The probe is still the skeleton. index.ts:95-120 runs five hops (schema resolution, fingerprint, registry lookup, admission, admission-refuses) of A2’s nine; index.ts:4 still reads “the apply path is C2’s”. M3.3 is untouched.

What changed is that the gate’s failure is now measurable rather than structural: the artefact, its schema, its writer and its checker all exist, and M3.3 plus a three-run campaign is the whole remaining distance.

G-P3-3 — re-invocation returns already-emitted, opens no second PR

Section titled “G-P3-3 — re-invocation returns already-emitted, opens no second PR”

FAIL, unchanged. grep -rn 'idempot|already' cli/src/probes cli/tests/probes returns three comment-only hits, none an assertion. The CLI verbs carry idempotency_key (cli/src/idempotency.ts), the probe does not. M3.4 has no artefact and no commit.

G-P3-4 — VCRM moves six SRs to test-verified

Section titled “G-P3-4 — VCRM moves six SRs to test-verified”

FAIL, unchanged. docs/PTV-VCRM-0001.md does not exist at 71195501. M3.6 untouched. Of the six SRs only PTV-SR-0005/PTV-SR-0006 are cited by any hop.

G-P3-5 — induced failure emits refusal code + next action

Section titled “G-P3-5 — induced failure emits refusal code + next action”

FAIL, unchanged. No refusal code is attached to any recovery string: grep -rn 'PTV-RF|refusal_code' cli/src/probes returns nothing. spec/refusals.yaml was edited twice in this window (3f54ff8c, 79b97d23) — both repairs to its own header and referent, neither a publication. Nothing under host/src publishes /errors.json; the only in-tree references are host/tests/refusals.test.ts and spec/refusals.yaml’s own comments.

G-P3-6 — structured per-run records at a console-readable path, parsed back

Section titled “G-P3-6 — structured per-run records at a console-readable path, parsed back”

FAIL. Materially moved; two of three defects discharged.

  • Emission — probe_run.ts writes each record to docs/evidence/g-p3-2-probe-runs.jsonl. The record is no longer caller-less.
  • Console read path — host/src/sources/evidence.ts + host/src/tools/evidence.ts read the artefact and expose it, with caveats that cannot be dropped by the caller. scripts/vercel-build.sh:32 stages the whole docs/ tree.
  • Still failing — the gate wants one record read back and parsed in the round. There are zero records. Nothing to parse.
  • Carried — PTV-FND-0062 records that the “reachable” clause cannot be read unambiguously: Vercel stages docs/ wholesale, the Railway image copies docs/decisions only, so the clause is true on one deployed surface and false on the other. That is a gate-wording defect and it survives at 71195501.

G-P3-7 — F-23 discharged: law fetch returns exact bytes, no curl workaround

Section titled “G-P3-7 — F-23 discharged: law fetch returns exact bytes, no curl workaround”

FAIL, and the gate is now demonstrably not dischargeable by work in this repo.

Eight skills changed in this window. Step 1 now reads “Fetch … with curl, not with a summarising fetch tool” plus a verify clause (Law fingerprint: line, Source commit: line, order of 8 KB) — skills/petrova-verify-round/SKILL.md:14-20 and seven siblings. That is the waiver’s remedy for method discipline, and it is a real improvement.

It is not F-23’s discharge. F-23 asks that the law fetch return exact bytes without the curl workaround; the merged change codifies the workaround. Thirteen days of every session working around the same environment constraint — this record included — is a standing condition of the environment, not a gap in the code. No commit in this repo can discharge it.

Recommendation, not a verdict: G-P3-7 should be reworded to what the repo can actually assert (method declared, fingerprint verified, byte count checked), or the environment must change. Both are decisions for the operator. Leaving it an open FAIL implies buildable work that does not exist — the shape spec/refusals.yaml’s header exists to prevent. This round does not reword it; L6 forbids that here.

G-P3-8 — F-24 discharged: ten cold fetches, zero refusals

Section titled “G-P3-8 — F-24 discharged: ten cold fetches, zero refusals”

FAIL. Moved from unevaluable to evaluable and empty.

The round’s finding was that the gate named no artefact. It now names one: docs/evidence/g-p3-8-law-fetch.jsonl + schemas/law-fetch-attempt.v1.json + scripts/check-law-fetch-evidence.mjs + .github/workflows/law-fetch-evidence.yml. The file is 0 bytes — zero of ten attempts.

Same standing condition as G-P3-7: the campaign can only be produced by fresh sessions in an environment whose fetch tool paraphrases. Same recommendation, same refusal to act on it here.

Discharged in this window: PTV-FND-0063 (a checker printing “every recorded campaign is citable” over zero records). Measured at 71195501, both checkers now print “rules hold over 0 attempt(s) — the artefact exists and asserts nothing yet. This is not evidence toward G-P3-8” and exit 0. The vacuous green is gone.

G-P3-9 — F-26 discharged: documented location, in every phase skill, populated here

Section titled “G-P3-9 — F-26 discharged: documented location, in every phase skill, populated here”

FAIL, narrowly, and on one reading of one clause. This is the largest move of the nine; all three clauses were dead at b71930ea.

  1. Documented location — holds. state/README.md (merged 9a65cb96) names state/<slug>.yaml (current_phase, gate_open) and state/transitions/<slug>.jsonl, documents the derivation, and states that null means unknown, not empty.
  2. In every phase skill’s preconditions — holds. petrova-phase-open:32-34, petrova-phase-close:27-29, petrova-verify-round:28-30. petrova-phase-cycle does not carry it and is not a counterexample: it was deprecated 2026-08-13 and ships no workflow.
  3. Populated for petrova-codes — partial. state/petrova-codes.yaml:158-159 now reads current_phase: Phase-3 / gate_open: true, written by a scheduled sweep (fe513a4a), after F-49’s regex fix landed in cli/src/phase-slugs.ts (ede9c841). But state/transitions/petrova-codes.jsonl still does not exist while twelve other slugs have one — see F-57 below.

Clause 3 turns on whether “the location” is the yaml fields or both files state/README.md names. Under the first reading this gate passes. Under the second it does not. This round applies the precedent PTV-DEC-0021 set at G-P3-5 — half holds, so it fails — and records the reading dependency as F-58 rather than resolving it by choosing the reading that produces the nicer verdict.

G-P3-10 — G-P2-2/G-P2-3 re-entered and recorded PASS by an agent that did not do the work

Section titled “G-P3-10 — G-P2-2/G-P2-3 re-entered and recorded PASS by an agent that did not do the work”

FAIL, unchanged, and structurally not dischargeable by this agent. No record dated 2026-08-15 or later evaluates either gate; every reference remains a forward reference from the P3 open. The operator line required by PTV-FND-0026 on the two proxy-signed instruments is still unsupplied, and no agent may supply it.

Requiring an agent that did not do the work is a property of the gate. It will read as outstanding on every round this agent produces. Recorded here as such, not as backlog.


gateb71930ea71195501moved
G-P3-2FAILFAILyes — artefact, writer, schema, checker merged; 0 runs, 5/9 hops
G-P3-3FAILFAILno
G-P3-4FAILFAILno
G-P3-5FAILFAILno
G-P3-6FAILFAILyes — caller and console read path merged; 0 records to parse back
G-P3-7FAILFAILmethod codified; F-23 not discharged and not dischargeable here
G-P3-8FAILFAILartefact named; 0 attempts. Unevaluable → evaluable-and-empty
G-P3-9FAILFAIL (narrow)yes — 2 of 3 clauses discharged; third partial
G-P3-10FAILFAILno

One PASS, nine FAIL — the count is unchanged and so is the conclusion: P3 is not closeable. What changed is where the failures sit. Three gates now fail for want of runs rather than for want of machinery.

G-P3-7 and G-P3-8 are waiting on the environment, not on a build. G-P3-10 is waiting on a different agent and an operator line. The remaining buildable set is M3.3 (probe write path), M3.4 (re-invocation), M3.5 (refusal codes on the recovery paths) and M3.6 (VCRM).

M3.6 is the one that is self-contained and unblocks a gate on its own: G-P3-4 needs docs/PTV-VCRM-0001.md, and four of its six SR rows have no probe assertion behind them today — which is itself the content of the row, not a blocker on writing it.

IDItemClassTarget
F-57F-49’s fix landed in two of three call sites. cli/src/verbs/sweep_state.ts:72 keeps a third hand-copied ^phase-(\d+)-(open|close|complete)$, so the transitions log for petrova-codes is still never written while state/petrova-codes.yaml resolves correctly. A partial fix that leaves one surface stale is harder to see than no fix.DEFERREDP4 · M4.5
F-58G-P3-9 clause 3 does not say whether “populated” means the yaml phase fields or both files state/README.md names. The gate’s verdict currently depends on the reading.DEFERREDP4 · M4.8 (with F-55, gate/schema vocabulary)

Neither is absorbed into P3. F-57 is a one-line change and is deferred because it is one line — the shape F-22’s and F-47’s deferrals established.

The spine refused its own phase close on the check it shipped the same morning: ACCEPTANCE_GATE_PASSED fires against the phase that built it, by name. That is the correct outcome and is recorded as one rather than worked around.

  • git diff --name-only b71930ea 71195501 (124 files, 85 outside state/); git log --oneline b71930ea..71195501 (93 commits).
  • cli/src/verbs/probe_run.ts:1-112, cli/src/probes/write-probe/record.ts:1-103, cli/src/probes/write-probe/index.ts:1-121 — G-P3-2, G-P3-6.
  • docs/evidence/g-p3-2-probe-runs.jsonl, docs/evidence/g-p3-8-law-fetch.jsonl — both 0 bytes, measured at 71195501.
  • node scripts/check-probe-run-evidence.mjs / check-law-fetch-evidence.mjs — run at 71195501, both exit 0 with the zero-record caveat printed beside the count.
  • host/src/sources/evidence.ts:1-50, host/src/tools/evidence.ts:1-60, scripts/vercel-build.sh:17-32 — the console read path and what each surface stages.
  • skills/petrova-verify-round/SKILL.md:14-20 and seven siblings — G-P3-7.
  • state/README.md:1-60, state/petrova-codes.yaml:158-159, cli/src/phase-slugs.ts:28-38, cli/src/verbs/sweep_state.ts:72,247-254, skills/petrova-phase-open/SKILL.md:32-34, petrova-phase-close:27-29, petrova-verify-round:28-30 — G-P3-9, F-57.
  • docs/findings/20260825-1900-g-p3-6-names-the-wrong-gate-and-cannot-be-read-as-written.md (PTV-FND-0062), docs/findings/20260826-1230-a-green-that-cannot-tell-nothing-to-report-from-nothing-reported.md (PTV-FND-0063).
  • Subagent: PTV-SCF-0001 P3 verification round, re-evidencing pass (session 2026-08-27)
  • Human: ☐ countersign — accepts these re-evidenced verdicts.

Ticking this closes nothing and does not tick PTV-DEC-0021. Both records carry their own countersign; this one amends the other’s Part A and inherits every constraint it recorded, including that a P3 close in this state voids the P2 waiver.