Commit Graph

592 Commits

Author SHA1 Message Date
gsxdsm
7235b25fb8 Address PR review feedback (#1696)
- step() test helper now carries skillName, so the WS-6 round-trip fixture
  actually exercises the INVERSION CONTRACT for skillName (was silently dropped).
- executeWorkflowStep now strips an inherited FUSION_HEADLESS on board runs
  (unattended=false), preserving the U3 default-safe invariant — a board step
  nested under a headless-env parent could otherwise skip user questions.
  Added a regression test for the inherited-env strip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 00:07:20 -07:00
gsxdsm
c0f330e70c fix(review): apply autofix feedback
Address confirmed code-review findings on the CE workflow-step change:
- Graph-path spawn lifecycle (adversarial A-1/A-2): the graph path returns from
  execute() before its outer finally that calls terminateAllChildren, so U8's new
  coding-mode fn_spawn_agent children orphaned their sessions/worktrees and their
  ids accumulated in the per-parent spawn budget, starving later steps' fan-out.
  Call terminateAllChildren in maybeExecuteWorkflowGraph's finally (mirrors the
  non-graph cleanup).
- INVERSION CONTRACT parity (api-contract AC-2 + testing TF-001): add skillName to
  the workflow-steps-to-ir round-trip projections + a skill-step fixture, so the
  contract the comment claims is actually asserted.
- Silent skill-load degradation (adversarial A-3 / Risk-4): warn when a step names
  a skill but FUSION_CE_SKILLS_DIR is unset, instead of failing silent.
- Dead branch (maintainability M-01): drop the always-false unattendedRun guard;
  keep the delete + extension-point comment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 23:16:12 -07:00
gsxdsm
b564ee006c feat(engine): load CE skills + spawn + conventions on the graph-step path (U8/U1/U2/U3/U9)
The builtin compound-engineering workflow runs via runGraphCustomNode, which
never loaded the named skill or threaded the plugin-injected runtime env, and
fn_spawn_agent was registered only in the main session. This wires the real seam:

- U8: thread injected FUSION_CE_* env into skill/model graph steps (shared
  buildInjectedRuntimeEnv helper); register createSpawnAgentTool for coding-mode
  skill steps (readonly still strips spawn).
- U1: merge the step's skillName (namespaced + bare) into requestedSkillNames and
  pass FUSION_CE_SKILLS_DIR as additionalSkillPaths so the bundled SKILL.md is
  discovered and selected.
- U2: prepend the Fusion workflow-step conventions preamble (await-input sentinel,
  FUSION_HEADLESS degrade, persona fan-out via systemPromptOverride).
- U3: explicit unattended opt-in sets FUSION_HEADLESS=1 (default-safe board run).
- U9: path-confined persona read documented in the preamble; accepted
  write-capability posture documented at the coding-mode tool registration.
- KTD-6: verdict-JSON contract required only for gate / skill-less steps.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 22:47:39 -07:00
gsxdsm
7b85fead54 Address code-review findings on pause-abort + task-chat fixes
- Reliability (P3): emit an `Auto-recovered:`-prefixed log on the
  benign-todo stale-failure clear path so NotificationService
  proactively cancels the pending failure timer (recoveredStatus path)
  instead of relying only on the fire-time re-check, which is
  race-contingent when failureNotificationDelayMs is near 0. Scoped to
  the actual-clear path so the common no-failure re-queue isn't
  mislabeled as a recovery.
- Project-standards (P3): add the required yyyy-MM-dd-hh:mm stamp to the
  new FNXC comments (AGENTS.md FNXC_LOG convention).
- Maintainability (P3): extract the scheduler "queued" waiting marker to
  a named SCHEDULER_WAITING_STATUS constant.
- Testing: pin the guard's skip on a clean todo row, assert the
  Auto-recovered log fires on the stale-failure path, and add a
  paused+unassigned in-progress idle case (paused early-return wins over
  the ephemeral active-session path).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:07:07 -07:00
gsxdsm
2d327604ff Clear stale failed status on benign todo pause-abort
A pause/resume abort parked status:"failed" on an earlier non-todo
observation stays dispatchable (scheduler filters on column+paused, not
status, scheduler.ts:1288) and re-enters the FN-6782 benign-todo branch.
That branch logged "benign" but left status:"failed"/error on the row,
so the board kept showing it failed and the deferred failure
notification fired (notification-service fire-time check sees
status==="failed") — contradicting the benign log. recoverPausedAbortFailures
that would clear it is suppressed during global/engine pause
(self-healing.ts:8125), so the failure survived the pause window.

Reconcile the row with the benign reclassification: clear status/error
when the live row carries them, so the board agrees it's benign and the
pending notification is suppressed at dispatch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 19:47:56 -07:00
gsxdsm
08d1f09107 FN-6796: preserve benign in-review pause aborts
Preserve completed in-review tasks when benign pause/resume aborts surface after executor handoff.

- Detect non-user hard-cancel pause aborts on clean completed in-review rows and clear the transient abort marker without moving the task.
- Let self-healing recover persisted safe in-review pause-abort parks in place while keeping hard-cancel, pause, autoMerge:false, terminal merge, and live-execution guards intact.
- Cover executor and self-healing recovery paths with regression tests, document the audit metadata, and add a patch changeset.

Files changed:
 .../fn-6796-pause-resume-in-review-recovery.md     |  5 ++
 AGENTS.md                                          |  1 +
 docs/architecture.md                               |  2 +
 .../engine/src/__tests__/executor-recovery.test.ts | 97 +++++++++++++++++++++-
 .../active-worktree-removal-liveness.test.ts       |  2 +-
 .../self-healing-paused-abort-recovery.test.ts     | 90 +++++++++++++++++++-
 packages/engine/src/executor.ts                    | 35 ++++++++
 packages/engine/src/self-healing.ts                | 38 +++++++--
 8 files changed, 257 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-6796

Fusion-Task-Lineage: d2fe6c6d-c118-4f2f-b19e-58e6f1b29384
2026-06-20 15:11:22 -07:00
gsxdsm
7e7eb6299d Harden orphan-worktree/stale-task-dir cleanup (code-review follow-up)
Addresses findings from a multi-agent review of the two prior fixes.

P0 (executor.ts): the stale-conflict recovery force-removed worktreePath with
no bounds check; that path can come from a git admin entry resolving outside
.worktrees/. Now refuses unless the path is inside the worktrees dir, not a
symlink (realpathSync), not a registered worktree, and not actively owned, and
re-verifies liveness in the catch instead of trusting the error string. Also
excludes spawn failures (spawn git ENOENT) from the stale-path classification.

worktree-pool.ts: resolveGitdirPointer -> dotGitPointerIsDangling. Reaps only
when a .git link's gitdir target is confirmed missing; a real .git dir,
unparseable pointer, or any read/stat failure is treated as NOT dangling
(conservative) so a transient read error on a live worktree can't trigger rm.
Drops the string|"directory"|null sentinel union.

core store.ts: bypass the reconcile recency window when the live task table is
empty (corruption/restore: surviving task.json keep old mtimes) and when
fusion.db was auto-recovered on startup, so .recover row loss isn't stranded.
Adds an ignoreRecencyWindow option.

Tests: executor recovery + out-of-bounds refusal, unparseable .git skip,
recency boundary, empty-DB/forced bypass. engine 135 + core 12 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 12:46:34 -07:00
gsxdsm
438cd75eaf Fix leaked orphan worktree dirs failing execute node
Directories under .worktrees/ that survive with a dangling .git pointer
(present on disk, but their .git/worktrees/<name> admin entry is gone) are
invisible to `git worktree list`/`prune` yet collide with freshly generated
worktree names. The executor's conflict cleanup then fails with
"is not a working tree", failing the workflow graph at node 'execute' after
3 attempts.

- executor.ts: extend FN-4813 stale-conflict recovery to also treat
  "is not a working tree" and ENOENT (not just "validation failed, cannot
  remove working tree") as "no live worktree here" — prune the admin entry,
  force-remove the leftover dir, and proceed with fresh creation.
- worktree-pool.ts: reapOrphanWorktrees skipped any dir on mere .git-file
  presence, contradicting its own documented invariant. Resolve the .git
  pointer and only skip when the gitdir target exists; reap dangling
  pointers like any other orphan so they stop accumulating across runs.
- Tests for both the dangling (reaped) and valid (skipped) .git cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 09:58:23 -07:00
gsxdsm
d2fc70ac91 FN-6793: enforce dependency gates before review
Dependency gating now blocks executor and review recovery paths when dependencies remain unmet.

- Re-check unmet scheduling dependencies before workflow graph or authoritative executor dispatch and requeue blocked tasks with blockedBy.
- Rebound auto-merge-eligible in-review tasks with live unmet dependencies back to todo while preserving progress, worktree, and resume state.
- Add run-audit documentation, a patch changeset, and regression coverage for executor, scheduler, and self-healing behavior.

Files changed:
 .changeset/fn-6793-dependency-gating.md            |   7 +
 AGENTS.md                                          |   1 +
 docs/architecture.md                               |   2 +
 .../engine/src/__tests__/executor-core.test.ts     |  68 +++++++++
 .../in-review-unmet-dependency-reconcile.test.ts   | 115 +++++++++++++++
 packages/engine/src/__tests__/scheduler.test.ts    |  36 +++++
 packages/engine/src/__tests__/self-healing.test.ts | 159 +++++++++++++++++++++
 packages/engine/src/executor.ts                    |  46 ++++++
 packages/engine/src/self-healing.ts                | 112 +++++++++++++++
 9 files changed, 546 insertions(+)

Fusion-Task-Id: FN-6793

Fusion-Task-Lineage: b209264c-faae-41aa-a024-c33e0d8b61be
2026-06-20 08:13:33 -07:00
gsxdsm
7eaf513944 Address PR #1687 review: harden pause-abort recovery + FNXC comments
Substantive (A1 recoverPausedAbortFailures):
- Self-guard on globalPause/enginePaused at method entry (greptile P1) — the
  public method must not requeue tasks an operator intentionally froze.
- Re-validate the FULL predicate with a FRESH executing set on the re-read
  before the backward move (coderabbit Major + greptile): add fresh.userPaused
  and column re-check so a task that became ineligible across awaits is skipped.
- Isolate audit emission in its own try/catch (coderabbit) so an audit throw
  after a successful mutation can't log a false "recovery failed".
- Decouple the recovery predicate from the literal error text via shared
  PAUSE_ABORT_PARK_ERROR_MARKER/OPERATOR_MARKER constants (greptile) — the
  executor builds the parked message from the same constants.
- Use the wired clearPhantomExecutorBinding (live-session-guarded) instead of
  the declared-but-never-wired releaseExecutorWorktreeOwnership, which no-op'd.

Nits:
- FNXC-prefix new comments in executor.ts, run-audit.ts, and the benign test
  per repo comment policy.
- Fix a test-only type error on the clearPhantomExecutorBinding mock.

Added a test asserting the globalPause self-guard. Engine typecheck clean;
pause-abort/reaper/benign + regression suites pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 20:10:50 -07:00
gsxdsm
8e4b9e4f0f Add leaked-slot reaper (A2) to self-healing
reapLeakedConcurrencySlots() reclaims in-memory worktree slots whose
holder is no longer in-progress (the FN-6756 "in todo yet still a
maxWorktrees holder" leak) without an engine restart — defense-in-depth
behind the source fix.

- executor: new listWorktreeHolders() read-only introspection over
  activeWorktrees; wired through in-process-runtime to SelfHealingManager.
- reaper releases ONLY when every guard agrees: not executing, task
  missing or in todo/triage, past a 60s grace, and clearPhantomExecutor
  Binding itself refuses (returns false) if a live session surface is
  registered — so it can never pull a worktree from a running agent.
- registered in maintenance batch 2 (respects globalPause/enginePaused
  skip + FN-4962 ordering).
- widened the clearPhantomExecutorBinding option type to surface its
  boolean refusal signal.

Engine typecheck clean; 19 tests pass (new reaper 7 cases + regression).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 20:03:24 -07:00
gsxdsm
9643563874 Fix pause-abort worktree leak + retry storm; add auto-recovery
A global pause/resume cycle parked tasks that had re-queued to todo as
status:"failed" ("operator action required") and leaked their in-memory
worktree slot. The scheduler kept re-dispatching the todo task, the
genuine-pause-abort branch re-fired on the still-set pausedAborted marker,
and it re-parked instantly with no backoff — a retry storm (75x/hr) that
pinned maxWorktrees=3/3 and concurrency-starved the whole queue.

- R1+R2 (executor.ts handleGraphFailure): treat a pause-abort that left a
  task in `todo` as benign (FN-6782) — don't park failed, clear the
  pausedAborted marker so the next dispatch is clean, and release the
  leaked activeWorktrees slot. Operator-action failure preserved for
  genuinely stranded non-todo columns (FN-6478).
- A1 (self-healing.ts recoverPausedAbortFailures): new maintenance sweep
  that auto-recovers any pause-abort park still on the board and requeues
  it (status:null = schedulable) so the board self-heals.
- run-audit.ts: new mutation types for the recovery telemetry.

Corrected the spec's null-vs-queued assumption: the scheduler dispatch set
is column==="todo" && !paused (scheduler.ts:1288); status:"queued" is the
*blocked* marker, status:null is runnable — so recovered tasks are left null.

Deferred (documented): A2 leaked-slot reaper needs a new executor
listWorktreeHolders introspection API to reap in-memory worktree slots
safely; R1 closes the observed leak at its source.

Tests: self-healing-paused-abort-recovery.test.ts (3),
executor-paused-abort-todo-benign.test.ts (2). Engine typecheck clean;
106 existing pause/graph-failure/limbo tests still pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 19:50:46 -07:00
gsxdsm
711bf3e1b8 FN-6746: attribute token analytics per runtime model
Persist and expand per-model token usage so Command Center reports every model used by a task.

- Add a nullable per-model token usage column and task model bucket types.
- Merge session token deltas into provider/model buckets while retaining task-level totals.
- Expand model/provider analytics from per-model buckets with legacy fallbacks for older rows.
- Cover persistence, migration, aggregation, and session accumulation behavior with tests.
- Document the per-model storage contract alongside existing token analytics tables.

Files changed:
 docs/storage.md                                    |   2 +
 packages/core/src/__tests__/db-migrate.test.ts     |  62 ++++++++++
 .../core/src/__tests__/store-persistence.test.ts   |  49 ++++++++
 .../core/src/__tests__/token-analytics.test.ts     | 127 ++++++++++++++++++++-
 packages/core/src/db.ts                            |  13 ++-
 packages/core/src/index.ts                         |   2 +-
 packages/core/src/store.ts                         |   7 +-
 packages/core/src/token-analytics.ts               |  58 ++++++++--
 packages/core/src/types.ts                         |  32 ++++++
 .../src/__tests__/session-token-usage.test.ts      |  23 ++++
 packages/engine/src/executor.ts                    |  20 +++-
 packages/engine/src/session-token-usage.ts         |  50 +++++++-
 packages/engine/src/step-session-executor.ts       |   7 ++
 13 files changed, 429 insertions(+), 23 deletions(-)

Fusion-Task-Id: FN-6746

Fusion-Task-Lineage: 1b1a3b31-b669-4e89-ac38-a871f3349015
2026-06-19 16:47:34 -07:00
gsxdsm
df139ec84c FN-6736: reclaim phantom executor bindings
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
2026-06-19 16:47:33 -07:00
gsxdsm
340da92400 FN-6735: treat benign merge-seam pause aborts as retryable
Treat benign pause/resume aborts at workflow merge seams as retryable transient merge failures.

- Classify legacy, merge-region, manual-hold, and retry node ids as merge-seam graph failures.
- Route clean in-review pause/resume aborts back through bounded auto-merge retry when eligible.
- Keep conflict, contamination, foreign-work, exhausted-retry, global/user pause, and confirmed-merge cases terminal.
- Cover the lifecycle with a reliability regression test and architecture notes.

Files changed:
 docs/architecture.md                               |   4 +-
 .../merge-node-paused-abort-retryable.test.ts      | 227 +++++++++++++++++++++
 packages/engine/src/executor.ts                    |  77 ++++++-
 packages/engine/src/workflow-graph-executor.ts     |   2 +-
 4 files changed, 301 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-6735

Fusion-Task-Lineage: 3560c1e3-91e9-405a-bdfc-a243f7052803
2026-06-19 16:47:33 -07:00
gsxdsm
ef544597da FN-6665: group token analytics by runtime model
Record runtime model snapshots so token analytics group usage by the model that actually generated it.

- Add token-usage provider/model snapshot columns, store mapping, and migration support.
- Preserve actually-used session model metadata during executor/session token accumulation without changing task model overrides.
- Prefer runtime model snapshots in token provider/model aggregation and cover the behavior with regression tests and docs.

Files changed:
 .changeset/fn-6665-tokens-by-model.md              |  5 ++
 docs/dashboard-guide.md                            |  2 +-
 docs/storage.md                                    |  2 +
 .../core/src/__tests__/store-token-usage.test.ts   |  4 ++
 .../core/src/__tests__/token-analytics.test.ts     | 54 ++++++++++++++++++++-
 packages/core/src/db.ts                            | 12 ++++-
 packages/core/src/store.ts                         | 10 +++-
 packages/core/src/token-analytics.ts               | 12 ++++-
 packages/core/src/types.ts                         | 10 ++++
 .../src/__tests__/session-token-usage.test.ts      | 55 ++++++++++++++++++++--
 packages/engine/src/executor.ts                    | 37 +++++++++++++--
 packages/engine/src/session-token-usage.ts         |  7 +++
 12 files changed, 194 insertions(+), 16 deletions(-)

Fusion-Task-Id: FN-6665

Fusion-Task-Lineage: e103de14-6298-4a9e-93af-4dd15798fde5
2026-06-18 16:58:11 -07:00
gsxdsm
b6823af049 fix(FN-6648): treat completed in-review tasks as benign despite lingering non-user paused flag
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
2026-06-18 13:21:59 -07:00
gsxdsm
a6a3260fa3 FN-6647: preserve completed handoffs after graph aborts
Persist completed workflow handoffs so trailing graph aborts stay benign after executor cleanup.

- Derive finalized completion state from persisted task rows when volatile executor markers are gone.
- Keep genuine pause, global-pause, merge-seam, incomplete, and failed/error rows on their existing failure paths.
- Expand executor recovery tests for no-commit completions, terminal rows, stale marker cleanup, and durable classifier controls.
- Document the persisted completion-finalize classifier contract.

Files changed:
 docs/architecture.md                               |   2 +-
 .../engine/src/__tests__/executor-recovery.test.ts | 164 ++++++++++++++++++---
 packages/engine/src/executor.ts                    |  18 ++-
 3 files changed, 160 insertions(+), 24 deletions(-)

Fusion-Task-Id: FN-6647

Fusion-Task-Lineage: 71605a4c-4077-4219-bfa9-44bba2d8372c
2026-06-18 12:36:48 -07:00
gsxdsm
3b32b535d0 FN-6644: preserve finalized graph aborts
Keep no-commit completion handoffs in review when teardown reclassifies their abort provenance.

- Track completed finalize-to-review handoffs with a durable executor marker.
- Suppress false operator-action graph failures after hard-cancel teardown overwrites completion-finalize provenance.
- Cover preserved user/global pause, merge-seam, hard-cancel, terminal, and redispatch cleanup behavior.
- Document the finalized completion abort exception and add a patch changeset.

Files changed:
 .changeset/fn-6644-finalize-to-review-abort-overwrite.md  |   5 +
 docs/architecture.md                                      |   2 +-
 packages/engine/src/__tests__/executor-recovery.test.ts   | 300 +++++++++++++++++++++
 packages/engine/src/executor.ts                           |  40 ++-
 4 files changed, 342 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-6644
Fusion-Task-Lineage: 569fa84f-2cbe-45ae-b12c-874dd45cea73
2026-06-18 11:18:03 -07:00
gsxdsm
b6ac5f2e51 FN-6608: bound engine verification runs
Add durable engine-level guardrails for verification command timeouts.

- Add project-level verificationCommandTimeoutMs settings plumbing and docs.
- Enforce configured verification budgets and hard caps in executor and merger verification paths.
- Detect marathon verification commands, soft-cap them by default, and require allowFullSuite for explicit full-suite runs.
- Cover timeout defaults, marathon detection, and guidance updates with engine/core tests.

Files changed:
 .changeset/fn-6608-verification-bound.md           |   5 +
 docs/settings-reference.md                         |   1 +
 docs/testing.md                                    |   2 +
 .../src/__tests__/settings-consistency.test.ts     |   5 +
 packages/core/src/agent-prompts.ts                 |   6 +-
 packages/core/src/settings-schema.ts               |   7 +-
 packages/core/src/types.ts                         |   6 +
 .../engine/src/__tests__/executor-core.test.ts     |   3 +
 .../src/__tests__/run-verification-command.test.ts | 176 ++++++++++++++++++++-
 packages/engine/src/executor.ts                    |  11 +-
 packages/engine/src/merger.ts                      |   9 +-
 packages/engine/src/run-verification-tool.ts       | 142 +++++++++++++++--
 packages/engine/src/verification-utils.ts          |  13 +-
 13 files changed, 360 insertions(+), 26 deletions(-)

Fusion-Task-Id: FN-6608
Fusion-Task-Lineage: c593a96d-eb8b-492c-82c7-8943c239f588
2026-06-18 01:27:09 -07:00
gsxdsm
4315cd01c6 FN-6598: suppress stuck detection during verification
Treat bounded verification subprocesses as healthy activity so progressing tasks avoid false stuck-loop recovery.

- Bracket fn_run_verification commands with stuck-detector start/end signals.
- Suppress loop and no-progress churn while verification is active, with timeout-bounded cleanup.
- Add regression coverage for verification heartbeats, compact-and-resume recovery, and no-progress churn behavior.
- Document verification suppression in reliability guidance.

Files changed:
 docs/architecture.md                               |   5 +-
 docs/testing.md                                    |   1 +
 .../src/__tests__/executor-step-session.test.ts    |  10 +-
 .../non-progress-churn.test.ts                     |  55 +++++++++
 .../src/__tests__/run-verification-command.test.ts |  45 ++++++-
 .../src/__tests__/stuck-task-detector.test.ts      | 136 +++++++++++++++++++++
 packages/engine/src/executor.ts                    |   2 +
 packages/engine/src/run-verification-tool.ts       |  33 +++--
 packages/engine/src/stuck-task-detector.ts         |  69 +++++++++++
 9 files changed, 341 insertions(+), 15 deletions(-)

Fusion-Task-Id: FN-6598

Fusion-Task-Lineage: 5449b413-c500-46aa-b46d-cf94c2d88710
2026-06-18 00:39:01 -07:00
gsxdsm
98ccf8a293 FN-6625: classify completion finalization aborts
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
2026-06-18 00:01:32 -07:00
gsxdsm
a013bc0309 FN-6607: align step tools with zero-based prompt steps
Align executor step tools and review bookkeeping with the 0-based Step N labels agents see in PROMPT.md.

- Treat fn_task_update and fn_review_step step parameters as 0-indexed values, including validation, logs, checkpoints, and review verdict maps.
- Update executor/reviewer/step-runner guidance and generated tool docs to describe Step 0 semantics consistently.
- Adjust affected executor and reliability tests and add coverage proving Step 0 progress, review, and revise handling work without off-by-one shifts.
- Add a patch changeset for the published Fusion CLI package.

Files changed:
 .changeset/fn-6607-step-numbering.md               |   5 +
 .../cli/skill/fusion/references/engine-tools.md    |   4 +-
 .../engine/src/__tests__/executor-pause.test.ts    |   2 +-
 .../executor-review-step-indexing.test.ts          |  18 +-
 .../src/__tests__/executor-review-verdicts.test.ts |  18 +-
 .../executor-step-numbering-zero-based.test.ts     | 196 +++++++++++++++++++++
 .../src/__tests__/executor-step-session.test.ts    |  24 ++-
 ...executor-task-done-revise-verdict-guard.test.ts |   4 +-
 .../executor-pending-review-skip-retry.test.ts     |   8 +-
 .../task-done-refusal-x-invariant.test.ts          |   2 +-
 packages/engine/src/__tests__/step-runner.test.ts  |   4 +-
 packages/engine/src/executor.ts                    |  57 +++---
 packages/engine/src/reviewer.ts                    |   3 +
 packages/engine/src/step-runner.ts                 |   6 +-
 14 files changed, 284 insertions(+), 67 deletions(-)

Fusion-Task-Id: FN-6607

Fusion-Task-Lineage: 1b1fb1d8-07ca-4a33-84f5-1dab83388c01
2026-06-17 19:52:20 -07:00
gsxdsm
403bd9d716 FN-6582: enforce workflow gate artifact verdicts
Enforce custom workflow terminal gates for required artifacts and malformed pre-merge verdicts.

- Add runtime validation that declared workflow artifacts exist before reporting workflow success.
- Treat malformed pre-merge gate output as a blocking failure instead of a skipped success.
- Cover required-artifact and malformed-verdict gate behavior with focused engine tests.
- Document the required-artifact gate and add a patch changeset for the published CLI package.

Files changed:
 .changeset/fn-6582-workflow-gates.md               |   5 +
 docs/workflow-steps.md                             |   5 +-
 .../workflow-malformed-verdict-gate.test.ts        | 114 +++++++++++++++++++
 .../workflow-required-artifact-gate.test.ts        | 123 +++++++++++++++++++++
 packages/engine/src/executor.ts                    |  63 +++++++----
 packages/engine/src/workflow-task-runtime.ts       |  41 ++++++-
 6 files changed, 326 insertions(+), 25 deletions(-)

Fusion-Task-Id: FN-6582

Fusion-Task-Lineage: 6f59fc33-dd35-4e28-bf6b-85b709c77453
2026-06-17 14:52:56 -07:00
gsxdsm
0cc557121c FN-6590: inject task-detail chat into active step sessions
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
2026-06-17 14:52:56 -07:00
gsxdsm
8037ef15a3 Merge main into feature/factory-view: reconcile lazy-view inventory to 23
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>
2026-06-17 11:46:31 -07:00
gsxdsm
6ced5d73de FN-6568: route merge-seam graph aborts to retry
Classify merge-seam abort provenance so non-paused merge graph failures retry instead of parking as pauses.

- Track paused-abort provenance separately from the legacy pause-abort bit.
- Route merge and requestMerge graph failures through bounded auto-merge retry when they are not genuine pauses.
- Preserve user/global pause parking behavior with regression coverage and document the lifecycle invariant.

Files changed:
 .../fn-6568-merge-seam-abort-classification.md     |   5 +
 docs/architecture.md                               |   1 +
 .../engine/src/__tests__/executor-recovery.test.ts | 131 ++++++++++++++++++++-
 packages/engine/src/executor.ts                    | 122 +++++++++++++------
 4 files changed, 221 insertions(+), 38 deletions(-)

Fusion-Task-Id: FN-6568

Fusion-Task-Lineage: 5d9ee4f8-0336-4fb9-aa95-beb65e6c1ed9
2026-06-17 04:16:10 -07:00
gsxdsm
cb91d3fc06 FN-6482: preserve awaiting graph failure states
Preserve resumable workflow graph waits instead of parking them as execute failures.

- Classify awaiting user input and CLI approval node values before terminal graph failure handling.\n- Read foreach container context values for step-execute instances.\n- Cover awaiting graph exits and genuine step-execute-unwired failures in executor recovery tests.\n\nFiles changed:\n .../engine/src/__tests__/executor-recovery.test.ts | 87 ++++++++++++++++++++++\n packages/engine/src/executor.ts                    | 34 +++++++++\n 2 files changed, 121 insertions(+)

Fusion-Task-Id: FN-6482

Fusion-Task-Lineage: 2443d4cd-1307-470a-b456-2f3b44b9cc83
2026-06-16 15:08:24 -07:00
gsxdsm
ab9fdc4136 feat(telemetry): U1 — queryable usage_events table + emitUsageEvent capture
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.
2026-06-15 19:20:38 -07:00
gsxdsm
bc6dfd386e FN-6478: surface paused workflow graph failures
Surface stranded paused workflow exits as actionable executor failures.

- Treat paused or aborted graph exits as benign only while the live task remains in-progress.
- Preserve terminal/review lifecycle state while recording operator-actionable failure evidence for advanced columns.
- Cover user-paused, pause-aborted, existing-failure, in-progress, in-review, todo, and done column recovery paths.
- Document the workflow lifecycle invariant and add a patch changeset.

Files changed:
 .changeset/fn-6478-paused-workflow-executions.md   |   5 +
 docs/architecture.md                               |   1 +
 .../engine/src/__tests__/executor-recovery.test.ts | 283 +++++++++++++++++++++
 packages/engine/src/executor.ts                    |  30 ++-
 4 files changed, 315 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-6478

Fusion-Task-Lineage: 219d8612-6604-4dbc-9a3a-a1c7837419c1
2026-06-15 02:30:41 -07:00
gsxdsm
dd0ceec7dd Merge main: keep ce-* agent install alongside stale-session recovery; address PR review
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>
2026-06-13 16:08:51 -07:00
gsxdsm
e0ec3d1fbd FN-6368: route task chat steering to active sessions
Ensure task chat messages reach the live execution surface instead of waiting for a future session.

- Track seen steering comments for legacy, step-session, and workflow-step execution paths.
- Forward new task chat steering to active step sessions and workflow step sessions, including parallel step handles.
- Remove misleading inactive-session composer copy and cover the steering paths with regression tests.
- Add a patch changeset for the published Fusion package.

Files changed:
 .changeset/fn-6368-steering-running-session.md     |   5 +
 packages/dashboard/app/components/TaskChatTab.tsx  |  12 +-
 .../app/components/__tests__/TaskChatTab.test.tsx  |  18 +-
 .../src/__tests__/executor-step-session.test.ts    | 108 ++++++++++++
 .../engine/src/__tests__/executor-test-helpers.ts  |   3 +
 .../src/__tests__/step-session-executor.test.ts    |  40 +++++
 packages/engine/src/executor.ts                    | 186 ++++++++++++++-------
 packages/engine/src/step-session-executor.ts       |  16 ++
 8 files changed, 312 insertions(+), 76 deletions(-)

Fusion-Task-Id: FN-6368

Fusion-Task-Lineage: 610a6185-b136-4fea-a4bd-ea78ab5aab47
2026-06-13 09:41:20 -07:00
gsxdsm
a43639b11a feat(engine): pause workflow on skill-emitted await-input sentinel (U6)
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>
2026-06-13 09:04:54 -07:00
gsxdsm
195f731b9d feat(engine): optional systemPromptOverride for fn_spawn_agent (U2)
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>
2026-06-13 07:03:10 -07:00
gsxdsm
c850a30cde feat(workflow): headless step signal + bundle CE shipping skills (U1, U8)
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>
2026-06-13 06:56:22 -07:00
gsxdsm
4e6df035c1 FN-6275: allow verified no-op completions
Allow executors to finish already-satisfied tasks without fabricating commits while preserving existing completion guards.

- Add leading sentinel parsing for premise-stale, no-op, duplicate, and redundant completion summaries.
- Permit zero-commit fn_task_done only for recognized sentinels or existing no-commit contracts, with audit log/activity details.
- Document the verified no-op completion contract and add regression coverage for accepted and refused paths.

Files changed:
 .changeset/fn-6275-no-op-completion.md             |   5 ++
 docs/architecture.md                               |   1 +
 .../src/__tests__/no-op-completion-marker.test.ts  |  55 ++++++++++++
 packages/core/src/agent-prompts.ts                 |   4 +
 packages/core/src/index.ts                         |   5 ++
 packages/core/src/no-op-completion-marker.ts       |  48 ++++++++++
 .../__tests__/executor-task-done-invariant.test.ts | 100 +++++++++++++++++++++
 .../engine/src/__tests__/executor-test-helpers.ts  |   1 +
 packages/engine/src/executor.ts                    |  64 ++++++++++++-
 9 files changed, 279 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-6275

Fusion-Task-Lineage: 0a2ec21b-415f-411c-bfcd-4f1c19a6a136
2026-06-13 02:54:57 -07:00
gsxdsm
000a73b3f0 Merge origin/main into fix/fn-352-no-commit-coordination
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>
2026-06-13 00:01:30 -07:00
gsxdsm
1450d39976 Merge origin/main into fix/fn-424-plan-only-no-commit
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>
2026-06-12 21:47:57 -07:00
gsxdsm
ac8ad834ce Merge branch 'main' into fix/fn-352-no-commit-coordination 2026-06-12 21:39:07 -07:00
Phil Larson
285f238e92 fix(FN-424): keep audit logging non-blocking 2026-06-12 16:08:00 -07:00
Phil Larson
f331419867 fix(FN-424): simplify prompt scope parsing 2026-06-12 15:59:58 -07:00
Phil Larson
c6bcbe26a2 fix(FN-352): address no-commit review feedback 2026-06-12 15:54:47 -07:00
Phil Larson
3a729f53a9 fix(FN-352): allow no-commit coordination completion 2026-06-12 15:51:50 -07:00
Phil Larson
e9b48bd50c fix(FN-424): address no-commit review edge cases 2026-06-12 15:45:04 -07:00
Phil Larson
ab35c87114 test(FN-424): prove no-commit guard preserves worktree checks
Fusion-Task-Id: FN-424

Co-authored-by: Fusion <noreply@runfusion.ai>
2026-06-12 15:00:19 -07:00
Phil Larson
35502afdb8 fix(FN-424): align no-commit regression fixtures
Fusion-Task-Id: FN-424

Co-authored-by: Fusion <noreply@runfusion.ai>
2026-06-12 14:58:40 -07:00
Phil Larson
cb128f5824 test(FN-424): cover plan-only no-commit finalization
Fusion-Task-Id: FN-424

Co-authored-by: Fusion <noreply@runfusion.ai>
2026-06-12 14:58:39 -07:00
gsxdsm
751d94244c FN-6294: collapse workflow merge primitives
Collapse built-in workflow merge-policy primitives back to the legacy merge seam until graph execution owns merge policy end-to-end.

- Treat all merge-policy primitive node kinds as a synthetic legacy merge node during graph traversal.
- Preserve shadow-stage parity by mapping the synthetic merge node into legacy stage transitions.
- Add regression coverage for success, failure, pre-merge review failure, and alternate merge-region entry points.
- Record a patch changeset for the published Fusion package.

Files changed:
 .changeset/fn-6294-merge-region-collapse.md        |   5 +
 .../workflow-graph-executor-handlers.test.ts       |  13 ++-
 .../workflow-graph-merge-region-collapse.test.ts   | 116 +++++++++++++++++++++
 packages/engine/src/executor.ts                    |  14 ++-
 packages/engine/src/workflow-graph-executor.ts     |  63 ++++++++++-
 5 files changed, 203 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-6294

Fusion-Task-Lineage: fe86b5e2-861f-448d-8db0-b0332e6ad76f
2026-06-12 14:21:18 -07:00
gsxdsm
ba610a1c0e FN-6296: fix stuck-kill force-requeue cleanup
Reap hung executor surfaces before requeueing stuck-kill timeout tasks.

- terminate spawned child agents and active session surfaces before clearing execution guards
- remove stale worktrees during force-requeue while preserving concurrent recovery ownership
- add regression coverage and architecture notes for the cleanup contract

Files changed:
 docs/architecture.md                               |   2 +
 .../engine/src/__tests__/executor-recovery.test.ts | 248 ++++++++++++++++++++-
 packages/engine/src/executor.ts                    |  61 ++++-
 3 files changed, 305 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-6296

Fusion-Task-Lineage: a393e2b1-a72c-4d7b-9de2-6bf7268986d4
2026-06-12 14:08:52 -07:00
gsxdsm
0897b2a0bf FN-6281: add bounded graph resume retries
Add a narrow persisted retry path for transient workflow-graph failures during resume after restart or unpause.

- Persist graphResumeRetryCount with schema migration, store round-tripping, manual retry reset, and task serialization coverage.
- Retry only no-progress execute-seam graph failures immediately following resume markers, then clear transient status/error and re-run within a capped budget.
- Preserve terminal graph failure handling for explicit reasons, durable task failures, completed progress, non-resume cases, and exhausted retry budgets.
- Document the resume-limbo retry contract and add a patch changeset for @runfusion/fusion.

Files changed:
 .changeset/fn-6281-graph-resume-retry.md           |   5 +
 docs/architecture.md                               |   1 +
 packages/core/src/__tests__/db-migrate.test.ts     |  30 +--
 packages/core/src/__tests__/db.test.ts             |  44 ++---
 packages/core/src/__tests__/goals-schema.test.ts   |   2 +-
 packages/core/src/__tests__/insight-store.test.ts  |  10 +-
 .../core/src/__tests__/manual-retry-reset.test.ts  |   1 +
 .../src/__tests__/merge-request-record.test.ts     |   2 +-
 packages/core/src/__tests__/mission-store.test.ts  |   2 +-
 packages/core/src/__tests__/run-audit.test.ts      |   4 +-
 .../core/src/__tests__/store-merge-queue.test.ts   |   2 +-
 .../core/src/__tests__/store-persistence.test.ts   |  22 +++
 packages/core/src/__tests__/task-documents.test.ts |   2 +-
 packages/core/src/db.ts                            |  10 +-
 packages/core/src/manual-retry-reset.ts            |   1 +
 packages/core/src/store.ts                         |  14 +-
 packages/core/src/types.ts                         |   5 +
 .../engine/src/__tests__/executor-recovery.test.ts | 201 +++++++++++++++++++++
 packages/engine/src/executor.ts                    |  54 ++++++
 19 files changed, 359 insertions(+), 53 deletions(-)

Fusion-Task-Id: FN-6281

Fusion-Task-Lineage: f9061445-8624-465a-9255-c3d02eac1bdb
2026-06-12 11:10:12 -07:00