From afdadc77ff9ca94520614f11a0558f38acd33687 Mon Sep 17 00:00:00 2001 From: furiosa Date: Mon, 26 Jan 2026 12:27:18 -0800 Subject: [PATCH] fix(hook): enable cross-prefix bead hooking with database routing When agents hook beads from different prefixes (e.g., rig worker hooking hq-* bead), the status check now uses ResolveHookDir to find the correct database for fetching the hooked bead. Also adds fallback scanning of town-level beads for rig-level roles when no hooked beads are found locally. Fixes: gt-rphsv Co-Authored-By: Claude Opus 4.5 --- internal/cmd/molecule_status.go | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/internal/cmd/molecule_status.go b/internal/cmd/molecule_status.go index 9863048e..a91dc8b0 100644 --- a/internal/cmd/molecule_status.go +++ b/internal/cmd/molecule_status.go @@ -372,8 +372,14 @@ func runMoleculeStatus(cmd *cobra.Command, args []string) error { // IMPORTANT: Don't use ParseAgentFieldsFromDescription - the description // field may contain stale data, causing the wrong issue to be hooked. if agentBead.HookBead != "" { - // Fetch the bead on the hook - hookBead, err = b.Show(agentBead.HookBead) + // Fetch the bead on the hook, using cross-prefix database routing. + // The hooked bead may be in a different database than the agent bead + // (e.g., hq-* bead hooked by a rig worker). Use ResolveHookDir to + // find the correct database directory based on the bead's prefix. + // See: https://github.com/steveyegge/gastown/issues/gt-rphsv + hookBeadDir := beads.ResolveHookDir(townRoot, agentBead.HookBead, workDir) + hookBeadDB := beads.New(hookBeadDir) + hookBead, err = hookBeadDB.Show(agentBead.HookBead) if err != nil { // Hook bead referenced but not found - report error but continue hookBead = nil @@ -438,6 +444,24 @@ func runMoleculeStatus(cmd *cobra.Command, args []string) error { hookedBeads = scanAllRigsForHookedBeads(townRoot, target) } + // For rig-level roles, also check town-level beads (hq-* prefix). + // Agents can hook cross-prefix beads (e.g., crew worker taking an HQ task). + // See: https://github.com/steveyegge/gastown/issues/gt-rphsv + if len(hookedBeads) == 0 && !isTownLevelRole(target) { + townBeadsDir := filepath.Join(townRoot, ".beads") + if _, statErr := os.Stat(townBeadsDir); statErr == nil { + townBeads := beads.New(townBeadsDir) + townHooked, listErr := townBeads.List(beads.ListOptions{ + Status: beads.StatusHooked, + Assignee: target, + Priority: -1, + }) + if listErr == nil && len(townHooked) > 0 { + hookedBeads = townHooked + } + } + } + status.HasWork = len(hookedBeads) > 0 if len(hookedBeads) > 0 {