From a5ff31428bb96aaea53b7dbe62153fdb71f47157 Mon Sep 17 00:00:00 2001 From: shiny Date: Mon, 5 Jan 2026 00:21:42 -0800 Subject: [PATCH] fix(sling): use correct beads database for rig-level beads (gt-n5gga) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When slinging rig-level beads (gt-*, bd-*, etc.), the BEADS_DIR was unconditionally set to town beads, which could bypass the redirect-based routing needed for these beads. This caused assignee updates to potentially fail silently or target the wrong database. Changes: - sling.go: Only set BEADS_DIR for town-level (hq-*) beads; rig-level beads now use redirect from polecat worktree for proper routing - convoy.go: Add --no-daemon to bd show calls to ensure fresh data 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/cmd/convoy.go | 8 +++++--- internal/cmd/sling.go | 21 +++++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/internal/cmd/convoy.go b/internal/cmd/convoy.go index 18834dc1..3ea0babb 100644 --- a/internal/cmd/convoy.go +++ b/internal/cmd/convoy.go @@ -1130,8 +1130,9 @@ func getIssueDetailsBatch(issueIDs []string) map[string]*issueDetails { return result } - // Build args: bd show id1 id2 id3 ... --json - args := append([]string{"show"}, issueIDs...) + // Build args: bd --no-daemon show id1 id2 id3 ... --json + // Use --no-daemon to ensure fresh data (avoid stale cache from daemon) + args := append([]string{"--no-daemon", "show"}, issueIDs...) args = append(args, "--json") showCmd := exec.Command("bd", args...) @@ -1177,7 +1178,8 @@ func getIssueDetailsBatch(issueIDs []string) map[string]*issueDetails { // Prefer getIssueDetailsBatch for multiple issues to avoid N+1 subprocess calls. func getIssueDetails(issueID string) *issueDetails { // Use bd show with routing - it should find the issue in the right rig - showCmd := exec.Command("bd", "show", issueID, "--json") + // Use --no-daemon to ensure fresh data (avoid stale cache) + showCmd := exec.Command("bd", "--no-daemon", "show", issueID, "--json") var stdout bytes.Buffer showCmd.Stdout = &stdout diff --git a/internal/cmd/sling.go b/internal/cmd/sling.go index be121016..6865775a 100644 --- a/internal/cmd/sling.go +++ b/internal/cmd/sling.go @@ -431,11 +431,15 @@ func runSling(cmd *cobra.Command, args []string) error { } // Hook the bead using bd update - // Set BEADS_DIR to town-level beads so hq-* beads are accessible - // even when running from polecat worktree (which only sees gt-* via redirect) + // For town-level beads (hq-*), set BEADS_DIR to town beads + // For rig-level beads (gt-*, bd-*, etc.), use redirect-based routing from hookWorkDir hookCmd := exec.Command("bd", "--no-daemon", "update", beadID, "--status=hooked", "--assignee="+targetAgent) - hookCmd.Env = append(os.Environ(), "BEADS_DIR="+townBeadsDir) - if hookWorkDir != "" { + if strings.HasPrefix(beadID, "hq-") { + // Town-level bead: set BEADS_DIR explicitly + hookCmd.Env = append(os.Environ(), "BEADS_DIR="+townBeadsDir) + hookCmd.Dir = townRoot + } else if hookWorkDir != "" { + // Rig-level bead: use redirect from polecat's worktree hookCmd.Dir = hookWorkDir } else { hookCmd.Dir = townRoot @@ -1403,9 +1407,14 @@ func runBatchSling(beadIDs []string, rigName string, townBeadsDir string) error } // Hook the bead + // For town-level beads (hq-*), set BEADS_DIR; for rig-level beads use redirect hookCmd := exec.Command("bd", "--no-daemon", "update", beadID, "--status=hooked", "--assignee="+targetAgent) - hookCmd.Env = append(os.Environ(), "BEADS_DIR="+townBeadsDir) - if hookWorkDir != "" { + if strings.HasPrefix(beadID, "hq-") { + // Town-level bead: set BEADS_DIR and run from town root (parent of townBeadsDir) + hookCmd.Env = append(os.Environ(), "BEADS_DIR="+townBeadsDir) + hookCmd.Dir = filepath.Dir(townBeadsDir) + } else if hookWorkDir != "" { + // Rig-level bead: use redirect from polecat's worktree hookCmd.Dir = hookWorkDir } hookCmd.Stderr = os.Stderr