fix(rig): Reject rig names with hyphens, dots, or spaces (GHI #23)

Add validation in Manager.AddRig() to reject rig names containing
characters that break agent ID parsing. Agent IDs use format
<prefix>-<rig>-<role>[-<name>] with hyphens as delimiters, so
hyphenated rig names like op-baby cause parsing failures.

The validation rejects hyphens, dots, and spaces, and suggests a
sanitized alternative in the error message.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
capable
2026-01-02 12:15:10 -08:00
committed by Steve Yegge
parent c5ee18c6ab
commit 1f72285a76
2 changed files with 39 additions and 0 deletions

View File

@@ -174,6 +174,13 @@ func (m *Manager) AddRig(opts AddRigOptions) (*Rig, error) {
return nil, ErrRigExists
}
// Validate rig name: reject characters that break agent ID parsing
// Agent IDs use format <prefix>-<rig>-<role>[-<name>] with hyphens as delimiters
if strings.ContainsAny(opts.Name, "-. ") {
sanitized := strings.NewReplacer("-", "", ".", "", " ", "").Replace(opts.Name)
return nil, fmt.Errorf("rig name %q contains invalid characters (hyphens, dots, or spaces break agent ID parsing); use %q instead", opts.Name, sanitized)
}
rigPath := filepath.Join(m.townRoot, opts.Name)
// Check if directory already exists

View File

@@ -3,6 +3,7 @@ package rig
import (
"os"
"path/filepath"
"strings"
"testing"
"github.com/steveyegge/gastown/internal/config"
@@ -166,6 +167,37 @@ func TestRemoveRigNotFound(t *testing.T) {
}
}
func TestAddRig_RejectsInvalidNames(t *testing.T) {
root, rigsConfig := setupTestTown(t)
manager := NewManager(root, rigsConfig, git.NewGit(root))
tests := []struct {
name string
wantError string
}{
{"op-baby", `rig name "op-baby" contains invalid characters`},
{"my.rig", `rig name "my.rig" contains invalid characters`},
{"my rig", `rig name "my rig" contains invalid characters`},
{"op-baby-test", `rig name "op-baby-test" contains invalid characters`},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := manager.AddRig(AddRigOptions{
Name: tt.name,
GitURL: "git@github.com:test/test.git",
})
if err == nil {
t.Errorf("AddRig(%q) succeeded, want error containing %q", tt.name, tt.wantError)
return
}
if !strings.Contains(err.Error(), tt.wantError) {
t.Errorf("AddRig(%q) error = %q, want error containing %q", tt.name, err.Error(), tt.wantError)
}
})
}
}
func TestListRigNames(t *testing.T) {
root, rigsConfig := setupTestTown(t)
rigsConfig.Rigs["rig1"] = config.RigEntry{}