refactor(witness,refinery): ZFC-compliant state management
Remove state files from witness and refinery managers, following the "Discover, Don't Track" principle. Tmux session existence is now the source of truth for running state (like deacon). Changes: - Add IsRunning() that checks tmux HasSession - Change Status() to return *tmux.SessionInfo - Remove loadState/saveState/stateManager - Simplify Start()/Stop() to not use state files - Update CLI commands (witness/refinery/rig) for new API - Update tests to be ZFC-compliant This fixes state file divergence issues where witness/refinery could show "running" when the actual tmux session was dead. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Steve Yegge
parent
126ec84bb3
commit
5218102f49
@@ -337,6 +337,14 @@ func runRefineryStop(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RefineryStatusOutput is the JSON output format for refinery status.
|
||||
type RefineryStatusOutput struct {
|
||||
Running bool `json:"running"`
|
||||
RigName string `json:"rig_name"`
|
||||
Session string `json:"session,omitempty"`
|
||||
QueueLength int `json:"queue_length"`
|
||||
}
|
||||
|
||||
func runRefineryStatus(cmd *cobra.Command, args []string) error {
|
||||
rigName := ""
|
||||
if len(args) > 0 {
|
||||
@@ -348,58 +356,42 @@ func runRefineryStatus(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
ref, err := mgr.Status()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting status: %w", err)
|
||||
}
|
||||
// ZFC: tmux is source of truth for running state
|
||||
running, _ := mgr.IsRunning()
|
||||
sessionInfo, _ := mgr.Status() // may be nil if not running
|
||||
|
||||
// Get queue from beads
|
||||
queue, _ := mgr.Queue()
|
||||
queueLen := len(queue)
|
||||
|
||||
// JSON output
|
||||
if refineryStatusJSON {
|
||||
output := RefineryStatusOutput{
|
||||
Running: running,
|
||||
RigName: rigName,
|
||||
QueueLength: queueLen,
|
||||
}
|
||||
if sessionInfo != nil {
|
||||
output.Session = sessionInfo.Name
|
||||
}
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
enc.SetIndent("", " ")
|
||||
return enc.Encode(ref)
|
||||
return enc.Encode(output)
|
||||
}
|
||||
|
||||
// Human-readable output
|
||||
fmt.Printf("%s Refinery: %s\n\n", style.Bold.Render("⚙"), rigName)
|
||||
|
||||
stateStr := string(ref.State)
|
||||
switch ref.State {
|
||||
case refinery.StateRunning:
|
||||
stateStr = style.Bold.Render("● running")
|
||||
case refinery.StateStopped:
|
||||
stateStr = style.Dim.Render("○ stopped")
|
||||
case refinery.StatePaused:
|
||||
stateStr = style.Dim.Render("⏸ paused")
|
||||
}
|
||||
fmt.Printf(" State: %s\n", stateStr)
|
||||
|
||||
if ref.StartedAt != nil {
|
||||
fmt.Printf(" Started: %s\n", ref.StartedAt.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
|
||||
if ref.CurrentMR != nil {
|
||||
fmt.Printf("\n %s\n", style.Bold.Render("Currently Processing:"))
|
||||
fmt.Printf(" Branch: %s\n", ref.CurrentMR.Branch)
|
||||
fmt.Printf(" Worker: %s\n", ref.CurrentMR.Worker)
|
||||
if ref.CurrentMR.IssueID != "" {
|
||||
fmt.Printf(" Issue: %s\n", ref.CurrentMR.IssueID)
|
||||
if running {
|
||||
fmt.Printf(" State: %s\n", style.Bold.Render("● running"))
|
||||
if sessionInfo != nil {
|
||||
fmt.Printf(" Session: %s\n", sessionInfo.Name)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf(" State: %s\n", style.Dim.Render("○ stopped"))
|
||||
}
|
||||
|
||||
// Get queue length
|
||||
queue, _ := mgr.Queue()
|
||||
pendingCount := 0
|
||||
for _, item := range queue {
|
||||
if item.Position > 0 { // Not currently processing
|
||||
pendingCount++
|
||||
}
|
||||
}
|
||||
fmt.Printf("\n Queue: %d pending\n", pendingCount)
|
||||
|
||||
if ref.LastMergeAt != nil {
|
||||
fmt.Printf(" Last merge: %s\n", ref.LastMergeAt.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
fmt.Printf("\n Queue: %d pending\n", queueLen)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user