perf(executor): recover approved steps on engine restart

When the engine restarts mid-step, an in-progress step may have already
passed plan + code review but not yet been flipped to done by the agent's
next task_update call. Previously, the next executor pass re-entered the
step and replayed both reviews — measured at 5-20 min of pure waste per
restart (observed in FN-2215 Step 1 and FN-2207 Step 6).

recoverApprovedStepsOnResume scans the task log for any in-progress step
whose most recent "code review Step N: APPROVE" entry is newer than its
most recent "Step N → pending" transition, and marks those steps done
before execute() runs. Safely skips steps that were reset after approval
(e.g. by a workflow revision) or only received REVISE verdicts.

Called from both the engine-restart path (resumeOrphaned) and the
unpause path, matching the two places the task log shows as vulnerable
to this race.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Fusion
2026-04-21 09:02:42 -07:00
committed by gsxdsm
parent 9033f7ada7
commit c21e6fef15
33 changed files with 414 additions and 90 deletions

View File

@@ -128,7 +128,8 @@ function maskToken(token: string): string {
export interface DaemonOptions {
/** Port to listen on (default: 0 for random port) */
port?: number;
/** Host to bind to (default: 0.0.0.0) */
/** Host to bind to (default: 127.0.0.1 — localhost only). Pass "0.0.0.0" to
* expose on all interfaces. */
host?: string;
/** Specific token to use (generated if not provided) */
token?: string;
@@ -207,7 +208,7 @@ export async function runDaemon(opts: DaemonOptions = {}) {
}
}
const selectedHost = opts.host ?? "0.0.0.0";
const selectedHost = opts.host ?? "127.0.0.1";
const cwd = await resolveRuntimeProjectPath();
// ── CentralCore: global coordination + ntfy project ID lookup ─────────
@@ -466,13 +467,16 @@ export async function runDaemon(opts: DaemonOptions = {}) {
console.warn(`[daemon] Failed to set local node online: ${message}`);
}
// Print startup banner with full token (shown once at startup)
// Print startup banner with a masked token. The full token is persisted in
// global settings (~/.fusion/settings.json, chmod 0600) and can be retrieved
// with `fn daemon --token-only` — printing it here would write the raw
// secret to terminal scrollback, CI logs, and screen-capture tools.
console.log();
console.log(` Fusion Daemon`);
console.log(` ────────────────────────`);
console.log(` → http://${selectedHost}:${actualPort}`);
console.log();
console.log(` Token: ${daemonToken}`);
console.log(` Token: ${maskToken(daemonToken)} (run "fn daemon --token-only" to retrieve)`);
console.log();
console.log(` Health: GET /api/health`);
console.log(` API: /api/* (bearer token required)`);