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,461 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* infinity-harness — daemon/index.ts
|
|
3
|
+
*
|
|
4
|
+
* Detached entry: owns the run, heartbeat, bounded stop.
|
|
5
|
+
* Spawned via: spawn(process.execPath, [daemonEntry, targetDir], { detached:true, stdio:["ignore", logFd, logFd], windowsHide:true, env:{..., WORKER_ENV:"1"} }) + child.unref().
|
|
6
|
+
* The extension captures ctx.model -> run.json.baseModel at arm time before spawning.
|
|
7
|
+
*
|
|
8
|
+
* Lifecycle: arm run.json -> preflight tiers -> run sequential units (one worker at a time v3.0)
|
|
9
|
+
* -> decideNext via Core loop, stream to supervisor.json+activity.json, gate, advance/steer/stop.
|
|
10
|
+
* Budget (token+cost+X tripwire), worker recycling on compaction, CredentialSynchronizationError handling.
|
|
11
|
+
*/
|
|
12
|
+
import { resolve } from "node:path";
|
|
13
|
+
import { existsSync } from "node:fs";
|
|
14
|
+
import { ensureDir } from "../core/fsx.js";
|
|
15
|
+
import { loadConfig } from "../core/config.js";
|
|
16
|
+
import { loadFeatureList } from "../core/featureList.js";
|
|
17
|
+
import { loadRunState, saveRunState, disarmRun } from "../core/runState.js";
|
|
18
|
+
import { decideNext } from "../loop.js";
|
|
19
|
+
import { buildBrief, renderBrief } from "../core/brief.js";
|
|
20
|
+
import { guardSingleOwner, isDaemonAlive, loadDaemon, writeDaemon, newDaemonInfo, startHeartbeat, clearDaemon } from "./guard.js";
|
|
21
|
+
import { startServer, stopServer } from "./server.js";
|
|
22
|
+
import { saveSupervisor, appendActivity } from "./supervisorState.js";
|
|
23
|
+
import { runPreflight } from "./preflight.js";
|
|
24
|
+
import { addUsageForTier, isCapExceeded, xLeakReason } from "./budget.js";
|
|
25
|
+
import { effectiveDifficultyForTask as effectiveDifficulty, clampThinkingForProvider } from "../core/modelRouter.js";
|
|
26
|
+
import { dirname } from "node:path";
|
|
27
|
+
export const WORKER_ENV = "INFINITY_HARNESS_WORKER";
|
|
28
|
+
let stopping = false;
|
|
29
|
+
let heartbeatStop = null;
|
|
30
|
+
let server = null;
|
|
31
|
+
async function main() {
|
|
32
|
+
const targetDir = process.argv[2] ?? process.cwd();
|
|
33
|
+
const logPath = resolve(targetDir, "harness", "daemon.log");
|
|
34
|
+
try {
|
|
35
|
+
ensureDir(dirname(logPath));
|
|
36
|
+
}
|
|
37
|
+
catch { }
|
|
38
|
+
// Guard: single owner
|
|
39
|
+
const existing = guardSingleOwner(targetDir);
|
|
40
|
+
if (existing && isDaemonAlive(existing)) {
|
|
41
|
+
console.error(`infinity-harness daemon already running pid ${existing.pid}`);
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
const runState = loadRunState(targetDir);
|
|
45
|
+
if (!runState?.armed) {
|
|
46
|
+
console.error("no armed run — run.json is not armed");
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
if (!runState.baseModel) {
|
|
50
|
+
console.error("no baseModel in run.json — extension must capture ctx.model at arm time");
|
|
51
|
+
// Refuse to arm: this is the path that silently used pi's default (the X leak).
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
// Preflight distinct tiers
|
|
55
|
+
const { loadConfig: _loadConfig } = await import("../core/config.js");
|
|
56
|
+
const cfg = _loadConfig(targetDir).config;
|
|
57
|
+
const tiersRaw = cfg.tiers ?? {};
|
|
58
|
+
const hasTier = Object.keys(tiersRaw).length > 0;
|
|
59
|
+
if (hasTier) {
|
|
60
|
+
const pre = await runPreflight({ targetDir, tiers: tiersRaw });
|
|
61
|
+
if (pre.blocked) {
|
|
62
|
+
console.error(`tier preflight failed: ${pre.blocked.tier} ${pre.blocked.reason}`);
|
|
63
|
+
// Record to run.json and stop
|
|
64
|
+
const rs = loadRunState(targetDir);
|
|
65
|
+
if (rs) {
|
|
66
|
+
rs.tiers = pre.tierResults;
|
|
67
|
+
saveRunState(targetDir, rs);
|
|
68
|
+
}
|
|
69
|
+
appendActivity(targetDir, { level: "error", worker: null, text: `preflight failed ${pre.blocked.tier}: ${pre.blocked.reason}` });
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
if (runState) {
|
|
73
|
+
runState.tiers = pre.tierResults;
|
|
74
|
+
saveRunState(targetDir, runState);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Start server (port 0, token from run)
|
|
78
|
+
const { server: srv, port, token } = await startServer({
|
|
79
|
+
targetDir,
|
|
80
|
+
onHalt: async () => { await boundedStop(targetDir, "halted by user"); return { ok: true }; },
|
|
81
|
+
onRun: async () => ({ ok: true, daemon: loadDaemon(targetDir) }),
|
|
82
|
+
onApprove: async (body) => {
|
|
83
|
+
try {
|
|
84
|
+
const note = typeof body?.note === "string" ? String(body.note) : "";
|
|
85
|
+
const { resolveApproval: _resolveApproval } = await import("../approval.js");
|
|
86
|
+
await _resolveApproval(targetDir, note || true);
|
|
87
|
+
appendActivity(targetDir, { level: "good", worker: null, text: `approved: ${note || "(no note)"}` });
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
91
|
+
}
|
|
92
|
+
return { ok: true };
|
|
93
|
+
},
|
|
94
|
+
onReplan: async (body) => {
|
|
95
|
+
try {
|
|
96
|
+
const b = body;
|
|
97
|
+
const { amendPlan: _amendPlan } = await import("../replan.js");
|
|
98
|
+
const r = await _amendPlan({ projectDir: targetDir, reason: typeof b.reason === "string" ? b.reason : undefined, addFeatures: b.addFeatures, addTasks: b.addTasks });
|
|
99
|
+
appendActivity(targetDir, { level: "info", worker: null, text: `replan +${r.added.features}f +${r.added.tasks}t rev ${r.baseRevision}` });
|
|
100
|
+
return { ok: true, ...r };
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
onRework: async (body) => {
|
|
107
|
+
try {
|
|
108
|
+
const b = body;
|
|
109
|
+
const needle = String(b.task ?? b.key ?? "").trim();
|
|
110
|
+
if (!needle)
|
|
111
|
+
return { ok: false, error: "task required" };
|
|
112
|
+
const { flattenTasks } = await import("../core/featureList.js");
|
|
113
|
+
const list = loadFeatureList(targetDir).list;
|
|
114
|
+
const target = flattenTasks(list).find(t => t.compositeKey === needle || t.key === needle || t.id === needle);
|
|
115
|
+
if (!target)
|
|
116
|
+
return { ok: false, error: `no task ${needle}` };
|
|
117
|
+
const { startRework: _startRework } = await import("../rework.js");
|
|
118
|
+
const rs = loadRunState(targetDir);
|
|
119
|
+
const runId = rs?.runId ?? "daemon";
|
|
120
|
+
const res = await _startRework({ projectDir: targetDir, featureId: target.featureId, taskId: target.id, key: target.key, reason: typeof b.reason === "string" ? b.reason : "rework via daemon", runId });
|
|
121
|
+
appendActivity(targetDir, { level: "warn", worker: null, text: `rework ${target.compositeKey} → ${res.impacted.length} deps rev ${res.baseRevision}` });
|
|
122
|
+
return { ok: true, ...res };
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
onPilot: async (body) => {
|
|
129
|
+
try {
|
|
130
|
+
const b = body;
|
|
131
|
+
const p = String(b.pilot ?? "").trim().toLowerCase();
|
|
132
|
+
if (!["copilot", "autopilot", "full"].includes(p))
|
|
133
|
+
return { ok: false, error: `pilot must be copilot|autopilot|full, got ${JSON.stringify(b.pilot)}` };
|
|
134
|
+
const { loadConfig: _lc, saveConfig: _sc } = await import("../core/config.js");
|
|
135
|
+
const { applyPilotPreset: _app } = await import("../core/config.js");
|
|
136
|
+
const { withLock: _wl } = await import("../core/lock.js");
|
|
137
|
+
const { configPath: _cp } = await import("../core/paths.js");
|
|
138
|
+
await _wl(_cp(targetDir), () => {
|
|
139
|
+
const l = _lc(targetDir);
|
|
140
|
+
if (!l.ok)
|
|
141
|
+
throw new Error(l.error ?? "cannot load config");
|
|
142
|
+
l.config.pilot = p;
|
|
143
|
+
_app(l.config, p);
|
|
144
|
+
const ok = _sc(targetDir, l.config).ok;
|
|
145
|
+
if (!ok)
|
|
146
|
+
throw new Error("cannot save config");
|
|
147
|
+
return true;
|
|
148
|
+
});
|
|
149
|
+
appendActivity(targetDir, { level: "info", worker: null, text: `pilot → ${p}` });
|
|
150
|
+
return { ok: true, pilot: p };
|
|
151
|
+
}
|
|
152
|
+
catch (e) {
|
|
153
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
server = srv;
|
|
158
|
+
const info = newDaemonInfo(runState.runId, port);
|
|
159
|
+
// Preserve token from server (which may have generated one if daemon.json absent)
|
|
160
|
+
info.token = token || info.token;
|
|
161
|
+
writeDaemon(targetDir, info);
|
|
162
|
+
heartbeatStop = startHeartbeat(targetDir);
|
|
163
|
+
const onSignal = async (sig) => {
|
|
164
|
+
if (stopping)
|
|
165
|
+
return;
|
|
166
|
+
stopping = true;
|
|
167
|
+
console.log(`daemon signal ${sig}, stopping`);
|
|
168
|
+
await boundedStop(targetDir, `signal ${sig}`);
|
|
169
|
+
process.exit(0);
|
|
170
|
+
};
|
|
171
|
+
process.on("SIGTERM", () => void onSignal("SIGTERM"));
|
|
172
|
+
process.on("SIGINT", () => void onSignal("SIGINT"));
|
|
173
|
+
// Main loop: one unit at a time (v3.0 sequential). Continuous handoff in autopilot/full.
|
|
174
|
+
await runLoop(targetDir);
|
|
175
|
+
}
|
|
176
|
+
async function boundedStop(targetDir, reason) {
|
|
177
|
+
stopping = true;
|
|
178
|
+
if (heartbeatStop)
|
|
179
|
+
try {
|
|
180
|
+
heartbeatStop();
|
|
181
|
+
}
|
|
182
|
+
catch { }
|
|
183
|
+
if (server)
|
|
184
|
+
try {
|
|
185
|
+
await stopServer(server);
|
|
186
|
+
}
|
|
187
|
+
catch { }
|
|
188
|
+
server = null;
|
|
189
|
+
try {
|
|
190
|
+
disarmRun(targetDir, reason);
|
|
191
|
+
}
|
|
192
|
+
catch { }
|
|
193
|
+
try {
|
|
194
|
+
clearDaemon(targetDir);
|
|
195
|
+
}
|
|
196
|
+
catch { }
|
|
197
|
+
}
|
|
198
|
+
async function runLoop(targetDir) {
|
|
199
|
+
let iterations = 0;
|
|
200
|
+
const maxRecycles = (() => { try {
|
|
201
|
+
const c = loadConfig(targetDir).config;
|
|
202
|
+
return c.limits?.maxRecycles ?? 2;
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return 2;
|
|
206
|
+
} })();
|
|
207
|
+
const recycleCount = new Map();
|
|
208
|
+
// Outer run loop: decideNext -> prompt worker (or general A work) -> gate -> advance/steer/stop
|
|
209
|
+
while (!stopping) {
|
|
210
|
+
const runState = loadRunState(targetDir);
|
|
211
|
+
if (!runState?.armed) {
|
|
212
|
+
await boundedStop(targetDir, runState?.stopReason ?? "disarmed");
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
// Budget caps (token/cost) and X tripwire
|
|
216
|
+
try {
|
|
217
|
+
const capCheck = isCapExceeded(runState.budget ?? { byTier: {}, cap: {} });
|
|
218
|
+
if (capCheck.exceeded) {
|
|
219
|
+
appendActivity(targetDir, { level: "warn", worker: null, text: capCheck.reason ?? "cap exceeded" });
|
|
220
|
+
await boundedStop(targetDir, capCheck.reason ?? "cap exceeded");
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
// X leak is a defect signal, not a budget — check it regardless of cap
|
|
224
|
+
const hasConsultWorker = false; // v3.0 sequential: no consultation parallel workers yet
|
|
225
|
+
const { hasXLeak: _hasXLeak } = await import("./budget.js");
|
|
226
|
+
if (_hasXLeak(runState.budget ?? { byTier: {}, cap: {} }, hasConsultWorker)) {
|
|
227
|
+
const reason = xLeakReason(runState.budget ?? { byTier: {}, cap: {} });
|
|
228
|
+
appendActivity(targetDir, { level: "error", worker: null, text: reason });
|
|
229
|
+
await boundedStop(targetDir, reason);
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
catch { }
|
|
234
|
+
const decision = await decideNext({ targetDir, runId: runState.runId, skipGate: false });
|
|
235
|
+
const action = decision.decision.action;
|
|
236
|
+
if (action === "stop") {
|
|
237
|
+
const d = decision.decision;
|
|
238
|
+
appendActivity(targetDir, { level: "info", worker: null, text: d.detail ?? d.reason });
|
|
239
|
+
await boundedStop(targetDir, d.detail ?? d.reason);
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
if (action === "wait") {
|
|
243
|
+
const d = decision.decision;
|
|
244
|
+
appendActivity(targetDir, { level: "info", worker: null, text: d.detail ?? d.reason });
|
|
245
|
+
// Paused / awaiting approval — keep daemon alive but idle; poll.
|
|
246
|
+
await new Promise(r => setTimeout(r, 5_000));
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (action === "approve") {
|
|
250
|
+
const d = decision.decision;
|
|
251
|
+
appendActivity(targetDir, { level: "warn", worker: null, text: `awaiting approval: ${d.phase} — /infinity:approve to continue` });
|
|
252
|
+
saveSupervisor(targetDir, { runId: runState.runId, updatedAt: new Date().toISOString(), worker: null });
|
|
253
|
+
await new Promise(r => setTimeout(r, 5_000));
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
// continue / advanced both have a brief to work. We need to determine unit + routing.
|
|
257
|
+
const brief = await buildBrief(targetDir);
|
|
258
|
+
const list = loadFeatureList(targetDir).list;
|
|
259
|
+
const phase = brief.phase ?? loadConfig(targetDir).config.currentPhase;
|
|
260
|
+
// Derive unit: prefer current task, else nextActionableTask
|
|
261
|
+
let unitKey = brief.task?.key ?? brief.task?.id ?? null;
|
|
262
|
+
let difficulty = undefined;
|
|
263
|
+
let tierSpec = null;
|
|
264
|
+
try {
|
|
265
|
+
if (unitKey) {
|
|
266
|
+
const diff = effectiveDifficulty(list, unitKey, loadConfig(targetDir).config.session.handoff);
|
|
267
|
+
difficulty = diff;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
catch { }
|
|
271
|
+
// Fallback: use phase+feature hints when no task
|
|
272
|
+
const cfgForRouting = loadConfig(targetDir).config;
|
|
273
|
+
const tiers = cfgForRouting.tiers ?? {};
|
|
274
|
+
// General work (no unit) -> A
|
|
275
|
+
let askedTier = (difficulty ? (difficulty === "difficult" ? "D" : difficulty === "moderate" ? "C" : "B") : "A");
|
|
276
|
+
let routed = null;
|
|
277
|
+
if (askedTier && tiers[askedTier]) {
|
|
278
|
+
tierSpec = tiers[askedTier];
|
|
279
|
+
routed = tierSpec;
|
|
280
|
+
}
|
|
281
|
+
// Fallback to baseModel when tier slot empty
|
|
282
|
+
if (!routed) {
|
|
283
|
+
const bm = runState.baseModel;
|
|
284
|
+
if (bm)
|
|
285
|
+
routed = { provider: bm.provider, id: bm.id };
|
|
286
|
+
}
|
|
287
|
+
if (!routed) {
|
|
288
|
+
appendActivity(targetDir, { level: "error", worker: null, text: `no model for tier ${askedTier}: set config.tiers or baseModel` });
|
|
289
|
+
await new Promise(r => setTimeout(r, 2_000));
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
const askedModel = `${routed.provider}/${routed.id}`;
|
|
293
|
+
// Start one SDK worker for this unit (or general A work when unitKey null)
|
|
294
|
+
const workerLabel = unitKey ?? `_phase-${phase ?? "general"}`;
|
|
295
|
+
saveSupervisor(targetDir, {
|
|
296
|
+
runId: runState.runId,
|
|
297
|
+
updatedAt: new Date().toISOString(),
|
|
298
|
+
worker: {
|
|
299
|
+
name: "W1",
|
|
300
|
+
unitKey: workerLabel,
|
|
301
|
+
unitLabel: brief.task?.description ?? brief.feature?.name ?? String(phase ?? "general"),
|
|
302
|
+
level: brief.task ? "task" : "phase",
|
|
303
|
+
difficulty: difficulty ?? null,
|
|
304
|
+
model: askedModel,
|
|
305
|
+
askedModel,
|
|
306
|
+
servedModel: null,
|
|
307
|
+
thinking: clampThinkingForProvider(routed.provider, tierSpec?.thinkingLevel ?? "") || undefined,
|
|
308
|
+
state: "starting",
|
|
309
|
+
doing: "starting",
|
|
310
|
+
startedAt: new Date().toISOString(),
|
|
311
|
+
turns: 0,
|
|
312
|
+
recycles: recycleCount.get(workerLabel) ?? 0,
|
|
313
|
+
tokens: { input: 0, output: 0 },
|
|
314
|
+
contextRatio: null,
|
|
315
|
+
sessionId: null,
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
appendActivity(targetDir, { level: "work", worker: "W1", text: `working ${workerLabel} on ${askedModel}` });
|
|
319
|
+
const briefMarkdown = renderBrief(brief, cfgForRouting);
|
|
320
|
+
let recycles = recycleCount.get(workerLabel) ?? 0;
|
|
321
|
+
// Worker session lifecycle with recycle on compaction
|
|
322
|
+
let turn = null;
|
|
323
|
+
let workerHandle = null;
|
|
324
|
+
try {
|
|
325
|
+
const workerFactory = await import("./worker.js");
|
|
326
|
+
workerHandle = await workerFactory.createWorker({
|
|
327
|
+
cwd: targetDir,
|
|
328
|
+
modelSpec: { provider: routed.provider, id: routed.id, thinkingLevel: clampThinkingForProvider(routed.provider, tierSpec?.thinkingLevel ?? "") || undefined },
|
|
329
|
+
askedModel,
|
|
330
|
+
sessionManagerDir: `harness/sessions/${workerLabel.replace(/[^a-z0-9._-]/gi, "-")}`,
|
|
331
|
+
customTools: (await import("./isolation.js")).harnessToolsForWorker(),
|
|
332
|
+
});
|
|
333
|
+
// Capture served model lazily from events after prompt
|
|
334
|
+
turn = await workerFactory.promptWorker(workerHandle, { text: briefMarkdown, timeoutMs: cfgForRouting.limits?.unitWallClockMs ?? 30 * 60 * 1000 });
|
|
335
|
+
}
|
|
336
|
+
catch (e) {
|
|
337
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
338
|
+
const isCredentialSync = msg.includes("CredentialSynchronizationError") || e?.name === "CredentialSynchronizationError";
|
|
339
|
+
if (isCredentialSync) {
|
|
340
|
+
appendActivity(targetDir, { level: "warn", worker: "W1", text: `credential sync error — retrying once: ${msg}` });
|
|
341
|
+
await new Promise(r => setTimeout(r, 1500));
|
|
342
|
+
// Retry once
|
|
343
|
+
try {
|
|
344
|
+
const workerFactory = await import("./worker.js");
|
|
345
|
+
if (!workerHandle) {
|
|
346
|
+
workerHandle = await workerFactory.createWorker({
|
|
347
|
+
cwd: targetDir,
|
|
348
|
+
modelSpec: { provider: routed.provider, id: routed.id, thinkingLevel: clampThinkingForProvider(routed.provider, tierSpec?.thinkingLevel ?? "") || undefined },
|
|
349
|
+
askedModel,
|
|
350
|
+
sessionManagerDir: `harness/sessions/${workerLabel.replace(/[^a-z0-9._-]/gi, "-")}`,
|
|
351
|
+
customTools: (await import("./isolation.js")).harnessToolsForWorker(),
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
turn = await workerFactory.promptWorker(workerHandle, { text: briefMarkdown, timeoutMs: cfgForRouting.limits?.unitWallClockMs ?? 30 * 60 * 1000 });
|
|
355
|
+
}
|
|
356
|
+
catch (e2) {
|
|
357
|
+
appendActivity(targetDir, { level: "error", worker: "W1", text: `credential sync retry failed: ${e2 instanceof Error ? e2.message : String(e2)}` });
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
appendActivity(targetDir, { level: "error", worker: "W1", text: `worker failed: ${msg}` });
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
finally {
|
|
365
|
+
if (workerHandle) {
|
|
366
|
+
try {
|
|
367
|
+
workerHandle.dispose();
|
|
368
|
+
}
|
|
369
|
+
catch { }
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
if (!turn) {
|
|
373
|
+
// Worker never produced a turn — treat as non-event, re-brief next loop.
|
|
374
|
+
await new Promise(r => setTimeout(r, 1_000));
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
// Record asked vs served, usage, tools
|
|
378
|
+
const asked = askedModel;
|
|
379
|
+
const served = turn.servedModel ?? turn.askedModel ?? asked;
|
|
380
|
+
if (served && served !== asked) {
|
|
381
|
+
appendActivity(targetDir, { level: "warn", worker: "W1", text: `asked ${asked} but ${served} answered` });
|
|
382
|
+
}
|
|
383
|
+
// Budget accounting (per-tier, last reading IS total per session — we add it as one session's spend)
|
|
384
|
+
try {
|
|
385
|
+
const rs = loadRunState(targetDir);
|
|
386
|
+
if (rs) {
|
|
387
|
+
const tier = askedTier;
|
|
388
|
+
const inc = { input: turn.usage?.input ?? 0, output: turn.usage?.output ?? 0, cacheRead: turn.usage?.cacheRead ?? 0, cacheWrite: turn.usage?.cacheWrite ?? 0, cost: turn.usage?.cost ?? 0, calls: 1 };
|
|
389
|
+
addUsageForTier(rs.budget ?? { byTier: {}, cap: {} }, tier, inc);
|
|
390
|
+
rs.budget.byTier = rs.budget.byTier;
|
|
391
|
+
saveRunState(targetDir, rs);
|
|
392
|
+
const capCheck = isCapExceeded(rs.budget);
|
|
393
|
+
if (capCheck.exceeded) {
|
|
394
|
+
appendActivity(targetDir, { level: "warn", worker: "W1", text: capCheck.reason ?? "cap exceeded" });
|
|
395
|
+
await boundedStop(targetDir, capCheck.reason ?? "cap exceeded");
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
const hasConsult = false;
|
|
399
|
+
const { hasXLeak: _hasXLeak } = await import("./budget.js");
|
|
400
|
+
if (_hasXLeak(rs.budget, hasConsult)) {
|
|
401
|
+
await boundedStop(targetDir, xLeakReason(rs.budget));
|
|
402
|
+
break;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
catch { }
|
|
407
|
+
// Compaction => recycle the worker (fresh session, same unit, brief from disk)
|
|
408
|
+
if (turn.compacted) {
|
|
409
|
+
recycles += 1;
|
|
410
|
+
recycleCount.set(workerLabel, recycles);
|
|
411
|
+
appendActivity(targetDir, { level: "warn", worker: "W1", text: `compaction observed on ${workerLabel} — recycling (${recycles}/${maxRecycles})` });
|
|
412
|
+
if (recycles > maxRecycles) {
|
|
413
|
+
appendActivity(targetDir, { level: "error", worker: "W1", text: `maxRecycles exceeded for ${workerLabel} — stopping` });
|
|
414
|
+
await boundedStop(targetDir, `maxRecycles exceeded for ${workerLabel}`);
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
// Dispose and re-loop the same unit with a fresh session (brief from disk, not transcript).
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
// Zero-tool-calls settle => re-brief once, then it feeds no-progress fingerprint
|
|
421
|
+
if (!turn.tools || turn.tools.length === 0) {
|
|
422
|
+
appendActivity(targetDir, { level: "warn", worker: "W1", text: `worker settled with no tool calls — ${turn.summary?.slice(0, 120) ?? "(no summary)"}` });
|
|
423
|
+
}
|
|
424
|
+
// Run gate to decide next action (decideNext will run it again next loop, but we can steer immediately on FAIL).
|
|
425
|
+
// For now let decideNext be the referee: the loop top will call decideNext again and pick continue/advance/stop.
|
|
426
|
+
// Update supervisor with served/usage
|
|
427
|
+
try {
|
|
428
|
+
const sup = (await import("./supervisorState.js")).loadSupervisor(targetDir);
|
|
429
|
+
if (sup?.worker) {
|
|
430
|
+
sup.worker.servedModel = served;
|
|
431
|
+
sup.worker.tokens = { input: turn.usage?.input ?? 0, output: turn.usage?.output ?? 0, cacheRead: turn.usage?.cacheRead ?? 0, cacheWrite: turn.usage?.cacheWrite ?? 0, cost: turn.usage?.cost ?? 0, calls: sup.worker.tokens?.calls ?? 1 };
|
|
432
|
+
sup.worker.turns = (sup.worker.turns ?? 0) + 1;
|
|
433
|
+
(await import("./supervisorState.js")).saveSupervisor(targetDir, sup);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
catch { }
|
|
437
|
+
// If loop wants to steer on FAIL, it will do so next iteration. We just close the worker (handoff).
|
|
438
|
+
// One worker = one unit = one session; closing it is the handoff.
|
|
439
|
+
iterations += 1;
|
|
440
|
+
if (iterations > 10_000) {
|
|
441
|
+
await boundedStop(targetDir, "iteration guard");
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
// Small yield to keep dashboard/heartbeat flowing
|
|
445
|
+
await new Promise(r => setTimeout(r, 200));
|
|
446
|
+
}
|
|
447
|
+
await boundedStop(targetDir, "loop ended");
|
|
448
|
+
}
|
|
449
|
+
// Only run when executed as the daemon entry (not when imported).
|
|
450
|
+
if (process.argv[1] && resolve(process.argv[1]) === resolve(new URL(import.meta.url).pathname) || process.env[WORKER_ENV] !== "1") {
|
|
451
|
+
// Allow both: `node dist/daemon/index.js <dir>` or `node src/daemon/index.ts <dir>` with --experimental-strip-types.
|
|
452
|
+
// Detect daemon entry by checking argv[2] is a directory with harness.
|
|
453
|
+
const arg = process.argv[2];
|
|
454
|
+
if (arg && existsSync(resolve(arg, "harness"))) {
|
|
455
|
+
main().catch(e => { console.error(e); process.exit(1); });
|
|
456
|
+
}
|
|
457
|
+
else if (!arg) {
|
|
458
|
+
// In WSL/tests the daemon is not started automatically.
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/daemon/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* infinity-harness — daemon/isolation.ts
|
|
3
|
+
*
|
|
4
|
+
* Worker isolation: a worker session must not load the harness extension into
|
|
5
|
+
* the Daemon's process, and must receive the harness tools as customTools.
|
|
6
|
+
*
|
|
7
|
+
* The SDK loads discovered extensions by default (DefaultResourceLoader with
|
|
8
|
+
* reload()). infinity-harness IS an installed pi extension, so a default
|
|
9
|
+
* loader would load it inside the Daemon and each worker would register
|
|
10
|
+
* session_start, commands and widgets — sharing module state and driving runs.
|
|
11
|
+
*
|
|
12
|
+
* This module produces:
|
|
13
|
+
* - a harness-free ResourceLoader (noExtensions, noSkills where appropriate)
|
|
14
|
+
* - the harness ToolDefinitions to hand to workers as customTools
|
|
15
|
+
* - a helper to assert isolation in tests
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Build a ResourceLoader that WILL NOT discover the harness extension.
|
|
19
|
+
* Workers receive this as `resourceLoader`.
|
|
20
|
+
*/
|
|
21
|
+
export async function createIsolatedLoader(opts) {
|
|
22
|
+
const { DefaultResourceLoader, SettingsManager } = await import("@earendil-works/pi-coding-agent");
|
|
23
|
+
const settingsManager = SettingsManager.create(opts.cwd, opts.agentDir);
|
|
24
|
+
const loader = new DefaultResourceLoader({
|
|
25
|
+
cwd: opts.cwd,
|
|
26
|
+
agentDir: opts.agentDir ?? "",
|
|
27
|
+
settingsManager,
|
|
28
|
+
noExtensions: true,
|
|
29
|
+
noSkills: true,
|
|
30
|
+
noContextFiles: true,
|
|
31
|
+
});
|
|
32
|
+
await loader.reload();
|
|
33
|
+
return loader;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Minimal harness tools that a worker needs to function.
|
|
37
|
+
* Daemon hands these as `customTools` so the worker's ability to record work
|
|
38
|
+
* is declared, not discovered. A worker that cannot record is a worker whose
|
|
39
|
+
* unit loops forever.
|
|
40
|
+
*/
|
|
41
|
+
export function harnessToolsForWorker() {
|
|
42
|
+
return [
|
|
43
|
+
{
|
|
44
|
+
name: "infinity_plan",
|
|
45
|
+
description: "Atomic plan editor: submit the full task list. Omission=deletion, baseRevision guard, cycle/missingDep checks.",
|
|
46
|
+
parameters: {
|
|
47
|
+
type: "object",
|
|
48
|
+
properties: {
|
|
49
|
+
baseRevision: { type: "number" },
|
|
50
|
+
tasks: { type: "array", items: { type: "object" } },
|
|
51
|
+
features: { type: "array", items: { type: "object" } },
|
|
52
|
+
goal: { type: "string" },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
handler: async () => ({ content: [{ type: "text", text: "infinity_plan stub — Daemon replaces this handler" }] }),
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: "infinity_validate",
|
|
59
|
+
description: "Run the deterministic gate; model never decides PASS/FAIL.",
|
|
60
|
+
parameters: { type: "object", properties: {} },
|
|
61
|
+
handler: async () => ({ content: [{ type: "text", text: "infinity_validate stub" }] }),
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: "infinity_brief",
|
|
65
|
+
description: "Return the rendered brief for the next unit.",
|
|
66
|
+
parameters: { type: "object", properties: {} },
|
|
67
|
+
handler: async () => ({ content: [{ type: "text", text: "infinity_brief stub" }] }),
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Test assertion: a worker session's loader has zero harness extension instances.
|
|
73
|
+
* The session's extensionsResult captures what was loaded; we count any factory
|
|
74
|
+
* whose id contains "infinity-harness".
|
|
75
|
+
*/
|
|
76
|
+
export function assertZeroHarnessExtensions(extensionsResult) {
|
|
77
|
+
const result = extensionsResult;
|
|
78
|
+
const list = result?.extensions ?? [];
|
|
79
|
+
const found = list.filter((e) => String(e?.id ?? e?.name ?? "").includes("infinity-harness"));
|
|
80
|
+
if (found.length !== 0) {
|
|
81
|
+
throw new Error(`isolation violated: worker loaded ${found.length} harness extension(s): ${found.map(f => f.id ?? f.name).join(", ")}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=isolation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isolation.js","sourceRoot":"","sources":["../../../src/daemon/isolation.ts"],"names":[],"mappings":"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"}
|