loopforge 2.7.0 → 3.0.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 (173) hide show
  1. package/README.md +136 -182
  2. package/dist/canonical-event-writer.d.ts +20 -0
  3. package/dist/canonical-event-writer.d.ts.map +1 -0
  4. package/dist/canonical-event-writer.js +131 -0
  5. package/dist/canonical-event-writer.js.map +1 -0
  6. package/dist/canonical-state.d.ts +20 -16
  7. package/dist/canonical-state.d.ts.map +1 -1
  8. package/dist/canonical-state.js +211 -64
  9. package/dist/canonical-state.js.map +1 -1
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +11 -10
  12. package/dist/cli.js.map +1 -1
  13. package/dist/cognitive-governance.d.ts +48 -0
  14. package/dist/cognitive-governance.d.ts.map +1 -0
  15. package/dist/cognitive-governance.js +226 -0
  16. package/dist/cognitive-governance.js.map +1 -0
  17. package/dist/compiler-subgoals.d.ts +7 -0
  18. package/dist/compiler-subgoals.d.ts.map +1 -0
  19. package/dist/compiler-subgoals.js +93 -0
  20. package/dist/compiler-subgoals.js.map +1 -0
  21. package/dist/derive-id.d.ts +12 -0
  22. package/dist/derive-id.d.ts.map +1 -0
  23. package/dist/derive-id.js +31 -0
  24. package/dist/derive-id.js.map +1 -0
  25. package/dist/evidence-provider.d.ts +26 -26
  26. package/dist/evidence-provider.d.ts.map +1 -1
  27. package/dist/evidence-provider.js +45 -71
  28. package/dist/evidence-provider.js.map +1 -1
  29. package/dist/generate-schema.js +90 -2
  30. package/dist/generate-schema.js.map +1 -1
  31. package/dist/index.d.ts +23 -29
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +16 -26
  34. package/dist/index.js.map +1 -1
  35. package/dist/loop-compiler.d.ts +2 -2
  36. package/dist/loop-compiler.d.ts.map +1 -1
  37. package/dist/loop-compiler.js +321 -315
  38. package/dist/loop-compiler.js.map +1 -1
  39. package/dist/loop-extras-parser.d.ts +2 -2
  40. package/dist/loop-extras-parser.d.ts.map +1 -1
  41. package/dist/loop-extras-parser.js +2 -2
  42. package/dist/loop-extras-parser.js.map +1 -1
  43. package/dist/loop-store.d.ts +20 -58
  44. package/dist/loop-store.d.ts.map +1 -1
  45. package/dist/loop-store.js +232 -311
  46. package/dist/loop-store.js.map +1 -1
  47. package/dist/mcp/server.d.ts +3 -3
  48. package/dist/mcp/server.d.ts.map +1 -1
  49. package/dist/mcp/server.js +123 -19
  50. package/dist/mcp/server.js.map +1 -1
  51. package/dist/mcp/session-projection.d.ts +5 -0
  52. package/dist/mcp/session-projection.d.ts.map +1 -0
  53. package/dist/mcp/session-projection.js +18 -0
  54. package/dist/mcp/session-projection.js.map +1 -0
  55. package/dist/mcp/session-queue.d.ts +3 -0
  56. package/dist/mcp/session-queue.d.ts.map +1 -0
  57. package/dist/mcp/session-queue.js +18 -0
  58. package/dist/mcp/session-queue.js.map +1 -0
  59. package/dist/mcp/session-types.d.ts +72 -0
  60. package/dist/mcp/session-types.d.ts.map +1 -0
  61. package/dist/mcp/session-types.js +2 -0
  62. package/dist/mcp/session-types.js.map +1 -0
  63. package/dist/mcp/session.d.ts +65 -84
  64. package/dist/mcp/session.d.ts.map +1 -1
  65. package/dist/mcp/session.js +667 -224
  66. package/dist/mcp/session.js.map +1 -1
  67. package/dist/mcp/tools.d.ts +26 -1
  68. package/dist/mcp/tools.d.ts.map +1 -1
  69. package/dist/mcp/tools.js +401 -254
  70. package/dist/mcp/tools.js.map +1 -1
  71. package/dist/policy-metrics.d.ts +24 -0
  72. package/dist/policy-metrics.d.ts.map +1 -1
  73. package/dist/policy-metrics.js +174 -0
  74. package/dist/policy-metrics.js.map +1 -1
  75. package/dist/policy.d.ts +74 -12
  76. package/dist/policy.d.ts.map +1 -1
  77. package/dist/policy.js +124 -19
  78. package/dist/policy.js.map +1 -1
  79. package/dist/prompt-assembler.d.ts +8 -4
  80. package/dist/prompt-assembler.d.ts.map +1 -1
  81. package/dist/prompt-assembler.js +533 -86
  82. package/dist/prompt-assembler.js.map +1 -1
  83. package/dist/prompt-policy.d.ts +8 -1
  84. package/dist/prompt-policy.d.ts.map +1 -1
  85. package/dist/prompt-policy.js +26 -8
  86. package/dist/prompt-policy.js.map +1 -1
  87. package/dist/protocol.d.ts +259 -173
  88. package/dist/protocol.d.ts.map +1 -1
  89. package/dist/protocol.js +17 -96
  90. package/dist/protocol.js.map +1 -1
  91. package/dist/replay.d.ts +11 -3
  92. package/dist/replay.d.ts.map +1 -1
  93. package/dist/replay.js +51 -14
  94. package/dist/replay.js.map +1 -1
  95. package/dist/round-commit-store.d.ts +12 -0
  96. package/dist/round-commit-store.d.ts.map +1 -0
  97. package/dist/round-commit-store.js +13 -0
  98. package/dist/round-commit-store.js.map +1 -0
  99. package/dist/round-coordinator.d.ts +53 -22
  100. package/dist/round-coordinator.d.ts.map +1 -1
  101. package/dist/round-coordinator.js +140 -44
  102. package/dist/round-coordinator.js.map +1 -1
  103. package/dist/round-driver.d.ts +18 -10
  104. package/dist/round-driver.d.ts.map +1 -1
  105. package/dist/round-driver.js +11 -13
  106. package/dist/round-driver.js.map +1 -1
  107. package/dist/round-gate.d.ts +31 -0
  108. package/dist/round-gate.d.ts.map +1 -0
  109. package/dist/round-gate.js +259 -0
  110. package/dist/round-gate.js.map +1 -0
  111. package/dist/round-recovery.d.ts +17 -0
  112. package/dist/round-recovery.d.ts.map +1 -0
  113. package/dist/round-recovery.js +117 -0
  114. package/dist/round-recovery.js.map +1 -0
  115. package/dist/round-report.d.ts +16 -0
  116. package/dist/round-report.d.ts.map +1 -0
  117. package/dist/round-report.js +401 -0
  118. package/dist/round-report.js.map +1 -0
  119. package/dist/round-transaction.d.ts +23 -12
  120. package/dist/round-transaction.d.ts.map +1 -1
  121. package/dist/round-transaction.js +104 -91
  122. package/dist/round-transaction.js.map +1 -1
  123. package/dist/runtime-services.d.ts +59 -0
  124. package/dist/runtime-services.d.ts.map +1 -0
  125. package/dist/{engine.js → runtime-services.js} +157 -275
  126. package/dist/runtime-services.js.map +1 -0
  127. package/dist/storage.d.ts +3 -9
  128. package/dist/storage.d.ts.map +1 -1
  129. package/dist/storage.js +6 -17
  130. package/dist/storage.js.map +1 -1
  131. package/dist/token-utils.d.ts +12 -8
  132. package/dist/token-utils.d.ts.map +1 -1
  133. package/dist/token-utils.js +56 -10
  134. package/dist/token-utils.js.map +1 -1
  135. package/dist/vault-format.d.ts +4 -0
  136. package/dist/vault-format.d.ts.map +1 -0
  137. package/dist/vault-format.js +4 -0
  138. package/dist/vault-format.js.map +1 -0
  139. package/dist/vault-types.d.ts +24 -0
  140. package/dist/vault-types.d.ts.map +1 -0
  141. package/dist/vault-types.js +2 -0
  142. package/dist/vault-types.js.map +1 -0
  143. package/loop_policy.json +10 -12
  144. package/loopforge-policy.json +340 -0
  145. package/package.json +13 -7
  146. package/skills/perception/SKILL.md +200 -90
  147. package/dist/backends/interface.d.ts +0 -39
  148. package/dist/backends/interface.d.ts.map +0 -1
  149. package/dist/backends/interface.js +0 -6
  150. package/dist/backends/interface.js.map +0 -1
  151. package/dist/enforcement-gate.d.ts +0 -50
  152. package/dist/enforcement-gate.d.ts.map +0 -1
  153. package/dist/enforcement-gate.js +0 -501
  154. package/dist/enforcement-gate.js.map +0 -1
  155. package/dist/engine.d.ts +0 -59
  156. package/dist/engine.d.ts.map +0 -1
  157. package/dist/engine.js.map +0 -1
  158. package/dist/interop.d.ts +0 -35
  159. package/dist/interop.d.ts.map +0 -1
  160. package/dist/interop.js +0 -34
  161. package/dist/interop.js.map +0 -1
  162. package/dist/run.d.ts +0 -51
  163. package/dist/run.d.ts.map +0 -1
  164. package/dist/run.js +0 -200
  165. package/dist/run.js.map +0 -1
  166. package/dist/self-eval.d.ts +0 -23
  167. package/dist/self-eval.d.ts.map +0 -1
  168. package/dist/self-eval.js +0 -151
  169. package/dist/self-eval.js.map +0 -1
  170. package/dist/verification-gate.d.ts +0 -52
  171. package/dist/verification-gate.d.ts.map +0 -1
  172. package/dist/verification-gate.js +0 -527
  173. package/dist/verification-gate.js.map +0 -1
@@ -1,118 +1,228 @@
1
1
  ---
2
2
  name: perception
3
- description: Drive a recoverable multi-round coding task through LoopForge MCP while the Agent remains the execution owner.
3
+ description: Drive a recoverable multi-round task through the LoopForge MCP runtime while the Agent remains the execution owner.
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 for work that spans multiple context windows, needs an auditable
9
+ record, or must survive a process restart. LoopForge stores canonical facts and
10
+ compiles prompts; you remain responsible for inspecting the repository,
11
+ editing files, running tools, and making technical decisions.
11
12
 
12
- LoopForge maintains cognitive state. You remain the Agent that reads files,
13
- edits code, runs commands, delegates work, and decides how to reason.
13
+ There is one public execution path. Do not create a second plan scheduler,
14
+ background Agent, MCP Task, or local shadow state machine.
14
15
 
15
- ## Start
16
+ ## 1. Start one loop
16
17
 
17
18
  Call `loopforge_start` with:
18
19
 
19
- - `task`: the complete user objective.
20
- - `constraints`: hard boundaries that must survive every round.
21
- - `maxRounds`: optional safety limit. The default is 20.
22
- - `domain`: optional context label.
20
+ - `task`: the complete user objective, not a short reminder;
21
+ - `constraints`: hard boundaries that must survive every round;
22
+ - `successCriteria`: explicit verifiable completion criteria when the task has
23
+ more than the default objective-level criterion;
24
+ - `maxRounds`: an explicit safety limit when the default (100) is unsuitable;
25
+ - `domain`: an optional technology or repository hint;
26
+ - `planSource`: an optional path to a user-provided plan (reference only).
23
27
 
24
- Keep the returned `sessionId`, `roundId`, prompt, and level.
28
+ Keep the returned `sessionId`, `loopId`, `roundId`, prompt, and hashes. Execute
29
+ the returned prompt in the bound workspace before submitting a report.
25
30
 
26
- ## Execute a round
31
+ ## 2. Submit `RoundReport`
27
32
 
28
- 1. Execute the returned prompt. Do real repository work.
29
- 2. Use the available tools and reasoning approach that best fit the task.
30
- 3. Check actual evidence before claiming success.
31
- 4. Call `loopforge_next` with `sessionId` and a structured `evaluation`.
32
-
33
- Minimal evaluation:
33
+ Call `loopforge_next` after an accepted round. Call `loopforge_retry` only when
34
+ the previous logical round was rejected. Both calls require `sessionId` and a
35
+ canonical report; free-form text and the old `status` report are invalid.
34
36
 
35
37
  ```json
36
38
  {
37
- "success": false,
38
- "output_summary": "Implemented the parser and added 8 passing tests.",
39
- "constraint_violations": [],
40
- "should_continue": true
39
+ "format": "loopforge.round-report",
40
+ "outcome": "partial",
41
+ "continuation": "continue",
42
+ "summary": "Implemented the parser and ran focused tests.",
43
+ "violations": [],
44
+ "evidence": {
45
+ "files": ["src/parser.ts", "test/parser.test.ts"],
46
+ "checks": [{"name": "npm test -- parser", "status": "passed", "counts": {"passed": 8, "failed": 0, "skipped": 0}}],
47
+ "claims": [{"id": "claim-0123456789ab", "targetId": "cr-abcdef12", "evidenceRefs": ["command:npm test -- parser"]}],
48
+ "provenance": {}
49
+ },
50
+ "agentIntent": "Add parser regression coverage next"
41
51
  }
42
52
  ```
43
53
 
44
- Important fields:
54
+ ### Outcome versus continuation
55
+
56
+ - `outcome` is only this round's result: `success`, `partial`, `failed`, or
57
+ `blocked`.
58
+ - `continuation` is only the request to start another round: `continue` or
59
+ `stop`.
60
+ - `success` does not prove the total objective is complete. Completion requires
61
+ runtime-verified claims for every remaining criterion, no contradictory
62
+ checks, and no unresolved User Gate.
63
+ - `blocked` requires a `blocker` object. Use `continuation: "stop"` for a
64
+ user decision, external dependency, or side effect that must not be guessed.
65
+ An Agent-resolvable blocker may use `continue`, but state the required
66
+ evidence and resolution.
67
+
68
+ ### Report fields
45
69
 
46
- | Field | Rule |
70
+ | Field | How to use it |
47
71
  | --- | --- |
48
- | `success` | Use `true` only when the whole objective and every hard constraint are satisfied. |
49
- | `output_summary` | State what changed and what was verified. |
50
- | `constraint_violations` | Report real violations. Do not hide them to force progress. |
51
- | `should_continue` | Use `false` only when the entire task is complete. |
52
- | `execution_evidence` | Report changed files, test counts, met and remaining criteria, and progress when known. |
53
- | `discovered_constraints` | Add newly discovered guardrails. |
54
- | `objective_refinement` | Refine the objective when repository evidence changes its meaning. |
55
- | `wrong_assumptions` | Record assumptions disproved this round. |
56
- | `worker_results` | Record delegated subtask results and discoveries. |
72
+ | `summary` | Describe concrete work and observations from this round. |
73
+ | `violations` | List every actual hard-constraint violation; do not hide one to obtain acceptance. Prefer `c-XXXXXXXX` IDs. |
74
+ | `evidence` | Report files, checks, claims and references. Agent provenance is only a claim until a runtime provider observes it. |
75
+ | `discoveries` | Record wrong assumptions, emerged work, durable facts and newly discovered constraints. |
76
+ | `subGoalEvents` | Report completed, blocked or canceled existing sub-goals. Do not invent a second sub-goal lifecycle. Prefer `sg-XXXXXXXX` IDs. |
77
+ | `constraintEvents` | Retire a constraint only when repository evidence shows it is no longer valid. |
78
+ | `criterionRevisions` | Propose an old-to-new criterion change; never silently replace the user's objective. |
79
+ | `objectiveRefinement` | Add a safe clarification when evidence changes the interpretation; it is validated by the runtime. |
80
+ | `phaseBoundaryProposal` | Suggest a phase label and reason. The runtime decides whether the boundary is real. |
81
+ | `contextRequest` | Per-round emphasis, expansion or confusion requests. It is consumed once and is not durable state. |
82
+ | `agentIntent` | Optional Agent suggestion used only for audit and drift comparison. Runtime-derived Focus, Todo and Suggested Next Action take precedence. |
83
+ | `driftClarification` | When drift is detected, provide a concrete explanation and a criterion/constraint ID or observed file path. Runtime validates it; do not submit a waiver boolean. |
84
+
85
+ Do not submit derived `currentFocus`, `todoProjection`, `handoff`,
86
+ `progress`, `failedPatterns`, `nextAction`, or `verifiedFacts` as alternate
87
+ facts. These are internal or derived views. A progress estimate, if present in
88
+ the evidence supplied to an embedding, is never authoritative.
89
+
90
+ ## 3. Evidence discipline
91
+
92
+ Use stable IDs shown in the prompt:
93
+
94
+ - constraints: `[c-a3f2b1c0]`;
95
+ - criteria: `[cr-b5a6c7d8]`;
96
+ - sub-goals: `[sg-f1e2d3c4]`.
97
+
98
+ Claims should reference a concrete file, check, or provider observation. Do not
99
+ mark your own provenance `verified` to force progress. Runtime providers may
100
+ replace claimed evidence with `verified`, `contradicted`, or `unavailable`.
101
+ Missing provider output is unavailable, not a pass. A rejected attempt and its
102
+ claims are not canonical facts.
103
+
104
+ ## 4. Retry, backtrack and continuation
105
+
106
+ Read the returned `decision` and `enforcementAction`:
107
+
108
+ - `accepted`: execute the returned prompt for the next round;
109
+ - `rejected`: correct the evidence or work and call `loopforge_retry`; keep the
110
+ same logical `roundId` and do not call `next` to bypass rejection;
111
+ - `backtracked`: use the returned restore round and requirements, then continue
112
+ from the new prompt;
113
+ - `stopped` or `terminated`: do not submit another report unless a new loop is
114
+ explicitly started.
115
+
116
+ Backtrack is advisory and bounded. It never changes workspace files. Follow the
117
+ exact paths and checks returned by LoopForge, inspect the resulting workspace,
118
+ and report the restoration evidence. Never improvise an unbounded destructive
119
+ command such as `git clean -fd` or `git reset --hard`; ask for a User Gate when
120
+ the required action is destructive or authorization is unclear.
121
+
122
+ ## 5. User Gate and Agent Gate
123
+
124
+ For a risky action, call `loopforge_gate_check` with:
57
125
 
58
- Do not embed an evaluation marker in ordinary output when the MCP client accepts
59
- the structured `evaluation` argument.
126
+ ```json
127
+ {
128
+ "description": "Apply the production database migration",
129
+ "scope": ["db/migrations/2026-01.sql"],
130
+ "effects": ["data_migration", "production"],
131
+ "reversibility": "recoverable",
132
+ "authorization": "user_required"
133
+ }
134
+ ```
60
135
 
61
- ## Interpret the result
136
+ User Gate is required for production, credentials, data migration, publishing,
137
+ payment, external communication, public API changes, irreversible or unknown
138
+ actions, and unknown authorization. Limit the blocked scope and continue only
139
+ with allowed read-only investigation or dry runs. Agent Gate is for bounded,
140
+ reversible, explicitly `agent_allowed` workspace work or ordinary technical
141
+ blockers. Resolve a User Gate with `loopforge_gate_resolve` using the exact same
142
+ descriptor; its `actionHash` invalidates an approval if the action changes.
62
143
 
63
- If `prompt` is non-null, execute it and submit the next evaluation.
144
+ ## 6. Status, history and audit
64
145
 
65
- If `enforcementAction` is `reject`, redo the same logical round. The round ID
66
- stays stable and the attempt number increases. Follow the retry requirements;
67
- the rejected attempt has not been committed.
146
+ Use only the current twelve tools:
68
147
 
69
- If `prompt` is null, inspect `stopReason`:
148
+ ```text
149
+ loopforge_start loopforge_next loopforge_retry
150
+ loopforge_backtrack loopforge_resume loopforge_pause
151
+ loopforge_stop loopforge_status loopforge_history
152
+ loopforge_gate_check loopforge_gate_resolve loopforge_audit
153
+ ```
70
154
 
71
- | Reason | Meaning |
72
- | --- | --- |
73
- | `task_complete` | The complete objective was reported finished. |
74
- | `circuit_breaker` | Repeated failed rounds require a different approach or user input. |
75
- | `max_rounds` | The safety limit was reached. Summarize remaining work. |
76
- | `stalled` | Evaluation or execution did not produce a usable next state. |
77
- | `enforcement_terminated` | Repeated invalid claims or stalled progress terminated the loop. |
78
- | `paused` | The durable session remains available for resume. |
79
-
80
- ## Prompt levels
81
-
82
- - L0 is a same-round retry with the rejection reason and changed evidence.
83
- - L1 is the normal compact continuation view.
84
- - L2 is a full rehydration for the first round, a checkpoint, or a goal change.
85
-
86
- These levels control state density only. LoopForge does not choose a reasoning
87
- technique for you.
88
-
89
- ## Recovery and control
90
-
91
- - Use `loopforge_status` to inspect the live round and trajectory.
92
- - Use `loopforge_pause` before an intentional interruption.
93
- - Use `loopforge_resume` with the loop ID to reconstruct a durable session.
94
- - Use `loopforge_list` after a client restart to find recoverable sessions.
95
- - Use `loopforge_replay` for the committed timeline.
96
- - Use `loopforge_health` to inspect goal alignment and drift.
97
- - Use `loopforge_stop` only for an intentional terminal stop.
98
-
99
- The optional `.loopforge/state/<loopId>-state.md` file is a readable derived
100
- view. The typed JSON session and round documents are the recovery truth. If the
101
- state file exists, it can help you review the full state, but do not assume it is
102
- enabled.
103
-
104
- ## Delegation
105
-
106
- Delegation does not create a separate LoopForge mode. Give each worker a
107
- self-contained subtask and relevant hard constraints. Add the returned result to
108
- `worker_results` so discoveries can enter the next canonical state.
109
-
110
- ## Rules
111
-
112
- 1. Execute the prompt instead of generating another prompt.
113
- 2. Submit one honest structured evaluation after each attempt.
114
- 3. Treat required command evidence and verification errors as authoritative.
115
- 4. Keep one loop focused on one user objective.
116
- 5. Do not advance a paused or stopped session through another process.
117
- 6. Continue within the same Agent task when possible; LoopForge preserves state,
118
- but it does not create a background Agent.
155
+ - `loopforge_status({scope: "session", sessionId})` shows the live round. Add
156
+ `detail: "full"` for cognition projections, prompt diagnostics, metrics and
157
+ audit data.
158
+ - `loopforge_status({scope: "loop", loopId})` reads loop-level health and
159
+ audit. `scope: "all"` lists persisted loop summaries (including stopped
160
+ loops for audit/recovery inspection) and accepts no ID.
161
+ - `loopforge_history({loopId, view: "round", round})` reads one persisted
162
+ round. `view: "timeline"` reads events in `event_sequence` order; use
163
+ `fromSequence`, `toSequence` and `limit` (1-200) for pagination.
164
+ - `loopforge_audit({loopId})` is read-only and reports criteria coverage,
165
+ contradictions, evidence availability, unresolved User Gates, regression
166
+ obligations and `sequenceComplete`.
167
+
168
+ The old names `loopforge_list`, `loopforge_health`, `loopforge_inspect`, and
169
+ `loopforge_replay` are not public tools.
170
+
171
+ ## 7. Pause and resume
172
+
173
+ Call `loopforge_pause` before an intentional interruption. After a client or
174
+ process restart, call `loopforge_resume` with the saved `loopId`; do not start a
175
+ new loop just because the in-memory session disappeared. Compare the returned
176
+ `stateHash` and `promptHash`, then execute the rebuilt prompt. A loop can be
177
+ resumed only from its persisted vault state.
178
+
179
+ ## 8. Prompt levels and projections
180
+
181
+ - **L0**: compact same-round retry with the rejection gap.
182
+ - **L1**: normal continuation with current focus and required evidence.
183
+ - **L2**: full rehydration after the first round, a phase boundary, goal or
184
+ constraint change, stale or contradictory evidence, drift, recovery, or
185
+ repeated low-information rounds.
186
+
187
+ L0/L1/L2 control state density, not reasoning strategy. The prompt compiler
188
+ reads canonical Goal, RoundEvent, EvidenceEnvelope, Constraint, SubGoal and
189
+ GateDecision facts, then derives Phase, Focus, Todo, Handoff, progress and
190
+ diagnostics. Mandatory objective, focus, gate, hard constraints and required
191
+ fixes remain present under a prompt budget.
192
+
193
+ ## 9. Workspace and command safety
194
+
195
+ When LoopForge requests verification, run commands in the bound workspace only.
196
+ Use executable plus argument arrays, `shell: false`, timeouts, output limits and
197
+ path-boundary checks. Do not concatenate user-controlled strings into shell
198
+ commands. This is LoopForge's evidence boundary; it does not grant or revoke
199
+ the Agent's ordinary tool permissions.
200
+
201
+ ## 10. Long-horizon habits
202
+
203
+ Keep one loop focused on one user objective. Submit one honest report per
204
+ round, preserve criterion and constraint IDs, and include a concrete next
205
+ verification when continuing. Inspect the full state on L2 rounds. Use pause
206
+ before handoff and audit before claiming final completion. LoopForge supports
207
+ long runs through explicit rounds and durable replay, but it does not execute
208
+ rounds in the background for you.
209
+
210
+ ## 11. Reliability rules
211
+
212
+ An invalid report is an input error, not a round fact. The runtime leaves the
213
+ current `roundId`, attempt, state and vault unchanged and returns
214
+ `invalid_round_report`; submit a corrected report instead of starting a new
215
+ loop. A persistence error is not recoverable by pretending success: stop and
216
+ retry the operation after the storage boundary is healthy.
217
+
218
+ Evidence capture and recovery are asynchronous. `maxRounds` must be a positive
219
+ integer no greater than the configured policy limit. Corrupt JSON, an invalid
220
+ event format, or a sequence gap returns `storage_corruption`; the runtime never
221
+ sorts, fills, or rewrites damaged history. Terminal enforcement rules track
222
+ their escalation retry independently; the same rule terminates only after its
223
+ guided retry has already been used.
224
+
225
+ When intent drift is reported, use `driftClarification` with a concrete
226
+ explanation and an anchor that exists in the current criteria, constraints or
227
+ observed workspace evidence. Do not send `clarification_accepted: true`.
228
+ Runtime verification owns the clarification streak and any escalation.
@@ -1,39 +0,0 @@
1
- /** @deprecated Use LoopStore from loop-store.js directly.
2
- *
3
- * Kept for backward compatibility with modules that still reference
4
- * VaultBackend as a parameter type. New code should depend on LoopStore. */
5
- export interface VaultEntry {
6
- id?: string;
7
- task_id?: string;
8
- version_tag?: string;
9
- is_active?: boolean;
10
- timestamp?: string;
11
- user_intent?: string;
12
- task_type?: string;
13
- /** @deprecated Use `success` field instead. Kept for reading old vault data. */
14
- quality_score?: number;
15
- success?: boolean;
16
- skill_used?: string;
17
- loop_id?: string;
18
- loop_lineage?: Record<string, unknown>;
19
- loop_objective?: Record<string, unknown> | null;
20
- execution_feedback?: string;
21
- task?: string;
22
- output_summary?: string;
23
- constraint_violations?: string[];
24
- tags?: string[];
25
- full_prompt?: string;
26
- [key: string]: unknown;
27
- }
28
- export interface VaultBackend {
29
- /** Optional atomic critical section used by storage adapters. */
30
- withLock?<T>(fn: () => T): T;
31
- queryEntries(opts?: {
32
- prefix?: string;
33
- taskIdPattern?: string;
34
- feedbackOnly?: boolean;
35
- }): VaultEntry[];
36
- appendEntry(entry: VaultEntry): void;
37
- appendEntries(entries: VaultEntry[]): number;
38
- }
39
- //# sourceMappingURL=interface.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/backends/interface.ts"],"names":[],"mappings":"AAAA;;;6EAG6E;AAE7E,MAAM,WAAW,UAAU;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAG7B,YAAY,CAAC,IAAI,CAAC,EAAE;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,GAAG,UAAU,EAAE,CAAC;IAEjB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACrC,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;CAE9C"}
@@ -1,6 +0,0 @@
1
- /** @deprecated Use LoopStore from loop-store.js directly.
2
- *
3
- * Kept for backward compatibility with modules that still reference
4
- * VaultBackend as a parameter type. New code should depend on LoopStore. */
5
- export {};
6
- //# sourceMappingURL=interface.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/backends/interface.ts"],"names":[],"mappings":"AAAA;;;6EAG6E"}
@@ -1,50 +0,0 @@
1
- /** Enforcement Gate — Layer 2 round-boundary runtime enforcement (v1.13).
2
- *
3
- * Pure-function module. Receives the verification gate's findings plus
4
- * round-level context and decides whether to accept the round, reject it
5
- * (force the agent to redo), or terminate the loop.
6
- *
7
- * This is the "runtime" that prompt-only constraint systems lack.
8
- * Verification gate detects WHAT is wrong; enforcement gate decides
9
- * what to DO about it.
10
- *
11
- * Decision semantics:
12
- * - accept: round passes all checks; advance to next round as normal.
13
- * - reject: agent's self-evaluation or round output is invalid; the
14
- * agent receives a rejection prompt and must redo the SAME
15
- * round. Round counter does NOT increment.
16
- * - terminate: loop has reached an unrecoverable state; stop immediately
17
- * with stopReason "enforcement_terminated".
18
- */
19
- import type { VaultEntry } from "./backends/interface.js";
20
- import type { EnforcementResult, SelfEvaluation, VerificationFlag, VerificationResult } from "./protocol.js";
21
- /** Enforce round-boundary rules based on the verification gate's findings
22
- * and the agent's self-evaluation integrity.
23
- *
24
- * Rules run in priority order (R1 → R5). The first rule that fires wins.
25
- *
26
- * @param selfEval The agent's self-evaluation for the current round.
27
- * @param verifyResult The verification gate's output (from verifySelfEvaluation).
28
- * @param currentRound Current round number (1-based, BEFORE increment).
29
- * @param vaultEntries Vault entries for this loop (used for progress tracking).
30
- * @param consecutiveRejections How many consecutive rounds have already been rejected.
31
- * Starts at 0; increments on each reject; resets on accept.
32
- */
33
- export declare function enforceRound(selfEval: SelfEvaluation, verifyResult: VerificationResult, currentRound: number, vaultEntries: VaultEntry[], consecutiveRejections?: number, skipEvidenceRules?: boolean): EnforcementResult;
34
- /** Build a rejection prompt for the agent.
35
- *
36
- * The prompt clearly states the round was rejected, why, what the agent
37
- * must fix, and that the agent must redo the SAME round (not advance).
38
- *
39
- * v2.7: Accepts verificationFlags to render a diagnostic "Evidence Gap"
40
- * section. Each error/warn flag becomes a concrete claim-vs-evidence
41
- * mismatch statement so the agent knows exactly what to correct rather
42
- * than retrying blindly.
43
- *
44
- * @param currentRound The round number that was rejected (NOT incremented).
45
- * @param task The original loop task description.
46
- * @param enforceResult The enforcement decision with reason and fix instructions.
47
- * @param verificationFlags The verification gate's findings for this round.
48
- * Used to build the Evidence Gap section. */
49
- export declare function buildRejectionPrompt(currentRound: number, task: string, enforceResult: EnforcementResult, verificationFlags?: VerificationFlag[]): string;
50
- //# sourceMappingURL=enforcement-gate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"enforcement-gate.d.ts","sourceRoot":"","sources":["../src/enforcement-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,eAAe,CAAC;AAmevB;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,cAAc,EACxB,YAAY,EAAE,kBAAkB,EAChC,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,UAAU,EAAE,EAC1B,qBAAqB,GAAE,MAAU,EACjC,iBAAiB,UAAQ,GACxB,iBAAiB,CA0BnB;AAED;;;;;;;;;;;;;;sEAcsE;AACtE,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,iBAAiB,EAChC,iBAAiB,GAAE,gBAAgB,EAAO,GACzC,MAAM,CA6CR"}