loopforge 1.8.0 → 1.15.1
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/dist/backends/fs.d.ts.map +1 -1
- package/dist/backends/fs.js +13 -10
- package/dist/backends/fs.js.map +1 -1
- package/dist/backends/interface.d.ts +2 -0
- package/dist/backends/interface.d.ts.map +1 -1
- package/dist/builder.d.ts +13 -10
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +117 -96
- package/dist/builder.js.map +1 -1
- package/dist/enforcement-gate.d.ts +44 -0
- package/dist/enforcement-gate.d.ts.map +1 -0
- package/dist/enforcement-gate.js +253 -0
- package/dist/enforcement-gate.js.map +1 -0
- package/dist/engine.d.ts +13 -6
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +127 -171
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/loop-compiler.d.ts +10 -2
- package/dist/loop-compiler.d.ts.map +1 -1
- package/dist/loop-compiler.js +882 -583
- package/dist/loop-compiler.js.map +1 -1
- package/dist/mcp/session.d.ts +12 -2
- package/dist/mcp/session.d.ts.map +1 -1
- package/dist/mcp/session.js +127 -64
- package/dist/mcp/session.js.map +1 -1
- package/dist/mcp/tools.js +4 -4
- package/dist/memory-bridge.js +1 -1
- package/dist/memory-bridge.js.map +1 -1
- package/dist/observability.d.ts +1 -1
- package/dist/observability.js +1 -1
- package/dist/policy.d.ts +80 -10
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +101 -30
- package/dist/policy.js.map +1 -1
- package/dist/protocol.d.ts +70 -16
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +40 -8
- package/dist/protocol.js.map +1 -1
- package/dist/replay.js +7 -7
- package/dist/replay.js.map +1 -1
- package/dist/runtime.d.ts +11 -7
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +125 -144
- package/dist/runtime.js.map +1 -1
- package/dist/tests/builder.test.js +42 -28
- package/dist/tests/builder.test.js.map +1 -1
- package/dist/tests/enforcement-gate.test.d.ts +2 -0
- package/dist/tests/enforcement-gate.test.d.ts.map +1 -0
- package/dist/tests/enforcement-gate.test.js +328 -0
- package/dist/tests/enforcement-gate.test.js.map +1 -0
- package/dist/tests/engine.test.js +22 -22
- package/dist/tests/engine.test.js.map +1 -1
- package/dist/tests/generate-schema.test.js +10 -7
- package/dist/tests/generate-schema.test.js.map +1 -1
- package/dist/tests/loop-compiler.test.js +273 -47
- package/dist/tests/loop-compiler.test.js.map +1 -1
- package/dist/tests/mcp.test.js +31 -11
- package/dist/tests/mcp.test.js.map +1 -1
- package/dist/tests/memory-bridge.test.js +0 -1
- package/dist/tests/memory-bridge.test.js.map +1 -1
- package/dist/tests/policy.test.js +6 -16
- package/dist/tests/policy.test.js.map +1 -1
- package/dist/tests/protocol.test.js +3 -2
- package/dist/tests/protocol.test.js.map +1 -1
- package/dist/tests/replay.test.js +9 -9
- package/dist/tests/replay.test.js.map +1 -1
- package/dist/tests/runtime.test.js +27 -13
- package/dist/tests/runtime.test.js.map +1 -1
- package/dist/tests/verification-gate.test.js +1 -1
- package/dist/tests/verification-gate.test.js.map +1 -1
- package/dist/verification-gate.d.ts +8 -2
- package/dist/verification-gate.d.ts.map +1 -1
- package/dist/verification-gate.js +5 -4
- package/dist/verification-gate.js.map +1 -1
- package/loop_policy.json +13 -26
- package/package.json +1 -1
- package/skills/perception/SKILL.md +42 -23
- package/skills/prompt-techniques/SKILL.md +52 -52
- package/skills/prompt-techniques/references/chain-of-thought.md +207 -207
- package/skills/prompt-techniques/references/few-shot.md +174 -174
- package/skills/prompt-techniques/references/least-to-most.md +182 -182
- package/skills/prompt-techniques/references/step-back.md +160 -160
- package/skills/prompt-techniques/references/tree-of-thought.md +191 -191
- package/skills/prompt-techniques/references/zero-shot.md +97 -97
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Tests for technique routing and quality scoring. */
|
|
2
2
|
import { describe, it, beforeEach } from "node:test";
|
|
3
3
|
import assert from "node:assert/strict";
|
|
4
|
-
import { routeTechnique, routeTechniqueAdaptive,
|
|
4
|
+
import { routeTechnique, routeTechniqueAdaptive, } from "../builder.js";
|
|
5
5
|
import { resetPolicy } from "../policy.js";
|
|
6
6
|
describe("Builder — Route Technique", () => {
|
|
7
7
|
beforeEach(() => resetPolicy());
|
|
@@ -44,49 +44,28 @@ describe("Builder — Route Technique", () => {
|
|
|
44
44
|
assert.equal(analysis.technique, "zero-shot");
|
|
45
45
|
});
|
|
46
46
|
});
|
|
47
|
-
describe("Builder —
|
|
48
|
-
it("
|
|
49
|
-
assert.equal(scoreQuality({ success: true, constraint_violations: [], manual_fixes_needed: "" }), 5);
|
|
50
|
-
});
|
|
51
|
-
it("returns 4 for success with manual fixes needed but no violations", () => {
|
|
52
|
-
assert.equal(scoreQuality({ success: true, constraint_violations: [], manual_fixes_needed: "fix formatting" }), 4);
|
|
53
|
-
});
|
|
54
|
-
it("returns 3 for success with constraint violations", () => {
|
|
55
|
-
assert.equal(scoreQuality({ success: true, constraint_violations: ["missing check"] }), 3);
|
|
56
|
-
});
|
|
57
|
-
it("returns 2 for failure with constraint violations", () => {
|
|
58
|
-
assert.equal(scoreQuality({ success: false, constraint_violations: ["XSS vulnerability"] }), 2);
|
|
59
|
-
});
|
|
60
|
-
it("returns 1 for failure with no constraint violations", () => {
|
|
61
|
-
assert.equal(scoreQuality({ success: false, constraint_violations: [] }), 1);
|
|
62
|
-
});
|
|
63
|
-
it("returns 0 for null feedback", () => {
|
|
64
|
-
assert.equal(scoreQuality(null), 0);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
describe("Builder — Adaptive routing", () => {
|
|
68
|
-
it("falls back to keyword heuristic when no vault context", () => {
|
|
69
|
-
// "Audit" + "fix" → continuous + high → few-shot-cot
|
|
47
|
+
describe("Builder — Tier-gated routing", () => {
|
|
48
|
+
it("uses keyword heuristic when no vault context (Tier 1 default)", () => {
|
|
70
49
|
const analysis = routeTechniqueAdaptive("Fix the encryption protocol security audit", null, "");
|
|
71
50
|
assert.equal(analysis.technique, "few-shot-cot");
|
|
72
51
|
assert.equal(analysis.was_rotated, false);
|
|
73
52
|
});
|
|
74
|
-
it("
|
|
53
|
+
it("uses keyword heuristic when no loop_id (Tier 1 default)", () => {
|
|
75
54
|
const analysis = routeTechniqueAdaptive("Fix the encryption protocol security audit", { results: [] }, "");
|
|
76
55
|
assert.equal(analysis.technique, "few-shot-cot");
|
|
77
56
|
assert.equal(analysis.was_rotated, false);
|
|
78
57
|
});
|
|
79
|
-
it("
|
|
58
|
+
it("stays in Tier 1 by default", () => {
|
|
80
59
|
const vaultContext = {
|
|
81
60
|
results: [
|
|
82
61
|
{
|
|
83
62
|
loop_lineage: {
|
|
84
63
|
loop_id: "test-loop",
|
|
85
64
|
round: 1,
|
|
86
|
-
|
|
65
|
+
success: true,
|
|
87
66
|
},
|
|
88
67
|
technique_used: "few-shot-cot",
|
|
89
|
-
|
|
68
|
+
success: true,
|
|
90
69
|
},
|
|
91
70
|
],
|
|
92
71
|
};
|
|
@@ -94,5 +73,40 @@ describe("Builder — Adaptive routing", () => {
|
|
|
94
73
|
assert.equal(analysis.technique, "few-shot-cot");
|
|
95
74
|
assert.equal(analysis.was_rotated, false);
|
|
96
75
|
});
|
|
76
|
+
it("allows Tier 2 on checkpoint boundary", () => {
|
|
77
|
+
// Task triggers step-back keyword → Tier 2, normally downgraded
|
|
78
|
+
// But with isCheckpoint=true, should be allowed
|
|
79
|
+
const analysis = routeTechniqueAdaptive("重构 legacy 系统", null, "", true);
|
|
80
|
+
assert.equal(analysis.technique, "step-back");
|
|
81
|
+
});
|
|
82
|
+
it("downgrades Tier 2 to Tier 1 in normal round", () => {
|
|
83
|
+
// "重构 legacy 系统" triggers step-back (Tier 2), but without checkpoint it downgrades
|
|
84
|
+
const analysis = routeTechniqueAdaptive("重构 legacy 系统");
|
|
85
|
+
// step-back downgrades to few-shot-cot
|
|
86
|
+
assert.ok(["zero-shot", "few-shot", "zero-shot-cot", "few-shot-cot"].includes(analysis.technique));
|
|
87
|
+
});
|
|
88
|
+
// v1.15: Tier escalation removed — Agent freely chooses at L2.
|
|
89
|
+
// Consecutive failures no longer force Tier 2 techniques.
|
|
90
|
+
it("stays in Tier 1 after consecutive failures (v1.15 — escalation removed)", () => {
|
|
91
|
+
const vaultContext = {
|
|
92
|
+
results: [
|
|
93
|
+
{
|
|
94
|
+
loop_lineage: { loop_id: "test-loop", round: 1 },
|
|
95
|
+
success: false,
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
loop_lineage: { loop_id: "test-loop", round: 2 },
|
|
99
|
+
success: false,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
loop_lineage: { loop_id: "test-loop", round: 3 },
|
|
103
|
+
success: false,
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
};
|
|
107
|
+
const analysis = routeTechniqueAdaptive("Fix the encryption protocol security audit", vaultContext, "test-loop");
|
|
108
|
+
// Tier 1 only in normal round (no escalation)
|
|
109
|
+
assert.ok(["zero-shot", "few-shot", "zero-shot-cot", "few-shot-cot"].includes(analysis.technique));
|
|
110
|
+
});
|
|
97
111
|
});
|
|
98
112
|
//# sourceMappingURL=builder.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.test.js","sourceRoot":"","sources":["../../src/tests/builder.test.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EACL,cAAc,EACd,sBAAsB,
|
|
1
|
+
{"version":3,"file":"builder.test.js","sourceRoot":"","sources":["../../src/tests/builder.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enforcement-gate.test.d.ts","sourceRoot":"","sources":["../../src/tests/enforcement-gate.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/** Tests for enforcement-gate — Layer 2 round-boundary runtime enforcement. */
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import assert from "node:assert/strict";
|
|
4
|
+
import { makeEnforcementResult, makeExecutionEvidence, makeSelfEvaluation, makeVerificationFlag, makeVerificationResult, } from "../protocol.js";
|
|
5
|
+
import { enforceRound, buildRejectionPrompt } from "../enforcement-gate.js";
|
|
6
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
7
|
+
// Helpers
|
|
8
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
9
|
+
/** Build a minimal SelfEvaluation for testing. */
|
|
10
|
+
function se(overrides = {}) {
|
|
11
|
+
return makeSelfEvaluation({
|
|
12
|
+
success: true,
|
|
13
|
+
output_summary: "Task completed.",
|
|
14
|
+
constraint_violations: [],
|
|
15
|
+
should_continue: true,
|
|
16
|
+
...overrides,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/** Build a trusted VerificationResult with no flags. */
|
|
20
|
+
function trusted() {
|
|
21
|
+
return makeVerificationResult({ verdict: "trusted", flags: [] });
|
|
22
|
+
}
|
|
23
|
+
/** Build a VerificationResult with a "success_with_remaining_criteria" error flag. */
|
|
24
|
+
function contradictedSuccessWithRemaining(criteria) {
|
|
25
|
+
return makeVerificationResult({
|
|
26
|
+
verdict: "contradicted",
|
|
27
|
+
flags: [
|
|
28
|
+
makeVerificationFlag({
|
|
29
|
+
severity: "error",
|
|
30
|
+
field: "success",
|
|
31
|
+
check: "success_with_remaining_criteria",
|
|
32
|
+
detail: `Agent claims success but ${criteria.length} criteria remain unmet: ${criteria.join("; ")}`,
|
|
33
|
+
}),
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/** Build a VerificationResult with a "recurring_violation" error flag. */
|
|
38
|
+
function contradictedRecurringViolation(violation) {
|
|
39
|
+
return makeVerificationResult({
|
|
40
|
+
verdict: "contradicted",
|
|
41
|
+
flags: [
|
|
42
|
+
makeVerificationFlag({
|
|
43
|
+
severity: "error",
|
|
44
|
+
field: "constraint_violations",
|
|
45
|
+
check: "recurring_violation",
|
|
46
|
+
detail: `Constraint violation "${violation}" has appeared in 3 consecutive rounds without resolution`,
|
|
47
|
+
}),
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** Build a vault entry with round and optional progress data. */
|
|
52
|
+
function vaultRound(round, progressEstimate) {
|
|
53
|
+
const entry = {
|
|
54
|
+
task_id: `loop:test-loop:r${round}`,
|
|
55
|
+
loop_id: "test-loop",
|
|
56
|
+
loop_lineage: { round, success: true, task: "test task" },
|
|
57
|
+
};
|
|
58
|
+
if (typeof progressEstimate === "number") {
|
|
59
|
+
entry.execution_evidence = {
|
|
60
|
+
files_changed: ["src/foo.ts"],
|
|
61
|
+
test_results: { passed: 1, failed: 0, skipped: 0 },
|
|
62
|
+
success_criteria_met: [],
|
|
63
|
+
success_criteria_remaining: [],
|
|
64
|
+
progress_estimate: progressEstimate,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return entry;
|
|
68
|
+
}
|
|
69
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
70
|
+
// Happy path — trusted verdict, no issues
|
|
71
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
72
|
+
describe("enforcement-gate — happy path", () => {
|
|
73
|
+
it("accepts a round with trusted verdict and clean self-eval", () => {
|
|
74
|
+
const curr = se({
|
|
75
|
+
success: false,
|
|
76
|
+
execution_evidence: makeExecutionEvidence({
|
|
77
|
+
files_changed: ["src/foo.ts"],
|
|
78
|
+
test_results: { passed: 3, failed: 1, skipped: 0 },
|
|
79
|
+
progress_estimate: 0.5,
|
|
80
|
+
}),
|
|
81
|
+
});
|
|
82
|
+
const result = enforceRound(curr, trusted(), 2, [], 0);
|
|
83
|
+
assert.equal(result.action, "accept");
|
|
84
|
+
assert.equal(result.reason, "");
|
|
85
|
+
});
|
|
86
|
+
it("accepts a round with suspect verdict (warn only, not error)", () => {
|
|
87
|
+
const curr = se({
|
|
88
|
+
success: false,
|
|
89
|
+
execution_evidence: makeExecutionEvidence({
|
|
90
|
+
files_changed: ["src/bar.ts"],
|
|
91
|
+
test_results: { passed: 5, failed: 0, skipped: 0 },
|
|
92
|
+
progress_estimate: 0.3,
|
|
93
|
+
}),
|
|
94
|
+
});
|
|
95
|
+
const suspect = makeVerificationResult({
|
|
96
|
+
verdict: "suspect",
|
|
97
|
+
flags: [
|
|
98
|
+
makeVerificationFlag({
|
|
99
|
+
severity: "warn",
|
|
100
|
+
field: "progress_estimate",
|
|
101
|
+
check: "progress_regression",
|
|
102
|
+
detail: "Progress dropped from 0.5 to 0.3",
|
|
103
|
+
}),
|
|
104
|
+
],
|
|
105
|
+
});
|
|
106
|
+
const result = enforceRound(curr, suspect, 2, [], 0);
|
|
107
|
+
assert.equal(result.action, "accept");
|
|
108
|
+
});
|
|
109
|
+
it("accepts round 1 with no prior vault data", () => {
|
|
110
|
+
const curr = se({ success: false });
|
|
111
|
+
const result = enforceRound(curr, trusted(), 1, [], 0);
|
|
112
|
+
assert.equal(result.action, "accept");
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
116
|
+
// R1: success=true with remaining criteria
|
|
117
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
118
|
+
describe("enforcement-gate — R1: fake success", () => {
|
|
119
|
+
it("rejects when agent claims success but criteria remain unmet", () => {
|
|
120
|
+
const curr = se({
|
|
121
|
+
success: true,
|
|
122
|
+
execution_evidence: makeExecutionEvidence({
|
|
123
|
+
files_changed: ["src/foo.ts"],
|
|
124
|
+
success_criteria_met: ["criteria-1"],
|
|
125
|
+
success_criteria_remaining: ["criteria-2", "criteria-3"],
|
|
126
|
+
progress_estimate: 0.5,
|
|
127
|
+
}),
|
|
128
|
+
});
|
|
129
|
+
const result = enforceRound(curr, contradictedSuccessWithRemaining(["criteria-2", "criteria-3"]), 3, [], 0);
|
|
130
|
+
assert.equal(result.action, "reject");
|
|
131
|
+
assert.ok(result.reason.includes("criteria remain unmet"));
|
|
132
|
+
assert.ok(result.fix_instructions.length > 0);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
136
|
+
// R2: recurring violation
|
|
137
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
138
|
+
describe("enforcement-gate — R2: recurring violation", () => {
|
|
139
|
+
it("rejects when same violation appears in 3 consecutive rounds", () => {
|
|
140
|
+
const curr = se({
|
|
141
|
+
success: false,
|
|
142
|
+
constraint_violations: ["missing docs"],
|
|
143
|
+
});
|
|
144
|
+
const result = enforceRound(curr, contradictedRecurringViolation("missing docs"), 4, [], 0);
|
|
145
|
+
assert.equal(result.action, "reject");
|
|
146
|
+
assert.ok(result.reason.includes("3 consecutive rounds"));
|
|
147
|
+
assert.ok(result.fix_instructions.includes("DIFFERENT approach"));
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
151
|
+
// R3: empty success — no files changed, no tests, claims success
|
|
152
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
153
|
+
describe("enforcement-gate — R3: empty success", () => {
|
|
154
|
+
it("rejects when agent claims success with no files and no tests", () => {
|
|
155
|
+
const curr = se({
|
|
156
|
+
success: true,
|
|
157
|
+
execution_evidence: makeExecutionEvidence({
|
|
158
|
+
files_changed: [],
|
|
159
|
+
test_results: null,
|
|
160
|
+
progress_estimate: 1.0,
|
|
161
|
+
}),
|
|
162
|
+
});
|
|
163
|
+
const result = enforceRound(curr, trusted(), 2, [], 0);
|
|
164
|
+
assert.equal(result.action, "reject");
|
|
165
|
+
assert.ok(result.reason.includes("no verifiable evidence"));
|
|
166
|
+
});
|
|
167
|
+
it("accepts when success=true with files_changed (not empty)", () => {
|
|
168
|
+
const curr = se({
|
|
169
|
+
success: true,
|
|
170
|
+
execution_evidence: makeExecutionEvidence({
|
|
171
|
+
files_changed: ["src/fixed.ts"],
|
|
172
|
+
test_results: { passed: 10, failed: 0, skipped: 0 },
|
|
173
|
+
progress_estimate: 1.0,
|
|
174
|
+
}),
|
|
175
|
+
});
|
|
176
|
+
const result = enforceRound(curr, trusted(), 2, [], 0);
|
|
177
|
+
assert.equal(result.action, "accept");
|
|
178
|
+
});
|
|
179
|
+
it("skips when execution_evidence is undefined (heuristic fallback)", () => {
|
|
180
|
+
// Heuristic self-evaluations have no execution_evidence.
|
|
181
|
+
// R3 should not fire in this case — it only fires when
|
|
182
|
+
// execution_evidence IS provided but shows empty work.
|
|
183
|
+
const curr = makeSelfEvaluation({
|
|
184
|
+
success: true,
|
|
185
|
+
output_summary: "Done.",
|
|
186
|
+
constraint_violations: [],
|
|
187
|
+
should_continue: true,
|
|
188
|
+
});
|
|
189
|
+
// Explicitly remove execution_evidence (default factory sets it)
|
|
190
|
+
curr.execution_evidence = undefined;
|
|
191
|
+
const result = enforceRound(curr, trusted(), 2, [], 0);
|
|
192
|
+
assert.equal(result.action, "accept");
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
196
|
+
// R4: progress stall
|
|
197
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
198
|
+
describe("enforcement-gate — R4: progress stall", () => {
|
|
199
|
+
it("rejects when progress is flat for 3 rounds", () => {
|
|
200
|
+
const curr = se({
|
|
201
|
+
success: false,
|
|
202
|
+
execution_evidence: makeExecutionEvidence({
|
|
203
|
+
files_changed: ["src/foo.ts"],
|
|
204
|
+
progress_estimate: 0.33,
|
|
205
|
+
}),
|
|
206
|
+
});
|
|
207
|
+
const vault = [
|
|
208
|
+
vaultRound(1, 0.30),
|
|
209
|
+
vaultRound(2, 0.31),
|
|
210
|
+
vaultRound(3, 0.32),
|
|
211
|
+
];
|
|
212
|
+
const result = enforceRound(curr, trusted(), 4, vault, 0);
|
|
213
|
+
assert.equal(result.action, "reject");
|
|
214
|
+
assert.ok(result.reason.includes("stalled"));
|
|
215
|
+
});
|
|
216
|
+
it("accepts when progress is increasing", () => {
|
|
217
|
+
const curr = se({
|
|
218
|
+
success: false,
|
|
219
|
+
execution_evidence: makeExecutionEvidence({
|
|
220
|
+
files_changed: ["src/foo.ts"],
|
|
221
|
+
progress_estimate: 0.80,
|
|
222
|
+
}),
|
|
223
|
+
});
|
|
224
|
+
const vault = [
|
|
225
|
+
vaultRound(1, 0.30),
|
|
226
|
+
vaultRound(2, 0.50),
|
|
227
|
+
vaultRound(3, 0.70),
|
|
228
|
+
];
|
|
229
|
+
const result = enforceRound(curr, trusted(), 4, vault, 0);
|
|
230
|
+
assert.equal(result.action, "accept");
|
|
231
|
+
});
|
|
232
|
+
it("terminates on second consecutive stall rejection", () => {
|
|
233
|
+
const curr = se({
|
|
234
|
+
success: false,
|
|
235
|
+
execution_evidence: makeExecutionEvidence({
|
|
236
|
+
files_changed: ["src/foo.ts"],
|
|
237
|
+
progress_estimate: 0.33,
|
|
238
|
+
}),
|
|
239
|
+
});
|
|
240
|
+
const vault = [
|
|
241
|
+
vaultRound(1, 0.30),
|
|
242
|
+
vaultRound(2, 0.31),
|
|
243
|
+
vaultRound(3, 0.32),
|
|
244
|
+
];
|
|
245
|
+
// consecutiveRejections=1 (was already rejected once before)
|
|
246
|
+
const result = enforceRound(curr, trusted(), 4, vault, 1);
|
|
247
|
+
assert.equal(result.action, "terminate");
|
|
248
|
+
assert.ok(result.reason.includes("previous rejection"));
|
|
249
|
+
});
|
|
250
|
+
it("does not fire with less than 3 rounds of vault data", () => {
|
|
251
|
+
const curr = se({
|
|
252
|
+
success: false,
|
|
253
|
+
execution_evidence: makeExecutionEvidence({
|
|
254
|
+
progress_estimate: 0.32,
|
|
255
|
+
}),
|
|
256
|
+
});
|
|
257
|
+
const vault = [vaultRound(1, 0.30)];
|
|
258
|
+
const result = enforceRound(curr, trusted(), 2, vault, 0);
|
|
259
|
+
assert.equal(result.action, "accept");
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
263
|
+
// R5: max rejections
|
|
264
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
265
|
+
describe("enforcement-gate — R5: max rejections", () => {
|
|
266
|
+
it("terminates after 2 consecutive rejections", () => {
|
|
267
|
+
const curr = se({ success: false });
|
|
268
|
+
const result = enforceRound(curr, trusted(), 3, [], 2);
|
|
269
|
+
assert.equal(result.action, "terminate");
|
|
270
|
+
assert.ok(result.reason.includes("consecutive enforcement rejections"));
|
|
271
|
+
});
|
|
272
|
+
it("does not terminate with only 1 rejection", () => {
|
|
273
|
+
const curr = se({ success: false });
|
|
274
|
+
const result = enforceRound(curr, trusted(), 3, [], 1);
|
|
275
|
+
assert.equal(result.action, "accept");
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
279
|
+
// Priority — R1 takes precedence over R3 when both conditions exist
|
|
280
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
281
|
+
describe("enforcement-gate — rule priority", () => {
|
|
282
|
+
it("R1 (fake success) fires before R3 (empty success)", () => {
|
|
283
|
+
const curr = se({
|
|
284
|
+
success: true,
|
|
285
|
+
execution_evidence: makeExecutionEvidence({
|
|
286
|
+
files_changed: [], // triggers R3
|
|
287
|
+
test_results: null, // triggers R3
|
|
288
|
+
success_criteria_met: ["x"],
|
|
289
|
+
success_criteria_remaining: ["y", "z"], // triggers R1
|
|
290
|
+
progress_estimate: 1.0,
|
|
291
|
+
}),
|
|
292
|
+
});
|
|
293
|
+
const result = enforceRound(curr, contradictedSuccessWithRemaining(["y", "z"]), 2, [], 0);
|
|
294
|
+
// R1 should fire (criteria remaining), not R3 (empty success)
|
|
295
|
+
assert.equal(result.action, "reject");
|
|
296
|
+
assert.ok(result.reason.includes("criteria remain unmet"));
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
300
|
+
// buildRejectionPrompt
|
|
301
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
302
|
+
describe("buildRejectionPrompt", () => {
|
|
303
|
+
it("produces a prompt containing REJECTED, reason, and retry instructions", () => {
|
|
304
|
+
const enforceResult = makeEnforcementResult({
|
|
305
|
+
action: "reject",
|
|
306
|
+
reason: "Agent claims success but 3 criteria remain unmet.",
|
|
307
|
+
fix_instructions: "Complete all criteria or set success=false.",
|
|
308
|
+
});
|
|
309
|
+
const prompt = buildRejectionPrompt(5, "Audit the ERC20 token", enforceResult);
|
|
310
|
+
assert.ok(prompt.includes("REJECTED"));
|
|
311
|
+
assert.ok(prompt.includes("Round 5"));
|
|
312
|
+
assert.ok(prompt.includes("criteria remain unmet"));
|
|
313
|
+
assert.ok(prompt.includes("Complete all criteria"));
|
|
314
|
+
assert.ok(prompt.includes("Audit the ERC20 token"));
|
|
315
|
+
assert.ok(prompt.includes("Retry"));
|
|
316
|
+
assert.ok(prompt.includes("do NOT advance"));
|
|
317
|
+
});
|
|
318
|
+
it("includes the task in the retry section", () => {
|
|
319
|
+
const enforceResult = makeEnforcementResult({
|
|
320
|
+
action: "reject",
|
|
321
|
+
reason: "Test reason.",
|
|
322
|
+
fix_instructions: "Test fix.",
|
|
323
|
+
});
|
|
324
|
+
const prompt = buildRejectionPrompt(2, "Fix bugs in auth module", enforceResult);
|
|
325
|
+
assert.ok(prompt.includes("Fix bugs in auth module"));
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
//# sourceMappingURL=enforcement-gate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enforcement-gate.test.js","sourceRoot":"","sources":["../../src/tests/enforcement-gate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,8 +25,8 @@ describe("Engine — Initialisation", () => {
|
|
|
25
25
|
it("createEngine returns LoopForgeEngine instance", () => {
|
|
26
26
|
const engine = createEngine("skills");
|
|
27
27
|
assert.ok(engine instanceof LoopForgeEngine);
|
|
28
|
-
assert.equal(engine.skillsDir, "skills");
|
|
29
28
|
assert.equal(engine.state, null);
|
|
29
|
+
assert.equal(engine.lastTask, null);
|
|
30
30
|
});
|
|
31
31
|
it("engine lazy-inits state on first invocation", () => {
|
|
32
32
|
const engine = createEngine();
|
|
@@ -47,7 +47,7 @@ describe("Engine — Feedback mode", () => {
|
|
|
47
47
|
assert.equal(result.status, AgentStatus.ERROR);
|
|
48
48
|
assert.ok(result.response.error.includes("feedback payload"));
|
|
49
49
|
});
|
|
50
|
-
it("returns OK with
|
|
50
|
+
it("returns OK with success flag when feedback provided", () => {
|
|
51
51
|
const engine = createEngine();
|
|
52
52
|
const req = makeRequest({
|
|
53
53
|
mode: Mode.FEEDBACK,
|
|
@@ -60,31 +60,31 @@ describe("Engine — Feedback mode", () => {
|
|
|
60
60
|
});
|
|
61
61
|
const result = engine.invokeFeedback(req);
|
|
62
62
|
assert.equal(result.status, AgentStatus.OK);
|
|
63
|
-
assert.ok(result.response.prompt.includes("
|
|
63
|
+
assert.ok(result.response.prompt.includes("Success: true"));
|
|
64
64
|
});
|
|
65
|
-
it("
|
|
65
|
+
it("returns OK with success=false for failures", () => {
|
|
66
66
|
const engine = createEngine();
|
|
67
67
|
const req = makeRequest({
|
|
68
68
|
mode: Mode.FEEDBACK,
|
|
69
69
|
feedback: makeExecutionFeedback({
|
|
70
|
-
success:
|
|
70
|
+
success: false,
|
|
71
71
|
constraint_violations: [],
|
|
72
72
|
manual_fixes_needed: "formatting",
|
|
73
73
|
output: "Works with manual tweaks",
|
|
74
74
|
}),
|
|
75
75
|
});
|
|
76
76
|
const result = engine.invokeFeedback(req);
|
|
77
|
-
assert.ok(result.response.prompt.includes("
|
|
77
|
+
assert.ok(result.response.prompt.includes("Success: false"));
|
|
78
78
|
});
|
|
79
|
-
it("updates
|
|
79
|
+
it("updates success trend in state", () => {
|
|
80
80
|
const engine = createEngine();
|
|
81
81
|
const req = makeRequest({
|
|
82
82
|
mode: Mode.FEEDBACK,
|
|
83
83
|
feedback: makeExecutionFeedback({ success: true, output: "ok" }),
|
|
84
84
|
});
|
|
85
85
|
engine.invokeFeedback(req);
|
|
86
|
-
assert.equal(engine.state.
|
|
87
|
-
assert.equal(engine.state.
|
|
86
|
+
assert.equal(engine.state.success_trend.length, 1);
|
|
87
|
+
assert.equal(engine.state.success_trend[0], true);
|
|
88
88
|
});
|
|
89
89
|
});
|
|
90
90
|
describe("Engine — Circuit breaker", () => {
|
|
@@ -99,25 +99,25 @@ describe("Engine — Circuit breaker", () => {
|
|
|
99
99
|
mode: Mode.FEEDBACK,
|
|
100
100
|
feedback: makeExecutionFeedback({ success: true, output: "ok" }),
|
|
101
101
|
})); // init state
|
|
102
|
-
engine.state.
|
|
102
|
+
engine.state.success_trend = [true, true];
|
|
103
103
|
assert.equal(engine.shouldBreak(), false);
|
|
104
104
|
});
|
|
105
|
-
it("returns true when
|
|
105
|
+
it("returns true when 3 consecutive failures", () => {
|
|
106
106
|
const engine = createEngine();
|
|
107
107
|
engine.invokeFeedback(makeRequest({
|
|
108
108
|
mode: Mode.FEEDBACK,
|
|
109
109
|
feedback: makeExecutionFeedback({ success: true, output: "ok" }),
|
|
110
110
|
}));
|
|
111
|
-
engine.state.
|
|
111
|
+
engine.state.success_trend = [false, false, false];
|
|
112
112
|
assert.equal(engine.shouldBreak(), true);
|
|
113
113
|
});
|
|
114
|
-
it("returns false when
|
|
114
|
+
it("returns false when all successes (no longer trips on flat success)", () => {
|
|
115
115
|
const engine = createEngine();
|
|
116
116
|
engine.invokeFeedback(makeRequest({
|
|
117
117
|
mode: Mode.FEEDBACK,
|
|
118
118
|
feedback: makeExecutionFeedback({ success: true, output: "ok" }),
|
|
119
119
|
}));
|
|
120
|
-
engine.state.
|
|
120
|
+
engine.state.success_trend = [true, true, true];
|
|
121
121
|
assert.equal(engine.shouldBreak(), false);
|
|
122
122
|
});
|
|
123
123
|
});
|
|
@@ -197,7 +197,6 @@ describe("Engine — P0-P5 Cognitive Evolution (v1.7 E2E)", () => {
|
|
|
197
197
|
output_summary: "Found 2 reentrancy bugs",
|
|
198
198
|
constraint_violations: [],
|
|
199
199
|
manual_fixes_needed: "",
|
|
200
|
-
quality_score: 5,
|
|
201
200
|
discovered_constraints: ["Use SafeERC20 for all external calls"],
|
|
202
201
|
objective_refinement: "Scope includes upgradeable proxy patterns",
|
|
203
202
|
emerged_subtasks: ["Audit proxy init", "Verify timelock"],
|
|
@@ -250,7 +249,6 @@ describe("Engine — P0-P5 Cognitive Evolution (v1.7 E2E)", () => {
|
|
|
250
249
|
output_summary: "Fixed reentrancy in withdraw()",
|
|
251
250
|
constraint_violations: [],
|
|
252
251
|
manual_fixes_needed: "",
|
|
253
|
-
quality_score: 5,
|
|
254
252
|
execution_evidence: {
|
|
255
253
|
files_changed: ["contracts/Token.sol", "test/Token.test.ts"],
|
|
256
254
|
test_results: { passed: 24, failed: 0, skipped: 0 },
|
|
@@ -261,11 +259,15 @@ describe("Engine — P0-P5 Cognitive Evolution (v1.7 E2E)", () => {
|
|
|
261
259
|
},
|
|
262
260
|
});
|
|
263
261
|
assert.equal(r2.status, AgentStatus.OK);
|
|
262
|
+
// v1.14 Thin Prompt: progress dashboard lives in state file, not in prompt
|
|
263
|
+
const stateFile = r2.response.state_file_content;
|
|
264
|
+
assert.ok(stateFile, "P4: state_file_content should be set for L2 compile");
|
|
265
|
+
assert.ok(stateFile.includes("Progress Dashboard"), "P4: progress dashboard in state file");
|
|
266
|
+
assert.ok(stateFile.includes("1/3"), "P4: criteria count in state file");
|
|
267
|
+
assert.ok(stateFile.includes("Token.sol"), "P4: files_changed in state file");
|
|
268
|
+
// Thin prompt: progress dashboard should NOT be in the prompt text
|
|
264
269
|
const prompt = r2.response.prompt;
|
|
265
|
-
|
|
266
|
-
assert.ok(prompt.includes("Progress Dashboard"), "P4: progress dashboard missing");
|
|
267
|
-
assert.ok(prompt.includes("1/3"), "P4: criteria count missing");
|
|
268
|
-
assert.ok(prompt.includes("Token.sol"), "P4: files_changed missing");
|
|
270
|
+
assert.ok(!prompt.includes("Progress Dashboard"), "P4: thin prompt — dashboard in state file only");
|
|
269
271
|
});
|
|
270
272
|
it("P5: wrong_assumptions are forwarded to compiler as key lessons", () => {
|
|
271
273
|
const engine = createEngine();
|
|
@@ -290,7 +292,6 @@ describe("Engine — P0-P5 Cognitive Evolution (v1.7 E2E)", () => {
|
|
|
290
292
|
output_summary: "Found missing access control",
|
|
291
293
|
constraint_violations: [],
|
|
292
294
|
manual_fixes_needed: "",
|
|
293
|
-
quality_score: 2,
|
|
294
295
|
wrong_assumptions: ["Assumed OZ v4.0 has no known issues"],
|
|
295
296
|
retracted_constraints: [],
|
|
296
297
|
revised_success_criteria: [],
|
|
@@ -325,7 +326,6 @@ describe("Engine — P0-P5 Cognitive Evolution (v1.7 E2E)", () => {
|
|
|
325
326
|
output_summary: "Audited contracts",
|
|
326
327
|
constraint_violations: [],
|
|
327
328
|
manual_fixes_needed: "",
|
|
328
|
-
quality_score: 5,
|
|
329
329
|
discovered_constraints: ["No external deps"],
|
|
330
330
|
retracted_constraints: ["No external deps"],
|
|
331
331
|
wrong_assumptions: [],
|