From d4c076451c710d317149f81117b286d7b08e9139 Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Sat, 27 Dec 2025 17:53:38 -0800 Subject: [PATCH] Fix gt mol status: cross-rig scanning for town-level roles (gt-4ol8f) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When mayor/deacon checks their hook from ~/gt, gt mol status now scans all registered rigs for pinned beads. This ensures the propulsion principle works regardless of which directory the agent starts in. The scan uses routes.jsonl to find all rig beads directories. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/cmd/molecule_status.go | 49 +++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/internal/cmd/molecule_status.go b/internal/cmd/molecule_status.go index 9c52d320..96f62a19 100644 --- a/internal/cmd/molecule_status.go +++ b/internal/cmd/molecule_status.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "os/exec" + "path/filepath" "strings" "github.com/spf13/cobra" @@ -249,6 +250,11 @@ func runMoleculeStatus(cmd *cobra.Command, args []string) error { return fmt.Errorf("listing pinned beads: %w", err) } + // For town-level roles (mayor, deacon), scan all rigs if nothing found locally + if len(pinnedBeads) == 0 && isTownLevelRole(target) { + pinnedBeads = scanAllRigsForPinnedBeads(townRoot, target) + } + // Build status info status := MoleculeStatusInfo{ Target: target, @@ -711,3 +717,46 @@ func getGitRootForMolStatus() (string, error) { } return strings.TrimSpace(string(out)), nil } + +// isTownLevelRole returns true if the agent ID is a town-level role. +// Town-level roles (Mayor, Deacon) operate from the town root and may have +// pinned beads in any rig's beads directory. +func isTownLevelRole(agentID string) bool { + return agentID == "mayor" || agentID == "deacon" +} + +// scanAllRigsForPinnedBeads scans all registered rigs for pinned beads +// assigned to the target agent. Used for town-level roles that may have +// work pinned in any rig. +func scanAllRigsForPinnedBeads(townRoot, target string) []*beads.Issue { + // Load routes from town beads + townBeadsDir := filepath.Join(townRoot, ".beads") + routes, err := beads.LoadRoutes(townBeadsDir) + if err != nil { + return nil + } + + // Scan each rig's beads directory + for _, route := range routes { + rigBeadsDir := filepath.Join(townRoot, route.Path) + if _, err := os.Stat(rigBeadsDir); os.IsNotExist(err) { + continue + } + + b := beads.New(rigBeadsDir) + pinnedBeads, err := b.List(beads.ListOptions{ + Status: beads.StatusPinned, + Assignee: target, + Priority: -1, + }) + if err != nil { + continue + } + + if len(pinnedBeads) > 0 { + return pinnedBeads + } + } + + return nil +}