infinity-harness 2.8.9 → 2.8.11
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/CHANGELOG.md +18 -0
- package/dist/extensions/infinity-harness/index.js +3614 -0
- package/dist/extensions/infinity-harness/index.js.map +1 -0
- package/dist/src/approval.js +154 -0
- package/dist/src/approval.js.map +1 -0
- package/dist/src/core/brief.js +309 -0
- package/dist/src/core/brief.js.map +1 -0
- package/dist/src/core/config.js +539 -0
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/core/exec.js +106 -0
- package/dist/src/core/exec.js.map +1 -0
- package/dist/src/core/featureList.js +365 -0
- package/dist/src/core/featureList.js.map +1 -0
- package/dist/src/core/fsx.js +123 -0
- package/dist/src/core/fsx.js.map +1 -0
- package/dist/src/core/gates.js +490 -0
- package/dist/src/core/gates.js.map +1 -0
- package/dist/src/core/init.js +480 -0
- package/dist/src/core/init.js.map +1 -0
- package/dist/src/core/lock.js +183 -0
- package/dist/src/core/lock.js.map +1 -0
- package/dist/src/core/modelRouter.js +185 -0
- package/dist/src/core/modelRouter.js.map +1 -0
- package/dist/src/core/paths.js +129 -0
- package/dist/src/core/paths.js.map +1 -0
- package/dist/src/core/phases.js +254 -0
- package/dist/src/core/phases.js.map +1 -0
- package/dist/src/core/plan.js +15 -0
- package/dist/src/core/plan.js.map +1 -0
- package/dist/src/core/runState.js +126 -0
- package/dist/src/core/runState.js.map +1 -0
- package/dist/src/core/settings.js +877 -0
- package/dist/src/core/settings.js.map +1 -0
- package/dist/src/core/skills.js +319 -0
- package/dist/src/core/skills.js.map +1 -0
- package/dist/src/core/skillsAudit.js +194 -0
- package/dist/src/core/skillsAudit.js.map +1 -0
- package/dist/src/core/types.js +77 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/daemon/budget.js +85 -0
- package/dist/src/daemon/budget.js.map +1 -0
- package/dist/src/daemon/guard.js +122 -0
- package/dist/src/daemon/guard.js.map +1 -0
- package/dist/src/daemon/index.js +461 -0
- package/dist/src/daemon/index.js.map +1 -0
- package/dist/src/daemon/isolation.js +84 -0
- package/dist/src/daemon/isolation.js.map +1 -0
- package/dist/src/daemon/preflight.js +131 -0
- package/dist/src/daemon/preflight.js.map +1 -0
- package/dist/src/daemon/server.js +174 -0
- package/dist/src/daemon/server.js.map +1 -0
- package/dist/src/daemon/supervisorState.js +42 -0
- package/dist/src/daemon/supervisorState.js.map +1 -0
- package/dist/src/daemon/worker.js +239 -0
- package/dist/src/daemon/worker.js.map +1 -0
- package/dist/src/daemon/worktree.js +102 -0
- package/dist/src/daemon/worktree.js.map +1 -0
- package/dist/src/escalate.js +312 -0
- package/dist/src/escalate.js.map +1 -0
- package/dist/src/exec/piWorker.js +630 -0
- package/dist/src/exec/piWorker.js.map +1 -0
- package/dist/src/goal.js +317 -0
- package/dist/src/goal.js.map +1 -0
- package/dist/src/goalLoop.js +374 -0
- package/dist/src/goalLoop.js.map +1 -0
- package/dist/src/goalSpec.js +397 -0
- package/dist/src/goalSpec.js.map +1 -0
- package/dist/src/goalState.js +255 -0
- package/dist/src/goalState.js.map +1 -0
- package/dist/src/handoff.js +205 -0
- package/dist/src/handoff.js.map +1 -0
- package/dist/src/intake.js +203 -0
- package/dist/src/intake.js.map +1 -0
- package/dist/src/loop.js +592 -0
- package/dist/src/loop.js.map +1 -0
- package/dist/src/modelRouter.js +216 -0
- package/dist/src/modelRouter.js.map +1 -0
- package/dist/src/remote.js +246 -0
- package/dist/src/remote.js.map +1 -0
- package/dist/src/replan.js +262 -0
- package/dist/src/replan.js.map +1 -0
- package/dist/src/review.js +54 -0
- package/dist/src/review.js.map +1 -0
- package/dist/src/rework.js +241 -0
- package/dist/src/rework.js.map +1 -0
- package/dist/src/runState.js +4 -0
- package/dist/src/runState.js.map +1 -0
- package/dist/src/scheduler.js +270 -0
- package/dist/src/scheduler.js.map +1 -0
- package/dist/src/supervisor.js +787 -0
- package/dist/src/supervisor.js.map +1 -0
- package/dist/src/taskList.js +430 -0
- package/dist/src/taskList.js.map +1 -0
- package/dist/src/ui/config.js +268 -0
- package/dist/src/ui/config.js.map +1 -0
- package/dist/src/ui/dashboard.js +1288 -0
- package/dist/src/ui/dashboard.js.map +1 -0
- package/dist/src/ui/display.js +229 -0
- package/dist/src/ui/display.js.map +1 -0
- package/dist/src/ui/planTree.js +219 -0
- package/dist/src/ui/planTree.js.map +1 -0
- package/dist/src/ui/theme.js +298 -0
- package/dist/src/ui/theme.js.map +1 -0
- package/dist/src/ui/viewState.js +65 -0
- package/dist/src/ui/viewState.js.map +1 -0
- package/dist/src/ui/widget.js +721 -0
- package/dist/src/ui/widget.js.map +1 -0
- package/dist/src/ui/wizard.js +540 -0
- package/dist/src/ui/wizard.js.map +1 -0
- package/dist/src/unstuck.js +210 -0
- package/dist/src/unstuck.js.map +1 -0
- package/dist/src/worker.js +267 -0
- package/dist/src/worker.js.map +1 -0
- package/dist/src/workflow.js +250 -0
- package/dist/src/workflow.js.map +1 -0
- package/dist/tests/approval.test.js +144 -0
- package/dist/tests/approval.test.js.map +1 -0
- package/dist/tests/brief.test.js +271 -0
- package/dist/tests/brief.test.js.map +1 -0
- package/dist/tests/config.test.js +320 -0
- package/dist/tests/config.test.js.map +1 -0
- package/dist/tests/dashboard.test.js +277 -0
- package/dist/tests/dashboard.test.js.map +1 -0
- package/dist/tests/display.test.js +229 -0
- package/dist/tests/display.test.js.map +1 -0
- package/dist/tests/escalate.test.js +272 -0
- package/dist/tests/escalate.test.js.map +1 -0
- package/dist/tests/featureList.test.js +429 -0
- package/dist/tests/featureList.test.js.map +1 -0
- package/dist/tests/gates.test.js +333 -0
- package/dist/tests/gates.test.js.map +1 -0
- package/dist/tests/goal.test.js +229 -0
- package/dist/tests/goal.test.js.map +1 -0
- package/dist/tests/goalLoop.test.js +170 -0
- package/dist/tests/goalLoop.test.js.map +1 -0
- package/dist/tests/goalSpec.test.js +146 -0
- package/dist/tests/goalSpec.test.js.map +1 -0
- package/dist/tests/goalState.test.js +202 -0
- package/dist/tests/goalState.test.js.map +1 -0
- package/dist/tests/handoff.test.js +127 -0
- package/dist/tests/handoff.test.js.map +1 -0
- package/dist/tests/init.test.js +264 -0
- package/dist/tests/init.test.js.map +1 -0
- package/dist/tests/intake.test.js +288 -0
- package/dist/tests/intake.test.js.map +1 -0
- package/dist/tests/loop.test.js +453 -0
- package/dist/tests/loop.test.js.map +1 -0
- package/dist/tests/modelRouter.test.js +131 -0
- package/dist/tests/modelRouter.test.js.map +1 -0
- package/dist/tests/phases.test.js +244 -0
- package/dist/tests/phases.test.js.map +1 -0
- package/dist/tests/planTree.test.js +190 -0
- package/dist/tests/planTree.test.js.map +1 -0
- package/dist/tests/remote.test.js +380 -0
- package/dist/tests/remote.test.js.map +1 -0
- package/dist/tests/replan.test.js +113 -0
- package/dist/tests/replan.test.js.map +1 -0
- package/dist/tests/review.test.js +77 -0
- package/dist/tests/review.test.js.map +1 -0
- package/dist/tests/rework.test.js +109 -0
- package/dist/tests/rework.test.js.map +1 -0
- package/dist/tests/routing-live.test.js +121 -0
- package/dist/tests/routing-live.test.js.map +1 -0
- package/dist/tests/runState.test.js +73 -0
- package/dist/tests/runState.test.js.map +1 -0
- package/dist/tests/settings.test.js +311 -0
- package/dist/tests/settings.test.js.map +1 -0
- package/dist/tests/skills.test.js +387 -0
- package/dist/tests/skills.test.js.map +1 -0
- package/dist/tests/supervisor.test.js +437 -0
- package/dist/tests/supervisor.test.js.map +1 -0
- package/dist/tests/surface.test.js +203 -0
- package/dist/tests/surface.test.js.map +1 -0
- package/dist/tests/taskList.test.js +376 -0
- package/dist/tests/taskList.test.js.map +1 -0
- package/dist/tests/theme.test.js +149 -0
- package/dist/tests/theme.test.js.map +1 -0
- package/dist/tests/unstuck.test.js +268 -0
- package/dist/tests/unstuck.test.js.map +1 -0
- package/dist/tests/widget.test.js +424 -0
- package/dist/tests/widget.test.js.map +1 -0
- package/dist/tests/worker.test.js +306 -0
- package/dist/tests/worker.test.js.map +1 -0
- package/dist/tests/workflow.test.js +187 -0
- package/dist/tests/workflow.test.js.map +1 -0
- package/extensions/infinity-harness/index.ts +39 -12
- package/package.json +5 -2
- package/src/core/modelRouter.ts +23 -1
- package/src/daemon/index.ts +3 -3
- package/src/daemon/worker.ts +28 -5
- package/src/ui/config.ts +25 -1
- package/src/ui/wizard.ts +10 -5
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The escalation ladder, connected.
|
|
3
|
+
*
|
|
4
|
+
* `unstuck.ts` could always choose what to do when a run stalled — retry,
|
|
5
|
+
* reframe, consult, rework, replan, master — and nothing ever executed one.
|
|
6
|
+
* It was a chooser with no actuator, so `/infinity:run` did the only thing it
|
|
7
|
+
* could when the gate kept failing: count three strikes and stop. A run that
|
|
8
|
+
* could have escalated to a stronger model or reworked the task that poisoned
|
|
9
|
+
* everything downstream instead failed the same check three times and gave up.
|
|
10
|
+
*
|
|
11
|
+
* Wiring it in exposed three reasons it had never worked:
|
|
12
|
+
*
|
|
13
|
+
* 1. `reframe` had no budget, so it was eligible forever and shadowed every
|
|
14
|
+
* rung below it. The ladder could not climb past rung two.
|
|
15
|
+
* 2. `rework` and `replan` were vetoed unless the working tree had moved —
|
|
16
|
+
* but a stall is *defined* by the tree not moving, so the two rungs that
|
|
17
|
+
* exist for exactly this situation could never fire in it.
|
|
18
|
+
* 3. The budgets count effects on disk, which only appear if the agent acts.
|
|
19
|
+
* A stuck agent does not act, so the budget never moved and the ladder
|
|
20
|
+
* jammed, offering the same rung forever.
|
|
21
|
+
*
|
|
22
|
+
* These tests are the ones that would have caught all three.
|
|
23
|
+
*/
|
|
24
|
+
import assert from "node:assert/strict";
|
|
25
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
26
|
+
import { tmpdir } from "node:os";
|
|
27
|
+
import { join } from "node:path";
|
|
28
|
+
import { initHarness } from "../src/core/init.js";
|
|
29
|
+
import { loadConfig, saveConfig } from "../src/core/config.js";
|
|
30
|
+
import { writeTaskList } from "../src/taskList.js";
|
|
31
|
+
import { loadFeatureList, flattenTasks } from "../src/core/featureList.js";
|
|
32
|
+
import { decideNext } from "../src/loop.js";
|
|
33
|
+
import { escalate, emptyEscalationState, describeEscalation, escalationSummary } from "../src/escalate.js";
|
|
34
|
+
import { chooseUnstuckStrategy } from "../src/unstuck.js";
|
|
35
|
+
import { loadRework } from "../src/rework.js";
|
|
36
|
+
/** A project whose gate cannot pass and whose tree never moves. */
|
|
37
|
+
function stuckProject(router) {
|
|
38
|
+
const dir = mkdtempSync(join(tmpdir(), "pi-esc-"));
|
|
39
|
+
initHarness(dir);
|
|
40
|
+
const { config } = loadConfig(dir);
|
|
41
|
+
config.currentPhase = "build";
|
|
42
|
+
config.currentRole = "generator";
|
|
43
|
+
config.commands.test = "exit 1";
|
|
44
|
+
config.maxRetries = 999;
|
|
45
|
+
config.retry = {
|
|
46
|
+
tasks: { max: 999, count: 0 },
|
|
47
|
+
features: { max: 999, count: 0 },
|
|
48
|
+
phases: { max: 999, count: 0 },
|
|
49
|
+
};
|
|
50
|
+
saveConfig(dir, config);
|
|
51
|
+
if (router)
|
|
52
|
+
writeFileSync(join(dir, "harness", "model-router.json"), JSON.stringify(router, null, 2));
|
|
53
|
+
writeTaskList(dir, {
|
|
54
|
+
features: [{ id: "feature-001", name: "F", criteria: ["it works"] }],
|
|
55
|
+
tasks: [
|
|
56
|
+
{ key: "feature-001/task-001", subject: "the root task", status: "in_progress", difficulty: "moderate" },
|
|
57
|
+
{ key: "feature-001/task-002", subject: "built on the root", status: "pending", dependsOn: ["feature-001/task-001"] },
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
return dir;
|
|
61
|
+
}
|
|
62
|
+
const FULL_ROUTER = {
|
|
63
|
+
enabled: true,
|
|
64
|
+
byDifficulty: { easy: "small", moderate: "medium", difficult: "large" },
|
|
65
|
+
master: "the-master-model",
|
|
66
|
+
consultation: { enabled: true, maxPerTask: 1, oneStepOnly: true, requireExhaustion: true },
|
|
67
|
+
};
|
|
68
|
+
// ── the ladder climbs, and it ends ─────────────────────────────────────────
|
|
69
|
+
{
|
|
70
|
+
const dir = stuckProject(FULL_ROUTER);
|
|
71
|
+
const rungs = [];
|
|
72
|
+
let stopped = null;
|
|
73
|
+
for (let i = 0; i < 15; i++) {
|
|
74
|
+
const { decision } = await decideNext({ targetDir: dir, runId: "run-1" });
|
|
75
|
+
if (decision.action === "stop") {
|
|
76
|
+
stopped = { reason: decision.reason, detail: decision.detail };
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
const m = /escalated: ([a-z]+):/.exec(decision.reason);
|
|
80
|
+
if (m)
|
|
81
|
+
rungs.push(m[1]);
|
|
82
|
+
}
|
|
83
|
+
assert.deepEqual(rungs, ["retry", "reframe", "consult", "rework", "replan", "master"], `the ladder must climb every rung, in order — got ${rungs.join(" → ")}`);
|
|
84
|
+
assert.ok(stopped, "and then it must stop");
|
|
85
|
+
assert.equal(stopped.reason, "no-progress");
|
|
86
|
+
assert.match(stopped.detail, /retry → reframe → consult → rework → replan → master/);
|
|
87
|
+
assert.match(stopped.detail, /escalation ladder was spent first/);
|
|
88
|
+
rmSync(dir, { recursive: true, force: true });
|
|
89
|
+
console.log("✓ the ladder climbs every rung and then lets the run stop");
|
|
90
|
+
}
|
|
91
|
+
// The old behaviour, and why it was wrong: reframe shadowed everything below.
|
|
92
|
+
{
|
|
93
|
+
const first = chooseUnstuckStrategy({ strategies: ["reframe", "rework", "master"], fileDelta: false });
|
|
94
|
+
assert.equal(first.strategy, "reframe");
|
|
95
|
+
const second = chooseUnstuckStrategy({
|
|
96
|
+
strategies: ["reframe", "rework", "master"],
|
|
97
|
+
fileDelta: false,
|
|
98
|
+
tried: ["reframe"],
|
|
99
|
+
requireDeltaForRework: false,
|
|
100
|
+
});
|
|
101
|
+
assert.notEqual(second.strategy, "reframe", "a rung already taken must not be offered again");
|
|
102
|
+
console.log("✓ a rung gets one turn per stall, so the ladder can climb past it");
|
|
103
|
+
}
|
|
104
|
+
// And why rework/replan could never fire when it mattered.
|
|
105
|
+
{
|
|
106
|
+
const vetoed = chooseUnstuckStrategy({ strategies: ["rework"], fileDelta: false });
|
|
107
|
+
assert.equal(vetoed.strategy, null, "the review-bounce delta guard vetoes rework by default");
|
|
108
|
+
const allowed = chooseUnstuckStrategy({
|
|
109
|
+
strategies: ["rework"],
|
|
110
|
+
fileDelta: false,
|
|
111
|
+
requireDeltaForRework: false,
|
|
112
|
+
});
|
|
113
|
+
assert.equal(allowed.strategy, "rework", "a stall must be allowed to reach the rung that fixes it");
|
|
114
|
+
console.log("✓ the delta guard is a review-bounce policy, not a ladder policy");
|
|
115
|
+
}
|
|
116
|
+
// ── rework actually happens ────────────────────────────────────────────────
|
|
117
|
+
// The other rungs produce instructions; this one changes the plan. If it
|
|
118
|
+
// silently did nothing, every test above would still pass.
|
|
119
|
+
{
|
|
120
|
+
const dir = stuckProject();
|
|
121
|
+
let flipped = false;
|
|
122
|
+
for (let i = 0; i < 10; i++) {
|
|
123
|
+
const { decision } = await decideNext({ targetDir: dir, runId: "run-1" });
|
|
124
|
+
if (decision.action !== "continue" && decision.action !== "advanced")
|
|
125
|
+
break;
|
|
126
|
+
const statuses = flattenTasks(loadFeatureList(dir).list).map((t) => t.status);
|
|
127
|
+
if (statuses.every((s) => s === "rework")) {
|
|
128
|
+
flipped = true;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
assert.ok(flipped, "rework must actually flip the task and its dependents");
|
|
133
|
+
const record = loadRework(dir);
|
|
134
|
+
assert.ok(record, "and record where the pipeline has to return to");
|
|
135
|
+
assert.equal(record.returnFeature, "feature-001");
|
|
136
|
+
assert.deepEqual(record.impacted, ["feature-001/task-002"], "the dependent went with it");
|
|
137
|
+
const spent = escalationSummary(dir);
|
|
138
|
+
assert.equal(spent.reworks, 1);
|
|
139
|
+
assert.equal(spent.returnTo, "feature-001/task-001");
|
|
140
|
+
rmSync(dir, { recursive: true, force: true });
|
|
141
|
+
console.log("✓ rework flips the task and everything downstream, and records the return point");
|
|
142
|
+
}
|
|
143
|
+
// ── the instruction is the product ─────────────────────────────────────────
|
|
144
|
+
// A rung that does not change what the agent is told is a rung that does
|
|
145
|
+
// nothing, because the message is the entire mechanism.
|
|
146
|
+
{
|
|
147
|
+
const dir = stuckProject(FULL_ROUTER);
|
|
148
|
+
let state = emptyEscalationState();
|
|
149
|
+
const seen = new Map();
|
|
150
|
+
for (let i = 0; i < 8; i++) {
|
|
151
|
+
const result = await escalate({
|
|
152
|
+
targetDir: dir,
|
|
153
|
+
runId: "run-1",
|
|
154
|
+
phase: "build",
|
|
155
|
+
failures: ["tests: exit 1"],
|
|
156
|
+
fileDelta: false,
|
|
157
|
+
fingerprint: "same-every-time",
|
|
158
|
+
state,
|
|
159
|
+
});
|
|
160
|
+
state = result.next;
|
|
161
|
+
if (!result.strategy)
|
|
162
|
+
break;
|
|
163
|
+
assert.ok(result.instruction, `${result.strategy} produced no instruction`);
|
|
164
|
+
assert.ok(result.instruction.includes("tests: exit 1"), `${result.strategy} did not tell the agent what is failing`);
|
|
165
|
+
seen.set(result.strategy, result.instruction);
|
|
166
|
+
}
|
|
167
|
+
assert.ok(seen.size >= 5, `expected most of the ladder, saw ${[...seen.keys()].join(", ")}`);
|
|
168
|
+
assert.equal(new Set(seen.values()).size, seen.size, "every rung must say something different");
|
|
169
|
+
assert.match(seen.get("reframe"), /REFRAME/);
|
|
170
|
+
assert.match(seen.get("rework"), /REWORK/);
|
|
171
|
+
assert.match(seen.get("replan"), /infinity_replan/, "replan must name the tool that does it");
|
|
172
|
+
assert.match(seen.get("master"), /LAST RESORT/);
|
|
173
|
+
rmSync(dir, { recursive: true, force: true });
|
|
174
|
+
console.log("✓ every rung tells the agent something different, and names the failure");
|
|
175
|
+
}
|
|
176
|
+
// ── vendor neutrality ──────────────────────────────────────────────────────
|
|
177
|
+
// The last rung used to default to a specific third-party model, in a package
|
|
178
|
+
// that promises every routing slot ships empty.
|
|
179
|
+
{
|
|
180
|
+
const bare = chooseUnstuckStrategy({ strategies: ["master"], fileDelta: true });
|
|
181
|
+
assert.equal(bare.strategy, "master");
|
|
182
|
+
assert.equal(bare.nextModel, null, "MASTER must not silently redirect work to someone's model");
|
|
183
|
+
assert.match(bare.reason, /pi's current model/);
|
|
184
|
+
const configured = chooseUnstuckStrategy({
|
|
185
|
+
strategies: ["master"],
|
|
186
|
+
fileDelta: true,
|
|
187
|
+
projectDir: (() => {
|
|
188
|
+
const d = mkdtempSync(join(tmpdir(), "pi-master-"));
|
|
189
|
+
initHarness(d);
|
|
190
|
+
writeFileSync(join(d, "harness", "model-router.json"), JSON.stringify({ master: "chosen-by-the-user" }));
|
|
191
|
+
return d;
|
|
192
|
+
})(),
|
|
193
|
+
});
|
|
194
|
+
assert.equal(configured.nextModel, "chosen-by-the-user", "and must use one when the user set one");
|
|
195
|
+
console.log("✓ the last rung stays vendor-neutral unless the user chose a model");
|
|
196
|
+
}
|
|
197
|
+
// ── REVIEW bounces backwards instead of climbing ───────────────────────────
|
|
198
|
+
{
|
|
199
|
+
const dir = stuckProject();
|
|
200
|
+
const { config } = loadConfig(dir);
|
|
201
|
+
config.currentPhase = "review";
|
|
202
|
+
config.currentRole = "evaluator";
|
|
203
|
+
saveConfig(dir, config);
|
|
204
|
+
const result = await escalate({
|
|
205
|
+
targetDir: dir,
|
|
206
|
+
runId: "run-1",
|
|
207
|
+
phase: "review",
|
|
208
|
+
failures: ["rubric-content: missing"],
|
|
209
|
+
fileDelta: true,
|
|
210
|
+
fingerprint: "fp",
|
|
211
|
+
state: emptyEscalationState(),
|
|
212
|
+
});
|
|
213
|
+
assert.equal(result.strategy, "rework", "a failing review sends the work back, it does not reframe");
|
|
214
|
+
assert.match(result.reason, /review bounce/);
|
|
215
|
+
assert.ok(loadRework(dir), "and records the bounce");
|
|
216
|
+
rmSync(dir, { recursive: true, force: true });
|
|
217
|
+
console.log("✓ a failing REVIEW bounces the work back rather than climbing the ladder");
|
|
218
|
+
}
|
|
219
|
+
// ── it never takes the run down with it ────────────────────────────────────
|
|
220
|
+
{
|
|
221
|
+
// A project with no plan at all: every module the ladder touches will fail.
|
|
222
|
+
const dir = mkdtempSync(join(tmpdir(), "pi-esc-bare-"));
|
|
223
|
+
initHarness(dir);
|
|
224
|
+
const result = await escalate({
|
|
225
|
+
targetDir: dir,
|
|
226
|
+
runId: "run-1",
|
|
227
|
+
phase: "build",
|
|
228
|
+
failures: [],
|
|
229
|
+
fileDelta: false,
|
|
230
|
+
fingerprint: "fp",
|
|
231
|
+
state: emptyEscalationState(),
|
|
232
|
+
});
|
|
233
|
+
assert.ok(typeof result.reason === "string" && result.reason.length > 0, "it explains itself");
|
|
234
|
+
assert.ok(result.next, "and always returns usable state");
|
|
235
|
+
rmSync(dir, { recursive: true, force: true });
|
|
236
|
+
console.log("✓ an escalation that cannot run degrades instead of killing the run");
|
|
237
|
+
}
|
|
238
|
+
// ── a new stall gets a fresh ladder ────────────────────────────────────────
|
|
239
|
+
{
|
|
240
|
+
const dir = stuckProject();
|
|
241
|
+
const one = await decideNext({ targetDir: dir, runId: "run-1" });
|
|
242
|
+
assert.equal(one.decision.action, "continue");
|
|
243
|
+
const two = await decideNext({ targetDir: dir, runId: "run-1" });
|
|
244
|
+
assert.ok(two.state.escalation.tried.length > 0, "the first stall spent a rung");
|
|
245
|
+
// The agent does something real. The fingerprint is the working tree plus
|
|
246
|
+
// the plan, and a temp project is not a git repo, so the plan is the part
|
|
247
|
+
// that can actually move here.
|
|
248
|
+
writeTaskList(dir, {
|
|
249
|
+
tasks: [
|
|
250
|
+
{ key: "feature-001/task-001", subject: "the root task", status: "in_progress" },
|
|
251
|
+
{ key: "feature-001/task-002", subject: "built on the root", status: "pending", dependsOn: ["feature-001/task-001"] },
|
|
252
|
+
{ key: "feature-001/task-003", subject: "genuinely new work", status: "pending" },
|
|
253
|
+
],
|
|
254
|
+
});
|
|
255
|
+
const three = await decideNext({ targetDir: dir, runId: "run-1" });
|
|
256
|
+
assert.deepEqual(three.state.escalation.tried, [], "a moving tree resets the ladder");
|
|
257
|
+
assert.equal(three.state.noProgressStreak, 0);
|
|
258
|
+
rmSync(dir, { recursive: true, force: true });
|
|
259
|
+
console.log("✓ real progress resets the ladder; the budgets still bound the run");
|
|
260
|
+
}
|
|
261
|
+
{
|
|
262
|
+
assert.match(describeEscalation({
|
|
263
|
+
strategy: "rework", reason: "r", instruction: null, model: null,
|
|
264
|
+
applied: "flipped 2 tasks", next: emptyEscalationState(),
|
|
265
|
+
}), /rework: r \(flipped 2 tasks\)/);
|
|
266
|
+
assert.match(describeEscalation({
|
|
267
|
+
strategy: null, reason: "budgets exhausted", instruction: null, model: null,
|
|
268
|
+
applied: null, next: emptyEscalationState(),
|
|
269
|
+
}), /no escalation available/);
|
|
270
|
+
}
|
|
271
|
+
console.log("escalate.test.ts ✓");
|
|
272
|
+
//# sourceMappingURL=escalate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escalate.test.js","sourceRoot":"","sources":["../../tests/escalate.test.ts"],"names":[],"mappings":"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"}
|