Context
Authors do check ACs at intake. The gap is that the intake read decays across a long or complex implementation and nothing re-anchors it at PR-open (@tobiu: "it can happen to get 'lost in the forest', so a when-done check matters"). This is not a missing first check; it is a missing last one.
pull-request-workflow.md:160 forbids author self-review — correct, cross-model review is the gate. A pre-open AC re-anchor substitutes for nothing and is a different act.
Measured over the last 50 PRs (open + closed)
| metric |
value |
reviewed PRs with ≥1 CHANGES_REQUESTED |
37 / 47 = 79% |
| two-cycle RCs |
6 |
Drop+Supersede |
4 — #16457, #16405, #16400, #16383; 3 ended with the PR closed |
| review labour carried by GPT family |
74 / 98 = 76% (Emmy 39, Euclid 35; all others single digits) |
Sampled 8 RC bodies across families. Every one has the same skeleton — premise sound · placement right · not a D+S · but the implementation does not deliver what the ticket required:
- #16444 — "does not yet enforce #16443 … the guard is not invoked by CI"
- #16442 — "additive beside, rather than authoritative over, the existing verdict"
- #16466 — "can only detect churn when tests hand-inject history"
- #16421 — "do not yet deliver the requested behavior"
- #16436 — "the ticket explicitly required classification"
3 of 8 are one sub-pattern: the capability was built and the production path never uses it. Each is one command to falsify.
Economics: unit CI ~13m + a fanned-out review ~20m ≈ 33m per RC cycle; 37 cycles ≈ 20 hours in this window, before counting D+S, which costs the implementation rather than a cycle. Operator bar: "if a self-AC check reduced 20% or more RCs => already worth it" ≈ 4 hours plus GPT tokens, currently the binding constraint.
The Fix
Two questions in the pull-request workflow's pre-open sequence. Budget-verified: 197 bytes, against skills.manifest.json:14 maxPositiveDeltaBytes: 250 (gates per-file and aggregate):
**Pre-open AC re-anchor:** re-read the LIVE ticket. Per AC saying enforced/invoked/authoritative: name the production-path observable and run it. A test injecting state proves the unit, not the AC.
Question 1 targets the D+S class — #16457's D+S was exactly a stale-ticket-premise failure: I had amended that body myself, then opened against my memory of it. Question 2 targets the 3-of-8 wiring class.
Contract Ledger
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
pull-request-workflow.md pre-open sequence |
this ticket |
two-question re-anchor before opening |
none — discipline-only, no mechanical gate proposed |
the inserted lines are the doc |
lint-skill-manifest green post-insert |
| skill budget |
skills.manifest.json:14 |
net addition ≤ 250 bytes |
exceed ⇒ CI fails; no prose expansion permitted |
— |
measured 197 bytes |
Acceptance Criteria
Out of Scope
- Any mechanical enforcement. A hook that re-reads a ticket and diffs it against a diff is a much larger design; this is discipline-only text.
- Author self-review —
:160's ban stands untouched.
- Review-load redistribution. The 76% GPT concentration is the larger lever and is a separate, operator-owned decision.
- Reviewer-rigor questions. I probed review body size as a rigor proxy and it failed: Claude reviews are the longest (mine the longest of all, 13.5k median) and Emmy's the shortest at 8k while finding more. Under a mandated template, length is fixed overhead and shorter can mean better. No claim about reviewer rigor is carried here; I have no instrument for it.
Avoided Traps
- Do not target "PRs merged without an RC." That metric pushes toward smaller PRs and pre-negotiated reviews; some RCs are the system working (Emmy's D+S on #16457 produced a better decomposition than my own reduction chain). The quantity to reduce is author-findable findings per PR.
- Do not add prose. The 250-byte cap is the feature — it forces two questions instead of a checklist nobody re-reads.
- Do not present this as a review substitute. It removes what an author can reach so the cross-family cycle spends itself on what they cannot.
Related
#16448 / D#15758 — unrelated lane; cited only because #16457's D+S is the worked example above.
- #16457, #16405, #16400, #16383 — the four D+S in the sample. #16444, #16442, #16466, #16421, #16436, #16465, #16416, #16415 — the sampled RC bodies.
.agents/skills/skills.manifest.json — the byte budget. ai/scripts/lint/lint-skill-manifest.mjs — its enforcer.
Live sweep at creation: no open ticket proposes a pre-open AC check; the nearest substrate is pull-request-workflow.md:160's self-review ban, which this deliberately does not touch. A2A sweep: no [lane-claim] on the pull-request skill.
Origin Session ID: 11695cce-9854-4be2-80c3-8ea4322298bf
Retrieval Hint: query_raw_memories("pre-open AC re-anchor pull request workflow 79 percent RC rate production path observable")
Authored by Vega (Claude Opus 5, Claude Code) — from @tobiu's friction→gold framing and a 50-PR measurement.
Context
Authors do check ACs at intake. The gap is that the intake read decays across a long or complex implementation and nothing re-anchors it at PR-open (@tobiu: "it can happen to get 'lost in the forest', so a when-done check matters"). This is not a missing first check; it is a missing last one.
pull-request-workflow.md:160forbids author self-review — correct, cross-model review is the gate. A pre-open AC re-anchor substitutes for nothing and is a different act.Measured over the last 50 PRs (open + closed)
CHANGES_REQUESTEDDrop+SupersedeSampled 8 RC bodies across families. Every one has the same skeleton — premise sound · placement right · not a D+S · but the implementation does not deliver what the ticket required:
3 of 8 are one sub-pattern: the capability was built and the production path never uses it. Each is one command to falsify.
Economics: unit CI ~13m + a fanned-out review ~20m ≈ 33m per RC cycle; 37 cycles ≈ 20 hours in this window, before counting D+S, which costs the implementation rather than a cycle. Operator bar: "if a self-AC check reduced 20% or more RCs => already worth it" ≈ 4 hours plus GPT tokens, currently the binding constraint.
The Fix
Two questions in the pull-request workflow's pre-open sequence. Budget-verified: 197 bytes, against
skills.manifest.json:14maxPositiveDeltaBytes: 250(gates per-file and aggregate):Question 1 targets the D+S class — #16457's D+S was exactly a stale-ticket-premise failure: I had amended that body myself, then opened against my memory of it. Question 2 targets the 3-of-8 wiring class.
Contract Ledger
pull-request-workflow.mdpre-open sequencelint-skill-manifestgreen post-insertskills.manifest.json:14Acceptance Criteria
npm run ai:lint-skill-manifestpasses; the net positive delta is ≤ 250 bytes, measured and stated in the PR.§ref— a pointer-free inline addition.Out of Scope
:160's ban stands untouched.Avoided Traps
Related
#16448/D#15758— unrelated lane; cited only because #16457's D+S is the worked example above..agents/skills/skills.manifest.json— the byte budget.ai/scripts/lint/lint-skill-manifest.mjs— its enforcer.Live sweep at creation: no open ticket proposes a pre-open AC check; the nearest substrate is
pull-request-workflow.md:160's self-review ban, which this deliberately does not touch. A2A sweep: no[lane-claim]on the pull-request skill.Origin Session ID: 11695cce-9854-4be2-80c3-8ea4322298bf
Retrieval Hint:
query_raw_memories("pre-open AC re-anchor pull request workflow 79 percent RC rate production path observable")Authored by Vega (Claude Opus 5, Claude Code) — from @tobiu's friction→gold framing and a 50-PR measurement.