## Summary
Planning can no longer approve or execute against evidence from a
superseded dependency episode. Dependency mutations, approval decisions,
recovery, and execution admission now share serialized lifecycle rules,
so stale planner work cannot restore an invalid approval or release an
unplanned task.
Review also converges instead of discovering one blocker per round.
Planning performs a repository-grounded completeness pass up front; Plan
Review batches all independently discoverable blockers and carries an
episode-scoped decision ledger across revisions; code review traces
changed invariants through production consumers and tests. Repeated
feedback still advances the safety budget, while provider failures and
superseded episodes stay outside the remediation ledger.
The dashboard now exposes manual approval only for the intended
exhausted-review state, and refusal/recovery audit events make rejected
lifecycle transitions diagnosable without leaking prompt content.
## Validation
- `pnpm verify:fast` — scoped typechecks/builds, CLI build, and boot
smoke passed.
- Focused Core and Engine regression suites — 511 tests passed.
- `pnpm lint`, strict changeset validation, Core/Engine typechecks, and
package builds passed.
Fixes#3325.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Improved Plan Review approvals, rejections, and replan-cap handling
across task workflows.
* Added cumulative feedback and attempt tracking across repeated
planning reviews.
* Added safer recovery for stalled planning handoffs and interrupted
approval updates.
* **Bug Fixes**
* Prevented stale approvals and unplanned execution after dependency
changes.
* Improved concurrent approval handling, retryability, and
refusal-record deduplication.
* Refined dashboard approval indicators and responsive approval views.
* **Quality Improvements**
* Strengthened planning and code-review completeness checks and
blocking-finding coverage.
* Preserved review history while clearly marking outdated approvals.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## 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 -->
A rate-limited reviewer filled a task's Chat tab with 14 identical
"Reviewer using model: ..." markers and no review text, hammering an
already-limited provider.
Root cause: the reviewer was the only AI lane that never classified
provider errors, so a 429 became an UNAVAILABLE verdict. With no
validator fallback configured the fallback ladder re-ran the SAME model
instantly, and fn_review_step answered with "code review remains
blocking; retry once" — bounding the loop with prompt text rather than
code. The tool's catch-all also swallowed the error into tool output, so
withRateLimitRetry, UsageLimitPauser and RetryStormError never fired.
- reviewer: throw ReviewerProviderError for usage-limit/transient errors
instead of laundering them into UNAVAILABLE, and never spend the
fallback budget (which bounds bad reviews) on an outage.
- reviewer: absorb flaky-network blips in-lane via withRetry with
jittered backoff; rate limits still escalate immediately.
- executor: re-raise the fatal after the prompt via
throwDeferredReviewerFatal — pi-agent-core converts tool throws into
tool_error results, so a tool cannot throw out of session.prompt().
- executor: give code review a real MAX_CODE_REVIEW_UNAVAILABLE_RETRIES
counter, mirroring the plan/spec limiter.
- reviewer: dedupe the model marker on text, so same-model retries stay
silent while a genuine model switch still emits.
Also fixes the run-on rendering: AgentLogType gains `status` for complete
engine messages. `text` means "streamed delta" and is re-glued with
join(""), which is why N standalone markers rendered as one string. The
split is at the type, not a separator — a separator would reintroduce the
FN-5787/5789/5803 streamed-spacing regression.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>