fix: remove vestigial state.json files from agent directories
Agent directories (witness/, refinery/, mayor/) contained state.json files with last_active timestamps that were never updated, making them stale and misleading. This change removes: - initAgentStates function that created vestigial state.json files - AgentState type and related Load/Save functions from config package - MayorStateValidCheck from doctor checks - requesting_* lifecycle verification (dead code - flags were never set) - FileStateJSON constant and MayorStatePath function Kept intact: - daemon/state.json (actively used for daemon runtime state) - crew/<name>/state.json (operational CrewWorker metadata) - Agent state tracking via beads (the ZFC-compliant approach) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -113,50 +113,6 @@ func SaveRigsConfig(path string, config *RigsConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadAgentState loads an agent state file.
|
||||
func LoadAgentState(path string) (*AgentState, error) {
|
||||
data, err := os.ReadFile(path) //nolint:gosec // G304: path is constructed internally, not from user input
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("%w: %s", ErrNotFound, path)
|
||||
}
|
||||
return nil, fmt.Errorf("reading state: %w", err)
|
||||
}
|
||||
|
||||
var state AgentState
|
||||
if err := json.Unmarshal(data, &state); err != nil {
|
||||
return nil, fmt.Errorf("parsing state: %w", err)
|
||||
}
|
||||
|
||||
if err := validateAgentState(&state); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &state, nil
|
||||
}
|
||||
|
||||
// SaveAgentState saves an agent state to a file.
|
||||
func SaveAgentState(path string, state *AgentState) error {
|
||||
if err := validateAgentState(state); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
||||
return fmt.Errorf("creating directory: %w", err)
|
||||
}
|
||||
|
||||
data, err := json.MarshalIndent(state, "", " ")
|
||||
if err != nil {
|
||||
return fmt.Errorf("encoding state: %w", err)
|
||||
}
|
||||
|
||||
if err := os.WriteFile(path, data, 0644); err != nil { //nolint:gosec // G306: state files don't contain secrets
|
||||
return fmt.Errorf("writing state: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateTownConfig validates a TownConfig.
|
||||
func validateTownConfig(c *TownConfig) error {
|
||||
if c.Type != "town" && c.Type != "" {
|
||||
@@ -182,14 +138,6 @@ func validateRigsConfig(c *RigsConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateAgentState validates an AgentState.
|
||||
func validateAgentState(s *AgentState) error {
|
||||
if s.Role == "" {
|
||||
return fmt.Errorf("%w: role", ErrMissingField)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadRigConfig loads and validates a rig configuration file.
|
||||
func LoadRigConfig(path string) (*RigConfig, error) {
|
||||
data, err := os.ReadFile(path) //nolint:gosec // G304: path is constructed internally, not from user input
|
||||
|
||||
@@ -80,36 +80,6 @@ func TestRigsConfigRoundTrip(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAgentStateRoundTrip(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "state.json")
|
||||
|
||||
original := &AgentState{
|
||||
Role: "mayor",
|
||||
LastActive: time.Now().Truncate(time.Second),
|
||||
Session: "abc123",
|
||||
Extra: map[string]any{
|
||||
"custom": "value",
|
||||
},
|
||||
}
|
||||
|
||||
if err := SaveAgentState(path, original); err != nil {
|
||||
t.Fatalf("SaveAgentState: %v", err)
|
||||
}
|
||||
|
||||
loaded, err := LoadAgentState(path)
|
||||
if err != nil {
|
||||
t.Fatalf("LoadAgentState: %v", err)
|
||||
}
|
||||
|
||||
if loaded.Role != original.Role {
|
||||
t.Errorf("Role = %q, want %q", loaded.Role, original.Role)
|
||||
}
|
||||
if loaded.Session != original.Session {
|
||||
t.Errorf("Session = %q, want %q", loaded.Session, original.Session)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadTownConfigNotFound(t *testing.T) {
|
||||
_, err := LoadTownConfig("/nonexistent/path.json")
|
||||
if err == nil {
|
||||
@@ -129,12 +99,6 @@ func TestValidationErrors(t *testing.T) {
|
||||
if err := validateTownConfig(tc); err == nil {
|
||||
t.Error("expected error for wrong type")
|
||||
}
|
||||
|
||||
// Missing role
|
||||
as := &AgentState{}
|
||||
if err := validateAgentState(as); err == nil {
|
||||
t.Error("expected error for missing role")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRigConfigRoundTrip(t *testing.T) {
|
||||
|
||||
@@ -65,14 +65,6 @@ type BeadsConfig struct {
|
||||
Prefix string `json:"prefix"` // issue prefix
|
||||
}
|
||||
|
||||
// AgentState represents an agent's current state (*/state.json).
|
||||
type AgentState struct {
|
||||
Role string `json:"role"` // "mayor", "witness", etc.
|
||||
LastActive time.Time `json:"last_active"`
|
||||
Session string `json:"session,omitempty"`
|
||||
Extra map[string]any `json:"extra,omitempty"`
|
||||
}
|
||||
|
||||
// CurrentTownVersion is the current schema version for TownConfig.
|
||||
// Version 2: Added Owner and PublicName fields for federation identity.
|
||||
const CurrentTownVersion = 2
|
||||
|
||||
Reference in New Issue
Block a user