Add hq- prefix agent bead ID helpers

Add new helper functions for town-level agent bead IDs:
- MayorBeadIDTown() → "hq-mayor"
- DeaconBeadIDTown() → "hq-deacon"
- DogBeadIDTown(name) → "hq-dog-<name>"
- RoleBeadIDTown(role) → "hq-<role>-role"

These use the hq- prefix for town-level beads storage, distinct from
the gt- prefix used for rig-level beads.

Mark MayorBeadID() and DeaconBeadID() as deprecated in favor of the
new *Town() variants.

(gt-y24km)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
ace
2026-01-03 20:51:37 -08:00
committed by Steve Yegge
parent 0b88dc204b
commit b8250e139f
3 changed files with 151 additions and 30 deletions
+52
View File
@@ -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-<role> for singletons (mayor, deacon)
// - hq-dog-<name> for named agents (dogs)
// - hq-<role>-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-<name>
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>-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")
}
+91
View File
@@ -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)
}
}
+8 -30
View File
@@ -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) → <rig>/.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.