fix(install): add gt:role label to role beads during creation (#383)

Role beads created by gt install were missing the gt:role label required
by GetRoleConfig(), causing witness startup to fail with:
"bead hq-witness-role is not a role bead (missing gt:role label)"

This regression was introduced in 96970071 which migrated from type-based
to label-based bead classification. The install code used raw exec.Command
instead of the beads API, so it wasn't updated to add labels.

Changes:
- Use bd.CreateWithID() API which auto-converts Type:"role" to gt:role label
- Add RoleLabelCheck doctor migration to fix existing installations
- Add comprehensive unit tests with mocked dependencies

Co-authored-by: julianknutsen <julianknutsen@users.noreply.github>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Julian Knutsen
2026-01-12 09:45:21 +00:00
committed by GitHub
parent 7b35398ebc
commit 995476a9c0
4 changed files with 442 additions and 11 deletions

View File

@@ -126,6 +126,7 @@ func runDoctor(cmd *cobra.Command, args []string) error {
d.Register(doctor.NewBootHealthCheck())
d.Register(doctor.NewBeadsDatabaseCheck())
d.Register(doctor.NewCustomTypesCheck())
d.Register(doctor.NewRoleLabelCheck())
d.Register(doctor.NewFormulaCheck())
d.Register(doctor.NewBdDaemonCheck())
d.Register(doctor.NewPrefixConflictCheck())

View File

@@ -492,18 +492,18 @@ func initTownAgentBeads(townPath string) error {
continue // Already exists
}
// Create role bead using bd create --type=role
cmd := exec.Command("bd", "create",
"--type=role",
"--id="+role.id,
"--title="+role.title,
"--description="+role.desc,
)
cmd.Dir = townPath
if output, err := cmd.CombinedOutput(); err != nil {
// Create role bead using the beads API
// CreateWithID with Type: "role" automatically adds gt:role label
_, err := bd.CreateWithID(role.id, beads.CreateOptions{
Title: role.title,
Type: "role",
Description: role.desc,
Priority: -1, // No priority
})
if err != nil {
// Log but continue - role beads are optional
fmt.Printf(" %s Could not create role bead %s: %s\n",
style.Dim.Render("⚠"), role.id, strings.TrimSpace(string(output)))
fmt.Printf(" %s Could not create role bead %s: %v\n",
style.Dim.Render("⚠"), role.id, err)
continue
}
fmt.Printf(" ✓ Created role bead: %s\n", role.id)