From a2dc42bb4b0ec01e9345e2f1d31699ef50541d17 Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Sat, 20 Dec 2025 22:49:54 -0800 Subject: [PATCH] fix(mail): route all mail to town beads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mail router was incorrectly routing rig-level addresses (e.g., gastown/crew/max) to {rig}/.beads instead of town beads. This caused mail to be invisible when agents checked their inbox. Two-level beads architecture: - ALL mail uses town beads ({townRoot}/.beads) - Rig-level beads are for project issues only 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/mail/router.go | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/internal/mail/router.go b/internal/mail/router.go index f54c022f..eb20b71a 100644 --- a/internal/mail/router.go +++ b/internal/mail/router.go @@ -66,31 +66,19 @@ func detectTownRoot(startDir string) string { } // resolveBeadsDir returns the correct .beads directory for the given address. -// Town-level addresses (mayor/, deacon/) use {townRoot}/.beads. -// Rig-level addresses (rig/polecat) use {townRoot}/{rig}/.beads. +// +// Two-level beads architecture: +// - ALL mail uses town beads ({townRoot}/.beads) regardless of address +// - Rig-level beads ({rig}/.beads) are for project issues only, not mail +// +// This ensures messages are visible to all agents in the town. func (r *Router) resolveBeadsDir(address string) string { // If no town root, fall back to workDir's .beads if r.townRoot == "" { return filepath.Join(r.workDir, ".beads") } - // Town-level agents: mayor/, deacon/ - if isTownLevelAddress(address) { - return filepath.Join(r.townRoot, ".beads") - } - - // Rig-level addresses: rig/polecat, rig/refinery - parts := strings.SplitN(address, "/", 2) - if len(parts) >= 1 && parts[0] != "" { - rig := parts[0] - rigBeadsDir := filepath.Join(r.townRoot, rig, ".beads") - // Check if rig beads exists - if _, err := os.Stat(rigBeadsDir); err == nil { - return rigBeadsDir - } - } - - // Fall back to town-level beads + // All mail uses town-level beads return filepath.Join(r.townRoot, ".beads") }