loopforge 1.12.0 → 2.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.
- package/README.md +172 -95
- package/dist/backends/interface.d.ts +3 -9
- package/dist/backends/interface.d.ts.map +1 -1
- package/dist/backends/interface.js +1 -5
- package/dist/backends/interface.js.map +1 -1
- package/dist/canonical-state.d.ts +53 -0
- package/dist/canonical-state.d.ts.map +1 -0
- package/dist/canonical-state.js +161 -0
- package/dist/canonical-state.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +227 -0
- package/dist/cli.js.map +1 -0
- package/dist/enforcement-gate.d.ts +44 -0
- package/dist/enforcement-gate.d.ts.map +1 -0
- package/dist/enforcement-gate.js +271 -0
- package/dist/enforcement-gate.js.map +1 -0
- package/dist/engine.d.ts +17 -7
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +158 -249
- package/dist/engine.js.map +1 -1
- package/dist/evidence-provider.d.ts +113 -0
- package/dist/evidence-provider.d.ts.map +1 -0
- package/dist/evidence-provider.js +419 -0
- package/dist/evidence-provider.js.map +1 -0
- package/dist/index.d.ts +19 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -10
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +15 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +49 -0
- package/dist/init.js.map +1 -0
- package/dist/interop.d.ts +30 -0
- package/dist/interop.d.ts.map +1 -0
- package/dist/interop.js +29 -0
- package/dist/interop.js.map +1 -0
- package/dist/loop-compiler.d.ts +14 -64
- package/dist/loop-compiler.d.ts.map +1 -1
- package/dist/loop-compiler.js +307 -2001
- package/dist/loop-compiler.js.map +1 -1
- package/dist/loop-store.d.ts +82 -0
- package/dist/loop-store.d.ts.map +1 -0
- package/dist/loop-store.js +332 -0
- package/dist/loop-store.js.map +1 -0
- package/dist/mcp/server.d.ts +9 -6
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +109 -73
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/session.d.ts +84 -20
- package/dist/mcp/session.d.ts.map +1 -1
- package/dist/mcp/session.js +718 -316
- package/dist/mcp/session.js.map +1 -1
- package/dist/mcp/tools.d.ts +18 -268
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +225 -12
- package/dist/mcp/tools.js.map +1 -1
- package/dist/observability.d.ts +36 -16
- package/dist/observability.d.ts.map +1 -1
- package/dist/observability.js +82 -23
- package/dist/observability.js.map +1 -1
- package/dist/policy-metrics.d.ts +46 -0
- package/dist/policy-metrics.d.ts.map +1 -0
- package/dist/policy-metrics.js +146 -0
- package/dist/policy-metrics.js.map +1 -0
- package/dist/policy.d.ts +58 -75
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +122 -93
- package/dist/policy.js.map +1 -1
- package/dist/prompt-assembler.d.ts +30 -0
- package/dist/prompt-assembler.d.ts.map +1 -0
- package/dist/prompt-assembler.js +257 -0
- package/dist/prompt-assembler.js.map +1 -0
- package/dist/prompt-policy.d.ts +29 -0
- package/dist/prompt-policy.d.ts.map +1 -0
- package/dist/prompt-policy.js +51 -0
- package/dist/prompt-policy.js.map +1 -0
- package/dist/protocol.d.ts +117 -91
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +40 -36
- package/dist/protocol.js.map +1 -1
- package/dist/replay.d.ts.map +1 -1
- package/dist/replay.js +1 -27
- package/dist/replay.js.map +1 -1
- package/dist/round-coordinator.d.ts +90 -0
- package/dist/round-coordinator.d.ts.map +1 -0
- package/dist/round-coordinator.js +186 -0
- package/dist/round-coordinator.js.map +1 -0
- package/dist/round-driver.d.ts +53 -0
- package/dist/round-driver.d.ts.map +1 -0
- package/dist/round-driver.js +101 -0
- package/dist/round-driver.js.map +1 -0
- package/dist/round-transaction.d.ts +70 -0
- package/dist/round-transaction.d.ts.map +1 -0
- package/dist/round-transaction.js +290 -0
- package/dist/round-transaction.js.map +1 -0
- package/dist/runtime.d.ts +35 -17
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +357 -344
- package/dist/runtime.js.map +1 -1
- package/dist/storage.d.ts +38 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +201 -0
- package/dist/storage.js.map +1 -0
- package/dist/verification-gate.d.ts +39 -7
- package/dist/verification-gate.d.ts.map +1 -1
- package/dist/verification-gate.js +198 -9
- package/dist/verification-gate.js.map +1 -1
- package/loop_policy.json +26 -47
- package/package.json +13 -10
- package/skills/perception/SKILL.md +80 -249
- package/dist/backends/fs.d.ts +0 -36
- package/dist/backends/fs.d.ts.map +0 -1
- package/dist/backends/fs.js +0 -358
- package/dist/backends/fs.js.map +0 -1
- package/dist/builder.d.ts +0 -12
- package/dist/builder.d.ts.map +0 -1
- package/dist/builder.js +0 -259
- package/dist/builder.js.map +0 -1
- package/dist/mcp-server.d.ts +0 -12
- package/dist/mcp-server.d.ts.map +0 -1
- package/dist/mcp-server.js +0 -14
- package/dist/mcp-server.js.map +0 -1
- package/dist/memory-bridge.d.ts +0 -47
- package/dist/memory-bridge.d.ts.map +0 -1
- package/dist/memory-bridge.js +0 -290
- package/dist/memory-bridge.js.map +0 -1
- package/dist/tests/_helpers.d.ts +0 -25
- package/dist/tests/_helpers.d.ts.map +0 -1
- package/dist/tests/_helpers.js +0 -47
- package/dist/tests/_helpers.js.map +0 -1
- package/dist/tests/builder.test.d.ts +0 -2
- package/dist/tests/builder.test.d.ts.map +0 -1
- package/dist/tests/builder.test.js +0 -110
- package/dist/tests/builder.test.js.map +0 -1
- package/dist/tests/engine.test.d.ts +0 -2
- package/dist/tests/engine.test.d.ts.map +0 -1
- package/dist/tests/engine.test.js +0 -371
- package/dist/tests/engine.test.js.map +0 -1
- package/dist/tests/generate-schema.test.d.ts +0 -8
- package/dist/tests/generate-schema.test.d.ts.map +0 -1
- package/dist/tests/generate-schema.test.js +0 -199
- package/dist/tests/generate-schema.test.js.map +0 -1
- package/dist/tests/loop-compiler.test.d.ts +0 -2
- package/dist/tests/loop-compiler.test.d.ts.map +0 -1
- package/dist/tests/loop-compiler.test.js +0 -1051
- package/dist/tests/loop-compiler.test.js.map +0 -1
- package/dist/tests/mcp.test.d.ts +0 -7
- package/dist/tests/mcp.test.d.ts.map +0 -1
- package/dist/tests/mcp.test.js +0 -485
- package/dist/tests/mcp.test.js.map +0 -1
- package/dist/tests/memory-bridge.test.d.ts +0 -8
- package/dist/tests/memory-bridge.test.d.ts.map +0 -1
- package/dist/tests/memory-bridge.test.js +0 -383
- package/dist/tests/memory-bridge.test.js.map +0 -1
- package/dist/tests/policy.test.d.ts +0 -2
- package/dist/tests/policy.test.d.ts.map +0 -1
- package/dist/tests/policy.test.js +0 -49
- package/dist/tests/policy.test.js.map +0 -1
- package/dist/tests/protocol.test.d.ts +0 -2
- package/dist/tests/protocol.test.d.ts.map +0 -1
- package/dist/tests/protocol.test.js +0 -73
- package/dist/tests/protocol.test.js.map +0 -1
- package/dist/tests/replay.test.d.ts +0 -2
- package/dist/tests/replay.test.d.ts.map +0 -1
- package/dist/tests/replay.test.js +0 -222
- package/dist/tests/replay.test.js.map +0 -1
- package/dist/tests/runtime.test.d.ts +0 -7
- package/dist/tests/runtime.test.d.ts.map +0 -1
- package/dist/tests/runtime.test.js +0 -323
- package/dist/tests/runtime.test.js.map +0 -1
- package/dist/tests/verification-gate.test.d.ts +0 -2
- package/dist/tests/verification-gate.test.d.ts.map +0 -1
- package/dist/tests/verification-gate.test.js +0 -407
- package/dist/tests/verification-gate.test.js.map +0 -1
- package/skills/prompt-techniques/SKILL.md +0 -52
- package/skills/prompt-techniques/references/chain-of-thought.md +0 -207
- package/skills/prompt-techniques/references/few-shot.md +0 -174
- package/skills/prompt-techniques/references/least-to-most.md +0 -182
- package/skills/prompt-techniques/references/step-back.md +0 -160
- package/skills/prompt-techniques/references/tree-of-thought.md +0 -191
- package/skills/prompt-techniques/references/zero-shot.md +0 -97
|
@@ -1,287 +1,118 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: perception
|
|
3
|
-
description:
|
|
3
|
+
description: Drive a recoverable multi-round coding task through LoopForge MCP while the Agent remains the execution owner.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Perception
|
|
6
|
+
# Perception
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
detection — maintaining cognitive stability across long-horizon loops.
|
|
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.
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
LoopForge maintains cognitive state. You remain the Agent that reads files,
|
|
13
|
+
edits code, runs commands, delegates work, and decides how to reason.
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
(Coordinator mode), LoopForge tracks delegation history, inherits constraints
|
|
18
|
-
across Workers, and injects structured summaries into subsequent prompts.
|
|
19
|
-
No separate mode required — LoopForge treats all agents the same.
|
|
15
|
+
## Start
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
Call `loopforge_start` with:
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
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.
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
round (e.g. "audit the entire codebase and fix every issue").
|
|
24
|
+
Keep the returned `sessionId`, `roundId`, prompt, and level.
|
|
30
25
|
|
|
31
|
-
##
|
|
26
|
+
## Execute a round
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
│ │
|
|
38
|
-
│ 2. Execute the prompt (read, write, test, fix) │
|
|
39
|
-
│ Prepare a structured self-evaluation │
|
|
40
|
-
│ │
|
|
41
|
-
│ 3. loopforge_next(sessionId, evaluation, output?) │
|
|
42
|
-
│ → if prompt: go to step 2 │
|
|
43
|
-
│ → if prompt=null: loop ended, read stopReason │
|
|
44
|
-
│ │
|
|
45
|
-
│ After restart: loopforge_resume(loopId) │
|
|
46
|
-
│ → picks up from last saved round │
|
|
47
|
-
└──────────────────────────────────────────────────────────┘
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Step-by-step
|
|
51
|
-
|
|
52
|
-
**Step 1 — Start the loop:**
|
|
53
|
-
```
|
|
54
|
-
Call loopforge_start with:
|
|
55
|
-
task: required — the full task description
|
|
56
|
-
maxRounds: optional — default 20 from policy
|
|
57
|
-
constraints: optional — hard constraints as string[]
|
|
58
|
-
domain: optional — domain hint (solidity, react, rust…)
|
|
59
|
-
|
|
60
|
-
Keep the returned sessionId — you will need it for every subsequent call.
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
**Step 2 — Execute the round:**
|
|
64
|
-
Execute the compiled prompt exactly as you would any user task. Read files,
|
|
65
|
-
write code, run tests, fix bugs. The prompt already contains the task scope,
|
|
66
|
-
constraints, and quality expectations for this specific round.
|
|
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`.
|
|
67
32
|
|
|
68
|
-
|
|
69
|
-
`evaluation` parameter to `loopforge_next` — do NOT embed it as a text block
|
|
70
|
-
in the output. The `evaluation` parameter is a typed object with the fields
|
|
71
|
-
described below.
|
|
33
|
+
Minimal evaluation:
|
|
72
34
|
|
|
73
|
-
**New (v1.7+): Pass evaluation as a structured tool parameter.**
|
|
74
35
|
```json
|
|
75
36
|
{
|
|
76
|
-
"success":
|
|
77
|
-
"output_summary": "
|
|
37
|
+
"success": false,
|
|
38
|
+
"output_summary": "Implemented the parser and added 8 passing tests.",
|
|
78
39
|
"constraint_violations": [],
|
|
79
|
-
"should_continue": true
|
|
80
|
-
"discovered_constraints": [],
|
|
81
|
-
"objective_refinement": "",
|
|
82
|
-
"emerged_subtasks": [],
|
|
83
|
-
"execution_evidence": {
|
|
84
|
-
"files_changed": ["contracts/Token.sol", "test/Token.test.ts"],
|
|
85
|
-
"test_results": {"passed": 24, "failed": 0, "skipped": 0},
|
|
86
|
-
"success_criteria_met": ["No reentrancy vectors remain"],
|
|
87
|
-
"success_criteria_remaining": ["Access control verified", "Overflow checks complete"],
|
|
88
|
-
"progress_estimate": 0.4
|
|
89
|
-
},
|
|
90
|
-
"retracted_constraints": [],
|
|
91
|
-
"revised_success_criteria": [],
|
|
92
|
-
"wrong_assumptions": []
|
|
40
|
+
"should_continue": true
|
|
93
41
|
}
|
|
94
42
|
```
|
|
95
43
|
|
|
96
|
-
|
|
97
|
-
when the agent cannot pass structured tool parameters. The new parameter form
|
|
98
|
-
is preferred — it's validated by the MCP client before reaching the server.
|
|
44
|
+
Important fields:
|
|
99
45
|
|
|
100
|
-
|
|
46
|
+
| Field | Rule |
|
|
47
|
+
| --- | --- |
|
|
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. |
|
|
101
57
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
| `success` | boolean | `true` ONLY if all hard constraints met AND the task goal achieved |
|
|
105
|
-
| `output_summary` | string | Specific, actionable. What was DONE this round — not what was attempted |
|
|
106
|
-
| `constraint_violations` | string[] | Constraints the agent actually violated this round. Be honest — hiding violations corrupts the success signal and defeats the circuit breaker |
|
|
107
|
-
| `should_continue` | boolean | `false` ONLY when the ENTIRE task is complete. Partial progress = `true` |
|
|
108
|
-
| `discovered_constraints` | string[] | **P0 (optional)** — New constraints discovered this round. They become active guardrails for future rounds. Example: `["All external calls must use SafeERC20"]`. Empty `[]` if none. |
|
|
109
|
-
| `objective_refinement` | string | **P1 (optional)** — If this round deepened your understanding of what the task is really about, describe the refinement. APPENDED to (never replaces) the original objective. Empty `""` if unchanged. |
|
|
110
|
-
| `emerged_subtasks` | string[] | **P2 (optional)** — Sub-problems that surfaced during execution and need separate attention. Feed into next-round task suggestions. Example: `["Audit upgrade proxy", "Verify timelock"]`. Empty `[]` if none. |
|
|
111
|
-
| `execution_evidence` | object | **P4 (recommended)** — Structured record of what actually happened. `files_changed` (string[]), `test_results` ({passed, failed, skipped} | null), `success_criteria_met` (string[]), `success_criteria_remaining` (string[]), `progress_estimate` (0.0–1.0). Use this to give LoopForge real visibility into your progress. |
|
|
112
|
-
| `retracted_constraints` | string[] | **P5 (optional)** — Constraints you now believe are wrong. Removed from active guardrails. Only retract with evidence. Empty `[]` if none. |
|
|
113
|
-
| `revised_success_criteria` | object[] | **P5 (optional)** — Success criteria that need reformulation. Array of `{old: string, new: string}`. Applied to Loop Objective. Empty `[]` if none. |
|
|
114
|
-
| `wrong_assumptions` | string[] | **P5 (optional)** — Assumptions from earlier rounds that turned out to be incorrect. Recorded as key lessons. Empty `[]` if none. |
|
|
115
|
-
| `worker_results` | object[] | **Multi-Agent (optional)** — Results of sub-agent / Worker delegations this round. Each entry: `{ agentId, subAgentType, subTask, resultSummary, success, discoveredConstraints? }`. Engine auto-records to delegation journal. Empty `[]` if no delegations. |
|
|
58
|
+
Do not embed an evaluation marker in ordinary output when the MCP client accepts
|
|
59
|
+
the structured `evaluation` argument.
|
|
116
60
|
|
|
117
|
-
|
|
118
|
-
reaching the server — a missing or malformed evaluation causes an immediate
|
|
119
|
-
error, not a silent stall. The circuit breaker uses `success` + `violations`
|
|
120
|
-
to determine loop trajectory — lying here defeats the only mechanism that
|
|
121
|
-
prevents infinite loops. The optional fields (P0–P5) enable cognitive
|
|
122
|
-
evolution: discovering constraints, deepening understanding, surfacing
|
|
123
|
-
sub-problems, tracking real progress, and correcting wrong assumptions as
|
|
124
|
-
the loop executes.
|
|
61
|
+
## Interpret the result
|
|
125
62
|
|
|
126
|
-
|
|
127
|
-
```
|
|
128
|
-
Call loopforge_next with:
|
|
129
|
-
sessionId: from loopforge_start
|
|
130
|
-
evaluation: REQUIRED — structured self-evaluation object (see field table below)
|
|
131
|
-
output: OPTIONAL — raw output text for audit trail (can be omitted)
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
If the result has `prompt: null`, the loop has ended. Read `stopReason`:
|
|
135
|
-
- `task_complete` — you reported should_continue=false. Work is done.
|
|
136
|
-
- `circuit_breaker` — 3 consecutive failed rounds. Review your approach.
|
|
137
|
-
- `max_rounds` — hit the round limit. Decide whether to extend or accept.
|
|
138
|
-
- `stalled` — no valid self-evaluation provided. Check your evaluation parameter.
|
|
139
|
-
|
|
140
|
-
If the result has a non-null `prompt`, execute it and repeat from Step 2.
|
|
63
|
+
If `prompt` is non-null, execute it and submit the next evaluation.
|
|
141
64
|
|
|
142
|
-
|
|
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.
|
|
143
68
|
|
|
144
|
-
|
|
145
|
-
|------|-------------|-----------|------------|
|
|
146
|
-
| `loopforge_start` | Beginning of every loop | `task`, `maxRounds?`, `constraints?` | `sessionId`, round 1 `prompt` |
|
|
147
|
-
| `loopforge_next` | After executing every round | `sessionId`, `output` (with eval block) | next `prompt` or `null` + `stopReason` |
|
|
148
|
-
| `loopforge_status` | Mid-loop checkpoint, user asks "how's it going" | `sessionId` | `round`, `successTrajectory`, `status`, `technique` |
|
|
149
|
-
| `loopforge_stop` | User wants to abort, fatal error | `sessionId` | `roundsCompleted`, final trajectory |
|
|
150
|
-
| `loopforge_list` | User asks "what loops are running" | — | `sessions[]` (includes vault-persisted) |
|
|
151
|
-
| `loopforge_replay` | After loop ends, user asks "show me what happened" | `sessionId` | `timeline[]` with all rounds |
|
|
152
|
-
| `loopforge_resume` | Resume a loop after process restart | `loopId` | next `prompt` or `null` + `stopReason` |
|
|
153
|
-
| `loopforge_health` | Check loop health mid-run | `loopId` | goal alignment, constraint integrity, drift, strategy |
|
|
69
|
+
If `prompt` is null, inspect `stopReason`:
|
|
154
70
|
|
|
155
|
-
|
|
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. |
|
|
156
79
|
|
|
157
|
-
|
|
158
|
-
during a loop round, use these helpers to improve delegation quality:
|
|
80
|
+
## Prompt levels
|
|
159
81
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
have a license header." Use `filterConstraintsForSubTask(allConstraints, subTask)`
|
|
164
|
-
to get only the relevant subset.
|
|
165
|
-
2. **Format the prompt** — use `formatDelegationPrompt(subTask, subAgentType,
|
|
166
|
-
relevantConstraints, options?)` to produce a self-contained prompt. This is
|
|
167
|
-
critical: sub-agents cannot see your conversation. Every prompt must stand
|
|
168
|
-
alone — no "based on above," no "continue from previous."
|
|
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.
|
|
169
85
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
The engine auto-detects this field and writes delegation journals to the vault:
|
|
86
|
+
These levels control state density only. LoopForge does not choose a reasoning
|
|
87
|
+
technique for you.
|
|
173
88
|
|
|
174
|
-
|
|
175
|
-
{
|
|
176
|
-
"worker_results": [
|
|
177
|
-
{
|
|
178
|
-
"agentId": "abc123",
|
|
179
|
-
"subAgentType": "explore",
|
|
180
|
-
"subTask": "Search for deprecated API usage in src/",
|
|
181
|
-
"resultSummary": "Found 12 deprecated calls across 8 files",
|
|
182
|
-
"success": true,
|
|
183
|
-
"discoveredConstraints": ["All API calls must be versioned"]
|
|
184
|
-
}
|
|
185
|
-
]
|
|
186
|
-
}
|
|
187
|
-
```
|
|
89
|
+
## Recovery and control
|
|
188
90
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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.
|
|
194
98
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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.
|
|
199
103
|
|
|
200
|
-
##
|
|
104
|
+
## Delegation
|
|
201
105
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
`l2` (full recompile, significant change). L2 means the compiler detected a
|
|
206
|
-
major shift — read the prompt carefully.
|
|
207
|
-
- **Warnings** — constraint violations accumulating, task drift, quality
|
|
208
|
-
decline. These are the compiler begging you to course-correct.
|
|
209
|
-
- **Technique escalation** — the compiler may escalate from Tier 1 to
|
|
210
|
-
Tier 2 (step-back/least-to-most/ToT) after consecutive failures. Trust
|
|
211
|
-
the new technique — it's chosen for structured reasoning depth.
|
|
212
|
-
|
|
213
|
-
## Stop Condition Matrix
|
|
214
|
-
|
|
215
|
-
| Condition | stopReason | What to do |
|
|
216
|
-
|-----------|-----------|------------|
|
|
217
|
-
| You set `should_continue: false` | `task_complete` | Report final results to user |
|
|
218
|
-
| 3 consecutive failed rounds | `circuit_breaker` | Tell user the approach is stuck, suggest a different strategy |
|
|
219
|
-
| Round count reached `maxRounds` | `max_rounds` | Summarize progress, ask user whether to extend |
|
|
220
|
-
| No `---loopforge-eval` block found | `stalled` | Fix your output format and restart |
|
|
221
|
-
| User interrupts or fatal error | (call `loopforge_stop`) | Clean stop with trajectory preserved |
|
|
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.
|
|
222
109
|
|
|
223
110
|
## Rules
|
|
224
111
|
|
|
225
|
-
1.
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
narrow scope between rounds. Trust it — it sees the trajectory.
|
|
233
|
-
5. **Call loopforge_next within the same turn.** Don't leave a round hanging
|
|
234
|
-
across conversation turns. The MCP server is in-memory.
|
|
235
|
-
6. **After process restart, use loopforge_resume.** The session state is saved
|
|
236
|
-
to vault every round. Call `loopforge_resume` with the original `loopId` to
|
|
237
|
-
pick up where you left off — no need to restart from round 1.
|
|
238
|
-
|
|
239
|
-
## Example
|
|
240
|
-
|
|
241
|
-
```
|
|
242
|
-
User: /perception "Audit the ERC20 token in contracts/Token.sol for security issues"
|
|
243
|
-
|
|
244
|
-
Agent:
|
|
245
|
-
→ loopforge_start({ task: "Audit ERC20 token in contracts/Token.sol for security issues",
|
|
246
|
-
domain: "solidity",
|
|
247
|
-
constraints: ["must not break existing tests", "follow check-effects-interactions"] })
|
|
248
|
-
← { sessionId: "abc-123", round: 1, prompt: "## LoopForge Loop Compile — Round 1\n...", level: "l2" }
|
|
249
|
-
|
|
250
|
-
[Executes prompt: reads Token.sol, identifies 4 issues, discovers a new constraint]
|
|
251
|
-
|
|
252
|
-
→ loopforge_next({ sessionId: "abc-123",
|
|
253
|
-
evaluation: {
|
|
254
|
-
success: false,
|
|
255
|
-
output_summary: "Found 4 potential issues: 2 reentrancy, 1 overflow, 1 access control. Not yet fixed.",
|
|
256
|
-
constraint_violations: [],
|
|
257
|
-
should_continue: true,
|
|
258
|
-
discovered_constraints: ["All _mint() calls must emit Transfer event per ERC20 spec"]
|
|
259
|
-
} })
|
|
260
|
-
← { sessionId: "abc-123", round: 2, prompt: "## LoopForge Loop Compile — Round 2\n...", level: "l1" }
|
|
261
|
-
|
|
262
|
-
[Executes prompt: fixes 3 issues, deepens understanding of access control problem]
|
|
263
|
-
|
|
264
|
-
→ loopforge_next({ sessionId: "abc-123",
|
|
265
|
-
evaluation: {
|
|
266
|
-
success: false,
|
|
267
|
-
output_summary: "Fixed reentrancy in withdraw() and overflow in calcReward(). Access control in setOwner() needs design discussion — discovered it's part of a larger upgradeability concern.",
|
|
268
|
-
constraint_violations: [],
|
|
269
|
-
should_continue: true,
|
|
270
|
-
objective_refinement: "Access control audit scope expanded: setOwner() is unprotected because the contract follows an upgradeable proxy pattern where owner is set via initializer — need to verify the initializer guard and proxy admin separately",
|
|
271
|
-
emerged_subtasks: ["Audit upgrade proxy initialization flow", "Verify proxy admin is not renounced without recovery path"]
|
|
272
|
-
} })
|
|
273
|
-
← { sessionId: "abc-123", round: 3, prompt: "## LoopForge Loop Compile — Round 3\n Suggested Next Task: Audit upgrade proxy initialization flow; Verify proxy admin is not renounced without recovery path\n...", level: "l0" }
|
|
274
|
-
|
|
275
|
-
[Executes prompt: audits proxy pattern, documents findings, all fixes pass tests]
|
|
276
|
-
|
|
277
|
-
→ loopforge_next({ sessionId: "abc-123",
|
|
278
|
-
evaluation: {
|
|
279
|
-
success: true,
|
|
280
|
-
output_summary: "All fixable issues resolved. Proxy initialization verified — initializer modifier prevents double-init. Proxy admin held by multisig — low risk. 24/24 tests pass.",
|
|
281
|
-
constraint_violations: [],
|
|
282
|
-
should_continue: false
|
|
283
|
-
} })
|
|
284
|
-
← { sessionId: "abc-123", round: 3, prompt: null, stopReason: "task_complete", roundSuccess: true }
|
|
285
|
-
|
|
286
|
-
Reports to user: "Audit complete in 3 rounds. 3 issues fixed, 1 design question flagged. Discovered 1 new constraint during audit. Objective deepened to include proxy pattern verification."
|
|
287
|
-
```
|
|
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.
|
package/dist/backends/fs.d.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/** FSBackend — filesystem implementation of VaultBackend.
|
|
2
|
-
*
|
|
3
|
-
* Wraps Node.js fs for JSON vault read/write and Markdown lineage I/O.
|
|
4
|
-
* All file I/O is contained in this single module — engine.ts never
|
|
5
|
-
* touches the filesystem directly.
|
|
6
|
-
*/
|
|
7
|
-
import type { VaultBackend, VaultEntry } from "./interface.js";
|
|
8
|
-
export declare function readLineageMd(loopId: string, roundNum: number, vaultPath?: string): {
|
|
9
|
-
full_prompt: string;
|
|
10
|
-
metadata: Record<string, unknown>;
|
|
11
|
-
} | null;
|
|
12
|
-
export declare function writeLineageMd(loopId: string, roundNum: number, content: string, metadata: Record<string, unknown>, vaultPath?: string): string | null;
|
|
13
|
-
export declare function scanLineageMd(loopId: string, vaultPath?: string): VaultEntry[];
|
|
14
|
-
export declare class FSBackend implements VaultBackend {
|
|
15
|
-
private readonly vaultPath;
|
|
16
|
-
private readonly globalVaultPath;
|
|
17
|
-
/** Re-entrant lock depth — >0 means this process holds the lock. */
|
|
18
|
-
private lockDepth;
|
|
19
|
-
constructor(vaultPath?: string, globalVaultPath?: string);
|
|
20
|
-
/** File-system mutex via mkdir (atomic on POSIX and Windows).
|
|
21
|
-
* Re-entrant: nested calls from the same process bypass the lock. */
|
|
22
|
-
withLock<T>(fn: () => T): T;
|
|
23
|
-
readVault(): Record<string, unknown>;
|
|
24
|
-
writeVault(data: Record<string, unknown>): void;
|
|
25
|
-
queryEntries(opts?: {
|
|
26
|
-
prefix?: string;
|
|
27
|
-
taskIdPattern?: string;
|
|
28
|
-
feedbackOnly?: boolean;
|
|
29
|
-
}): VaultEntry[];
|
|
30
|
-
appendEntry(entry: VaultEntry): void;
|
|
31
|
-
appendEntries(entries: VaultEntry[]): number;
|
|
32
|
-
writeLineageMd(loopId: string, roundNum: number, content: string, metadata: Record<string, unknown>): string | null;
|
|
33
|
-
readLineageMd(loopId: string, roundNum: number): string | null;
|
|
34
|
-
scanLineageMd(loopId: string): VaultEntry[];
|
|
35
|
-
}
|
|
36
|
-
//# sourceMappingURL=fs.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/backends/fs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAsJ/D,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,CAkBnE;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAef;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,UAAU,EAAE,CAoDd;AAMD,qBAAa,SAAU,YAAW,YAAY;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,oEAAoE;IACpE,OAAO,CAAC,SAAS,CAAK;gBAGpB,SAAS,SAAmC,EAC5C,eAAe,SAAqC;IAMtD;0EACsE;IACtE,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IA0C3B,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAUpC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAU/C,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;IA+BhB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAUpC,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM;IAa5C,cAAc,CACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,MAAM,GAAG,IAAI;IAIhB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAK9D,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;CAG5C"}
|