Files
gastown/internal/beads/beads_role.go
gastown/crew/max a610283078 feat(roles): switch daemon to config-based roles, remove role beads (Phase 2+3)
Phase 2: Daemon now uses config.LoadRoleDefinition() instead of role beads
- lifecycle.go: getRoleConfigForIdentity() reads from TOML configs
- Layered override resolution: builtin → town → rig

Phase 3: Remove role bead creation and references
- Remove RoleBead field from AgentFields struct
- gt install no longer creates role beads
- Remove 'role' from custom types list
- Delete migrate_agents.go (no longer needed)
- Deprecate beads_role.go (kept for reading existing beads)
- Rewrite role_beads_check.go to validate TOML configs

Existing role beads are orphaned but harmless.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 12:58:01 -08:00

161 lines
4.6 KiB
Go

// Package beads provides role bead management.
//
// DEPRECATED: Role beads are deprecated. Role definitions are now config-based.
// See internal/config/roles/*.toml and config-based-roles.md for the new system.
//
// This file is kept for backward compatibility with existing role beads but
// new code should use config.LoadRoleDefinition() instead of reading role beads.
// The daemon no longer uses role beads as of Phase 2 (config-based roles).
package beads
import (
"errors"
"fmt"
)
// DEPRECATED: Role bead ID naming convention is no longer used.
// Role definitions are now config-based (internal/config/roles/*.toml).
//
// Role beads were stored in town beads (~/.beads/) with hq- prefix.
//
// Canonical format was: hq-<role>-role
//
// Examples:
// - hq-mayor-role
// - hq-deacon-role
// - hq-witness-role
// - hq-refinery-role
// - hq-crew-role
// - hq-polecat-role
//
// Legacy functions RoleBeadID() and RoleBeadIDTown() still work for
// backward compatibility but should not be used in new code.
// RoleBeadID returns the role bead ID for a given role type.
// Role beads define lifecycle configuration for each agent type.
// Deprecated: Use RoleBeadIDTown() for town-level beads with hq- prefix.
// Role beads are global templates and should use hq-<role>-role, not gt-<role>-role.
func RoleBeadID(roleType string) string {
return "gt-" + roleType + "-role"
}
// DogRoleBeadID returns the Dog role bead ID.
func DogRoleBeadID() string {
return RoleBeadID("dog")
}
// MayorRoleBeadID returns the Mayor role bead ID.
func MayorRoleBeadID() string {
return RoleBeadID("mayor")
}
// DeaconRoleBeadID returns the Deacon role bead ID.
func DeaconRoleBeadID() string {
return RoleBeadID("deacon")
}
// WitnessRoleBeadID returns the Witness role bead ID.
func WitnessRoleBeadID() string {
return RoleBeadID("witness")
}
// RefineryRoleBeadID returns the Refinery role bead ID.
func RefineryRoleBeadID() string {
return RoleBeadID("refinery")
}
// CrewRoleBeadID returns the Crew role bead ID.
func CrewRoleBeadID() string {
return RoleBeadID("crew")
}
// PolecatRoleBeadID returns the Polecat role bead ID.
func PolecatRoleBeadID() string {
return RoleBeadID("polecat")
}
// GetRoleConfig looks up a role bead and returns its parsed RoleConfig.
// Returns nil, nil if the role bead doesn't exist or has no config.
//
// Deprecated: Use config.LoadRoleDefinition() instead. Role definitions
// are now config-based, not stored as beads.
func (b *Beads) GetRoleConfig(roleBeadID string) (*RoleConfig, error) {
issue, err := b.Show(roleBeadID)
if err != nil {
if errors.Is(err, ErrNotFound) {
return nil, nil
}
return nil, err
}
if !HasLabel(issue, "gt:role") {
return nil, fmt.Errorf("bead %s is not a role bead (missing gt:role label)", roleBeadID)
}
return ParseRoleConfig(issue.Description), nil
}
// HasLabel checks if an issue has a specific label.
func HasLabel(issue *Issue, label string) bool {
for _, l := range issue.Labels {
if l == label {
return true
}
}
return false
}
// RoleBeadDef defines a role bead's metadata.
//
// Deprecated: Role beads are no longer created. Role definitions are
// now config-based (internal/config/roles/*.toml).
type RoleBeadDef struct {
ID string // e.g., "hq-witness-role"
Title string // e.g., "Witness Role"
Desc string // Description of the role
}
// AllRoleBeadDefs returns all role bead definitions.
//
// Deprecated: Role beads are no longer created by gt install or gt doctor.
// This function is kept for backward compatibility only.
func AllRoleBeadDefs() []RoleBeadDef {
return []RoleBeadDef{
{
ID: MayorRoleBeadIDTown(),
Title: "Mayor Role",
Desc: "Role definition for Mayor agents. Global coordinator for cross-rig work.",
},
{
ID: DeaconRoleBeadIDTown(),
Title: "Deacon Role",
Desc: "Role definition for Deacon agents. Daemon beacon for heartbeats and monitoring.",
},
{
ID: DogRoleBeadIDTown(),
Title: "Dog Role",
Desc: "Role definition for Dog agents. Town-level workers for cross-rig tasks.",
},
{
ID: WitnessRoleBeadIDTown(),
Title: "Witness Role",
Desc: "Role definition for Witness agents. Per-rig worker monitor with progressive nudging.",
},
{
ID: RefineryRoleBeadIDTown(),
Title: "Refinery Role",
Desc: "Role definition for Refinery agents. Merge queue processor with verification gates.",
},
{
ID: PolecatRoleBeadIDTown(),
Title: "Polecat Role",
Desc: "Role definition for Polecat agents. Ephemeral workers for batch work dispatch.",
},
{
ID: CrewRoleBeadIDTown(),
Title: "Crew Role",
Desc: "Role definition for Crew agents. Persistent user-managed workspaces.",
},
}
}