You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: add loop FSM transitions, plan amendments, and audit rewind (#72)
* feat: add loop FSM transitions, plan amendments, and audit rewind
* refactor: consolidate loop transition logging and persist final_audit_fix phase
- Renumber migrations 138-140 to 141-143 to avoid collision with feat/loop-metrics
- Extract transitionSectionIndex and recordTerminalTransition single-source helpers
- Dedupe loops-repo bind params and unify setState/restoreState via persistState
- Persist final_audit_fix as a real phase; restart resumes the final-audit fix prompt
- Move plan-adjust guards into adjustRemainingSections under immediateTransaction
- Cache dashboard repos and strip amendment section content from poll payload
* fix: render dashboard machine graph SVG elements in correct namespace
* style: improve dashboard edge label contrast with yellow fill and stroke outline
---------
Co-authored-by: Forge <forge@example.com>
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -369,7 +369,7 @@ Model and variant selection follows this priority order:
369
369
370
370
## Loop
371
371
372
-
The loop is an iterative development system with four phases, ending with an optional post-completion action:
372
+
The loop is an iterative development system with five persisted phases (`coding`, `auditing`, `final_auditing`, `final_audit_fix`, `post_action`), ending with an optional post-completion action:
373
373
374
374
1.**Coding phase** — A Code session works on the task
375
375
2.**Auditing phase** — The Auditor agent reviews changes against project conventions and stored review findings
Copy file name to clipboardExpand all lines: docs/api/README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -371,7 +371,7 @@ Model and variant selection follows this priority order:
371
371
372
372
## Loop
373
373
374
-
The loop is an iterative development system with four phases, ending with an optional post-completion action:
374
+
The loop is an iterative development system with five persisted phases (`coding`, `auditing`, `final_auditing`, `final_audit_fix`, `post_action`), ending with an optional post-completion action:
375
375
376
376
1.**Coding phase** — A Code session works on the task
377
377
2.**Auditing phase** — The Auditor agent reviews changes against project conventions and stored review findings
When a workspace carries a SHA pin (`extra.startRef`, set by remote loop launches), the new branch is created from that exact commit instead of the clone's current `HEAD`. If the commit is not present locally, the adapter fetches the sync ref (`extra.syncRef`, default `refs/forge/<loopName>`) from the configured git remote first, and fails with a descriptive error when the SHA still cannot be resolved. Existing branches always win — the pin is ignored when the loop branch already exists. On final teardown the sync ref is deleted from the shared git remote. See [Configuration → Remotes](configuration.md#remotes).
192
+
When a workspace carries a SHA pin (`extra.startRef`, set by remote loop launches), the new branch is created from that exact commit instead of the clone's current `HEAD`. If the commit is not present locally, the adapter fetches the sync ref (`extra.syncRef`, default `refs/forge/<loopName>`) from the configured git remote first, and fails with a descriptive error when the SHA still cannot be resolved. If the loop branch already exists, its tip must match the pinned SHA — a leftover same-named branch at a different commit fails creation with an actionable error instead of silently running old code (unpinned workspaces still reuse existing branches). On final teardown the sync ref is deleted from the shared git remote. See [Configuration → Remotes](configuration.md#remotes).
191
193
192
194
Benefits of worktree isolation:
193
195
- Isolation from ongoing development
@@ -215,7 +217,15 @@ In user-facing language, a plan is decomposed into **milestones** — ordered un
215
217
-`<!-- forge-section -->` markers in the architect plan output
216
218
-`section-read` tool reads the current or specified milestone
217
219
218
-
Decomposition is a one-shot preprocessing step at loop start (`services/deterministic-decomposer.ts`), not a runtime loop phase. Once milestones exist, the loop advances through them via `advance-section` transitions inside the `auditing` phase. When the `final_auditing` phase reports outstanding bug findings, the loop rotates to a coding session in "final-audit fix" mode — the code agent fixes the reported findings without rewinding to a specific section, and on idle the loop transitions straight back to `final_auditing` for re-verification.
220
+
Decomposition is a one-shot preprocessing step at loop start (`services/deterministic-decomposer.ts`), not a runtime loop phase. Once milestones exist, the loop advances through them via `advance-section` transitions inside the `auditing` phase. When the `final_auditing` phase reports outstanding bug findings, the loop rotates to a coding session in the persisted `final_audit_fix` phase — the code agent fixes the reported findings without rewinding to a specific section, and on idle the loop transitions straight back to `final_auditing` for re-verification. A loop stopped mid-fix restarts as a coding pass that re-sends the final-audit fix prompt (rebuilt from the persisted `lastAuditResult`).
221
+
222
+
### Plan Amendments
223
+
224
+
After decomposition, the *remaining* (not yet started) milestones can still be amended mid-loop: during a section audit, the auditor may call the `plan-adjust` tool to replace the pending section suffix when completed work makes the remaining sections unable to achieve the plan objective as written. The objective and verification criteria are immutable, completed/current sections cannot be changed, goal loops are excluded, and the resulting total is capped at 24 sections. Every amendment is recorded in the `plan_amendments` table with before/after snapshots and a rationale. If an amendment appends sections while the loop is already in `final_auditing`, the loop reverts to `auditing` to execute them.
225
+
226
+
### Transition Log
227
+
228
+
Every persisted phase change appends exactly one row to the `loop_transitions` table (event type, transition kind, from/to phase, iteration, section index, and terminal status/reason for terminate rows). The dashboard renders this log as a live state-machine graph with per-edge traversal counts. Transition history survives loop restarts (loop rows are restored in place, never delete+reinserted) but is removed with the loop row by the terminal-loop sweep.
219
229
220
230
## Completion Conditions
221
231
@@ -224,7 +234,7 @@ A loop completes when the active phase emits a clean audit result (optionally fo
224
234
- Non-sectioned loops complete on `audit-clear`.
225
235
- Sectioned loops advance through clean section audits, then complete on `final-audit-clean`.
226
236
- Dirty section audits rotate back to coding for the same section so findings can be addressed.
227
-
- Dirty final audits rotate to coding in "final-audit fix" mode (no section rewind); when the fix coding pass goes idle, the loop returns straight to `final_auditing`.
237
+
- Dirty final audits rotate to a coding session in the `final_audit_fix` phase (no section rewind); when the fix coding pass goes idle, the loop returns straight to `final_auditing`.
228
238
- After a clean final audit, if `loop.postAction.enabled` is `true` and specifies a `skill` or `prompt`, the loop enters a `post_action` phase that runs inside the worktree before teardown. Completion occurs when the post-action session goes idle (`post-action-complete` event).
Copy file name to clipboardExpand all lines: docs/api/_media/tools.md
+12Lines changed: 12 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,6 +10,7 @@ See also: [Agents and Slash Commands](agents-and-commands.md), [Configuration](c
10
10
|---|---|---|
11
11
|`plan-read`| Read the current session or loop plan, or list/search recent project plans. |[`src/tools/plan-kv.ts`](../src/tools/plan-kv.ts)|
12
12
|`section-read`| Read a section plan and status for the active loop session. |[`src/tools/section-read.ts`](../src/tools/section-read.ts)|
13
+
|`plan-adjust`| Replace the remaining (not yet started) sections of the active loop plan; auditor-only, logged as a plan amendment. |[`src/tools/plan-adjust.ts`](../src/tools/plan-adjust.ts)|
13
14
|`review-write`| Store a review finding. |[`src/tools/review.ts`](../src/tools/review.ts)|
|`review-delete`| Delete a review finding. |[`src/tools/review.ts`](../src/tools/review.ts)|
@@ -46,6 +47,17 @@ Arguments:
46
47
|---|---|
47
48
|`section_index`| Optional 0-based section index. If omitted, returns the lowest-index incomplete section. |
48
49
50
+
### `plan-adjust`
51
+
52
+
Only callable by the current auditor session of a sectioned plan loop during the `auditing` phase (rejected in goal loops and during the final audit). Replaces the pending section suffix (from the current section + 1 onward); the plan objective and verification are immutable. The resulting total may not exceed 24 sections. Every adjustment is recorded in the `plan_amendments` table with before/after snapshots.
53
+
54
+
Arguments:
55
+
56
+
| Argument | Description |
57
+
|---|---|
58
+
|`sections`| Replacement list of `{ title, content }` for the remaining sections. An empty list removes the entire pending suffix. |
59
+
|`rationale`| Why the plan needs adjustment. |
60
+
49
61
## Review Tools
50
62
51
63
Review findings are scoped to the current loop when invoked from a loop session. Sectioned loops automatically scope findings to the current section unless overridden.
0 commit comments