refactor: ZFC cleanup - move Go heuristics to Deacon molecule (gt-gaxo)
Remove Go code that makes workflow decisions. All health checking, staleness detection, nudging, and escalation belongs in the Deacon molecule where Claude executes it. Removed: - internal/daemon/backoff.go (190 lines) - exponential backoff decisions - internal/doctor/stale_check.go (284 lines) - staleness detection - IsFresh/IsStale/IsVeryStale from keepalive.go - pokeMayor, pokeWitnesses, pokeWitness from daemon.go - Heartbeat staleness classification from pokeDeacon Changed: - Lifecycle parsing now uses structured body (JSON or simple text) instead of keyword matching on subject line - Daemon now only ensures Deacon is running and sends simple heartbeats - No backoff, no staleness classification, no decision-making Total: ~800 lines removed from Go code The Deacon molecule will handle all health checking, nudging, and escalation. Go is now just a message router. See gt-gaxo epic for full rationale. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -86,26 +86,7 @@ func Read(workspaceRoot string) *State {
|
||||
// Returns a very large duration if the state is nil.
|
||||
func (s *State) Age() time.Duration {
|
||||
if s == nil {
|
||||
return 24 * time.Hour * 365 // Very stale
|
||||
return 24 * time.Hour * 365 // No keepalive
|
||||
}
|
||||
return time.Since(s.Timestamp)
|
||||
}
|
||||
|
||||
// IsFresh returns true if the keepalive is less than 2 minutes old.
|
||||
func (s *State) IsFresh() bool {
|
||||
return s != nil && s.Age() < 2*time.Minute
|
||||
}
|
||||
|
||||
// IsStale returns true if the keepalive is 2-5 minutes old.
|
||||
func (s *State) IsStale() bool {
|
||||
if s == nil {
|
||||
return false
|
||||
}
|
||||
age := s.Age()
|
||||
return age >= 2*time.Minute && age < 5*time.Minute
|
||||
}
|
||||
|
||||
// IsVeryStale returns true if the keepalive is more than 5 minutes old.
|
||||
func (s *State) IsVeryStale() bool {
|
||||
return s == nil || s.Age() >= 5*time.Minute
|
||||
}
|
||||
|
||||
@@ -39,47 +39,29 @@ func TestReadNonExistent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStateAge(t *testing.T) {
|
||||
// Test nil state
|
||||
// Test nil state returns very large age
|
||||
var nilState *State
|
||||
if nilState.Age() < 24*time.Hour {
|
||||
t.Error("nil state should have very large age")
|
||||
}
|
||||
|
||||
// Test fresh state
|
||||
// Test fresh state returns accurate age
|
||||
freshState := &State{Timestamp: time.Now().Add(-30 * time.Second)}
|
||||
if !freshState.IsFresh() {
|
||||
t.Error("30-second-old state should be fresh")
|
||||
}
|
||||
if freshState.IsStale() {
|
||||
t.Error("30-second-old state should not be stale")
|
||||
}
|
||||
if freshState.IsVeryStale() {
|
||||
t.Error("30-second-old state should not be very stale")
|
||||
age := freshState.Age()
|
||||
if age < 29*time.Second || age > 31*time.Second {
|
||||
t.Errorf("expected ~30s age, got %v", age)
|
||||
}
|
||||
|
||||
// Test stale state (3 minutes)
|
||||
staleState := &State{Timestamp: time.Now().Add(-3 * time.Minute)}
|
||||
if staleState.IsFresh() {
|
||||
t.Error("3-minute-old state should not be fresh")
|
||||
}
|
||||
if !staleState.IsStale() {
|
||||
t.Error("3-minute-old state should be stale")
|
||||
}
|
||||
if staleState.IsVeryStale() {
|
||||
t.Error("3-minute-old state should not be very stale")
|
||||
// Test older state returns accurate age
|
||||
olderState := &State{Timestamp: time.Now().Add(-5 * time.Minute)}
|
||||
age = olderState.Age()
|
||||
if age < 4*time.Minute+55*time.Second || age > 5*time.Minute+5*time.Second {
|
||||
t.Errorf("expected ~5m age, got %v", age)
|
||||
}
|
||||
|
||||
// Test very stale state (10 minutes)
|
||||
veryStaleState := &State{Timestamp: time.Now().Add(-10 * time.Minute)}
|
||||
if veryStaleState.IsFresh() {
|
||||
t.Error("10-minute-old state should not be fresh")
|
||||
}
|
||||
if veryStaleState.IsStale() {
|
||||
t.Error("10-minute-old state should not be stale (it's very stale)")
|
||||
}
|
||||
if !veryStaleState.IsVeryStale() {
|
||||
t.Error("10-minute-old state should be very stale")
|
||||
}
|
||||
// NOTE: IsFresh(), IsStale(), IsVeryStale() were removed as part of ZFC cleanup.
|
||||
// Staleness classification belongs in Deacon molecule, not Go code.
|
||||
// See gt-gaxo epic for rationale.
|
||||
}
|
||||
|
||||
func TestDirectoryCreation(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user