Observation
ORA-2026-0071 — Narrative amendments leave the reducer stuck when a BLOCKED-on-Chad prereq is satisfied
ORA-2026-0071 — Narrative amendments leave the reducer stuck when a BLOCKED-on-Chad prereq is satisfied
Type: observation Date: 2026-04-25 Source: Chad in-session inquiry 2026-04-25T~12:30Z ("why was the ticket never claimed"); CMB-1182 chronological audit; CLAUDE-STRAT-DESKTOP-MacBook-Air-CAMBER-01 dispatcher state v2.3 carried_v2_3_protocol_candidates entry Observed by: CLAUDE-STRAT-DESKTOP-MacBook-Air-CAMBER-01
Observation
The fleet feed reducer recognizes state transitions only on --kind actionable posts. Narrative posts (which authors choose for "no state change, just adding context") leave the reducer's view of STATE and OWNER exactly as the last actionable post left it.
This is the correct, intended design for most amendments. But it produces a specific class of silent failure when:
1. A ticket lands state=BLOCKED owner=chad because some Chad-only physical action is the named blocker (Xcode login, Keychain access, GUI confirmation, etc.). 2. Chad performs the action. 3. The STRAT shepherd posts a narrative amendment saying "Chad's action is done; the prereq is satisfied" — believing they've cleared the blocker. 4. The reducer keeps showing state=BLOCKED owner=chad, because the narrative post didn't transition state. 5. No Codex seat ever sees the ticket as claimable. It sits indefinitely.
The narrative post is informationally correct (it accurately describes the world) but structurally inert (it doesn't move the queue). The next claimer would have had to read the narrative manually, decide it satisfied the prereq, then file their own actionable transition — which doesn't happen because Codex seats grep for state=AWAITING_CLAIM owner=any-idle-<lane>-codex, not for narrative-comments-on-BLOCKEDs.
Evidence
CMB-1182 (Redline iPhone availability, BT-decomp child of CMB-1170):
| Time (UTC) | Author | Kind | Action | Reducer state after |
|---|---|---|---|---|
| 2026-04-25T01:05:44Z | CODEX-CLI-CAMBER-24 | actionable | dispatch | AWAITING_CLAIM, owner=any-idle-CAMBER-codex |
| 2026-04-25T01:07:26Z | CLAUDE-STRAT-DESKTOP-CAMBER-01 | narrative | constraint amendment ("no TestFlight") | (unchanged) |
| 2026-04-25T01:15:18Z | CODEX-DESKTOP-CAMBER-08 | actionable | claim | IN_PROGRESS, owner=CAMBER-08 |
| 2026-04-25T04:59:24Z | CLAUDE-STRAT-DESKTOP-CAMBER-01 | actionable | stale-owner re-route (CAMBER-08 dormant 3h+) | AWAITING_CLAIM, owner=any-idle-CAMBER-codex |
| 2026-04-25T05:01:05Z | CAMBER-08 (returned) | actionable | progress | IN_PROGRESS, owner=CAMBER-08 |
| 2026-04-25T05:15:48Z | CAMBER-08 | actionable | BLOCKED ("Xcode has no Apple ID account") | BLOCKED, owner=chad |
| 2026-04-25T05:18:59Z | CLAUDE-STRAT-DESKTOP-CAMBER-01 | narrative | "Xcode now logged in" amendment | (unchanged — STILL BLOCKED, owner=chad) |
| 2026-04-25T12:46:29Z | CLAUDE-CLI-MacBook-Air-ORA-01 | narrative | Xcode-blocker consolidation across CMB-0184 + CMB-1182 + CMB-1356 | (unchanged) |
| 2026-04-25T12:49:25Z | CLAUDE-STRAT-DESKTOP-CAMBER-01 | actionable | BLOCKED → AWAITING_CLAIM transition fix | AWAITING_CLAIM, owner=any-idle-CAMBER-codex |
Time-cost of the gap: the narrative-only amendment at 05:18:59Z was supposed to clear the blocker. The reducer treated it as a no-op. The ticket sat for 7h31m (05:18Z → 12:49Z) waiting for a state transition that never came. Chad's question at ~12:30Z surfaced the gap. Without that prompt, the ticket would have stayed BLOCKED indefinitely.
Mechanism the author over-applied: earlier in the same session at 2026-04-25T01:00:19Z, the same author learned that posting a no-op state amendment as --kind actionable gets rejected by the validator: error: ITEM X already has latest state Y / owner Z. The lesson recorded was "narrative kind for amendment-only posts; actionable kind requires state transition." That lesson is correct for amendments that don't change state. It is wrong for amendments that mark a state-changing prereq as satisfied — those need an actionable transition with the same state field that satisfies the validator (BLOCKED→AWAITING_CLAIM, or BLOCKED→DONE, etc.).
This is a generalization-too-far miss. The author internalized "narrative-for-amendments" as a unconditional rule when the actual rule is "narrative for context-only amendments; actionable for amendments that move the ticket out of its current state."
Fleet Lesson
When a ticket is BLOCKED owner=chad (or any owner whose action is the named blocker), and the blocker is satisfied, the unblock must be posted as an actionable state transition — typically BLOCKED → AWAITING_CLAIM owner=any-idle-<lane>-codex — not a narrative-kind comment.
A useful litmus question before posting any amendment:
Does this post describe new context, or does it mark a state-changing condition as satisfied?
- New context (e.g. "here's an additional constraint to honor"):
--kind narrativeis correct. - State-changing condition satisfied (e.g. "the prereq Chad/another-seat owed is done"):
--kind actionablewith the appropriate transition is required.
A second useful check: read the reducer view immediately after posting. If the reducer doesn't show the new state you intended, the post didn't move the queue — re-post as actionable.
Pattern-graduation criterion
This earns pattern status the first time it recurs in another session, with a different STRAT seat or a different ticket. The mechanism (narrative-vs-actionable validator semantics) is fleet-wide and not author-specific; one more confirmed instance demonstrates it's not a one-time author error.
It earns doctrine status the first time it causes a downstream Chad-deadline miss (e.g. Zack waits for a Redline build that never gets re-claimed because the BLOCKED→AWAITING transition never happened).
Adjacent doctrines
- ORA-2026-0029 (boot parity / doctrine surfaces) — narrative posts on doctrine surfaces work fine for stamping; this observation is specifically about the ticket-reducer surface.
- ORA-2026-0044 (names carry contracts) —
--kind narrativeand--kind actionableare contract-bearing names. Treating them as interchangeable for any "amendment" post violates the kind-specific contracts. - ORA-2026-0046 (deliverable reachability proof) — the same family of misses: a STRAT's stated outcome doesn't reach the reducer/grep target the next claimer uses.
- ORA-2026-0019 (wake-work pairing) — the WAKE field on a narrative-kind unblock amendment is informationally correct but doesn't change owner; the actionable transition is what makes WAKE binding.
Follow-ups
- CMB-1182 transition fix posted at 2026-04-25T12:49:25Z (resolves the immediate stuck ticket).
feed-appendergonomics: consider a runtime warning when a narrative post body contains words like "unblock," "prereq satisfied," "ready to claim," "BLOCKED → AWAITING_CLAIM" — those phrases in narrative-kind suggest the author meant to transition but used the wrong kind. Lightweight nudge, not a hard reject. (Out of scope for this observation; flagged for thefeed-appendmaintainer.)- STRAT shepherd protocol amendments: every shepherd protocol that uses
feed-appendshould add the litmus question to its amendment-handling section. - CMB-0184 + CMB-1356 (sister Xcode-blocker tickets per ORA-01's 12:46Z consolidation) likely have the same narrative-vs-actionable trap — verify their reducer state and post transitions if needed.