Recover wedged in-progress tasks by clearing stale executor bindings only after liveness proves the owner is gone.
- Add a guarded executor escape hatch that clears only stale in-memory task bookkeeping while refusing live session surfaces.
- Teach self-healing to identify phantom executor-active bindings using age, checkout, heartbeat, run-audit, and worktree liveness signals before requeueing preserved work.
- Record reclaim events in run audit and cover preserved-worktree recovery with reliability interaction tests.
- Document the recovery path and add a patch changeset for the published CLI package.
Files changed:
.changeset/fn-6736-phantom-executor-binding.md | 5 +
AGENTS.md | 1 +
docs/architecture.md | 1 +
.../reclaim-phantom-executor-binding.test.ts | 244 +++++++++++++++++++++
packages/engine/src/executor.ts | 35 +++
packages/engine/src/run-audit.ts | 2 +
packages/engine/src/runtimes/in-process-runtime.ts | 3 +-
packages/engine/src/self-healing.ts | 112 ++++++++++
8 files changed, 402 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-6736
Fusion-Task-Lineage: c76191ba-f4c3-4832-a790-67676e258ba2
The paused-after-completion graceful-exit path finalizes a fully completed task to in-review while leaving a non-user paused:true flag set (handoffToReview/applyInReviewEnterEffects clear status/blockedBy but not paused). handleGraphFailure's completion-finalized guards required paused!==true, so once the volatile completion markers were lost (execute() re-entry deletes completionFinalizedTaskIds; teardown overwrites provenance to hard-cancel) the trailing graph failure was misclassified as an operator-action pause abort and the completed task was parked status:failed (FN-6638 recurrence). Drop the paused!==true requirement from alreadyFinalizedToReview and suppressFinalizedCompletionAbort, and gate genuinePauseAbort's bare paused clause on the completion suppression. Genuine userPaused/global-pause/in-progress tasks are unaffected.
Fusion-Task-Id: FN-6648
Prevent completed no-commit executions that already advanced to review from being re-parked as pause-abort failures.
- Add completion-finalize pause-abort provenance and exclude it from genuine pause handling after review handoff.
- Mark paused-after-completion finalization paths with the new provenance before handing tasks to review.
- Cover the finalize-to-review abort recovery path with executor regression tests and document the lifecycle exception.
- Add a patch changeset for the published Fusion package.
Files changed:
.changeset/fn-6625-finalize-to-review-abort.md | 5 +
docs/architecture.md | 2 +-
.../engine/src/__tests__/executor-recovery.test.ts | 158 ++++++++++++++++++++-
packages/engine/src/executor.ts | 26 +++-
4 files changed, 185 insertions(+), 6 deletions(-)
Fusion-Task-Id: FN-6625
Fusion-Task-Lineage: 728f6fe5-4c27-4597-b17e-e16ff97b9277
Ensure task-detail comments are delivered to live executor threads and preserved for the next step prompt when no step session is active.
- Forward steering comments through legacy, step-session, and workflow-step executor targets with delivery status logging.
- Keep step-session task details updated and include pending steering comments in full and reduced step prompts.
- Track delivered steering comment IDs so comments are injected or queued exactly once across active and subsequent step sessions.
- Update step-session executor tests for live steering, queued prompt fallback, and reduced prompt behavior.
Files changed:
.../src/__tests__/executor-step-session.test.ts | 467 ++++++---------------
.../src/__tests__/step-session-executor.test.ts | 63 ++-
packages/engine/src/executor.ts | 34 +-
packages/engine/src/step-session-executor.ts | 69 ++-
4 files changed, 283 insertions(+), 350 deletions(-)
Fusion-Task-Id: FN-6590
Fusion-Task-Lineage: 18fffd41-7632-4f29-8721-daaf3c239a74
Resolves conflicts in the lazy-loaded heavy-views inventory. main independently
grew the curated list to 22 (adding AppModals lazy modals); this branch added the
Command Center view. Combined count is 23 — updated the AGENTS.md prose/inventory
and the lazy-loaded-views-docs test contract (count + length assertions) to 23,
keeping main's richer "App-level and AppModals" wording.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Schema migration 117→118 adds usage_events; events captured via a dedicated
emitUsageEvent seam wired through AgentLogger tool hooks + executor session
context (model/provider/nodeId), not by widening log signatures. meta is
size-capped and carries only non-sensitive descriptors.
Resolves the onLoad conflict in the compound-engineering plugin by keeping both
the bundled ce-* persona-def install (this branch) and main's
recoverStaleSessionsForContext call.
Also addresses PR #1672 review feedback:
- executor: sentinel resume now guards on !live.paused (mirrors
runAwaitInputNode) so a still-paused task can't consume a reply and re-enter
the skill early.
- TaskCard: make the Answer-questions button text/title/aria-label fallbacks
consistent ("Answer questions") for label-in-name a11y; update test.
- ce-work: replace the unshipped `skill: ce-worktree` reference with the real
git worktree commands so Option B can't dead-end.
- ce-resolve-pr-feedback: invoke bundled scripts by absolute path via the new
FUSION_CE_SKILLS_DIR env (sessions run with cwd=projectRoot); add the Fusion
await-input sentinel path instead of AskUserQuestion for workflow steps;
normalize whitespace-only review bodies like PR comments.
- plugin: expose FUSION_CE_SKILLS_DIR (installed skills root) to step sessions.
- plan doc: add language to fenced block (markdownlint MD040).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When a skill in a graph workflow step emits ===FUSION_AWAIT_INPUT===,
runGraphCustomNode now parks the task awaiting-user-input with the
question (reusing the runAwaitInputNode pause/watermark model so the
dashboard input banner + task-card button surface it), and halts the
walk. On resume the node re-runs; the resume check consumes the user's
steering reply and lets the skill continue with the answer.
Pure sentinel parser unit-tested (6 cases). End-to-end pause/resume
through the graph interpreter needs verification on a running board.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an optional systemPromptOverride to spawnAgentParams. When non-empty,
the spawned child runs under that persona system prompt instead of the
generic child base prompt (executor instructions still appended), so a
caller can spawn a specific persona — the primitive the compound-
engineering reviewer/research fan-out needs.
Two spikes confirmed the need: fn_spawn_agent had no persona param, and
Fusion has no plugin agent-contribution channel — so the lightweight path
is a generic override here + plugin-local persona defs the skill reads and
passes inline (revised KTD-4/U2/U3 in the plan). Behavioral coverage lands
with U10.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
U1: workflow-step sessions now carry FUSION_WORKFLOW_STEP=1 (scoped to
the step session, not the main executor) so skills detect autonomous
context and surface questions via await-input instead of a dead blocking
tool.
U8: bundle ce-commit, ce-commit-push-pr, and ce-resolve-pr-feedback
(vendored from compound-engineering 3.9.4) so the CE merge/PR flow has
its skills. Registered in COMPOUND_ENGINEERING_SKILLS; manifest test
updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reconcile the FN-352 no-commit coordination guard skip with main's
independently-landed FN-424 work. Both branches added a no_commits
guard bypass at the same fn_task_done call site:
- FN-352 (this branch): getNoCommitEligibilityReason(task) covering
Review Level 1 coordination prompts with board-only scope and
explicit no-source intent (e.g. "Do not change product source").
- FN-424 (main): evaluatePromptDerivedNoCommitEligibility(...) plus
non-blocking audit logging of the skip.
Their prompt phrase-matching differs, so neither alone satisfies the
merged test file. Resolved by OR-ing both eligibility checks and
wrapping the skip in main's audit-logging block. Both helpers still
refuse the contradictory implementation+coordination prompt.
All 18 executor-task-done-invariant tests pass; engine typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve conflicts from main's FN-6232 single-source triage prompt refactor:
- Drop the inline FAST_TRIAGE_SYSTEM_PROMPT const removed by main; the fast
triage prompt now lives in agent-prompts.ts (planning-fast seam).
- Migrate the PR's no-commit/operational-routing heuristic edits into the
fast block of agent-prompts.ts (standard block already carried them).
- Point triage tests at FAST_PLANNING_PROMPT/TRIAGE_POLICY_PROMPT instead of
the removed const.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Treat already-finalized or paused workflow-graph exits as benign instead of failure-worthy.
- log info-level benign messages when workflow graph runs end after a task is paused or has already advanced out of in-progress
- keep true in-progress graph failures on the existing failed-and-handoff path with failure logging
- add executor recovery coverage for todo, in-review, done, paused, and genuine failure cases
- add a patch changeset for the published CLI package
Files changed:
.changeset/fn-6141-benign-graph-exit.md | 5 +
.../engine/src/__tests__/executor-recovery.test.ts | 137 ++++++++++++++++++++-
packages/engine/src/executor.ts | 23 ++--
3 files changed, 150 insertions(+), 15 deletions(-)
Fusion-Task-Id: FN-6141
Fusion-Task-Lineage: 8d29159a-8d7a-4e84-b05a-fe83f6ccbb78
Normalize package file-filter verification to direct Vitest execution, kill timed-out process groups, and bound loop-recovery compaction so stuck tasks cannot spin indefinitely.
Fusion-Task-Id: FN-5994