fix(mail): route all mail to town beads

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 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-20 22:49:54 -08:00
parent 07aa044e3b
commit a2dc42bb4b

View File

@@ -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")
}