The proactive status narration printed the internal 0-based step index, so the
final step of a 13-step task announced "Starting Step 12" next to a card
showing "12/13". Display now uses index + 1 in both the engine builders and
the store-side updateStep narration; the 0-based tool/PROMPT.md contract is
unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Binary Release (v0.73.0-beta.5 was fully red):
- bun compile: mark chromium-bidi external — playwright-core@1.60 (feature-video)
optionally requires it and bun fails closed on unresolvable requires.
- Windows desktop EXE: quote -c.publish.channel=beta in release.yml; PowerShell
tokenizes the bare flag into `-c` + a path and electron-builder ENOENTs on it.
Full suite (all 4 shards red from stale-test drift, no product bugs found):
- engine: align mock stores/assertions with atomic store.moveTaskIf dispatch
(#2371), the fail-closed non-empty PROMPT.md artifact gate (#2390), oldest-
first admission (FN-8453), alreadyClaimed graph routing (#2393), startStep
step projection (#2403/FN-8464), structured retry presentation (FN-8503),
provider-lane pause reasons (#2339), typed column-boundary entry (#2378),
Type.Integer in CAS document schemas (#2375), bounded model-registry refresh.
- engine-no-blocking-shellout: re-pin 17 drifted allowlist line numbers and drop
the stale REBASE_HEAD entry whose execSync was removed.
- core: schema-applier expectations track migrations 0033-0035 (96 tables) and
the synthetic 0000 fixture gains workflow_work_items/mission_contract_assertions;
work-item terminal state is "succeeded" post-#2378.
Known follow-up (not addressed here): self-healing starved-refinement escalation
bumps task.priority, which FN-8453 oldest-first admission no longer consults.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Align MissionAutopilot expectations with autonomy-audit attribution: updateMission
carries the system actor options, and autopilot_disabled is recorded on the
mutation instead of a separate logMissionEvent mirror.
- usage-limit-detector + provider-health-monitor: make three bare listTasks()
callers explicit with { slim: true }, restoring the architecture-hot-paths
contract (they only read scalar pause/column/model-provider fields).
- pg-test-harness beforeEach: wipe <rootDir>/.fusion/tasks after TRUNCATE ...
RESTART IDENTITY so filesystem isolation matches the id reset; stale task
dirs from prior tests no longer collide with reused IDs (fixes
store-reservation-atomicity rollback assertions).
## Problem
With `pushAfterMerge` enabled (and `mergeStrategy` other than
`pull-request`), if `origin/<integration-branch>` advances externally
between the local squash-merge and the push, the divergence path opens a
clean-room `git pull --rebase` and an AI agent resolves and stages the
conflicts — but the flow could end there: no `git rebase --continue`, no
push, and no surfaced error.
Because finalize runs *before* the push, the task is already `done`, so
a reviewed, approved merge is silently left container-only, and every
subsequent merge on the project stalls the same way. Separately, an
abort mid-push (`MergeAbortedError`) was swallowed with only a
process-log warning — no task-log entry, no run-audit event.
## Change
- **Deterministic regression coverage** for the conflicting-divergence
path (real-git fixture) proving the rebase runs to completion and the
push lands (refs converge), plus abort/termination scenarios.
- **Recovery-branch safety net:** before the clean-room rebase starts,
the pre-rebase local squash is force-pushed to a per-task remote branch
`fusion/<task-id>-stranded`, so approved content is never container-only
— even across process death or abort. Deleted after a successful target
push; retained on failure/abort as the recovery source.
- **Never-silent outcomes:** every non-pushed outcome (failure or abort)
writes a durable task-log entry and a `push:origin` run-audit event. The
audit contract now documents `push:origin` as polymorphic (dashboard
Smart Push vs. automated post-merge push) and enumerates the automated
path's outcomes, including the new `"aborted"` shutdown case.
- **Cleanup hardening:** `isRebaseInProgress` now probes Git's
worktree-specific `rebase-merge`/`rebase-apply` state directories
(async, timeout-guarded) so a completed rebase can't receive a spurious
second `--continue`; unfinished rebases are cleaned up.
Out of scope by design: withholding the "merge confirmed" state until
the push succeeds — the `FNXC:MergePush` invariant ("a push problem can
never park or roll back a landed merge") is deliberate; the recovery
branch + surfacing satisfy the data-preservation intent without breaking
it.
## Files
`packages/engine/src/merger-ai.ts`, `packages/engine/src/merger.ts`,
`packages/engine/src/run-audit.ts`, new/updated tests under
`packages/engine/src/__tests__/`, `docs/settings-reference.md`,
`docs/dashboard-guide.md`, `AGENTS.md`, and a labeled changeset.
## Validation
`tsc --noEmit` clean; engine divergence + merger suites pass (41 tests);
rebased onto current `main` with no conflicts.
---
_Developed with Claude Code, under human supervision and review._
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Prevented approved post-merge pushes from becoming stranded when the
remote diverges by using a recovery-branch workflow and safer cleanup.
* Improved behavior and reporting when pushes are aborted or fail after
merge, including clearer non-fatal status and audit outcomes.
* **Documentation**
* Expanded push-after-merge and dashboard Smart Push documentation with
recovery-branch and `push:origin`/`push:recovery-branch` outcome
semantics.
* **Tests**
* Added end-to-end regression tests for divergent/conflicting AI
push-after-merge flows, including abort and worktree cleanup
verification.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Victor Cano <victortroz@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Render complete mission hierarchy details from the fn_mission_show agent tool.
- Format mission, linked-goal, milestone, slice, and feature metadata with IDs and statuses
- Link features to their tasks and bound verbose acceptance and verification text
- Cover populated and empty hierarchy responses with regression tests
- Add a patch changeset for the agent lookup fix
Files changed:
.changeset/fn-8540-mission-show-hierarchy.md | 7 ++
.../src/__tests__/agent-mission-tools.test.ts | 68 +++++++++++++++++++
packages/engine/src/agent-tools.ts | 77 +++++++++++++++++++++-
3 files changed, 150 insertions(+), 2 deletions(-)
Fusion-Task-Id: FN-8540
Fusion-Task-Lineage: f2282226-3f4e-4d9f-bd8e-d18ad9639c03
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Port the planning turn-admission invariant (FNXC:PlanningTurnAdmission,
2026-07-22) into the Compound Engineering orchestrator: at most one turn
(opening/answer/resume-rehydration) is admitted per CE session, reserved
synchronously and held until the turn settles — a re-entered mobile view
re-submitting a turn now gets CeTurnInProgressError (HTTP 409) instead of
displacing the in-flight turn's live agent, which surfaced as "Failed to
parse agent response: AI returned no valid JSON". cancel()/discard()
force-clear the reservation; releases are token-scoped so a stale release
can't drop a newer turn's slot.
In the engine interactive-ai-session seam: bump the reformat retry from
one to two attempts (non-Anthropic default models comply less reliably
with the JSON-only protocol), and log every failed parse with a bounded
raw-response snippet plus resolved provider/model — including a distinct
empty-assistant-message marker — so support can diagnose these reports
without a repro.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Code-review follow-up on 4413699de. Deleting an orphaned pending review
entry was a severity inversion: the merge gate blocks on pending/failed
results, not on an enabled step with NO result, so deletion silently
satisfied the gate and the task merged with its review skipped (verified
live: FN-8492 landed on main without Code Review re-running). Orphans are
now rewritten to status:"failed" — the gate stays closed and the
failed-pre-merge-steps recovery / FN-7720 operator-bypass paths own the
re-run decision.
Also from review: the sweep now runs in periodic maintenance too (a step
session can die without a restart), skips executor-owned in-progress rows
(resume is deferred ~30s at startup, so their liveness is unprovable when
startup recovery runs), re-reads the row immediately before the write so
the whole-array update cannot clobber a fresh lease, counts recovery on
the successful mutation rather than after the audit emit, and the new
audit event literal is registered in DatabaseMutationType (cast dropped).
Tests now cover all three liveness-triple legs, >500-row pagination,
in-progress skip, per-task write-failure isolation, and the never-delete
invariant; the needs-replan adoption row moved under a preserve-group
header.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
An engine restart that kills an in-flight pre-merge step session (FN-8492's
Code Review) left its pending workflowStepResult behind with no live session.
The merge gate read it as incomplete pre-merge steps, surfaced an identical
stall every 30 minutes, and the deadlock disposer parked the task failed two
hours later. resolveOrphanedPendingStepResults existed for exactly this but
shipped with no caller (same U9 gap as the adoption table).
Wire it: a startup sweep right after legacy adoption clears pending results
whose task has no live session (activeSessionRegistry / executingTaskLock /
isTaskActive), emitting task:reconcile-orphaned-pending-step-results with
ids/counts-only metadata. User pauses and live resumed sessions are never
disturbed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Instead of dropping a fallback-only grok-cli pair when no GROK_API_KEY is
Fusion-visible, defer it: the session runs the configured primary, and on
the first retryable model-selection failure it creates a session on the
Grok CLI runtime with the fallback model and re-issues the failed prompt
there; later prompts stay on the swapped session. Engagement reports
through onFallbackModelUsed and an ids-only
session:grok-cli-fallback-engaged run-audit event. The pair is dropped
(with audit flag) only when the Grok runtime plugin is unavailable.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A configured grok-cli fallback with no Fusion-visible GROK_API_KEY was
promoted to primary at session start (FN-7758 seam), so every planning
session silently ran grok-4.5 instead of the configured planning model.
The no-visible-key Grok CLI auto-route now fires only for a grok-cli
primary; a fallback-only grok-cli pair is dropped with a warning and an
audited grokCliFallbackDropped flag, and session:runtime-resolved now
records the post-transform model pair the session actually runs.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
## Summary
- Fix a false-positive in `StuckTaskDetector` where legitimate long
single-step work (E2E debugging, iterative fix/test cycles) was
classified as a loop and kill/requeued.
- Root cause: loop meant “no step status transition for
`taskStuckTimeoutMs` + high activity volume,” conflating **step
progress** with **actual activity**. Agents can stay productively busy
on one step for 10+ minutes with zero repetition.
- Loop now requires thrash evidence on top of volume + no step progress:
- **repetitive tool fingerprints** (`toolName` + primary-arg detail in a
sliding window), or
- **elevated ignored step-update rebuffs** (≥ 10)
- Wire tool name/detail from `AgentLogger` → executor / step-session
into `recordActivity(...)` so novelty is measurable.
- Document the thrash-evidence rule in `docs/architecture.md`.
## Test plan
- [x] `pnpm --filter @fusion/engine exec vitest run
src/__tests__/stuck-task-detector.test.ts
src/__tests__/reliability-interactions/non-progress-churn.test.ts`
- [x] Regression: high-volume **diverse** iterative activity (174
events) does **not** classify as loop
- [x] High bare text/heartbeat volume without tools does **not**
classify as loop
- [x] Repetitive identical tool fingerprint + timeout **does** classify
as loop
- [x] Ignored step-update thrash (≥10) with volume **does** classify as
loop
- [x] Existing FN-5168 no-progress-churn + FN-6598 verification
suppression paths still pass
- [ ] CI gate green
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved stuck/loop classification by requiring explicit “thrash
evidence” (repetitive tool fingerprints and/or elevated ignored progress
rebuffs), reducing false positives for busy but diverse work.
* Updated loop evidence tracking to incorporate tool name plus
summarized tool-argument detail.
* Cleared loop evidence appropriately after verification, progress
updates, and task resumption.
* Extended tool-start telemetry/callbacks to include optional tool
detail.
* **Documentation**
* Refined loop-classification criteria to match the new evidence gates.
* **Tests**
* Updated/expanded stuck/loop and churn scenarios to validate the
evidence-based behavior and callback ordering.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Chat-driven `fn_task_create` rejected freeform intake with `Approved
mission_lineage is required` even though the tool schema marks
`mission_lineage` as optional. That was FN-8307 mission admission
over-applied beyond autonomous heartbeat patrol.
This restores freeform chat/board-equivalent creates while keeping
idle-heartbeat mission-lineage enforcement.
## What changed
- **`fn_task_create` / `fn_delegate_task`**: omit `mission_lineage`
succeeds for user-directed surfaces; hard-require only when the tool is
registered with `requireMissionLineage` (idle heartbeat patrol).
- **Gates**: missing lineage is policy-governed (`allow` /
`require-approval` / `block`) instead of a hard pre-block, so
permanent-agent chat can create freeform tasks under normal policy.
- **Heartbeat no-task delegate**: also sets `requireMissionLineage:
true` so freeform off-mission work cannot bypass admission via
`fn_delegate_task`.
- Supplied lineage is still fully validated (Feature → Slice → Milestone
→ Mission) on every surface.
- Parent inheritance still applies when not in require mode.
## Test plan
- [x] Unit: freeform `fn_task_create` without lineage creates a task
with no `missionId`/`sliceId`
- [x] Unit: freeform `fn_delegate_task` without lineage succeeds
- [x] Unit: `requireMissionLineage: true` still hard-fails without
lineage
- [x] Unit: gates treat missing lineage as policy disposition, not hard
block
- [ ] CI gate green
## Symptom
**Original:** chat tool call `{ description: "Create a red button",
priority: "high" }` → `ERROR: Approved mission_lineage is required; no
task was created.`
**Expected after fix:** task is created freeform without mission fields.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Bug Fixes**
- Freeform chat task creation and delegation can now proceed without
`mission_lineage`.
- Permission policies continue to govern these actions, including
approval requirements.
- Autonomous idle patrols still require approved mission lineage before
creating or delegating tasks.
- Task creation no longer receives mission-specific metadata when no
lineage is provided.
- **Tests**
- Expanded coverage for freeform and mission-linked task creation,
delegation, and policy-gating scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Ordered task steps can no longer appear active ahead of unfinished
predecessors. Step starts now use the same dependency-aware ordering
guard as completions, while steps explicitly declared independent remain
parallelizable. Rejected executor updates explain that the lifecycle
transition was suppressed instead of implying completed work was
overwritten.
## Validation
- Reproduced the FN-8490 concurrent update sequence and verified later
steps remain pending.
- Passed 15 PostgreSQL step-order tests, the focused executor response
test, core and engine typechecks, changeset validation, and `pnpm
verify:fast` including boot smoke.
- The full `executor-prompt.test.ts` run retains five pause-behavior
expectation failures that reproduce unchanged on `origin/main`.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Enhanced the step start hook to support an awaited “pre-start
projection” that can reject startup via `false` (sync or async),
preventing step-session creation/completion.
* Added a step-start “verdict” so steps can be started or blocked
deterministically (including “resumed” behavior).
* **Bug Fixes**
* Prevented ordered/dependency steps from transitioning out-of-order by
enforcing guards for both in-progress and done transitions, including
concurrent update attempts.
* Improved integrity/out-of-order warning behavior and suppression
details when persisted status doesn’t match expectations.
* **Tests**
* Added/updated PostgreSQL and engine regression coverage for
blocked/resumed start and start-rejection control flow.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Project workflow model lanes now apply to tasks on every workflow
instead of only tasks using the active default workflow. Model selection
consistently resolves task-specific choice -> project workflow baseline
-> global lane -> selected-workflow value -> project/global default for
primary models, fallback models, and thinking levels.
The active default workflow remains the storage owner for backward
compatibility, while runtime resolution keeps its project baseline
distinct from lower-priority selected-workflow values. Non-model
workflow policies remain isolated to their selected workflow.
## Validation
- Core workflow/model resolution: 60 tests passed
- Engine effective settings and session resolution: 59 tests passed
- Reviewer: 85 tests passed
- Scheduler: 154 tests passed
- Heartbeat: 90 tests passed
- Settings UI: 67 tests passed
- Workspace lint and core/engine/dashboard typechecks passed
- `pnpm verify:fast` passed workspace builds, the published CLI build,
and real `/api/health` boot smoke
---
[](https://github.com/EveryInc/compound-engineering-plugin)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added **Project workflow model lanes** to establish a project baseline
for model selection and thinking levels across workflows.
* Updated model/fallback resolution to account for task overrides,
project baselines, global lanes, and selected-workflow values.
* **Bug Fixes**
* Improved effective settings merging so project baselines are applied
correctly (including scheduled/idle and heartbeat flows) while
preserving selected-workflow provenance.
* **Documentation**
* Refreshed settings and dashboard guidance for workflow lane
inheritance and resolution precedence.
* **Tests**
* Expanded unit test coverage for lane precedence, fallback detection,
and thinking-level behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Re-lands the completed Fusion board task FX-005 on current upstream
`main`, stacked on #2374 (FX-004).
- adds a narrowly authorized additive publication path for archived task
documents
- preserves archived task and mission state and keeps ordinary
replacement/deletion writes rejected
- exposes retained archived current/revision reads
- requires project-scoped revision/hash CAS for publication
- maps malformed, unauthorized, missing, inconsistent, and stale states
safely
- rebases preserved dashboard drafts explicitly after CAS conflicts
## Why
Operators need to append a correction or evidence revision to an
archived task without unarchiving it or weakening ordinary archived-task
immutability.
## Dependency
This branch contains #2374 plus the eight FX-005 commits because
cross-fork PRs cannot target a fork-only base branch. After #2374 lands,
this PR should be rebased or refreshed so its diff collapses to FX-005
only.
## Validation
- PostgreSQL task-store and archived-default suites: 33/33
- dashboard route and editor suites: 321/321
- agent document tools: 22/22
- core, dashboard, and engine typechecks pass
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added optimistic concurrency controls for task document creation and
editing using revisions and content hashes.
* Added safe, authenticated append-only corrections for documents
retained on archived tasks.
* Archived documents and revision history remain available for direct
reading.
* Agent and dashboard tools now report conflicts clearly and support
explicit draft rebasing.
* **Bug Fixes**
* Prevented stale updates from overwriting newer document content.
* Preserved archived-task immutability while allowing controlled
corrections.
* **Documentation**
* Updated CLI, dashboard, storage, task-management, and agent guidance
for these workflows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: fusion-merge-train <merge-train@topkoli.local>
Co-authored-by: Fusion <noreply@runfusion.ai>
Co-authored-by: v <v@v.speedport.ip>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
## Summary
Prevents the FN-8471 failure mode where planner overseer `retry_step`
bounced `in-progress → todo` while a live step-execute session was still
coding, hard-cancelling the agent up to three times until recovery
budget exhausted.
Also closes concurrent resume races after plan-review release that
parked `status=failed` on a losing graph while a peer session still
owned work.
### Changes
- **Overseer live gate:** `retryStep` skips the hard-cancel bounce when
`isTaskLiveForOverseerRetry` is true; returns `false` so attempt budget
is not burned; durable skip log is deduped per task/stage.
- **Single-flight graph dispatch:** `executeCore` claims `graphRouting`
before any await; `executeWorkflowGraph({ alreadyClaimed })` owns
release.
- **Single-flight unpause resume:** claim `resumingUnpaused` before
await; treat existing graph claim as already-owned; clear claim before
completed-work recovery.
- **No false park:** execute-family graph endings with a peer live
session no longer stamp `status=failed` (merge-region failures still
park).
### Tests
- `executor-live-overseer-retry-gate.test.ts` — live probe matrix,
execute-family preserve, merge still parks
- `planner-overseer-intervention-wiring.test.ts` — live skip keeps
column in-progress and `getAttemptCount === 0`
## Test plan
- [x] `vitest run` scoped to the two new/updated test files (16 passed)
- [ ] CI gate (lint/typecheck/build/test:gate)
- [ ] Optional manual: fail a raced graph with a live step session and
confirm overseer does not bounce to todo
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Bug Fixes**
- Improved overseer-retry “live session” gating to avoid interrupting
active work, covering more live surfaces and preventing multi-resume
races.
- Updated failure handling so execute-family failures can be preserved
when another live session is still running, while merge-attempt failures
are still marked failed.
- Added deduping for “retry skipped due to live session” logs so they’re
emitted only once per task stage, and ensured the recovery attempt
budget isn’t consumed when intentionally skipped.
- **Tests**
- Added coverage for live-gating, retry-skip/budget behavior, and the
revised failure-parking rules.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Re-lands #2337 directly on current main after its temporary base branch
was merged and deleted.\n\n- excludes userPaused tasks from scheduler
and remembered-owner selection\n- includes userPaused in candidacy
fingerprints and unpause scheduling\n- keeps normal unpaused dispatch
behavior\n- includes regressions and a release changeset\n\nValidation
on current main: scheduler suites 50/50, @fusion/core typecheck, and
@fusion/engine typecheck passed. The PostgreSQL routing file was
discovered but skipped without a configured test database.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Manually parked/paused tasks are no longer selected or dispatched
while they remain paused.
* A task only re-enters dispatch flow after it is explicitly unpaused.
* Unpausing a task promptly refreshes scheduling and makes it eligible
for dispatch.
* Scheduler state updates now correctly react to pause status changes
(including when pause is represented via `userPaused`).
* **Tests**
* Expanded scheduler and routing regression coverage for pause/unpause
and dispatch invalidation behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: v <v@v.speedport.ip>
Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>
## Summary
Restores green merge-gate and package-default suites after repeated
`origin/main` merges brought workflow-graph ownership cutover drift into
CI.
- Align engine/dashboard/core tests with post-cutover contracts
(`moveTaskIf`/`deleteTaskIf`, graph handoff, worktree-pool reclaim via
`removeWorktree` + `RemovalReason`, multi-step RESUMING parse,
soft-pause merge requester, graph-terminal failure surfaces).
- Small product fixes needed for real regressions uncovered by the
suite: soft-delete refuse before graph routing, skip DUPLICATE
step-heading withhold when an explicit marker is present, PG schema
applier guards, and related bookkeeping (research promote tool inventory
/ migration seed, stop shell `psql` in PG admin DDL).
- Quarantine/ledger hygiene only where required by standing rules; no
timeout/worker appeasement.
## Verification
- `pnpm test:gate` ×2 green
- `@fusion/engine` full package suite green (~9083 tests)
- Targeted core/dashboard clusters green (schema applier, agent-runs UI,
settings descriptions, mobile close)
## Test plan
- [x] `pnpm test:gate` (twice)
- [x] `pnpm --filter @fusion/engine test`
- [ ] CI full suite / PR checks on this branch
- [ ] Confirm no unrelated product behavior changes beyond the listed
regression fixes
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added support for `roadmap-item` native structure kinds, including
native structure embeds and metadata validation.
* Added Stable and Beta release channel options in General settings.
* Added per-action reporting target configuration with clearer “unset”
guidance.
* **Bug Fixes**
* Improved heartbeat/prompt behavior when patrol is disabled.
* Prevented deleted tasks from continuing through execution.
* Made recovery for explicit duplicate redirects more permissive.
* Hardened database migration and test database cleanup to reduce flaky
failures.
* **Documentation**
* Updated settings text for release channels, reporting targets, and
inheritance/unset behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Soft-deleted tasks with leftover plan-review work items caused getTask to throw
mid-drain, aborting the due list before later live cards (e.g. FN-8471) could
run. Isolate per-item loads, cancel terminal/missing orphans, and surface
pre-release unplanned promote failures distinctly from WIP capacity.
Classify the durable PROMPT.md writer as coordination-exempt (same class as
fn_task_document_write) so triage, replan, and Plan Review can persist specs
without an operator approval gate. Keep dashboard policy examples in sync.
FN-8453 merge-admission registration called getTaskStore() before
runtime.start(), which threw, left the singleton lock held, and made every
later engine start fail with blocked-by-lockfile. Use config.projectId instead.
Post-extension modelRegistry.refresh() had no timeout, so a hung remote
catalog fetch left the TUI on "Loading extensions…" forever. Use a shared
15s-bounded refresh across dashboard/serve/daemon and related registration paths.
## What changed
- Construct one `UsageLimitPauser` per project runtime and wire it into
both executor and triage.
- Replace the project-wide emergency stop for 429/quota failures with
provider-scoped task parking.
- Resolve execution, planning, validator, and merger providers for
active tasks; park only tasks routed through the unavailable provider.
- Preserve the actual reviewer provider on `ReviewerProviderError`, so a
Claude Plan Review 429 does not stop Codex work.
- Record `provider-rate-limit:<provider>` pause provenance without
storing provider response bodies in pause metadata.
- Run one daemon-owned provider-health monitor that probes only
providers with persisted rate-limit parks.
- Resume exact matching provider parks across every project only after
the existing authenticated usage probe succeeds and all reported
capacity windows are usable.
- Probe at five-minute intervals for the first five checks, then back
off independently per provider to 10/20/40/60 minutes with a one-hour
cap.
## Root cause and impact
The runtime refactor left `usageLimitPauser` undefined for
`TriageProcessor`. In the observed FN-922 incident, Claude Plan Review
returned four explicit 429 responses; Fusion backed off for roughly
60/120/240 seconds and then failed the task, but never invoked its pause
coordinator. The older coordinator also used `globalPause`, which would
terminate healthy sessions on every other provider.
After this change, active tasks using the unavailable provider are
parked while work routed exclusively through healthy providers
continues. Recovery is a provider-health state transition: the daemon
checks Claude/Codex authentication and metered capacity independently of
task execution, including after restart, and clears only exact
`provider-rate-limit:<provider>` parks. Logged-out, errored, exhausted,
manually paused, user-paused, and other-provider tasks remain parked.
Explicit global/engine pause controls remain unchanged.
## Surface enumeration
- executor usage-limit catches
- triage planner and Plan Review catches
- reviewer provider-error propagation
- merger usage-limit catches
- per-project runtime construction and wiring
- task model overrides plus project/global execution, planning,
validator, and merger resolution
- daemon startup/listen and shutdown lifecycle
- multi-project provider-probe deduplication
- Claude and Codex authenticated usage/capacity probes
- done/archived/already-paused task exclusions
- manual, user, generic, and other-provider pause provenance
## Symptom verification
**Original symptom:** Anthropic/Claude 429s retried and failed FN-922
without pausing Claude-routed work; a functioning global pauser would
also have stopped Codex, and provider parks had no positive-health
recovery path.
**Exact reproduction:** Raise `ReviewerProviderError("429
overloaded_error", "usage-limit", { provider: "anthropic" })` during
Plan Review with Anthropic and Codex tasks present, then return
logged-out/error/exhausted and finally healthy Claude usage responses
from the daemon probe.
**Assertion it is gone:** Anthropic-routed active tasks receive
`provider-rate-limit:anthropic`; Codex-only tasks are not paused and
`globalPause` is never changed. Unhealthy probes leave the Anthropic
tasks parked; a positive authenticated response with remaining capacity
resumes only exact Anthropic provider parks without executing a model
call as a probe.
## Validation
- `packages/engine/src/__tests__/usage-limit-detector.test.ts`: 49
passed
- `packages/dashboard/src/__tests__/provider-health-monitor.test.ts`: 8
passed
- Engine TypeScript check passed
- Dashboard server and app TypeScript checks passed
- Scoped ESLint passed
- Changeset strict format check passed
- Reapply script passed `bash -n`, two consecutive fixture applications,
and `node --check`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Tasks paused due to a provider’s rate limits can now automatically
resume when capacity returns.
- Provider health is monitored in the background, including retry
backoff for unavailable providers.
- **Bug Fixes**
- Rate-limit issues now pause only affected provider-routed tasks
instead of stopping unrelated work.
- Provider failures are handled separately from invalid review results,
improving recovery behavior.
- Healthy providers remain available while another provider is
rate-limited.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: v <v@v.speedport.ip>