loopforge 3.8.2 → 3.9.0

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 (75) hide show
  1. package/README.md +145 -123
  2. package/dist/canonical-state.d.ts +1 -2
  3. package/dist/canonical-state.d.ts.map +1 -1
  4. package/dist/canonical-state.js +4 -12
  5. package/dist/canonical-state.js.map +1 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +115 -15
  8. package/dist/cli.js.map +1 -1
  9. package/dist/committed-round.d.ts +35 -7
  10. package/dist/committed-round.d.ts.map +1 -1
  11. package/dist/committed-round.js +81 -23
  12. package/dist/committed-round.js.map +1 -1
  13. package/dist/enforcement-gate.d.ts +21 -5
  14. package/dist/enforcement-gate.d.ts.map +1 -1
  15. package/dist/enforcement-gate.js +194 -139
  16. package/dist/enforcement-gate.js.map +1 -1
  17. package/dist/engine.d.ts.map +1 -1
  18. package/dist/engine.js +4 -5
  19. package/dist/engine.js.map +1 -1
  20. package/dist/evidence-provider.d.ts +44 -2
  21. package/dist/evidence-provider.d.ts.map +1 -1
  22. package/dist/evidence-provider.js +125 -23
  23. package/dist/evidence-provider.js.map +1 -1
  24. package/dist/loop-compiler.d.ts.map +1 -1
  25. package/dist/loop-compiler.js +1 -4
  26. package/dist/loop-compiler.js.map +1 -1
  27. package/dist/loop-store.d.ts.map +1 -1
  28. package/dist/loop-store.js +44 -7
  29. package/dist/loop-store.js.map +1 -1
  30. package/dist/mcp/round-lifecycle.d.ts +32 -1
  31. package/dist/mcp/round-lifecycle.d.ts.map +1 -1
  32. package/dist/mcp/round-lifecycle.js +102 -14
  33. package/dist/mcp/round-lifecycle.js.map +1 -1
  34. package/dist/mcp/server.d.ts.map +1 -1
  35. package/dist/mcp/server.js +7 -0
  36. package/dist/mcp/server.js.map +1 -1
  37. package/dist/mcp/tools.d.ts.map +1 -1
  38. package/dist/mcp/tools.js +0 -6
  39. package/dist/mcp/tools.js.map +1 -1
  40. package/dist/policy.d.ts +14 -6
  41. package/dist/policy.d.ts.map +1 -1
  42. package/dist/policy.js +52 -14
  43. package/dist/policy.js.map +1 -1
  44. package/dist/prompt-assembler.d.ts.map +1 -1
  45. package/dist/prompt-assembler.js +8 -24
  46. package/dist/prompt-assembler.js.map +1 -1
  47. package/dist/protocol.d.ts +4 -8
  48. package/dist/protocol.d.ts.map +1 -1
  49. package/dist/protocol.js +0 -2
  50. package/dist/protocol.js.map +1 -1
  51. package/dist/round-coordinator.d.ts +43 -0
  52. package/dist/round-coordinator.d.ts.map +1 -1
  53. package/dist/round-coordinator.js +104 -15
  54. package/dist/round-coordinator.js.map +1 -1
  55. package/dist/round-driver.d.ts +4 -0
  56. package/dist/round-driver.d.ts.map +1 -1
  57. package/dist/round-driver.js +2 -0
  58. package/dist/round-driver.js.map +1 -1
  59. package/dist/round-transaction.d.ts +5 -0
  60. package/dist/round-transaction.d.ts.map +1 -1
  61. package/dist/round-transaction.js +3 -0
  62. package/dist/round-transaction.js.map +1 -1
  63. package/dist/self-eval.d.ts +10 -0
  64. package/dist/self-eval.d.ts.map +1 -1
  65. package/dist/self-eval.js +14 -4
  66. package/dist/self-eval.js.map +1 -1
  67. package/dist/verification-gate.d.ts +18 -1
  68. package/dist/verification-gate.d.ts.map +1 -1
  69. package/dist/verification-gate.js +133 -41
  70. package/dist/verification-gate.js.map +1 -1
  71. package/dist/version.d.ts +1 -1
  72. package/dist/version.js +1 -1
  73. package/loop_policy.json +58 -59
  74. package/package.json +1 -1
  75. package/skills/perception/SKILL.md +326 -264
@@ -1,264 +1,326 @@
1
- ---
2
- name: perception
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
- ---
5
-
6
- # Perception
7
-
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
-
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.
15
-
16
- ## Start
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
-
21
- Call `loopforge_start` with:
22
-
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.
73
-
74
- ## Execute a round
75
-
76
- 1. Execute the returned prompt and do the repository work.
77
- 2. Use the tools and reasoning approach that fit the slice.
78
- 3. Check actual evidence before claiming success.
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.
87
-
88
- The four core evaluation fields are strict:
89
-
90
- | Field | Requirement |
91
- | --- | --- |
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.
180
-
181
- When backtrack occurs:
182
-
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.
187
-
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.
191
-
192
- ## Interpret results
193
-
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.
197
- - `enforcementAction: "backtrack"`: restore the workspace, then continue from
198
- the restored prompt and round.
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`.
218
-
219
- ## Prompt levels and views
220
-
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.
225
-
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.
231
-
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.
235
-
236
- ## Gates and delegation
237
-
238
- Use `loopforge_pause` for an intentional interruption,
239
- `loopforge_resume` to reconstruct a durable session, and `loopforge_stop` only
240
- for an intentional terminal stop.
241
-
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.
254
-
255
- ## Rules
256
-
257
- 1. Execute the prompt instead of generating another prompt.
258
- 2. Submit one honest structured evaluation after each attempt.
259
- 3. Treat required command evidence and verification findings as authoritative.
260
- 4. Restore the workspace before working after backtrack.
261
- 5. Keep one loop focused on one user objective.
262
- 6. Do not advance a paused or stopped session through another process.
263
- 7. Continue in the same Agent task when possible. LoopForge preserves state but
264
- does not create a background Agent.
1
+ ---
2
+ name: perception
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
+ ---
5
+
6
+ # Perception
7
+
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
+
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.
15
+
16
+ ## Start
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
+
21
+ Call `loopforge_start` with:
22
+
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. Size the slice by what one machine-checkable outcome covers — a
64
+ requirements list is not a round list, and coupled changes that share one
65
+ objective, one evidence story, and one recovery path belong in the same round.
66
+ Bind each item to a configured evidence command with `verify_with`, and limit
67
+ `scope` to files or directories that slice may touch. The proposal becomes
68
+ active only after its declaring round commits.
69
+ While it is open, restating the same proposal continues it; a different
70
+ proposal is ignored as `contract_premature`. If the slice is blocked, report
71
+ `outcome: "blocked"` with a concrete `blocker` instead of silently replacing
72
+ the active contract.
73
+
74
+ This is a planning aid, not a second gate. LoopForge learns the plan only from
75
+ committed evaluation fields, contract proposals, observations, and changes.
76
+
77
+ ## Execute a round
78
+
79
+ 1. Execute the returned prompt and do the repository work.
80
+ 2. Use the tools and reasoning approach that fit the slice.
81
+ 3. Check actual evidence before claiming success.
82
+ 4. Submit exactly one structured evaluation with `loopforge_next`.
83
+
84
+ After the strict boundary accepts the payload, LoopForge collects before/after
85
+ evidence, runs the **verification gate**, then runs the **enforcement gate**.
86
+ The verification gate checks evaluation consistency, evidence integrity, plan
87
+ and contract conformance, and progress and recovery. The enforcement gate
88
+ turns those findings into one disposition: accept, reject, backtrack, or
89
+ terminate.
90
+
91
+ The four core evaluation fields are strict:
92
+
93
+ | Field | Requirement |
94
+ | --- | --- |
95
+ | `success` | Boolean. `true` only when the whole objective and hard constraints are satisfied. |
96
+ | `output_summary` | String describing what changed and what was verified. |
97
+ | `constraint_violations` | Array of real violations, preferably using `c-XXXXXXXX` IDs. |
98
+ | `should_continue` | Boolean. `false` only when the whole task is complete. |
99
+
100
+ Useful optional fields include `execution_report` (`files_changed`,
101
+ `tests_reported`, `criterion_claims`, and `contract_item_claims`),
102
+ `discovered_constraints`, `emerged_subtasks`,
103
+ `subgoal_updates`, `prompt_requests`, `round_contract`, `retroactiveClaims`,
104
+ `gate_ids`, `worker_results`, and objective or constraint revisions.
105
+
106
+ `emerged_subtasks` is the only sub-goal creation channel. It contains plain
107
+ descriptions, never `sg-` IDs. `subgoal_updates` changes existing active IDs;
108
+ done and canceled are terminal and cannot be reopened.
109
+
110
+ `outcome` may be `success`, `partial`, `failed`, or `blocked`. A blocked
111
+ outcome needs a concrete `blocker`; `stop_reason` of `blocked` or
112
+ `needs_human_input` also stops without claiming success.
113
+
114
+ Optional malformed values are normalized or dropped. The strict exceptions are
115
+ `subgoal_updates`, `round_contract`, and
116
+ `execution_report.contract_item_claims`. Shape, reference, duplicate, command,
117
+ and workspace-containment errors return `evaluation_invalid` or
118
+ `contract_invalid` before advance. Correct the payload and resubmit the same
119
+ `roundId`; nothing is committed and no rejection counter moves.
120
+
121
+ Every successful round still needs an `execution_report` with
122
+ `files_changed` and `tests_reported`. `no_change_reason` is an escape only when
123
+ no enabled verification command exists. It never creates evidence and never
124
+ excuses an open contract.
125
+
126
+ Agent reports are claims quoted for audit. They never become verified facts.
127
+ Do not infer a missing field from natural language or put a guessed evaluation
128
+ in free text.
129
+
130
+ ## IDs and contracts
131
+
132
+ Prompts render stable IDs beside constraints, criteria, sub-goals, and contract
133
+ items. Prefer those IDs for `constraint_violations`, criterion claims, status
134
+ updates, and item claims.
135
+
136
+ A sub-goal ID belongs to its declaration event. Re-declaring the same text in a
137
+ later round creates a new sub-goal. Status changes require the exact active
138
+ `sg-` ID; description matching is not a fallback.
139
+
140
+ A Round Contract is a set of evidence-bound items, not prose. Each item must
141
+ bind at least one configured, enabled, after-capable command. The runtime
142
+ derives content-addressed `rc-XXXXXXXX` and `rci-XXXXXXXX` IDs, so restating an
143
+ unchanged proposal keeps its identity. `subgoal_refs` belongs on the item; a
144
+ machine-verified item backs exactly the sub-goals it names, without changing
145
+ their declared `SubGoal.status`.
146
+
147
+ Item status is machine-derived:
148
+
149
+ - `pending`: not claimed as met;
150
+ - `insufficient`: claimed as met but not backed by all required observations;
151
+ - `contradicted`: a bound observation fails, or its entrypoint/configuration is
152
+ no longer trustworthy;
153
+ - `verified`: the Agent claims `met`, every bound command passes in the closing
154
+ round's after phase, and the declaration binding remains intact.
155
+
156
+ The contract closes only when every item is `verified` or a round reports
157
+ `outcome: "blocked"`. Repeated unbacked claims create bounded verification
158
+ debt. The same-check streak escalates at
159
+ `engine.unverified_claim_streak_limit` (default 3) instead of retrying forever.
160
+
161
+ Sub-goals may evolve during execution. LoopForge does not use fuzzy intent or
162
+ similarity to judge drift. The enforced boundary is contract `scope`: work
163
+ outside it is `round_scope_drift`, a machine fact no explanation waives. Revert
164
+ the out-of-scope change, or close the contract as blocked and declare the
165
+ expanded scope in a new proposal whose `scope` covers **every** file this round
166
+ changed outside the current one — a partial expansion is still drift.
167
+
168
+ ## Evidence commands
169
+
170
+ Contract items are backed by commands the OPERATOR configures. The Agent never
171
+ declares one, and does not discover or run project scripts to invent one. They
172
+ live in `loop_policy.json` under `evidence.commands`, in the workspace the
173
+ server was started in:
174
+
175
+ ```json
176
+ {
177
+ "version": "5",
178
+ "evidence": {
179
+ "commands": [{
180
+ "name": "verify",
181
+ "enabled": true,
182
+ "executable": "node",
183
+ "args": ["scripts/verify.mjs"],
184
+ "cwd": ".",
185
+ "phase": "after",
186
+ "required": true,
187
+ "timeout_ms": 120000,
188
+ "max_output_chars": 8000,
189
+ "success_exit_codes": [0]
190
+ }]
191
+ }
192
+ }
193
+ ```
194
+
195
+ `executable` and `args` are spawned without a shell and confined to the
196
+ workspace. `loopforge doctor` statically checks every configured command —
197
+ its name, executable, arguments, timeouts, and workspace containment — and
198
+ never executes one.
199
+
200
+ Every prepared round returns `capability`: which providers are available, which
201
+ commands are enabled and after-capable, and `contractVerificationAvailable`.
202
+ When that is `false`, no configured command can back a contract item: run
203
+ rounds without a contract instead of declaring items that cannot close. The
204
+ `warnings` list states the same thing in words.
205
+
206
+ A command's ENTRYPOINT is the file it names plus `package.json` when a package
207
+ manager runs it. It must already be part of the workspace when the round
208
+ starts, and it must not change during the round that runs it — the runtime
209
+ records those files at round start and compares them afterwards, whether or not
210
+ git can see them. A changed entrypoint makes the observation untrustworthy:
211
+ restore it to its round-start content. Do not author the verification script
212
+ inside the round you expect it to verify — that round cannot be closed by it.
213
+
214
+ To keep a script that must survive a rollback, it has to be part of the
215
+ committed workspace rather than an uncommitted change: the post-backtrack
216
+ restore check rejects a skipped file that is still byte-identical to its state
217
+ at the rollback, so a script left sitting in the working tree blocks the redo.
218
+ Prepare it before the round that depends on it.
219
+
220
+ ## Backtrack and recovery
221
+
222
+ A progress stall requires observable Git history over the lookback window.
223
+ Committed work counts as motion through the Git HEAD change, even when the
224
+ closing worktree is clean, and the round you are submitting counts too: if it
225
+ moved files or committed, it cancels the verdict. If machine history cannot be
226
+ read, no stall verdict is made. A machine-backed success round is finishing,
227
+ even if its closing round changes no files.
228
+
229
+ Backtrack records a rollback directive and restores the round counter to the
230
+ last clean committed round. Rejected attempts are never history. The next
231
+ submission is the redo of `restorePoint + 1` and must reuse the prompt's round
232
+ ID. A successful redo retires the rollback record.
233
+
234
+ The Recovery Brief identifies the trigger, restore point, redo ID, failed
235
+ approaches, falsified assumptions, valid discoveries, files to revert, and
236
+ target HEAD. It states restoration facts, not a prescribed command.
237
+
238
+ When backtrack occurs:
239
+
240
+ 1. Restore the workspace exactly as requested before doing more work: the
241
+ restore point's HEAD, with none of the failed rounds' changes left behind.
242
+ Work in progress the restore point already carried may stay.
243
+ 2. Submit one recovery evaluation from the restored state, so LoopForge can
244
+ verify the restore before the redo's own work — and any commit — follows.
245
+ 3. Read the Recovery Brief, restored prompt, and derived state.
246
+ 4. Do not repeat a failed approach without addressing its cause.
247
+ 5. Carry valid discoveries into later evaluations.
248
+
249
+ If the rolled-back work used an active contract, close the stalled contract in
250
+ the redo with `outcome: "blocked"` and declare the revised contract in that
251
+ same submission. Restating the stalled contract commits more of the same.
252
+
253
+ ## Interpret results
254
+
255
+ - Non-null `prompt`: execute it and submit the next evaluation.
256
+ - `enforcementAction: "reject"`: retry the same logical round and ID; the
257
+ attempt increases.
258
+ - `enforcementAction: "backtrack"`: restore the workspace, submit one recovery
259
+ evaluation from the restored state, then redo the round from its restored
260
+ prompt and round ID.
261
+ - Null `prompt`: inspect `stopReason`.
262
+
263
+ Read `verificationStatus`, `roundSuccess`, `level`, `warnings`, and
264
+ `enforcementReason` before planning the next slice. `trusted` means claimed
265
+ work is machine-backed, `insufficient` means evidence is missing, and
266
+ `contradicted` means a machine fact denies a claim. These are evidence
267
+ postures, not subjective quality scores.
268
+
269
+ Errors use `{ok: false, error: {code, message, retryable, ...}}`. Branch on the
270
+ stable `code`, not the prose in `message`. Payload errors such as
271
+ `evaluation_invalid`, `contract_invalid`, `policy_invalid`, and round-ID
272
+ errors are retryable with the same ID. `session_not_found`, `state_unavailable`,
273
+ and `gate_disabled` describe state or policy; do not blindly resubmit.
274
+
275
+ `completed` means success plus every active contract item is `verified`, or
276
+ there is no active contract. Explicit `blocked` always wins over success.
277
+ `incomplete` means completion was not machine-verified. Other terminal reasons
278
+ include `failed`, `max_rounds`, `stalled`, `enforcement_terminated`, `paused`,
279
+ and `cancelled`.
280
+
281
+ ## Prompt levels and views
282
+
283
+ L0 is a lean same-round retry, L1 normal continuation, and L2 full
284
+ rehydration. They control state density only, never a reasoning technique. L2
285
+ comes from round facts such as the first round, a plan or checkpoint boundary,
286
+ recovery, contradiction, or repeated rejection. It is not a round-count timer.
287
+
288
+ Use `loopforge_status` with `view: "session"` for the live round,
289
+ `view: "loop"` for committed health, `view: "all"` after a restart,
290
+ `view: "audit"` for completeness and evidence, and `view: "explain"` for a
291
+ round's active contract, observations, flags, and decision. Use
292
+ `loopforge_replay` for the committed timeline and diffs.
293
+
294
+ The optional `.loopforge/state/<loopId>-state.md` is derived and regenerable.
295
+ Read it when an L2 prompt points to it, but never treat it as a second source
296
+ of truth.
297
+
298
+ ## Gates and delegation
299
+
300
+ Use `loopforge_pause` for an intentional interruption,
301
+ `loopforge_resume` to reconstruct a durable session, and `loopforge_stop` only
302
+ for an intentional terminal stop.
303
+
304
+ The two gate tools are opt-in through `policy.gate.enabled`. When enabled,
305
+ `loopforge_gate_check` preflights a structured action with its description,
306
+ scope, effects, reversibility, and authorization. Classification is
307
+ conservative: anything not provably safe becomes `user_required`. Present the
308
+ approval question, record the decision with `loopforge_gate_resolve`, and cite
309
+ the approved gate ID in `evaluation.gate_ids`. LoopForge records the process,
310
+ but cannot prove that a human was present because the Agent submits the resolve
311
+ call. Safe investigation and dry-runs need no gate.
312
+
313
+ Delegation does not create another LoopForge mode. Give each worker a
314
+ self-contained subtask and hard constraints, then place the result in
315
+ `worker_results` so it can enter the next Canonical State.
316
+
317
+ ## Rules
318
+
319
+ 1. Execute the prompt instead of generating another prompt.
320
+ 2. Submit one honest structured evaluation after each attempt.
321
+ 3. Treat required command evidence and verification findings as authoritative.
322
+ 4. Restore the workspace before working after backtrack.
323
+ 5. Keep one loop focused on one user objective.
324
+ 6. Do not advance a paused or stopped session through another process.
325
+ 7. Continue in the same Agent task when possible. LoopForge preserves state but
326
+ does not create a background Agent.