PTV-SCF-0001 P3 — phase open
Date: 2026-08-14
Status: open
Supersedes: none
Superseded-by: none — current
Phase: PTV-SCF-0001 P3 · Verification harness
Predecessor: P2 · Golden prompts as skills — CLOSED 2026-08-13 with two gates waived
Shape: G-01 (docs/PETROVA-GOLDEN-PROMPTS.md §2), run through skills/petrova-phase-open/SKILL.md
Terminal state of this record: a phase opened with scope, gates and carried
friction, plus a dry-run start_phase invocation. It applies nothing, seeds no
work, and runs no part of the phase it opens.
What was loaded
Section titled “What was loaded”https://petrova.blog/llms-preamble.txt— 8,235 bytes, fetched withcurl, not with a summarising fetch tool. The skill says “fetch”; the tool that ordinarily does so returns a model-written paraphrase, which is F-23. The method used is named here because F-36 records that no skill specifies one. Operating underL1–L7andW1–W4as written in those bytes../.petrova/contract.yaml— present,slug: petrova-codes, schema_version 1. The repo is onboarded, so the skill’s second refusal condition does not fire../.petrova/brand.yaml— absent. The skill’s footer resolves links throughbrand.yaml#blog.base. It resolved through the literal default instead. This is F-29, and it is live in the control plane, not only in consumers.
Law is cited by label throughout (L2, L6), never by meta-rule number (W1).
Step 1 — what phase is currently open
Section titled “Step 1 — what phase is currently open”None. Read from merged decision-doc history (L5), each path proved to
resolve on origin/main with git cat-file -e origin/main:<path>:
| Record | Resolves on origin/main | Verdict |
|---|---|---|
2026-08-13-ptv-scf-0001-p2-open.md | yes | opened P2 |
2026-08-13-ptv-scf-0001-p2-verification-round.md | yes | the round — 4 gates PASS, 2 FAIL |
2026-08-13-waiver-ptv-scf-0001-p2.md | yes | waives G-P2-2 and G-P2-3 |
2026-08-13-ptv-scf-0001-p2-close.md | yes | P2 CLOSED, countersigned ☑ at line 213 |
ls docs/decisions/ | grep -i p3 returns nothing. No record opens P3 or any
later phase. No phase is open, so the skill’s first refusal condition does not
fire.
The machine mirror disagrees, and the source wins (L5).
state/petrova-codes.yaml:158-159 carries current_phase: null and
gate_open: null — which happens to agree that no phase is open, but agreed by
never having been written rather than by tracking anything;
state/transitions/petrova-codes.jsonl does not exist. The decision-doc history
is authoritative and was read directly (W4). The mirror is raised below as
new friction, not repaired here.
Step 2 — is the predecessor CLOSED
Section titled “Step 2 — is the predecessor CLOSED”Yes — and closed with two acceptance gates recorded FAIL and waived, never passed. Stating it any other way would be the projection the close record itself forbids.
2026-08-13-ptv-scf-0001-p2-close.md:16-19— CLOSED; four gates PASS on re-run evidence, G-P2-2 and G-P2-3 FAIL-and-waived.- Human countersign present and ticked (
:213). - The waiver is a merged instrument of its own with a declared shape
(
2026-08-13-acceptance-gate-waiver-shape.md).
P2’s close explicitly authorises this phase to open (:178-179): P3 ·
Verification harness may open, and inherits the ledger.
Step 3 — entry criteria
Section titled “Step 3 — entry criteria”The scaffold declares phases sequential and gated
(docs/specs/2026-08-12-ptv-scf-0001-scaffold-rev-a.xml:146,
carry-over-discipline) with no per-phase entry-criteria block. The criteria are
therefore the sequencing discipline itself plus the predecessor close’s
consequence clause — the same reading P2’s open used
(2026-08-13-ptv-scf-0001-p2-open.md:36).
| # | Criterion | Verdict | Evidence |
|---|---|---|---|
| 1 | Predecessor phase closed | MET | P2 close merged a4d87af (#278), countersigned. |
| 2 | No phase skipped | MET, with the P0 defect still standing | P0, P1, P2 each have terminal artefacts merged. P0 still has no close record — carried below as F-39, unrepaired. |
| 3 | The predecessor explicitly authorises this phase to open | MET | P2 close :178-179. |
| 4 | Deferred friction targeted at this phase is enumerable | MET | Thirteen items, §Carried friction. |
| 5 | The waiver P2 closed on is still live | MET, and conditional | 2026-08-13-waiver-ptv-scf-0001-p2.md:2-6 — live, and void if this phase closes without discharging F-23, F-24 and F-26. |
No criterion is unmet or unevidenced. No halt condition applies.
Step 4 — F-14’s route, decided here
Section titled “Step 4 — F-14’s route, decided here”P2’s close required this record to state which route F-14 took
(2026-08-13-ptv-scf-0001-p2-close.md:220-223). It takes the second:
adoption at P3’s open, not a P2 addendum round.
The history, stated plainly:
- P2’s open raised F-14 · P0 has no close record and routed it into P2’s
verification round for classification (
…p2-open.md:57). - P2’s round never mentions it. That is a miss in the round, found by the close.
- P2’s close refused to classify it — classification is the round’s act, and a
close performing it is precisely what G-03 forbids. It carried it
UNCLASSIFIED (
…p2-close.md:133). - The ID also collides: P1’s round already bound F-14 to “ARES is on the
master with no registered slug behind it”, classified IN-BUDGET there
(
2026-08-12-ptv-scf-0001-p1-verification-round.md:164,191).
Route taken. The item is re-issued here as F-39 · P0 has no close record, the first free identifier in the series (F-00…F-38 are all in use). It enters P3 as inherited friction and will be classified by P3’s own verification round, which is a round’s act performed by a round.
The alternative — an addendum verification round scoped to P2 for this one item — is the more literal reading of G-02 and is rejected on cost, not on principle: it reopens a closed phase’s paperwork for a single classification that P3’s round can perform without reopening anything. Anyone who holds that the literal reading should have won has the whole argument here to make it with.
P1’s F-14 is untouched. It keeps its ID, its meaning and its IN-BUDGET
classification. Nothing in this record edits a merged decision (L3).
A · The scaffold’s stated objective
Section titled “A · The scaffold’s stated objective”From docs/specs/2026-08-12-ptv-scf-0001-scaffold-rev-a.xml:232-254. Objective:
“Discharge the verification debt. This is what makes the baseline defensible.”
| # | Task | Source |
|---|---|---|
| A1 | Register and provision the canary repo — dedicated scoped credential, reachable by nothing else. | :236-237 |
| A2 | Build the end-to-end write probe asserting every hop: schema resolution, fingerprint match, idempotency key, registry lookup, admission, phase integrity, dry-run render, apply, PR emission, metadata parse-back. | :238-244 |
| A3 | The re-invocation assertion is mandatory — re-invocation returns already-emitted, never a duplicate. Idempotency never exercised under re-invocation is an assumption, not a property. | :245-246 |
| A4 | Emit structured per-run records where the console can read them. | :247-248 |
| A5 | Produce the VCRM (docs/PTV-VCRM-0001.md) mapping probe assertions to PTV-SR-0001/0002/0005/0006/0007/0008. | :249-250, :452 |
B · The three discharge-critical carried items
Section titled “B · The three discharge-critical carried items”In scope because the waiver is void without them
(2026-08-13-waiver-ptv-scf-0001-p2.md:139-142), not because this phase chose
them.
| # | Item | Why it is load-bearing |
|---|---|---|
| B1 | F-23 · the fetch path returns a summary, not the artefact | Every skill’s law citation currently rests on a paraphrase. This record had to route around it with curl to be correct. |
| B2 | F-24 · the preamble’s voice reads as prompt injection; intermittent outright fetch refusal | A skill whose step 1 is “fetch the law” fails intermittently at step 1. |
| B3 | F-26 · no skill says where phase state lives | The one mandatory load, contract.yaml, carries no phase state at all. Confirmed again in this session. |
C · Carried, and permitted to slip to P4
Section titled “C · Carried, and permitted to slip to P4”The waiver’s asymmetry (:144-146) says F-22, F-27, F-28, F-29, F-30 and F-31
may slip to P4 without voiding it. They are carried here as real scope with that
permission stated, not silently deprioritised. F-25, F-36, F-38 and F-39 are
carried with no such permission and no discharge-criticality — they are P3’s to
classify or discharge.
Explicitly out of scope
Section titled “Explicitly out of scope”- Applying the C4 DR allocation. It is ratified and deliberately unapplied,
blocked on F-20 (
estate.propose_element/estate.modify_elementunbuilt). - Anything in
rocky-hq(F-32). UnderL4that repo’s findings belong in its own ledger; absorbing them here would be this repo writing another repo’s project truth. - Any change under
.github/workflows/. Write verbs refuse those paths unconditionally (W3); if P3’s work needs one, it is flagged as a human commit and never composed as a verb.
Carried friction — inputs, not extras
Section titled “Carried friction — inputs, not extras”Every item the predecessor’s round and close deferred into P3, with its source.
Under L6 these are inputs to this phase; omitting one, or restating it without
its source, is a refusal condition of the skill that composed this record.
| ID | Item | Source | Note |
|---|---|---|---|
| F-22 | Preamble self-contradicts on W1 — one line forbids citing meta-rules by number, another instructs it | round :69 | may slip to P4 |
| F-23 | Fetch path returns a summary, not the artefact | round :70 | discharge-critical |
| F-24 | Preamble’s voice reads as injection; intermittent fetch refusal | round :71 | discharge-critical |
| F-25 | verify_round and close_phase schemas disagree with the golden prompts on who classifies friction | round :72 | — |
| F-26 | No skill says where phase state lives; contract.yaml carries none | round :73 | discharge-critical |
| F-27 | petrova-onboard has no already-admitted exit; consumer-local registry.yaml is a wrong-file trap | round :74 | may slip to P4 |
| F-28 | Verb payload schemas sit under ## Reference, not ## Load first | round :75 | may slip to P4 |
| F-29 | .petrova/brand.yaml absent in consumers and here; no stated fallback | round :76 | may slip to P4 |
| F-30 | Skills mandate undefined vocabularies (severity scale, legal milestone states) | round :77 | may slip to P4 |
| F-31 | commands/ slash-command invokers unexercised; install path unverified | round :78 | may slip to P4 — partially exercised by this session, see below |
| F-36 | ”merged” is undefined and unevaluable without git history | close :130 | — |
| F-38 | close_phase schema cannot express a waiver; blocks every consumer that needs one | close :132 | — |
| F-39 | P0 has no close record — adopted here from the unclassified F-14, §Step 4 | …p2-open.md:57, close :133 | classification is P3’s round’s act |
F-32 is not carried into P3. Its target is rocky-hq’s own ledger (L4),
which is a named target that is not “the next phase” — recorded so its absence
here reads as a routing decision rather than an omission.
New friction raised at this open
Section titled “New friction raised at this open”Surfaced by running the act, not looked for. Both go to P3’s round.
- F-40 · the machine mirror of phase state is not written by anything.
state/petrova-codes.yaml:158-159carriescurrent_phase: null/gate_open: null, andstate/transitions/petrova-codes.jsonldoes not exist while eleven other slugs have one. The values are not stale so much as never populated. It is F-26’s shape confirmed in the control plane itself: the authoritative phase state is merged decision-doc history and nothing projects it. Not repaired here — hand-editingstate/is exactly the boundary the verb surface exists to gate. - F-41 ·
start_phase’s declared side effects do not exist in this repo. The schema’sside_effectssays it “modifies MILESTONES.md to add phase header + seeded milestones” (spec/verbs/start_phase.schema.json:7). There is noMILESTONES.mdat this repo’s root — onlycore/templates/MILESTONES.md.tmpl. A verb that cannot state where its own output lands cannot be dry-run honestly, which is why §Verb invocation below reports what it reports.
Partial discharge evidence for F-31: the petrova-phase-open skill was
loaded and followed end-to-end to produce this record. That exercises the skill
body. It does not exercise the commands/petrova-phase-open.md slash-command
invoker or the symlink install path, which remain unverified — so F-31 stays open
and is not claimed as discharged.
Acceptance gates
Section titled “Acceptance gates”No G-P3-* gates existed before this record; writing them is this act’s output.
Each is evaluable true or false by someone who was not in this session.
| ID | Gate | Evidence kind |
|---|---|---|
| G-P3-1 | The canary repo exists, appears in registry.yaml, and its credential is scoped to it alone — demonstrated by that credential failing against a second governed repo. | test |
| G-P3-2 | The probe asserts every hop named in scope A2 and runs green on three consecutive runs, with the three run identifiers cited in the round record. | test |
| G-P3-3 | Re-invoking the probe with an already-used idempotency key returns already-emitted and opens no second pull request — asserted, not assumed. | test |
| G-P3-4 | docs/PTV-VCRM-0001.md exists and shows PTV-SR-0001, -0002, -0005, -0006, -0007, -0008 moved from claimed-on-inspection to test-verified, each row naming the probe assertion that verifies it. | fixture |
| G-P3-5 | An induced probe failure emits a named recovery path — a refusal code from errors.json and a stated next action — not a stack trace. | test |
| G-P3-6 | Structured per-run records are emitted at a path a console read can reach, and one is read back and parsed in the round. | script |
| G-P3-7 | F-23 discharged: a skill’s law-fetch step returns the artefact’s exact bytes, byte-count matching curl, demonstrated in a session that did not use curl as a workaround. | test |
| G-P3-8 | F-24 discharged: ten consecutive law-fetch attempts across fresh sessions return the artefact with zero refusals. | test |
| G-P3-9 | F-26 discharged: a named, documented location for a governed repo’s phase state exists, is stated in every phase skill’s preconditions, and is populated for petrova-codes itself. | fixture |
| G-P3-10 | G-P2-2 and G-P2-3 are re-evaluated against fresh cold-session runs and record PASS — by an agent that did not do the work that made them pass. Not by assertion, and not by this phase’s author. | human-signoff |
G-P3-10 is the waiver’s own discharge condition
(2026-08-13-waiver-ptv-scf-0001-p2.md:134-137), restated as a gate so P3 cannot
close while treating it as someone else’s business.
Sub-milestones
Section titled “Sub-milestones”Seeded with a state and one acceptance gate each. All open.
| ID | Chunk | State | Acceptance gate |
|---|---|---|---|
| M3.1 | C0 · canary repo registered and credential scoped | open | G-P3-1 |
| M3.2 | C1 · probe skeleton: schema resolution, fingerprint, registry lookup, admission | open | G-P3-2 (partial — hops asserted individually) |
| M3.3 | C2 · probe write path: dry-run render, apply, PR emission, metadata parse-back | open | G-P3-2 |
| M3.4 | C3 · re-invocation and idempotency assertion | open | G-P3-3 |
| M3.5 | C4 · structured per-run records and named recovery paths | open | G-P3-5, G-P3-6 |
| M3.6 | C5 · VCRM — six SRs to test-verified | open | G-P3-4 |
| M3.7 | C6 · discharge F-23, F-24, F-26 | open | G-P3-7, G-P3-8, G-P3-9 |
| M3.8 | C7 · verification round, then close — two acts, two sessions | open | G-P3-10 |
C7 is two separate acts by rule: petrova-verify-round produces the round
record, and only after that merges does petrova-phase-close run.
Standing constraints on this phase
Section titled “Standing constraints on this phase”These are inherited, not chosen, and are restated because a phase that forgets them closes on a lapsed instrument.
- P3 may not waive G-P2-2 or G-P2-3 again. It inherits the work, not the
exemption (
…p2-close.md:180-181, waiver:148-163). - If P3 closes without discharging F-23, F-24 and F-26, the waiver is void,
both gates revert to FAIL, and P2 stands closed on a lapsed instrument. That
is a finding to be raised at P3’s close, not a matter of interpretation
(waiver
:139-142). - No reversion to pasting the law. Skills continue to fetch
(
…p2-close.md:188-189). F-23’s fix is to make the fetch return the artefact, not to abandon fetching. - The work that makes a gate pass may not be done by the agent that evaluates it (G-P3-10). P2’s round found that every genuinely independent verification found something.
Verb invocation
Section titled “Verb invocation”None, and the reason is structural rather than incidental. petrova-codes
carries fleets_allowed: [] in its own registry self-entry by design —
control-plane changes go through human PR review, never agent automation. There
is no addressable verb surface here to dry-run against, the same finding P2’s
close recorded (:191-199). This record, merged by human review, is the
deliverable.
The invocation is composed anyway, because L2 makes the dry-run the deliverable
and a composed payload is inspectable where a shrug is not. It is presented as a
payload, not as a runnable command:
{ "envelope": { "verb": "start_phase", "target_repo": "petrova-codes", "dry_run": true, "actor": "human:alex@devarno.com", "triggered_by": { "kind": "phase_close", "ref": "docs/decisions/2026-08-13-ptv-scf-0001-p2-close.md" }, "idempotency_key": "<sha256 of start_phase|petrova-codes|<canonical params>, computed at compose time>" }, "params": { "phase_number": 3, "name": "Verification harness", "scope": "Discharge the verification debt: canary repo, end-to-end write probe with a mandatory re-invocation assertion, structured per-run records, VCRM for PTV-SR-0001/0002/0005/0006/0007/0008; plus the three discharge-critical carried items F-23, F-24, F-26.", "acceptance_gate": [ { "claim": "Canary repo registered; its credential fails against any second governed repo.", "evidence_kind": "test" }, { "claim": "Probe asserts every declared hop and runs green three consecutive times, run IDs cited.", "evidence_kind": "test" }, { "claim": "Re-invocation with a used idempotency key returns already-emitted and opens no second PR.", "evidence_kind": "test" }, { "claim": "VCRM shows six named SRs moved to test-verified, each citing its probe assertion.", "evidence_kind": "fixture" }, { "claim": "Induced probe failure emits a named recovery path, not a stack trace.", "evidence_kind": "test" }, { "claim": "Per-run records emitted at a console-readable path and parsed back in the round.", "evidence_kind": "script" }, { "claim": "Law fetch returns the artefact's exact bytes without a curl workaround.", "evidence_kind": "test" }, { "claim": "Ten consecutive cold law-fetches return the artefact with zero refusals.", "evidence_kind": "test" }, { "claim": "A documented phase-state location exists, is named in every phase skill, and is populated for petrova-codes.", "evidence_kind": "fixture" }, { "claim": "G-P2-2 and G-P2-3 re-evaluated PASS on fresh cold runs by an agent that did not do the work.", "evidence_kind": "human-signoff" } ], "seeded_milestones": [ { "id": "M3.1", "title": "Canary repo registered and credential scoped" }, { "id": "M3.2", "title": "Probe skeleton — resolution, fingerprint, registry, admission" }, { "id": "M3.3", "title": "Probe write path — render, apply, PR, parse-back" }, { "id": "M3.4", "title": "Re-invocation and idempotency assertion" }, { "id": "M3.5", "title": "Structured per-run records and named recovery paths" }, { "id": "M3.6", "title": "VCRM — six SRs to test-verified" }, { "id": "M3.7", "title": "Discharge F-23, F-24, F-26" }, { "id": "M3.8", "title": "Verification round, then close" } ], "friction_carryover": [ "F-22", "F-23", "F-24", "F-25", "F-26", "F-27", "F-28", "F-29", "F-30", "F-31", "F-36", "F-38", "F-39" ] }}Two mismatches between that payload and this repo, stated rather than smoothed:
friction_carryoveris typed as “deferred milestone IDs”. These are friction IDs, which is the only vocabulary the round and close records use. The schema and the golden prompts disagree here in the same way F-25 records for classification — noted against F-25 rather than resolved by inventing milestone IDs that no record uses.- The verb’s declared
side_effectswriteMILESTONES.md, which does not exist in this repo. That is F-41 above.
Sources
Section titled “Sources”docs/specs/2026-08-12-ptv-scf-0001-scaffold-rev-a.xml:146,232-254,452,473— sequencing, P3 tasks, exit gate, P3 artefacts.docs/PETROVA-GOLDEN-PROMPTS.md:110-151— G-01.skills/petrova-phase-open/SKILL.md— the skill run to produce this.docs/decisions/2026-08-13-ptv-scf-0001-p2-close.md:115-199,220-223— the ledger, P3’s consequences, F-14’s undecided route.docs/decisions/2026-08-13-ptv-scf-0001-p2-verification-round.md:67-82— the fourteen classified items.docs/decisions/2026-08-13-waiver-ptv-scf-0001-p2.md:2-6,134-146,148-163— discharge set, void condition, P4-slip asymmetry, what the waiver does not license.docs/decisions/2026-08-13-ptv-scf-0001-p2-open.md:57— F-14 as raised.docs/decisions/2026-08-12-ptv-scf-0001-p1-verification-round.md:164,191— P1’s F-14, untouched.docs/PETROVA-SDD-BASELINE.md:223-276— the six SR texts G-P3-4 moves.spec/verbs/start_phase.schema.json,spec/verbs/_common.schema.json— payload shape.state/petrova-codes.yaml:158-159— the unpopulated mirror, F-40.
Sign-off
Section titled “Sign-off”- Subagent: PTV-SCF-0001 P3 open (session 2026-08-14)
- Human: ☑ (proxy) countersign — opens P3 · Verification harness, accepts F-14’s
route as adoption at open under the new ID F-39, accepts the ten
G-P3-*gates as written, and accepts the four standing constraints above.- Countersigned by
human:devarnoon 2026-08-14, by explicit directive in session (“approved — sign it”). Ticked by the agent as scribe, not as signatory: the human act is the directive, and this line is its record. No other part of this document is edited — a sign-off block reaching its terminal state is not a revision of the record’s body (L3). - PTV-SCF-0001 P3 · Verification harness is OPEN as of 2026-08-14. The
thirteen carried items are its inputs, the ten
G-P3-*gates are the only conditions under which it may close, and the two new items raised at this open (F-40, F-41) belong to its verification round.
- Countersigned by