fix: ZFC improvements - query tmux directly instead of marker TTL
Two ZFC fixes: 1. Boot marker file (hq-zee5n): Changed IsRunning() to query tmux.HasSession() directly instead of checking marker file freshness with TTL. Removed stale marker check from doctor. 2. Branch pattern matching (hq-zwuh6): Replaced hardcoded "polecat/" strings with constants.BranchPolecatPrefix for consistency. Also removed 60-second WaitForCommand blocking from crew Start() which was causing gt crew start to hang. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Steve Yegge
parent
e0858096f6
commit
c94d59dca7
@@ -23,15 +23,12 @@ import (
|
||||
// to return true when only Boot is running.
|
||||
const SessionName = "gt-boot"
|
||||
|
||||
// MarkerFileName is the file that indicates Boot is currently running.
|
||||
// MarkerFileName is the lock file for Boot startup coordination.
|
||||
const MarkerFileName = ".boot-running"
|
||||
|
||||
// StatusFileName stores Boot's last execution status.
|
||||
const StatusFileName = ".boot-status.json"
|
||||
|
||||
// DefaultMarkerTTL is how long a marker is considered valid before it's stale.
|
||||
const DefaultMarkerTTL = 5 * time.Minute
|
||||
|
||||
// Status represents Boot's execution status.
|
||||
type Status struct {
|
||||
Running bool `json:"running"`
|
||||
@@ -78,22 +75,9 @@ func (b *Boot) statusPath() string {
|
||||
}
|
||||
|
||||
// IsRunning checks if Boot is currently running.
|
||||
// Returns true if marker exists and isn't stale, false otherwise.
|
||||
// Queries tmux directly for observable reality (ZFC principle).
|
||||
func (b *Boot) IsRunning() bool {
|
||||
info, err := os.Stat(b.markerPath())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if marker is stale (older than TTL)
|
||||
age := time.Since(info.ModTime())
|
||||
if age > DefaultMarkerTTL {
|
||||
// Stale marker - clean it up
|
||||
_ = os.Remove(b.markerPath())
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
return b.IsSessionAlive()
|
||||
}
|
||||
|
||||
// IsSessionAlive checks if the Boot tmux session exists.
|
||||
@@ -106,7 +90,7 @@ func (b *Boot) IsSessionAlive() bool {
|
||||
// Returns error if Boot is already running.
|
||||
func (b *Boot) AcquireLock() error {
|
||||
if b.IsRunning() {
|
||||
return fmt.Errorf("boot is already running (marker exists)")
|
||||
return fmt.Errorf("boot is already running (session exists)")
|
||||
}
|
||||
|
||||
if err := b.EnsureDir(); err != nil {
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/steveyegge/gastown/internal/beads"
|
||||
"github.com/steveyegge/gastown/internal/constants"
|
||||
"github.com/steveyegge/gastown/internal/git"
|
||||
"github.com/steveyegge/gastown/internal/rig"
|
||||
"github.com/steveyegge/gastown/internal/style"
|
||||
@@ -32,7 +33,7 @@ func parseBranchName(branch string) branchInfo {
|
||||
info := branchInfo{Branch: branch}
|
||||
|
||||
// Try polecat/<worker>/<issue> format
|
||||
if strings.HasPrefix(branch, "polecat/") {
|
||||
if strings.HasPrefix(branch, constants.BranchPolecatPrefix) {
|
||||
parts := strings.SplitN(branch, "/", 3)
|
||||
if len(parts) == 3 {
|
||||
info.Worker = parts[1]
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/steveyegge/gastown/internal/beads"
|
||||
"github.com/steveyegge/gastown/internal/claude"
|
||||
"github.com/steveyegge/gastown/internal/config"
|
||||
"github.com/steveyegge/gastown/internal/constants"
|
||||
"github.com/steveyegge/gastown/internal/git"
|
||||
"github.com/steveyegge/gastown/internal/rig"
|
||||
"github.com/steveyegge/gastown/internal/session"
|
||||
@@ -536,8 +535,10 @@ func (m *Manager) Start(name string, opts StartOptions) error {
|
||||
// Set up C-b n/p keybindings for crew session cycling (non-fatal)
|
||||
_ = t.SetCrewCycleBindings(sessionID)
|
||||
|
||||
// Wait for Claude to start (non-fatal: session continues even if this times out)
|
||||
_ = t.WaitForCommand(sessionID, constants.SupportedShells, constants.ClaudeStartTimeout)
|
||||
// Note: We intentionally don't wait for Claude to start here.
|
||||
// The session is created in detached mode, and blocking for 60 seconds
|
||||
// serves no purpose. If the caller needs to know when Claude is ready,
|
||||
// they can check with IsClaudeRunning().
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package doctor
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/steveyegge/gastown/internal/boot"
|
||||
@@ -84,24 +83,9 @@ func (c *BootHealthCheck) Run(ctx *CheckContext) *CheckResult {
|
||||
details = append(details, "No previous run recorded")
|
||||
}
|
||||
|
||||
// Check 4: Marker file freshness (stale marker indicates crash)
|
||||
markerPath := filepath.Join(bootDir, boot.MarkerFileName)
|
||||
if info, err := os.Stat(markerPath); err == nil {
|
||||
age := time.Since(info.ModTime())
|
||||
if age > boot.DefaultMarkerTTL {
|
||||
return &CheckResult{
|
||||
Name: c.Name(),
|
||||
Status: StatusWarning,
|
||||
Message: "Boot marker is stale (possible crash)",
|
||||
Details: []string{
|
||||
fmt.Sprintf("Marker age: %s", age.Round(time.Second)),
|
||||
fmt.Sprintf("TTL: %s", boot.DefaultMarkerTTL),
|
||||
},
|
||||
FixHint: "Stale marker will be cleaned on next daemon tick",
|
||||
}
|
||||
}
|
||||
// Marker exists and is fresh - Boot is currently running
|
||||
details = append(details, fmt.Sprintf("Currently running (marker age: %s)", age.Round(time.Second)))
|
||||
// Check 4: Currently running (uses tmux session state per ZFC principle)
|
||||
if sessionAlive {
|
||||
details = append(details, "Currently running (tmux session active)")
|
||||
}
|
||||
|
||||
// All checks passed
|
||||
|
||||
@@ -742,8 +742,8 @@ func (c *PolecatClonesValidCheck) Run(ctx *CheckContext) *CheckResult {
|
||||
branchOutput, err := cmd.Output()
|
||||
if err == nil {
|
||||
branch := strings.TrimSpace(string(branchOutput))
|
||||
if !strings.HasPrefix(branch, "polecat/") {
|
||||
warnings = append(warnings, fmt.Sprintf("%s: on branch '%s' (expected polecat/*)", polecatName, branch))
|
||||
if !strings.HasPrefix(branch, constants.BranchPolecatPrefix) {
|
||||
warnings = append(warnings, fmt.Sprintf("%s: on branch '%s' (expected %s*)", polecatName, branch, constants.BranchPolecatPrefix))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -663,7 +663,7 @@ func (m *Manager) FindMR(idOrBranch string) (*MergeRequest, error) {
|
||||
if item.MR.Branch == idOrBranch {
|
||||
return item.MR, nil
|
||||
}
|
||||
if "polecat/"+idOrBranch == item.MR.Branch {
|
||||
if constants.BranchPolecatPrefix+idOrBranch == item.MR.Branch {
|
||||
return item.MR, nil
|
||||
}
|
||||
// Match by worker name (partial match for convenience)
|
||||
|
||||
Reference in New Issue
Block a user