diff --git a/internal/beads/agent_ids.go b/internal/beads/agent_ids.go new file mode 100644 index 00000000..b2ca44b1 --- /dev/null +++ b/internal/beads/agent_ids.go @@ -0,0 +1,52 @@ +// Package beads provides a wrapper for the bd (beads) CLI. +package beads + +import "fmt" + +// Town-level agent bead IDs use the "hq-" prefix and are stored in town beads. +// These are global agents that operate at the town level (mayor, deacon, dogs). +// +// The naming convention is: +// - hq- for singletons (mayor, deacon) +// - hq-dog- for named agents (dogs) +// - hq--role for role definition beads + +// MayorBeadIDTown returns the Mayor agent bead ID for town-level beads. +// This uses the "hq-" prefix for town-level storage. +func MayorBeadIDTown() string { + return "hq-mayor" +} + +// DeaconBeadIDTown returns the Deacon agent bead ID for town-level beads. +// This uses the "hq-" prefix for town-level storage. +func DeaconBeadIDTown() string { + return "hq-deacon" +} + +// DogBeadIDTown returns a Dog agent bead ID for town-level beads. +// Dogs are town-level agents, so they follow the pattern: hq-dog- +func DogBeadIDTown(name string) string { + return fmt.Sprintf("hq-dog-%s", name) +} + +// RoleBeadIDTown returns the role bead ID for town-level storage. +// Role beads define lifecycle configuration for each agent type. +// Uses "hq-" prefix for town-level storage: hq--role +func RoleBeadIDTown(role string) string { + return fmt.Sprintf("hq-%s-role", role) +} + +// MayorRoleBeadIDTown returns the Mayor role bead ID for town-level storage. +func MayorRoleBeadIDTown() string { + return RoleBeadIDTown("mayor") +} + +// DeaconRoleBeadIDTown returns the Deacon role bead ID for town-level storage. +func DeaconRoleBeadIDTown() string { + return RoleBeadIDTown("deacon") +} + +// DogRoleBeadIDTown returns the Dog role bead ID for town-level storage. +func DogRoleBeadIDTown() string { + return RoleBeadIDTown("dog") +} diff --git a/internal/beads/agent_ids_test.go b/internal/beads/agent_ids_test.go new file mode 100644 index 00000000..c1f49281 --- /dev/null +++ b/internal/beads/agent_ids_test.go @@ -0,0 +1,91 @@ +package beads + +import "testing" + +// TestMayorBeadIDTown tests the town-level Mayor bead ID. +func TestMayorBeadIDTown(t *testing.T) { + got := MayorBeadIDTown() + want := "hq-mayor" + if got != want { + t.Errorf("MayorBeadIDTown() = %q, want %q", got, want) + } +} + +// TestDeaconBeadIDTown tests the town-level Deacon bead ID. +func TestDeaconBeadIDTown(t *testing.T) { + got := DeaconBeadIDTown() + want := "hq-deacon" + if got != want { + t.Errorf("DeaconBeadIDTown() = %q, want %q", got, want) + } +} + +// TestDogBeadIDTown tests town-level Dog bead IDs. +func TestDogBeadIDTown(t *testing.T) { + tests := []struct { + name string + want string + }{ + {"alpha", "hq-dog-alpha"}, + {"rex", "hq-dog-rex"}, + {"spot", "hq-dog-spot"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := DogBeadIDTown(tt.name) + if got != tt.want { + t.Errorf("DogBeadIDTown(%q) = %q, want %q", tt.name, got, tt.want) + } + }) + } +} + +// TestRoleBeadIDTown tests town-level role bead IDs. +func TestRoleBeadIDTown(t *testing.T) { + tests := []struct { + roleType string + want string + }{ + {"mayor", "hq-mayor-role"}, + {"deacon", "hq-deacon-role"}, + {"dog", "hq-dog-role"}, + {"witness", "hq-witness-role"}, + } + + for _, tt := range tests { + t.Run(tt.roleType, func(t *testing.T) { + got := RoleBeadIDTown(tt.roleType) + if got != tt.want { + t.Errorf("RoleBeadIDTown(%q) = %q, want %q", tt.roleType, got, tt.want) + } + }) + } +} + +// TestMayorRoleBeadIDTown tests the Mayor role bead ID for town-level. +func TestMayorRoleBeadIDTown(t *testing.T) { + got := MayorRoleBeadIDTown() + want := "hq-mayor-role" + if got != want { + t.Errorf("MayorRoleBeadIDTown() = %q, want %q", got, want) + } +} + +// TestDeaconRoleBeadIDTown tests the Deacon role bead ID for town-level. +func TestDeaconRoleBeadIDTown(t *testing.T) { + got := DeaconRoleBeadIDTown() + want := "hq-deacon-role" + if got != want { + t.Errorf("DeaconRoleBeadIDTown() = %q, want %q", got, want) + } +} + +// TestDogRoleBeadIDTown tests the Dog role bead ID for town-level. +func TestDogRoleBeadIDTown(t *testing.T) { + got := DogRoleBeadIDTown() + want := "hq-dog-role" + if got != want { + t.Errorf("DogRoleBeadIDTown() = %q, want %q", got, want) + } +} diff --git a/internal/beads/beads.go b/internal/beads/beads.go index 989b67e4..2b2ba33e 100644 --- a/internal/beads/beads.go +++ b/internal/beads/beads.go @@ -1169,11 +1169,19 @@ func AgentBeadID(rig, role, name string) string { } // MayorBeadID returns the Mayor agent bead ID. +// +// Deprecated: Use MayorBeadIDTown() for town-level beads (hq- prefix). +// This function returns "gt-mayor" which is for rig-level storage. +// Town-level agents like Mayor should use the hq- prefix. func MayorBeadID() string { return "gt-mayor" } // DeaconBeadID returns the Deacon agent bead ID. +// +// Deprecated: Use DeaconBeadIDTown() for town-level beads (hq- prefix). +// This function returns "gt-deacon" which is for rig-level storage. +// Town-level agents like Deacon should use the hq- prefix. func DeaconBeadID() string { return "gt-deacon" } @@ -1189,36 +1197,6 @@ func DogRoleBeadID() string { return RoleBeadID("dog") } -// Town-level agent bead ID helpers (hq- prefix, stored in town beads). -// These are the canonical IDs for the two-level beads architecture: -// - Town-level agents (Mayor, Deacon, Dogs) → ~/gt/.beads/ with hq- prefix -// - Rig-level agents (Witness, Refinery, Polecats) → /.beads/ with rig prefix - -// MayorBeadIDTown returns the town-level Mayor agent bead ID. -// Deprecated: Use MayorBeadID() which still returns gt-mayor for compatibility. -// After migration to two-level architecture, this will become the canonical ID. -func MayorBeadIDTown() string { - return "hq-mayor" -} - -// DeaconBeadIDTown returns the town-level Deacon agent bead ID. -// Deprecated: Use DeaconBeadID() which still returns gt-deacon for compatibility. -// After migration to two-level architecture, this will become the canonical ID. -func DeaconBeadIDTown() string { - return "hq-deacon" -} - -// DogBeadIDTown returns a town-level Dog agent bead ID. -func DogBeadIDTown(name string) string { - return "hq-dog-" + name -} - -// RoleBeadIDTown returns a town-level role definition bead ID. -// Role beads are global templates stored in town beads. -func RoleBeadIDTown(role string) string { - return "hq-" + role + "-role" -} - // CreateDogAgentBead creates an agent bead for a dog. // Dogs use a different schema than other agents - they use labels for metadata. // Returns the created issue or an error.