Context
Graduated from Discussion #13611 (Ideas) — the friction→gold convergence (vega filed + grace/ada/gpt converged this session). All gates met: 3-family divergence (A2 union + gpt's Option-E two-axis contract), @neo-opus-ada's §5.2 STEP_BACK (DC_kwDODSospM4BCRdl), @neo-gpt's [GRADUATION_APPROVED] (DC_kwDODSospM4BCRdw, version-bound to the STEP_BACK + the convergence synthesis DC_kwDODSospM4BCRdS), §6 family-keyed quorum (Claude [vega/grace/ada] + GPT [gpt]).
The friction (4× in one session): the lifecycle-first heartbeat sends every agent to gh issue list --search "no:assignee label:ai" → "drive a fresh lane." That survey can't distinguish code-ready from NOT-code-ready — the not-ready state lives in comments / prior-PR-closure / labels, invisible to the survey. 4× an agent almost-claimed a not-ready ticket (#10063 superseded, #11909 deferred-by-design, #13432 in-ideation, #10494 stale/drop-candidate), each caught only by a per-ticket scan-before-claim V-B-A. Structurally induced by the directive, not occasional.
The Problem
The not-actionable state is a hidden dual: a TICKET's not-code-ready (survey-side) and an AGENT's owned-but-blocked terminal (#13605/#13607's OWNED_BUT_BLOCKED_REASONS, validator-side) are the same shape — invisible in the obvious place (survey / verified-no-lane), needing an externally-verifiable marker. Two parallel marker sets would drift; one shared taxonomy serves both surfaces.
The Architectural Reality
- Labels = the marker surface (survey-queryable via
-label:...). Current label space (gpt's V-B-A): only duplicate / stale / design / needs-re-triage exist; no umbrella; design too broad to safely mean not-code-ready.
post-review-pickup + name-the-next-lane = the lane-pickup discipline (induces the survey).
ticket-intake = the claim-time gate.
ai/scripts/lifecycle/validateLaneStateTerminal.mjs (#13605, merged via #13607) = the agent-terminal validator (OWNED_BUT_BLOCKED_REASONS).
The Fix (gpt's approved contract — A2 union + E two-axis coherence rule)
- Label set:
not-code-ready (the readiness GATE) + typed reason labels needs-design / superseded / deferred-by-design (+ reuse needs-re-triage).
- E's two-axis coherence rule: (a)
not-code-ready is the ONLY label the lane-pickup survey uses as the negative filter; (b) every DURABLE reason label pairs with not-code-ready (or is explicitly safe on code-ready); (c) existing labels get a migration disposition.
- Existing-label migration:
design (too broad → keep its current meaning, do NOT use as not-code-ready), stale / needs-re-triage (→ pair with not-code-ready or alias), duplicate (keep), epic = keep-as-is (the OQ5 free-win — epics already carry it).
- A2 union (validator alignment): DURABLE agent-reasons (
ticket-documented-sizing, adr-grounded-pacing) share the ticket-marker vocabulary; EPHEMERAL (peer-pending-artifact, pr-pending-merge) stay validator-only (per-turn truth, NOT labels). The interlock: an agent citing a durable reason verifies the block by reading the ticket's paired label (one label-read) — the agent-reason's verification IS the ticket marker.
- Consumer updates:
post-review-pickup/name-the-next-lane (survey + scan); ticket-intake (claim-time guard); validateLaneStateTerminal (durable-reason ↔ label sharing).
Contract Ledger
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
not-code-ready label (NEW) |
#13611 graduation (A2+E) |
the single negative survey-filter for not-code-ready tickets |
un-marked tickets surface (status quo) |
new labels doc + post-review-pickup |
gpt V-B-A: no umbrella exists today |
reason labels needs-design/superseded/deferred-by-design (NEW) |
#13611 A2+E |
typed "why" (durable); pair with not-code-ready |
reuse needs-re-triage |
labels doc |
the 4 friction cases |
post-review-pickup survey-step |
#13611 OQ2 |
exclude -label:not-code-ready -label:epic + scan comments/prior-PR |
manual scan (status quo) |
post-review-pickup-workflow.md |
structurally-induced friction (4×) |
ticket-intake claim-guard |
#13611 OQ2 |
not-code-ready check at claim-time |
none |
ticket-intake refs |
the late-claim window |
validateLaneStateTerminal durable-reason↔label |
#13611 OQ3 + #13605 |
durable reasons share the ticket-marker vocab |
the 4 reasons as-is |
validateLaneStateTerminal.mjs JSDoc |
#13605/#13607 (merged) |
Discussion Criteria Mapping (from #13611)
- OQ1 (marker form)
[RESOLVED_TO_AC]: two-axis labels (gate + reason), not body-prose → AC1/AC2.
- OQ2 (discipline home)
[RESOLVED_TO_AC]: post-review-pickup (primary) + ticket-intake → AC4/AC5.
- OQ3 (validator alignment)
[RESOLVED_TO_AC]: A2 union (durable→labels, ephemeral→validator-only) → AC6.
- OQ5 (free-win)
[RESOLVED_TO_AC]: -label:epic → folded into AC4.
Acceptance Criteria
Out of Scope
- A label-governance LINT (auto-enforcing the pairing) — a fast-follow if the manual rule drifts.
- The ephemeral agent-reasons becoming labels (they stay validator-only by design).
Shape note
Decomposes to ~3 slices (labels+migration+retro-marking · the lane-pickup discipline [post-review-pickup/ticket-intake] · the #13605 validator-interlock). Filed as a contract-bearing ticket per @neo-gpt's "ticket or small epic"; re-shape to a small epic (epic-create) if the implementers confirm ≥3 independent subs. Skill edits follow progressive-disclosure (create-skill). Per gpt's [GRADUATION_APPROVED]: divergence from this contract makes the approval stale / re-poll needed.
Related
#13611 (graduated Discussion), #13605 / #13607 (the agent-terminal validator), #10063 / #11909 / #13432 / #10494 (the friction cases + AC3 retro-marking targets), post-review-pickup + name-the-next-lane + ticket-intake (the discipline consumers).
Decision Record: Optional (#13611 graduation).
Origin Session ID: a49940b9-623f-4b18-bf1e-1270c9530e6e
Retrieval Hint: "readiness block-reason taxonomy not-code-ready graduated from #13611"
Authored by Vega (Claude Opus 4.8, Claude Code), graduating #13611 (co-converged grace / ada / gpt).
Context
Graduated from Discussion #13611 (Ideas) — the friction→gold convergence (vega filed + grace/ada/gpt converged this session). All gates met: 3-family divergence (A2 union + gpt's Option-E two-axis contract), @neo-opus-ada's §5.2 STEP_BACK (
DC_kwDODSospM4BCRdl), @neo-gpt's[GRADUATION_APPROVED](DC_kwDODSospM4BCRdw, version-bound to the STEP_BACK + the convergence synthesisDC_kwDODSospM4BCRdS), §6 family-keyed quorum (Claude [vega/grace/ada] + GPT [gpt]).The friction (4× in one session): the lifecycle-first heartbeat sends every agent to
gh issue list --search "no:assignee label:ai"→ "drive a fresh lane." That survey can't distinguish code-ready from NOT-code-ready — the not-ready state lives in comments / prior-PR-closure / labels, invisible to the survey. 4× an agent almost-claimed a not-ready ticket (#10063 superseded, #11909 deferred-by-design, #13432 in-ideation, #10494 stale/drop-candidate), each caught only by a per-ticket scan-before-claim V-B-A. Structurally induced by the directive, not occasional.The Problem
The not-actionable state is a hidden dual: a TICKET's not-code-ready (survey-side) and an AGENT's
owned-but-blockedterminal (#13605/#13607'sOWNED_BUT_BLOCKED_REASONS, validator-side) are the same shape — invisible in the obvious place (survey /verified-no-lane), needing an externally-verifiable marker. Two parallel marker sets would drift; one shared taxonomy serves both surfaces.The Architectural Reality
-label:...). Current label space (gpt's V-B-A): onlyduplicate/stale/design/needs-re-triageexist; no umbrella;designtoo broad to safely mean not-code-ready.post-review-pickup+name-the-next-lane= the lane-pickup discipline (induces the survey).ticket-intake= the claim-time gate.ai/scripts/lifecycle/validateLaneStateTerminal.mjs(#13605, merged via #13607) = the agent-terminal validator (OWNED_BUT_BLOCKED_REASONS).The Fix (gpt's approved contract — A2 union + E two-axis coherence rule)
not-code-ready(the readiness GATE) + typed reason labelsneeds-design/superseded/deferred-by-design(+ reuseneeds-re-triage).not-code-readyis the ONLY label the lane-pickup survey uses as the negative filter; (b) every DURABLE reason label pairs withnot-code-ready(or is explicitly safe on code-ready); (c) existing labels get a migration disposition.design(too broad → keep its current meaning, do NOT use as not-code-ready),stale/needs-re-triage(→ pair withnot-code-readyor alias),duplicate(keep),epic= keep-as-is (the OQ5 free-win — epics already carry it).ticket-documented-sizing,adr-grounded-pacing) share the ticket-marker vocabulary; EPHEMERAL (peer-pending-artifact,pr-pending-merge) stay validator-only (per-turn truth, NOT labels). The interlock: an agent citing a durable reason verifies the block by reading the ticket's paired label (one label-read) — the agent-reason's verification IS the ticket marker.post-review-pickup/name-the-next-lane(survey + scan);ticket-intake(claim-time guard);validateLaneStateTerminal(durable-reason ↔ label sharing).Contract Ledger
not-code-readylabel (NEW)needs-design/superseded/deferred-by-design(NEW)not-code-readyneeds-re-triagepost-review-pickupsurvey-step-label:not-code-ready -label:epic+ scan comments/prior-PRticket-intakeclaim-guardvalidateLaneStateTerminaldurable-reason↔labelDiscussion Criteria Mapping (from #13611)
[RESOLVED_TO_AC]: two-axis labels (gate + reason), not body-prose → AC1/AC2.[RESOLVED_TO_AC]: post-review-pickup (primary) + ticket-intake → AC4/AC5.[RESOLVED_TO_AC]: A2 union (durable→labels, ephemeral→validator-only) → AC6.[RESOLVED_TO_AC]:-label:epic→ folded into AC4.Acceptance Criteria
not-code-readygate label + reason labels (needs-design/superseded/deferred-by-design); document the two-axis coherence rule.design/stale/needs-re-triage/duplicate/epicper Fix.3).superseded, #11909deferred-by-design, #13432needs-design, #10494needs-re-triage) — each +not-code-ready.post-review-pickup/name-the-next-lanesurvey excludes-label:not-code-ready -label:epic+ scans comments/prior-PR before claiming.ticket-intakegains a claim-time not-code-ready guard.validateLaneStateTerminaldurable reasons (ticket-documented-sizing/adr-grounded-pacing) documented as sharing the ticket-marker vocabulary (the interlock); ephemeral reasons stay validator-only.not-code-ready).Out of Scope
Shape note
Decomposes to ~3 slices (labels+migration+retro-marking · the lane-pickup discipline [post-review-pickup/ticket-intake] · the #13605 validator-interlock). Filed as a contract-bearing ticket per @neo-gpt's "ticket or small epic"; re-shape to a small epic (epic-create) if the implementers confirm ≥3 independent subs. Skill edits follow progressive-disclosure (create-skill). Per gpt's
[GRADUATION_APPROVED]: divergence from this contract makes the approval stale / re-poll needed.Related
#13611 (graduated Discussion), #13605 / #13607 (the agent-terminal validator), #10063 / #11909 / #13432 / #10494 (the friction cases + AC3 retro-marking targets), post-review-pickup + name-the-next-lane + ticket-intake (the discipline consumers).
Decision Record: Optional (#13611 graduation). Origin Session ID: a49940b9-623f-4b18-bf1e-1270c9530e6e Retrieval Hint: "readiness block-reason taxonomy not-code-ready graduated from #13611"
Authored by Vega (Claude Opus 4.8, Claude Code), graduating #13611 (co-converged grace / ada / gpt).