#4850·gastown

gc hook claim: no_work despite valid lease+assignee; gt-bd hook-gate false-positives on plain-text bead-like tokens

Author: AlexBelousCreated Sep 11, 2026Updated Sep 11, 2026
Labelsstatus/needs-triage

Two related bugs hit live today in gascity-cloud (city: gascity-cloud, bead gc-8jjbq.7).

Bug 1: gc hook claim returns no_work despite a valid lease and correct assignee/status

Repro sequence (role: clerk):

  1. Bead routed to clerk (gc.routed_to=clerk), durable handoff accepted, gt-bd claim lease acquired, bd assignee set to clerk, status in_progress.
  2. gc hook current kept returning a different clerk-routed bead (also legitimately in_progress, held by another live session) instead of this one — a priority-tiering issue where the hook seems to prefer an existing_assignment over the newly-claimed bead even after the other bead's contention cleared.
  3. After the other bead was closed (contention cleared), retried gc hook claim for the correct bead. Now returns action: drain, reason: no_work — even though:
    • gt-bd check-lease confirms a valid lease held by the claiming session
    • bd list shows exactly this bead as in_progress assigned to that session
  4. Compared metadata against a bead that was picked up successfully earlier the same day: the working one had gc.claimed_at and gc.session_id set; the stuck one did not. Manually set both fields to match — no change, still no_work.
  5. Left the bead deferred+unassigned again rather than force/fabricate anything. gc.claimed_at/gc.session_id remained stale on the bead after this (set from the earlier attempt, no longer matching the deferred+unassigned state) — this mismatch is suspected to be part of what confuses the no_work check, but unconfirmed since a same-session repro wasn't available (the diagnosing session, mayor, can only run gc hook claim for its own session, not clerk's).

Suspected root cause direction: a repeat claim after a defer/undefer cycle may not restamp gc.claimed_at/gc.session_id correctly, and/or gc hook claim's no_work check may be keying off stale claim-stamp metadata left over from a prior (abandoned) claim attempt on the same bead, rather than the bead's current status/assignee/lease state.

This looks like it could be the same class of issue as a previously-diagnosed tier1 crash-recovery limit=1 bug (one bead per session in that tier), manifesting here as two concurrently-claimed same-role beads confusing which one is "current."

Bug 2: gt-bd hook-gate false-positives on plain descriptive words in note/message/command text

gt-bd hook-gate (the PreToolUse gate that enforces "you need a lease on bead X before touching it") appears to scan the entire text of a Bash command — not just bd/gt-bd subcommands and their bead-ID operands — for bead-ID-shaped tokens, and blocks the whole command if it finds one that isn't currently leased by the session. In practice this fires on ordinary short lowercase words with no relation to any real bead ID.

Reproductions collected today:

  1. A bd update --append-notes call was blocked because the note's prose contained ordinary words (reported by the diagnosing agent as things like "with", "skips", "no-ops") that got pattern-matched as bead-like tokens requiring their own lease.
  2. A gc session nudge <target> ... call (not a bd/gt-bd command at all) whose message text happened to contain the word "ALSO" (from "if X ALSO fails") was blocked with an error naming "ALSO" as an unleased bead alongside the real bead ID also mentioned in the text.
  3. A gh issue create --body "..." call (also not a bd/gt-bd command) was blocked because the body text — a bug report describing bug 2 itself — contained the ordinary word "call", which was flagged the same way.

Expected: hook-gate should only require a lease for bead IDs that are actual operands of a bd/gt-bd write operation, not for every bead-ID-shaped substring anywhere in a command's text (including free-form message/note prose, and commands that aren't bd operations at all like gc session nudge or arbitrary shell commands that happen to quote text containing common words).

Practical impact: this makes it very hard to write any moderately long note, nudge, or command argument without triggering spurious lease-denial errors on unrelated words, and forces agents to reword legitimate text to route around the false positive (as both reporters here had to do).

Environment

  • City: gascity-cloud
  • Beads involved: gc-8jjbq.7 (repro 1), text mentioning "gc-8jjbq.7" and "ALSO" (repro 2), text containing "call" (repro 3)
  • Roles: clerk (bug 1, both reports; bug 2 repro 1+2), mayor (bug 2 repro 3, filing this issue)