docs(handoff): fix queue-drift root cause — live Gitea state is the sole source of truth
Build ErsatzTV Image / Docs update reminder (push) Has been skipped
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 8m17s
Build ErsatzTV Image / Build & push image (amd64) (push) Has been cancelled
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Has been cancelled
Build ErsatzTV Image / Docs update reminder (push) Has been skipped
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 8m17s
Build ErsatzTV Image / Build & push image (amd64) (push) Has been cancelled
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Has been cancelled
Recent session pickups re-did finished work (thought closed issues were still open). Root cause: DONE/OPEN status lived in append-only prose (arc inline markers + each comment's 'Recommended next'), which lags real issue state — worst across parallel sessions narrating each other's merges. Kickoff prompt fixes: - SOURCE OF TRUTH = live Gitea state, never prose; verify OPEN (issue AND milestone) before claiming. - Gate/frontier defined structurally (lowest-numbered open arc item), not hardcoded to an issue number (an earlier pass re-planted the bug by hardcoding '#197 cluster'/'#91b milestone CLOSED'). - Label-based ranking: arc order -> gate(review label/milestone) -> priority. - Pick order across arc-frontier / priority-pickup / audit pools. - Bound the comment read (~6 newest); MCP-down REST fallback; #237 canonical. - New lore bullet capturing the drift root cause + structural cure. Companion edits to tracker #237 body (prune arc status -> 'Done (history)' section) made live; noted in a session comment there. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -32,12 +32,32 @@ Everything else (claiming, worktrees, dispatching implementers, CI monitoring, p
|
||||
bookkeeping, routine merges of green reviewed PRs with user consent) stays at your level.
|
||||
|
||||
Then work the queue:
|
||||
1. Read the pinned tracker **ersatztv#237** — body = goal + ordered arc + session protocol —
|
||||
and its most recent session comments; list open issues in the `Blazor removal (#91 phase b)`
|
||||
milestone and with the `review` label; ALSO list open `ersatztv`-labeled issues in
|
||||
**timothy/adversarial-reviewer** — unclaimed audits there are pickup candidates too
|
||||
(read-only, parallel-safe; see the tracker's "Pending adversarial reviews" section).
|
||||
2. Pick the top arc item that is open and NOT labeled `in-progress` (or the item the user names).
|
||||
1. Read the pinned tracker **ersatztv#237** — body = goal + ordered arc + session protocol — and
|
||||
its **last ~6 session comments** (newest-first; the full comment payload is large, so stop at ~6).
|
||||
**SOURCE OF TRUTH = live Gitea issue state, NEVER the prose.** The arc body carries ORDER + goal
|
||||
only; a session comment's "Recommended next" is a forward *guess* written before the next session
|
||||
acted. Both go stale the instant an item closes (especially under parallel sessions narrating each
|
||||
other's work as "the gate that unblocks X"). So derive the candidate set from LIVE state, not from
|
||||
any inline marker or a prior comment's "next": the **current gate = the lowest-numbered OPEN arc
|
||||
item in #237's arc list**; its open children are the gate cluster (query them by the `review`
|
||||
label). Cross-check every arc / "recommended" item's real open/closed state (issue **and**
|
||||
milestone) before trusting it — do NOT hardcode which issue is the frontier; read it. ALSO list
|
||||
open `ersatztv`-labeled issues in **timothy/adversarial-reviewer** — unclaimed audits there are
|
||||
pickup candidates too (read-only, parallel-safe; see the tracker's "Pending adversarial reviews"
|
||||
section). If the Gitea MCP is down, hit the REST API directly (creds in your global CLAUDE.md):
|
||||
`curl -u <user>:<pass> http://192.168.1.95:3000/api/v1/repos/timothy/ersatztv/issues/237`.
|
||||
**The authoritative pickup + ranking protocol lives in #237's "Session protocol" section — this is a summary; if the two ever disagree, #237 wins.**
|
||||
2. Pick the highest-ranked OPEN, un-`in-progress` candidate (or the item the user names). **Rank by
|
||||
labels, not just arc position** (labels are live state; prose is not): (1) arc order in #237, then
|
||||
(2) **gate vs backlog** — an item marked gate by the `review` label OR membership in an open gate
|
||||
milestone outranks anything unmilestoned; then (3) **`priority:`** label — `high` > `medium` >
|
||||
`low` within a tier. Pick order across the three pools: the **arc frontier** (lowest-numbered open
|
||||
arc item) first; an unclaimed Blocker/High **priority-pickup** (`review` + `priority: high`, e.g.
|
||||
#253) beats a *non-frontier* arc item; reviewer-repo **audits** are read-only and run in parallel.
|
||||
**Confirm the pick is genuinely OPEN in Gitea first.** If the prose says "recommended next / now
|
||||
unblocked" but the issue (or its milestone) is already CLOSED, it is done — skip it and fix the
|
||||
stale line in your session comment. Prose lags live state; live state wins; milestone + `priority:`
|
||||
labels decide gate-vs-backlog, not the prose. (This mirrors #237's Session-protocol ranking — #237 is canonical.)
|
||||
3. **Claim it**: add the `in-progress` label + a "claiming" comment on the issue(s);
|
||||
reviewer-repo audits are claimed by comment only.
|
||||
4. Read the issue bodies (they carry the task context/evidence) and work the item under the
|
||||
@@ -282,3 +302,20 @@ HARD CONSTRAINTS:
|
||||
transport/timeout exceptions must be caught and turned into a response (a `-32603`), else the failure escapes
|
||||
the handler and the client hangs awaiting a reply that never comes. Proved live with a black-hole socket
|
||||
(accept, never respond) → 1s timeout → error in ~1s, no hang.
|
||||
- **Queue-drift root cause + standing rule (2026-07-12, user-surfaced)**: pickups repeatedly re-picked
|
||||
already-done work — #91b was framed "recommended next / now unblocked" for two sessions *after* it had
|
||||
merged (2026-07-11), and the #251/#252 priority-pickups sat listed "open" after closing — requiring a
|
||||
reactive body correction (tracker comment 16:00). ROOT CAUSE: DONE/OPEN status was read from **prose** (the
|
||||
arc body's inline "DONE" markers + each session comment's "Recommended next"), which is append-only and
|
||||
hand-edited, so it lags real issue state — worst under parallel sessions that narrate each other's merges as
|
||||
"the gate that unblocks X" (#271 got cast as the last gate for an already-merged #91b). It is a *structural*
|
||||
bug, not a stale-writer bug: any status embedded in prose will drift. STANDING FIX (don't just re-patch the
|
||||
body next time): **live Gitea state is the ONLY source of truth for status.** The arc body carries order+goal;
|
||||
a comment's "Recommended next" is a *candidate* that MUST be re-verified OPEN (issue **and** milestone) at
|
||||
pickup. When prose disagrees with live state, live state wins — correct the prose in your session comment,
|
||||
never propagate it. STRUCTURAL CURE (2026-07-12 review, Fable): #237's arc no longer carries inline `DONE`
|
||||
markers — closed items move to a "Done (history)" section, so status lives ONLY in live Gitea state and can't
|
||||
drift; and the gate/frontier is defined **structurally** (lowest-numbered open arc item), never hardcoded to
|
||||
an issue number. Beware: the *first* pass at this fix re-planted the very bug by hardcoding "#197 cluster" /
|
||||
"#91b milestone CLOSED" into the kickoff — if you name today's frontier issue in this standing file, you are
|
||||
writing the next drift. Gate cluster = open `review`-labeled issues serving the current open arc item.
|
||||
|
||||
Reference in New Issue
Block a user