feat(FN-4092): complete Step 5 — document unavailable recovery contract

Fusion-Task-Id: FN-4092
Fusion-Task-Lineage: fcee3a44-5c36-4899-bf9d-835d36abdf2e
This commit is contained in:
Fusion
2026-05-13 02:56:03 -07:00
committed by gsxdsm
parent 2fbe7fff3e
commit 79cef0111d
3 changed files with 19 additions and 3 deletions

View File

@@ -553,9 +553,20 @@ See [Memory Plugin Contract](./memory-plugin-contract.md) for the full plan.
### Agent roles
- **Planning**: the planning processor generates task plans (`PROMPT.md`) and selects eligible planning tasks by priority first, then FIFO (`createdAt` ascending) within each priority tier.
- **Executor**: `TaskExecutor` (`executor.ts`) implements tasks in worktrees
- **Reviewer**: `reviewStep()` (`reviewer.ts`) performs plan/code reviews
- **Reviewer**: `reviewStep()` (`reviewer.ts`) performs plan/code/spec reviews
- **Merger**: `aiMergeTask()` (`merger.ts`) merges approved work
#### Reviewer verdict recovery contract (FN-4092)
- Reviewer verdicts are `APPROVE`, `REVISE`, `RETHINK`, or `UNAVAILABLE`.
- For non-pause `UNAVAILABLE` or non-context reviewer prompt errors, `reviewStep()` retries once:
- Prefer configured validator fallback model (`validatorFallbackProvider` + `validatorFallbackModelId`, including project overrides), or
- Retry once on the same model with stricter `Verdict:` output instructions when no fallback model is configured.
- Pause/engine-pause short-circuits still return `UNAVAILABLE` immediately and do not spawn/retry reviewer sessions.
- Executor handling in `createReviewStepTool()` is now explicit:
- `plan`/`spec` `UNAVAILABLE` is advisory after retry exhaustion (`UNAVAILABLE (advisory)`), and execution proceeds.
- `code` `UNAVAILABLE` remains blocking; step completion must wait for a usable review verdict.
- Advisory and blocking paths are both logged to task logs for operator visibility.
### Scheduling and execution
- `Scheduler` (`scheduler.ts`) — dependency-aware task scheduling that dispatches eligible todo tasks by priority first, then FIFO (`createdAt` ascending) within each priority tier.
- `blockedBy` invariant (FN-3924/FN-4091): the field is only durable when it references a current unresolved explicit dependency (or, for dependency-free tasks, an active overlap blocker). Completion gating now validates `blockedBy` through live task resolution: missing blockers and blockers already in `done`/`archived` are treated as stale, while only still-active blockers continue to prevent `fn_task_done`. If no current blocker remains, scheduler/event reconciliation clears `blockedBy` to `null` and re-evaluates from live task state.