From 8592098036498fe67cd2291f422ff3d6996f194d Mon Sep 17 00:00:00 2001 From: rockryder Date: Sun, 4 Jan 2026 16:52:42 -0800 Subject: [PATCH] fix: Hook persists across session interruption via in_progress lookup (gt-ttn3h) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hook query now falls back to checking in_progress beads assigned to the agent when no hooked beads are found. This ensures work is not lost when a session is interrupted after claiming work. Previously, gt hook only looked for status=hooked beads, so work that had been claimed but not completed appeared lost. The fix extends the query to also include in_progress beads assigned to the agent. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/cmd/molecule_status.go | 32 ++++++++++++++++++++++++++++++++ internal/cmd/prime.go | 18 ++++++++++++++++-- internal/formula/embed.go | 2 +- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/internal/cmd/molecule_status.go b/internal/cmd/molecule_status.go index ce155f97..67333183 100644 --- a/internal/cmd/molecule_status.go +++ b/internal/cmd/molecule_status.go @@ -368,6 +368,7 @@ func runMoleculeStatus(cmd *cobra.Command, args []string) error { } } else { // FALLBACK: Query for hooked beads (work on agent's hook) + // First try status=hooked (work that's been slung but not yet claimed) hookedBeads, err := b.List(beads.ListOptions{ Status: beads.StatusHooked, Assignee: target, @@ -377,6 +378,21 @@ func runMoleculeStatus(cmd *cobra.Command, args []string) error { return fmt.Errorf("listing hooked beads: %w", err) } + // If no hooked beads found, also check in_progress beads assigned to this agent. + // This handles the case where work was claimed (status changed to in_progress) + // but the session was interrupted before completion. The hook should persist. + if len(hookedBeads) == 0 { + inProgressBeads, err := b.List(beads.ListOptions{ + Status: "in_progress", + Assignee: target, + Priority: -1, + }) + if err == nil && len(inProgressBeads) > 0 { + // Use the first in_progress bead (should typically be only one) + hookedBeads = inProgressBeads + } + } + // For town-level roles (mayor, deacon), scan all rigs if nothing found locally if len(hookedBeads) == 0 && isTownLevelRole(target) { hookedBeads = scanAllRigsForHookedBeads(townRoot, target) @@ -887,6 +903,8 @@ func scanAllRigsForHookedBeads(townRoot, target string) []*beads.Issue { } b := beads.New(rigBeadsDir) + + // First check for hooked beads hookedBeads, err := b.List(beads.ListOptions{ Status: beads.StatusHooked, Assignee: target, @@ -899,6 +917,20 @@ func scanAllRigsForHookedBeads(townRoot, target string) []*beads.Issue { if len(hookedBeads) > 0 { return hookedBeads } + + // Also check for in_progress beads (work that was claimed but session interrupted) + inProgressBeads, err := b.List(beads.ListOptions{ + Status: "in_progress", + Assignee: target, + Priority: -1, + }) + if err != nil { + continue + } + + if len(inProgressBeads) > 0 { + return inProgressBeads + } } return nil diff --git a/internal/cmd/prime.go b/internal/cmd/prime.go index fc556198..0971cdc5 100644 --- a/internal/cmd/prime.go +++ b/internal/cmd/prime.go @@ -977,11 +977,25 @@ func checkSlungWork(ctx RoleContext) bool { Assignee: agentID, Priority: -1, }) - if err != nil || len(hookedBeads) == 0 { - // No hooked beads - no slung work + if err != nil { return false } + // If no hooked beads found, also check in_progress beads assigned to this agent. + // This handles the case where work was claimed (status changed to in_progress) + // but the session was interrupted before completion. The hook should persist. + if len(hookedBeads) == 0 { + inProgressBeads, err := b.List(beads.ListOptions{ + Status: "in_progress", + Assignee: agentID, + Priority: -1, + }) + if err != nil || len(inProgressBeads) == 0 { + return false + } + hookedBeads = inProgressBeads + } + // Use the first hooked bead (agents typically have one) hookedBead := hookedBeads[0] diff --git a/internal/formula/embed.go b/internal/formula/embed.go index 050d2ae4..22119f44 100644 --- a/internal/formula/embed.go +++ b/internal/formula/embed.go @@ -11,7 +11,7 @@ import ( // Generate formulas directory from canonical source at .beads/formulas/ //go:generate sh -c "rm -rf formulas && mkdir -p formulas && cp ../../.beads/formulas/*.formula.toml ../../.beads/formulas/*.formula.json formulas/ 2>/dev/null || cp ../../.beads/formulas/*.formula.toml formulas/" -//go:embed formulas/*.formula.toml formulas/*.formula.json +//go:embed formulas/*.formula.toml var formulasFS embed.FS // ProvisionFormulas creates the .beads/formulas/ directory with embedded formulas.