loopforge 3.7.1 → 3.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/README.md +84 -130
  2. package/dist/audit.d.ts +53 -1
  3. package/dist/audit.d.ts.map +1 -1
  4. package/dist/audit.js +106 -22
  5. package/dist/audit.js.map +1 -1
  6. package/dist/canonical-state.d.ts +52 -67
  7. package/dist/canonical-state.d.ts.map +1 -1
  8. package/dist/canonical-state.js +134 -147
  9. package/dist/canonical-state.js.map +1 -1
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +103 -4
  12. package/dist/cli.js.map +1 -1
  13. package/dist/cognitive-facts.d.ts +13 -0
  14. package/dist/cognitive-facts.d.ts.map +1 -1
  15. package/dist/cognitive-facts.js +28 -13
  16. package/dist/cognitive-facts.js.map +1 -1
  17. package/dist/committed-round.d.ts +103 -21
  18. package/dist/committed-round.d.ts.map +1 -1
  19. package/dist/committed-round.js +188 -45
  20. package/dist/committed-round.js.map +1 -1
  21. package/dist/contract-items.d.ts +55 -0
  22. package/dist/contract-items.d.ts.map +1 -0
  23. package/dist/contract-items.js +180 -0
  24. package/dist/contract-items.js.map +1 -0
  25. package/dist/enforcement-gate.d.ts +20 -2
  26. package/dist/enforcement-gate.d.ts.map +1 -1
  27. package/dist/enforcement-gate.js +197 -386
  28. package/dist/enforcement-gate.js.map +1 -1
  29. package/dist/engine.d.ts +1 -1
  30. package/dist/engine.d.ts.map +1 -1
  31. package/dist/engine.js +53 -38
  32. package/dist/engine.js.map +1 -1
  33. package/dist/evidence-claims.d.ts +4 -4
  34. package/dist/evidence-claims.d.ts.map +1 -1
  35. package/dist/evidence-claims.js +16 -14
  36. package/dist/evidence-claims.js.map +1 -1
  37. package/dist/evidence-provider.d.ts +85 -89
  38. package/dist/evidence-provider.d.ts.map +1 -1
  39. package/dist/evidence-provider.js +328 -184
  40. package/dist/evidence-provider.js.map +1 -1
  41. package/dist/explain.d.ts +76 -0
  42. package/dist/explain.d.ts.map +1 -0
  43. package/dist/explain.js +127 -0
  44. package/dist/explain.js.map +1 -0
  45. package/dist/generate-schema.js +152 -16
  46. package/dist/generate-schema.js.map +1 -1
  47. package/dist/index.d.ts +6 -6
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +5 -5
  50. package/dist/index.js.map +1 -1
  51. package/dist/loop-compiler.d.ts +40 -53
  52. package/dist/loop-compiler.d.ts.map +1 -1
  53. package/dist/loop-compiler.js +229 -553
  54. package/dist/loop-compiler.js.map +1 -1
  55. package/dist/loop-extras-parser.d.ts +0 -1
  56. package/dist/loop-extras-parser.d.ts.map +1 -1
  57. package/dist/loop-extras-parser.js +0 -4
  58. package/dist/loop-extras-parser.js.map +1 -1
  59. package/dist/loop-projection.d.ts.map +1 -1
  60. package/dist/loop-projection.js +3 -1
  61. package/dist/loop-projection.js.map +1 -1
  62. package/dist/mcp/round-lifecycle.d.ts +30 -21
  63. package/dist/mcp/round-lifecycle.d.ts.map +1 -1
  64. package/dist/mcp/round-lifecycle.js +47 -103
  65. package/dist/mcp/round-lifecycle.js.map +1 -1
  66. package/dist/mcp/server.d.ts.map +1 -1
  67. package/dist/mcp/server.js +51 -7
  68. package/dist/mcp/server.js.map +1 -1
  69. package/dist/mcp/session.d.ts +39 -23
  70. package/dist/mcp/session.d.ts.map +1 -1
  71. package/dist/mcp/session.js +148 -163
  72. package/dist/mcp/session.js.map +1 -1
  73. package/dist/mcp/submission-boundary.d.ts +89 -0
  74. package/dist/mcp/submission-boundary.d.ts.map +1 -0
  75. package/dist/mcp/submission-boundary.js +203 -0
  76. package/dist/mcp/submission-boundary.js.map +1 -0
  77. package/dist/mcp/tools.d.ts.map +1 -1
  78. package/dist/mcp/tools.js +249 -128
  79. package/dist/mcp/tools.js.map +1 -1
  80. package/dist/policy-metrics.js +2 -2
  81. package/dist/policy-metrics.js.map +1 -1
  82. package/dist/policy.d.ts +55 -93
  83. package/dist/policy.d.ts.map +1 -1
  84. package/dist/policy.js +149 -38
  85. package/dist/policy.js.map +1 -1
  86. package/dist/prompt-assembler.d.ts +1 -32
  87. package/dist/prompt-assembler.d.ts.map +1 -1
  88. package/dist/prompt-assembler.js +282 -435
  89. package/dist/prompt-assembler.js.map +1 -1
  90. package/dist/prompt-policy.d.ts +1 -4
  91. package/dist/prompt-policy.d.ts.map +1 -1
  92. package/dist/prompt-policy.js +6 -7
  93. package/dist/prompt-policy.js.map +1 -1
  94. package/dist/protocol.d.ts +365 -142
  95. package/dist/protocol.d.ts.map +1 -1
  96. package/dist/protocol.js +21 -66
  97. package/dist/protocol.js.map +1 -1
  98. package/dist/replay.js +2 -2
  99. package/dist/replay.js.map +1 -1
  100. package/dist/round-contract.d.ts +69 -57
  101. package/dist/round-contract.d.ts.map +1 -1
  102. package/dist/round-contract.js +104 -64
  103. package/dist/round-contract.js.map +1 -1
  104. package/dist/round-coordinator.d.ts +36 -16
  105. package/dist/round-coordinator.d.ts.map +1 -1
  106. package/dist/round-coordinator.js +166 -102
  107. package/dist/round-coordinator.js.map +1 -1
  108. package/dist/round-driver.d.ts +3 -5
  109. package/dist/round-driver.d.ts.map +1 -1
  110. package/dist/round-driver.js +0 -1
  111. package/dist/round-driver.js.map +1 -1
  112. package/dist/round-facts.d.ts +96 -0
  113. package/dist/round-facts.d.ts.map +1 -0
  114. package/dist/round-facts.js +216 -0
  115. package/dist/round-facts.js.map +1 -0
  116. package/dist/round-transaction.d.ts +19 -9
  117. package/dist/round-transaction.d.ts.map +1 -1
  118. package/dist/round-transaction.js +90 -22
  119. package/dist/round-transaction.js.map +1 -1
  120. package/dist/self-eval.d.ts +87 -9
  121. package/dist/self-eval.d.ts.map +1 -1
  122. package/dist/self-eval.js +396 -27
  123. package/dist/self-eval.js.map +1 -1
  124. package/dist/subgoal-state.d.ts +77 -0
  125. package/dist/subgoal-state.d.ts.map +1 -0
  126. package/dist/subgoal-state.js +198 -0
  127. package/dist/subgoal-state.js.map +1 -0
  128. package/dist/token-utils.d.ts +52 -19
  129. package/dist/token-utils.d.ts.map +1 -1
  130. package/dist/token-utils.js +83 -72
  131. package/dist/token-utils.js.map +1 -1
  132. package/dist/verification-gate.d.ts +14 -31
  133. package/dist/verification-gate.d.ts.map +1 -1
  134. package/dist/verification-gate.js +178 -496
  135. package/dist/verification-gate.js.map +1 -1
  136. package/dist/version.d.ts +1 -1
  137. package/dist/version.js +1 -1
  138. package/dist/workspace.d.ts +9 -0
  139. package/dist/workspace.d.ts.map +1 -1
  140. package/dist/workspace.js +17 -0
  141. package/dist/workspace.js.map +1 -1
  142. package/loop_policy.json +59 -83
  143. package/package.json +67 -67
  144. package/skills/perception/SKILL.md +218 -204
@@ -1,250 +1,264 @@
1
1
  ---
2
2
  name: perception
3
- description: Drive a recoverable multi-round coding task through LoopForge MCP while the external Agent remains the execution owner.
3
+ description: Drive multi-round coding tasks through LoopForge MCP so objectives, constraints, evidence, and decisions survive context loss and restarts. The external Agent remains responsible for planning, file changes, tools, and execution.
4
4
  ---
5
5
 
6
6
  # Perception
7
7
 
8
- Use LoopForge when a coding task needs several rounds, must survive context
9
- compression or process restart, or benefits from an auditable record of goals,
10
- constraints, evidence, and decisions.
8
+ Use LoopForge when a task spans several meaningful work slices, must survive a
9
+ restart or context loss, or needs an auditable distinction between Agent claims
10
+ and machine-verified facts.
11
11
 
12
- LoopForge has one factual source, the committed typed round documents in the
13
- Vault, and one cognitive source, the Canonical State compiled from them. You
14
- remain the Agent that reads files, edits code, runs commands, delegates work,
15
- and decides how to reason.
12
+ LoopForge has one factual source, committed typed round documents in the Vault,
13
+ and one cognitive source, Canonical State compiled from those documents. The
14
+ Agent still decides what to do and how to reason.
16
15
 
17
16
  ## Start
18
17
 
18
+ Call `loopforge_status` with `view: "all"` before starting. Reuse an existing
19
+ session for the same objective instead of opening a second loop.
20
+
19
21
  Call `loopforge_start` with:
20
22
 
21
- - `task`: the complete user objective.
22
- - `constraints`: hard boundaries that must survive every round.
23
- - `maxRounds`: optional positive safety limit. The default is 20.
24
- - `domain`: optional context label.
25
-
26
- Keep the returned `sessionId`, `roundId`, prompt, and level. Always pass the
27
- most recent `roundId` to `loopforge_next`. It anchors the submission to the
28
- exact round being reported.
29
-
30
- ## Plan round boundaries
31
-
32
- LoopForge does not decide how the Agent thinks about a large task. The Agent
33
- chooses the next useful slice of work, while LoopForge checks the submitted
34
- facts and evidence at the round boundary. Do not try to predict an exact number
35
- of rounds before inspecting the repository. Re-plan after each committed round.
36
-
37
- Choose a round around a coherent, verifiable change:
38
-
39
- 1. Start with the dependency or discovery work that determines later choices.
40
- 2. Group changes that must be edited and tested together; split unrelated work
41
- or work with different rollback risks.
42
- 3. End the round when its slice has a concrete result, a known blocker, or a
43
- machine-checkable next boundary. A round may be small when uncertainty or
44
- risk is high, and larger when the changes are tightly coupled.
45
- 4. Before submitting, check the actual diff, relevant tests, hard constraints,
46
- and the next action. Do not mark the whole task complete because one slice
47
- is complete.
48
-
49
- For work that spans several rounds, declare a `round_contract` as a proposal for
50
- the next slice. Keep its `work_item` narrow, list observable `done_when` items,
51
- name only configured evidence commands in `verification_plan`, and constrain
52
- `scope` to the files or directories that slice may touch. The proposal becomes
53
- active only after the current round commits. If the slice is blocked, report
54
- `outcome: "blocked"` with a concrete `blocker`; do not silently replace the
55
- active contract.
56
-
57
- This is a granularity preflight, not another gate: ask whether the slice has a
58
- clear boundary, evidence, and recovery path. LoopForge cannot see an implicit
59
- plan inside the model. It learns only from committed evaluation fields,
60
- Round Contract proposals, observed evidence, and the resulting changes. A
61
- reasonable split may therefore be revised by the next prompt, a verification
62
- finding, or a backtrack diagnosis.
23
+ - `task`: the complete user objective;
24
+ - `constraints`: hard boundaries that must survive every round;
25
+ - optional `maxRounds`, `domain`, `loopId`, and `planSource`.
26
+
27
+ Keep the returned `sessionId`, `roundId`, prompt, and level. Pass the latest
28
+ `roundId` to every `loopforge_next`; it anchors the submission to the exact
29
+ round being reported.
30
+
31
+ ## What is a round?
32
+
33
+ A round is one coherent work slice that can be described, checked, and
34
+ disposed of at the next boundary. It is not a fixed number of files, tokens,
35
+ commits, or minutes. A capable Agent may complete a large change in one round
36
+ when the change shares one objective, one evidence story, and one recovery
37
+ path. Split it when those boundaries diverge.
38
+
39
+ Before choosing the slice, ask:
40
+
41
+ 1. **Coherence:** does the work serve one immediate objective rather than
42
+ several unrelated goals?
43
+ 2. **Verifiability:** can the result and its hard constraints be checked with
44
+ the available tests, commands, or other machine observations?
45
+ 3. **Disposition:** will the boundary produce a clear continuation, stop,
46
+ blocker, rejection, or recovery decision?
47
+ 4. **Recovery:** can the slice be safely retried or rolled back without
48
+ invalidating unrelated work?
49
+
50
+ Make a round larger when changes are tightly coupled and can be verified
51
+ together. Make it smaller when uncertainty, external effects, evidence gaps,
52
+ or rollback risk is high. Do not combine independent objectives merely because
53
+ the Agent can edit them in one context. Do not split a single atomic change
54
+ only to create more round records.
55
+
56
+ At the end of a round, inspect the actual diff, relevant tests, hard
57
+ constraints, and remaining work. A completed slice is not the same as a
58
+ completed task.
59
+
60
+ ## Plan the next slice
61
+
62
+ For work that spans rounds, submit `round_contract` as a proposal for the next
63
+ slice. Keep `work_item` narrow, bind each item to a configured evidence command
64
+ with `verify_with`, and limit `scope` to files or directories that slice may
65
+ touch. The proposal becomes active only after its declaring round commits.
66
+ While it is open, restating the same proposal continues it; a different
67
+ proposal is ignored as `contract_premature`. If the slice is blocked, report
68
+ `outcome: "blocked"` with a concrete `blocker` instead of silently replacing
69
+ the active contract.
70
+
71
+ This is a planning aid, not a second gate. LoopForge learns the plan only from
72
+ committed evaluation fields, contract proposals, observations, and changes.
63
73
 
64
74
  ## Execute a round
65
75
 
66
- 1. Execute the returned prompt and do real repository work.
67
- 2. Use the tools and reasoning approach that fit the task.
76
+ 1. Execute the returned prompt and do the repository work.
77
+ 2. Use the tools and reasoning approach that fit the slice.
68
78
  3. Check actual evidence before claiming success.
69
- 4. Submit one structured `evaluation` with `loopforge_next`.
79
+ 4. Submit exactly one structured evaluation with `loopforge_next`.
80
+
81
+ After the strict boundary accepts the payload, LoopForge collects before/after
82
+ evidence, runs the **verification gate**, then runs the **enforcement gate**.
83
+ The verification gate checks evaluation consistency, evidence integrity, plan
84
+ and contract conformance, and progress and recovery. The enforcement gate
85
+ turns those findings into one disposition: accept, reject, backtrack, or
86
+ terminate.
70
87
 
71
88
  The four core evaluation fields are strict:
72
89
 
73
- | Field | Rule |
90
+ | Field | Requirement |
74
91
  | --- | --- |
75
- | `success` | Boolean. Use `true` only when the whole objective and every hard constraint are satisfied. |
76
- | `output_summary` | String. State what changed and what was verified this round. |
77
- | `constraint_violations` | Array of strings. Report real violations; prefer constraint IDs such as `c-XXXXXXXX`. |
78
- | `should_continue` | Boolean. Use `false` only when the entire task is complete. |
79
-
80
- All other evaluation fields are optional and normalized by LoopForge. Useful
81
- fields include `execution_evidence`, `discovered_constraints`,
82
- `emerged_subtasks` (the only sub-goal creation channel — never an `sg-` ID),
83
- `subgoal_updates` (explicit status transitions: active `sg-` IDs with a target
84
- status; done/canceled are terminal and never reopen), `next_action`,
85
- `drift_clarification`, `prompt_requests`, `outcome`, `blocker`,
86
- `round_contract`, `retroactiveClaims`, `gate_ids` (only when the gate layer is
87
- enabled), and `worker_results` (each entry declares an `outcome`; entries
88
- without one are dropped).
89
-
90
- Optional malformed values are ignored or defaulted. They do not turn a valid
91
- submission into a transport error. Missing or mistyped core fields return
92
- `evaluation_invalid` with `details.missing` and `details.invalid`. Correct the
93
- payload and resubmit the same `roundId`. This does not save session state,
94
- write a round, enter either gate, increment rejection state, or record metrics.
95
-
96
- Minimal evaluation:
97
-
98
- ```json
99
- {
100
- "success": false,
101
- "output_summary": "Implemented the parser and added 8 passing tests.",
102
- "constraint_violations": [],
103
- "should_continue": true,
104
- "execution_evidence": {
105
- "files_changed": ["src/parser.ts", "tests/parser.test.ts"],
106
- "test_results": { "passed": 8, "failed": 0, "skipped": 0 },
107
- "success_criteria_met": [],
108
- "success_criteria_remaining": ["All parser edge cases covered"],
109
- "progress_estimate": 0.4
110
- }
111
- }
112
- ```
113
-
114
- Do not put a guessed evaluation in free text. The structured object is the
115
- authoritative submission; `output` is optional supporting context.
116
-
117
- If a submission warns that its `roundId` no longer matches, the reported round
118
- already committed. Use the returned held prompt and its `roundId` rather than
119
- submitting against a later round.
120
-
121
- ## Stable IDs and contracts
122
-
123
- Prompts render stable IDs beside constraints, criteria, and sub-goals:
124
-
125
- - Constraints: `[c-a3f2b1c0] No plaintext passwords`
126
- - Criteria: `[cr-b5a6c7d8] Unit test coverage >= 90%`
127
- - Sub-goals: `[sg-f1e2d3c4] Add error handling to login`
128
-
129
- Prefer IDs for `constraint_violations`, criteria lists, and drift
130
- clarifications (which may also anchor on real file paths). Sub-goal status
131
- changes REQUIRE exact ACTIVE `sg-` IDs via `subgoal_updates` — description
132
- matching is not a fallback there. Unknown, terminal (done/canceled), or
133
- illegal transitions return `evaluation_invalid` before the round advances:
134
- fix the payload and resubmit the same `roundId` (nothing is committed, no
135
- rejection counter moves).
136
-
137
- An optional `round_contract` is a proposal for the next round. It becomes
138
- active only after the declaring round commits. While active, its `done_when`,
139
- `verification_plan`, and `scope` govern the current task until a committed eval
140
- completes it or reports `outcome: "blocked"`. A verification plan must be
141
- observed passing in the closing round.
142
-
143
- ## Backtrack
144
-
145
- A progress stall (stalled or exactly-flat window over the lookback rounds)
146
- can trigger backtrack to the last clean committed round — the most recent
147
- committed round with no error-level verification flags. The backtrack commits
148
- a rollback directive that stays out of final history: your next submission is
149
- the REDO of round `restorePoint + 1` and must reuse the round ID the prompt
150
- carries; when it commits, the rollback record is replaced and disappears from
151
- history views.
152
-
153
- The backtrack prompt opens with a derived **Recovery Brief**:
154
-
155
- - the trigger rule and the restore point;
156
- - the redo round's ID (pass it back unchanged to `loopforge_next`);
157
- - the failed rounds and their approaches — what must NOT be repeated;
158
- - falsified assumptions — do not rebuild on these;
159
- - discoveries from the skipped rounds that remain valid;
160
- - the files to revert and the git commands to do it (the prompt may offer
161
- `git stash` / `git checkout -- .` / `git reset --hard <restore-commit>`).
162
-
163
- The same brief renders in `.loopforge/state/<loopId>-state.md` under Recent
164
- while the recovery window is open; it is derived from committed rounds plus
165
- the in-flight attempt (rejected payloads are never a source) and disappears
166
- once the redo commits.
92
+ | `success` | Boolean. `true` only when the whole objective and hard constraints are satisfied. |
93
+ | `output_summary` | String describing what changed and what was verified. |
94
+ | `constraint_violations` | Array of real violations, preferably using `c-XXXXXXXX` IDs. |
95
+ | `should_continue` | Boolean. `false` only when the whole task is complete. |
96
+
97
+ Useful optional fields include `execution_report` (`files_changed`,
98
+ `tests_reported`, `criterion_claims`, `contract_item_claims`, and
99
+ `progress_estimate`), `discovered_constraints`, `emerged_subtasks`,
100
+ `subgoal_updates`, `prompt_requests`, `round_contract`, `retroactiveClaims`,
101
+ `gate_ids`, `worker_results`, and objective or constraint revisions.
102
+
103
+ `emerged_subtasks` is the only sub-goal creation channel. It contains plain
104
+ descriptions, never `sg-` IDs. `subgoal_updates` changes existing active IDs;
105
+ done and canceled are terminal and cannot be reopened.
106
+
107
+ `outcome` may be `success`, `partial`, `failed`, or `blocked`. A blocked
108
+ outcome needs a concrete `blocker`; `stop_reason` of `blocked` or
109
+ `needs_human_input` also stops without claiming success.
110
+
111
+ Optional malformed values are normalized or dropped. The strict exceptions are
112
+ `subgoal_updates`, `round_contract`, and
113
+ `execution_report.contract_item_claims`. Shape, reference, duplicate, command,
114
+ and workspace-containment errors return `evaluation_invalid` or
115
+ `contract_invalid` before advance. Correct the payload and resubmit the same
116
+ `roundId`; nothing is committed and no rejection counter moves.
117
+
118
+ Every successful round still needs an `execution_report` with
119
+ `files_changed` and `tests_reported`. `no_change_reason` is an escape only when
120
+ no enabled verification command exists. It never creates evidence and never
121
+ excuses an open contract.
122
+
123
+ Agent reports are claims quoted for audit. They never become verified facts.
124
+ Do not infer a missing field from natural language or put a guessed evaluation
125
+ in free text.
126
+
127
+ ## IDs and contracts
128
+
129
+ Prompts render stable IDs beside constraints, criteria, sub-goals, and contract
130
+ items. Prefer those IDs for `constraint_violations`, criterion claims, status
131
+ updates, and item claims.
132
+
133
+ A sub-goal ID belongs to its declaration event. Re-declaring the same text in a
134
+ later round creates a new sub-goal. Status changes require the exact active
135
+ `sg-` ID; description matching is not a fallback.
136
+
137
+ A Round Contract is a set of evidence-bound items, not prose. Each item must
138
+ bind at least one configured, enabled, after-capable command. The runtime
139
+ derives content-addressed `rc-XXXXXXXX` and `rci-XXXXXXXX` IDs, so restating an
140
+ unchanged proposal keeps its identity. `subgoal_refs` belongs on the item; a
141
+ machine-verified item backs exactly the sub-goals it names, without changing
142
+ their declared `SubGoal.status`.
143
+
144
+ Item status is machine-derived:
145
+
146
+ - `pending`: not claimed as met;
147
+ - `insufficient`: claimed as met but not backed by all required observations;
148
+ - `contradicted`: a bound observation fails, or its entrypoint/configuration is
149
+ no longer trustworthy;
150
+ - `verified`: the Agent claims `met`, every bound command passes in the closing
151
+ round's after phase, and the declaration binding remains intact.
152
+
153
+ The contract closes only when every item is `verified` or a round reports
154
+ `outcome: "blocked"`. Repeated unbacked claims create bounded verification
155
+ debt. The same-check streak escalates at
156
+ `engine.unverified_claim_streak_limit` (default 3) instead of retrying forever.
157
+
158
+ Sub-goals may evolve during execution. LoopForge does not use fuzzy intent or
159
+ similarity to judge drift. The enforced boundary is contract `scope`: work
160
+ outside it is `round_scope_drift`, a machine fact no explanation waives. Revert
161
+ the out-of-scope change, or close the contract as blocked and declare the
162
+ expanded scope in a new proposal.
163
+
164
+ ## Backtrack and recovery
165
+
166
+ A progress stall is machine-first when Git history is observable over the
167
+ lookback window. Self-reported `progress_estimate` is only a fallback when
168
+ machine history cannot be read. Machine motion can excuse a stall but cannot
169
+ create one. A machine-backed success round is finishing, even if its closing
170
+ round changes no files.
171
+
172
+ Backtrack records a rollback directive and restores the round counter to the
173
+ last clean committed round. Rejected attempts are never history. The next
174
+ submission is the redo of `restorePoint + 1` and must reuse the prompt's round
175
+ ID. A successful redo retires the rollback record.
176
+
177
+ The Recovery Brief identifies the trigger, restore point, redo ID, failed
178
+ approaches, falsified assumptions, valid discoveries, files to revert, and
179
+ target HEAD. It states restoration facts, not a prescribed command.
167
180
 
168
181
  When backtrack occurs:
169
182
 
170
- 1. Restore the workspace exactly as requested before doing more work — the
171
- next submission's git evidence is checked against the restore point's HEAD.
172
- 2. Read the Recovery Brief, the restored prompt, and the derived state.
173
- 3. Do not repeat a failed approach listed in the brief without addressing it.
174
- 4. Keep valid discoveries from skipped rounds in later evaluations.
175
-
176
- If the workspace is not restored, the next submission is rejected with
177
- `backtrack_workspace_not_restored`. A stalled active contract should be closed
178
- with `outcome: "blocked"` and a blocker while proposing the revised contract
179
- in the same submission.
183
+ 1. Restore the workspace exactly as requested before doing more work.
184
+ 2. Read the Recovery Brief, restored prompt, and derived state.
185
+ 3. Do not repeat a failed approach without addressing its cause.
186
+ 4. Carry valid discoveries into later evaluations.
180
187
 
181
- ## Drift
182
-
183
- The verification gate compares the previous `next_action` with the current
184
- work. When intentionally changing direction, provide a substantive
185
- `drift_clarification` with a concrete constraint, criterion, sub-goal ID, or
186
- file path that actually exists in your report or the vault. Three consecutive
187
- weak clarifications terminate the loop.
188
+ If the rolled-back work used an active contract, close the stalled contract in
189
+ the redo with `outcome: "blocked"` and declare the revised contract in that
190
+ same submission. Restating the stalled contract commits more of the same.
188
191
 
189
192
  ## Interpret results
190
193
 
191
- - `prompt` is non-null: execute it and submit the next evaluation.
192
- - `enforcementAction: "reject"`: redo the same logical round. The round ID is
193
- stable and the attempt increases.
194
+ - Non-null `prompt`: execute it and submit the next evaluation.
195
+ - `enforcementAction: "reject"`: retry the same logical round and ID; the
196
+ attempt increases.
194
197
  - `enforcementAction: "backtrack"`: restore the workspace, then continue from
195
198
  the restored prompt and round.
196
- - `prompt` is null: inspect `stopReason`.
197
-
198
- `completed` means the task ended with success. `failed` means the Agent gave
199
- up. `blocked` means current constraints prevent progress. `max_rounds` is the
200
- safety limit. `stalled` means no usable next state was produced.
201
- `enforcement_terminated` means repeated integrity failures reached a terminal
202
- ladder. `paused` means the durable session remains available for resume.
199
+ - Null `prompt`: inspect `stopReason`.
200
+
201
+ Read `verificationStatus`, `roundSuccess`, `level`, `warnings`, and
202
+ `enforcementReason` before planning the next slice. `trusted` means claimed
203
+ work is machine-backed, `insufficient` means evidence is missing, and
204
+ `contradicted` means a machine fact denies a claim. These are evidence
205
+ postures, not subjective quality scores.
206
+
207
+ Errors use `{ok: false, error: {code, message, retryable, ...}}`. Branch on the
208
+ stable `code`, not the prose in `message`. Payload errors such as
209
+ `evaluation_invalid`, `contract_invalid`, `policy_invalid`, and round-ID
210
+ errors are retryable with the same ID. `session_not_found`, `state_unavailable`,
211
+ and `gate_disabled` describe state or policy; do not blindly resubmit.
212
+
213
+ `completed` means success plus every active contract item is `verified`, or
214
+ there is no active contract. Explicit `blocked` always wins over success.
215
+ `incomplete` means completion was not machine-verified. Other terminal reasons
216
+ include `failed`, `max_rounds`, `stalled`, `enforcement_terminated`, `paused`,
217
+ and `cancelled`.
203
218
 
204
219
  ## Prompt levels and views
205
220
 
206
- L0 is a lean same-round retry, L1 is normal continuation, and L2 is full
207
- rehydration. They control state density only and never prescribe a reasoning
208
- technique. Mandatory prompt sections and the token budget remain enforced.
221
+ L0 is a lean same-round retry, L1 normal continuation, and L2 full
222
+ rehydration. They control state density only, never a reasoning technique. L2
223
+ comes from round facts such as the first round, a plan or checkpoint boundary,
224
+ recovery, contradiction, or repeated rejection. It is not a round-count timer.
209
225
 
210
- Use `loopforge_status` with `view: "session"` for the live round and typed
211
- projection, `view: "loop"` for alignment and drift, `view: "all"` after a
212
- restart, and `view: "audit"` for the read-only completeness and evidence audit.
213
- Use `loopforge_replay` for the committed timeline and round diffs. Replay
214
- answers what happened; Audit checks whether facts and claims are supported.
226
+ Use `loopforge_status` with `view: "session"` for the live round,
227
+ `view: "loop"` for committed health, `view: "all"` after a restart,
228
+ `view: "audit"` for completeness and evidence, and `view: "explain"` for a
229
+ round's active contract, observations, flags, and decision. Use
230
+ `loopforge_replay` for the committed timeline and diffs.
215
231
 
216
- The optional `.loopforge/state/<loopId>-state.md` file is derived and can be
217
- regenerated. Read it in L2 pointer mode when the prompt asks for full context,
218
- but do not treat it as an independent source of truth.
232
+ The optional `.loopforge/state/<loopId>-state.md` is derived and regenerable.
233
+ Read it when an L2 prompt points to it, but never treat it as a second source
234
+ of truth.
219
235
 
220
- ## Control and delegation
236
+ ## Gates and delegation
221
237
 
222
- Use `loopforge_pause` before an intentional interruption,
238
+ Use `loopforge_pause` for an intentional interruption,
223
239
  `loopforge_resume` to reconstruct a durable session, and `loopforge_stop` only
224
240
  for an intentional terminal stop.
225
241
 
226
- The two gate tools are opt-in (`policy.gate.enabled`, default false) and are
227
- hidden from `tools/list` when disabled. When enabled, preflight a high-risk
228
- action with `loopforge_gate_check` (a structured `GateActionDescriptor`): a
229
- `user_required` verdict returns a gate id and an approval question, and only
230
- an approved gate may be cited via `evaluation.gate_ids` in the round that
231
- performs the action. Present the approval question to the human and record
232
- their decision with `loopforge_gate_resolve`. Safe preparation work
233
- (investigation, dry-runs, rollback evidence) never needs a gate. Remember:
234
- approval is recorded through you, the Agent — LoopForge cannot machine-verify
235
- a human is present.
236
-
237
- Delegation does not create a separate LoopForge mode. Give each worker a
238
- self-contained subtask and relevant hard constraints, then place its result in
239
- `worker_results` so discoveries can enter the next Canonical State.
242
+ The two gate tools are opt-in through `policy.gate.enabled`. When enabled,
243
+ `loopforge_gate_check` preflights a structured action with its description,
244
+ scope, effects, reversibility, and authorization. Classification is
245
+ conservative: anything not provably safe becomes `user_required`. Present the
246
+ approval question, record the decision with `loopforge_gate_resolve`, and cite
247
+ the approved gate ID in `evaluation.gate_ids`. LoopForge records the process,
248
+ but cannot prove that a human was present because the Agent submits the resolve
249
+ call. Safe investigation and dry-runs need no gate.
250
+
251
+ Delegation does not create another LoopForge mode. Give each worker a
252
+ self-contained subtask and hard constraints, then place the result in
253
+ `worker_results` so it can enter the next Canonical State.
240
254
 
241
255
  ## Rules
242
256
 
243
257
  1. Execute the prompt instead of generating another prompt.
244
258
  2. Submit one honest structured evaluation after each attempt.
245
- 3. Restore the workspace before working after backtrack.
246
- 4. Treat required command evidence and verification errors as authoritative.
259
+ 3. Treat required command evidence and verification findings as authoritative.
260
+ 4. Restore the workspace before working after backtrack.
247
261
  5. Keep one loop focused on one user objective.
248
262
  6. Do not advance a paused or stopped session through another process.
249
- 7. Continue within the same Agent task when possible. LoopForge preserves state
250
- but does not create a background Agent.
263
+ 7. Continue in the same Agent task when possible. LoopForge preserves state but
264
+ does not create a background Agent.