From c0b84766024752075e389ed39a05b1607c988062 Mon Sep 17 00:00:00 2001 From: saymrwulf Date: Wed, 29 Apr 2026 12:59:47 +0200 Subject: [PATCH] Clarify engine resume state in app --- .../BraiinsRatchetMac/BraiinsRatchetApp.swift | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/macos/BraiinsRatchet/Sources/BraiinsRatchetMac/BraiinsRatchetApp.swift b/macos/BraiinsRatchet/Sources/BraiinsRatchetMac/BraiinsRatchetApp.swift index 1396127..afcf2b2 100644 --- a/macos/BraiinsRatchet/Sources/BraiinsRatchetMac/BraiinsRatchetApp.swift +++ b/macos/BraiinsRatchet/Sources/BraiinsRatchetMac/BraiinsRatchetApp.swift @@ -506,6 +506,10 @@ struct EngineConsole: View { Text(store.appState?.engineStatus.detail ?? "Loading engine state") .font(.callout) .foregroundStyle(.secondary) + Text(engineContext) + .font(.caption) + .foregroundStyle(.secondary) + .lineLimit(3) } Spacer() EngineBeacon(running: store.appState?.engineStatus.running == true) @@ -515,7 +519,7 @@ struct EngineConsole: View { Button { Task { await store.startEngine() } } label: { - Label("Start Forever Engine", systemImage: "dot.radiowaves.left.and.right") + Label(startEngineTitle, systemImage: "dot.radiowaves.left.and.right") } .buttonStyle(.glassProminent) .tint(.green) @@ -542,6 +546,29 @@ struct EngineConsole: View { .padding(20) } } + + private var startEngineTitle: String { + guard let state = store.appState else { return "Start Forever Engine" } + if state.operatorState.completedWatch != nil { return "Resume Forever Engine" } + if !state.operatorState.runningRuns.isEmpty { return "Recover Forever Engine" } + return "Start Forever Engine" + } + + private var engineContext: String { + guard let state = store.appState else { + return "Loading durable research state from SQLite." + } + if state.engineStatus.running { + return "Forever means watch, report, cooldown, then repeat until you stop it." + } + if let watch = state.operatorState.completedWatch { + return "Cooldown is active until \(watch.earliestActionLocal). Resume means wait, then continue automatically." + } + if !state.operatorState.runningRuns.isEmpty { + return "A previous run marker exists without a live engine. Refresh/recover before starting new research." + } + return "Stopped. Start begins the always-on monitor-only supervisor." + } } struct ReactorLens: View { @@ -1774,7 +1801,8 @@ struct RenderedReality: Codable { } switch section { case .deck: - buttons.append(contentsOf: ["Flight Deck: Start Forever Engine", "Flight Deck: Stop", "Flight Deck: One Sample"]) + let deckStart = appState?.operatorState.completedWatch == nil ? "Flight Deck: Start Forever Engine" : "Flight Deck: Resume Forever Engine" + buttons.append(contentsOf: [deckStart, "Flight Deck: Stop", "Flight Deck: One Sample"]) case .exposure: buttons.append(contentsOf: ["Exposure: Record Exposure", "Exposure: Close Exposure"]) case .vault: