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
package/dist/src/goal.js
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* infinity-harness — the goal loop, connected to the pipeline.
|
|
3
|
+
*
|
|
4
|
+
* `goalSpec`, `goalLoop` and `goalState` are a complete outer loop: state a
|
|
5
|
+
* goal, do a pass of work, judge whether the goal is actually met, and go
|
|
6
|
+
* round again if it is not, under iteration and wall-clock limits. Ported from
|
|
7
|
+
* pi-long-task, 1,600 lines, fully typed, well tested.
|
|
8
|
+
*
|
|
9
|
+
* And nothing ever turned the crank. `createGoalLoopState` was called by its
|
|
10
|
+
* own tests and by nothing else. The three modules were a state machine with
|
|
11
|
+
* no driver — which is why the harness could finish a pipeline and declare
|
|
12
|
+
* "complete" without anyone ever asking the only question that matters: is the
|
|
13
|
+
* thing the human asked for actually done?
|
|
14
|
+
*
|
|
15
|
+
* This module is the driver, and the mapping it chooses is the whole design:
|
|
16
|
+
*
|
|
17
|
+
* one goal iteration = one full pass of the phase pipeline
|
|
18
|
+
*
|
|
19
|
+
* DEFINE→SHIP produces work; the goal loop then asks whether that work met the
|
|
20
|
+
* goal. If it did, the run is over. If it did not, the pipeline is rewound to
|
|
21
|
+
* DEFINE with the remaining work named, and the next iteration begins. The
|
|
22
|
+
* gate decides whether the *work* is done; the goal loop decides whether the
|
|
23
|
+
* *goal* is done. They are different questions and the harness needed both.
|
|
24
|
+
*
|
|
25
|
+
* The reviewer's verdict comes from the agent, not from here. Whether a body
|
|
26
|
+
* of work satisfies a stated goal is a judgement, and the harness's rule is
|
|
27
|
+
* that judgements belong to the model while enforcement belongs to the gate.
|
|
28
|
+
* What this module enforces is that the judgement is recorded, bounded, and
|
|
29
|
+
* has consequences.
|
|
30
|
+
*/
|
|
31
|
+
import { resolve } from "node:path";
|
|
32
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
33
|
+
import { createGoalLoopState, startGoalIteration, recordGeneratedTodo, recordWorkerResult, recordReviewerResult, cancelGoalLoop, goalLoopStopReason, } from "./goalLoop.js";
|
|
34
|
+
import { GoalStateStore, canonicalGoalSpecPath } from "./goalState.js";
|
|
35
|
+
import { createGoalSpecification } from "./goalSpec.js";
|
|
36
|
+
import { loadConfig, saveConfig } from "./core/config.js";
|
|
37
|
+
import { loadFeatureList, computeProgress } from "./core/featureList.js";
|
|
38
|
+
import { writeTaskList } from "./taskList.js";
|
|
39
|
+
import { harnessDir } from "./core/paths.js";
|
|
40
|
+
import { readJsonSafe, writeJsonAtomic } from "./core/fsx.js";
|
|
41
|
+
import { getPhaseOrder } from "./core/phases.js";
|
|
42
|
+
import { PHASE_ROLE } from "./core/types.js";
|
|
43
|
+
/** Which goal run this project is on, so a new session can find it. */
|
|
44
|
+
export const GOAL_POINTER_FILE = "goal.json";
|
|
45
|
+
export function goalPointerPath(targetDir) {
|
|
46
|
+
return resolve(harnessDir(targetDir), GOAL_POINTER_FILE);
|
|
47
|
+
}
|
|
48
|
+
function readPointer(targetDir) {
|
|
49
|
+
return readJsonSafe(goalPointerPath(targetDir), null);
|
|
50
|
+
}
|
|
51
|
+
function storeFor(targetDir, pointer) {
|
|
52
|
+
return new GoalStateStore({
|
|
53
|
+
cwd: targetDir,
|
|
54
|
+
goalRunId: pointer.goalRunId,
|
|
55
|
+
goalRunDir: pointer.goalRunDir,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
export function viewOf(state) {
|
|
59
|
+
const last = state.iterations[state.iterations.length - 1];
|
|
60
|
+
return {
|
|
61
|
+
goal: state.goal,
|
|
62
|
+
goalRunId: state.goalRunId,
|
|
63
|
+
status: state.status,
|
|
64
|
+
phase: state.phase,
|
|
65
|
+
iteration: state.currentIteration,
|
|
66
|
+
maxIterations: state.limits.maxIterations,
|
|
67
|
+
remainingWork: last?.reviewerResult?.remainingWork ?? [],
|
|
68
|
+
completion: state.completion,
|
|
69
|
+
startedAt: state.startedAt,
|
|
70
|
+
deadlineAt: state.deadlineAt,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/** The goal run this project is on, or null. Never throws. */
|
|
74
|
+
export async function loadGoal(targetDir) {
|
|
75
|
+
const pointer = readPointer(targetDir);
|
|
76
|
+
if (!pointer)
|
|
77
|
+
return null;
|
|
78
|
+
try {
|
|
79
|
+
return await storeFor(targetDir, pointer).loadState();
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* State a goal and open iteration 1.
|
|
87
|
+
*
|
|
88
|
+
* The goal specification is written to `harness/goals/GOAL_SPEC.json` — a
|
|
89
|
+
* committed, human-readable statement of what this run is for — while the
|
|
90
|
+
* loop's own state lives under `tmp/`, because it is run bookkeeping and
|
|
91
|
+
* nobody wants it in a diff.
|
|
92
|
+
*/
|
|
93
|
+
export async function startGoal(options) {
|
|
94
|
+
const { targetDir, runId } = options;
|
|
95
|
+
const goal = options.goal.trim();
|
|
96
|
+
if (!goal)
|
|
97
|
+
throw new Error("a goal needs to say something");
|
|
98
|
+
const existing = await loadGoal(targetDir);
|
|
99
|
+
if (existing && existing.status === "running") {
|
|
100
|
+
throw new Error(`This project is already pursuing a goal: "${existing.goal}". ` +
|
|
101
|
+
`Finish it or cancel it (/infinity:goal cancel) before starting another.`);
|
|
102
|
+
}
|
|
103
|
+
const spec = createGoalSpecification({ goalRunId: runId, originalGoal: goal, now: () => options.now ?? new Date() });
|
|
104
|
+
let state = createGoalLoopState({
|
|
105
|
+
goal,
|
|
106
|
+
goalRunId: runId,
|
|
107
|
+
cwd: targetDir,
|
|
108
|
+
maxIterations: options.maxIterations,
|
|
109
|
+
timeoutMs: options.timeoutMs,
|
|
110
|
+
now: () => options.now ?? new Date(),
|
|
111
|
+
});
|
|
112
|
+
state = startGoalIteration(state, { now: options.now });
|
|
113
|
+
const store = new GoalStateStore({ cwd: targetDir, goalRunId: runId, goalRunDir: state.goalRunDir });
|
|
114
|
+
await store.ensureRunDir();
|
|
115
|
+
await store.saveGoalSpecificationWithCanonical(spec, targetDir);
|
|
116
|
+
await store.saveState(state);
|
|
117
|
+
writeJsonAtomic(goalPointerPath(targetDir), {
|
|
118
|
+
goalRunId: runId,
|
|
119
|
+
goalRunDir: state.goalRunDir,
|
|
120
|
+
startedAt: state.startedAt,
|
|
121
|
+
});
|
|
122
|
+
// The goal also becomes the pipeline's goal, so every brief carries it.
|
|
123
|
+
rewindPipeline(targetDir, goal, [], 1, state.limits.maxIterations);
|
|
124
|
+
return { state, spec };
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Record that the pipeline has produced a pass of work.
|
|
128
|
+
*
|
|
129
|
+
* Called when the phase pipeline completes. Moves the iteration through
|
|
130
|
+
* `todo_generated` → `todo_executed`, which is what makes it reviewable.
|
|
131
|
+
*/
|
|
132
|
+
export async function recordPipelinePass(targetDir, summary, now) {
|
|
133
|
+
const pointer = readPointer(targetDir);
|
|
134
|
+
if (!pointer)
|
|
135
|
+
return null;
|
|
136
|
+
const store = storeFor(targetDir, pointer);
|
|
137
|
+
let state;
|
|
138
|
+
try {
|
|
139
|
+
state = await store.loadState();
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
if (state.status !== "running")
|
|
145
|
+
return state;
|
|
146
|
+
const iteration = state.currentIteration;
|
|
147
|
+
const { list } = loadFeatureList(targetDir);
|
|
148
|
+
const progress = computeProgress(list);
|
|
149
|
+
const at = (now ?? new Date()).toISOString();
|
|
150
|
+
if (state.phase === "goal_received") {
|
|
151
|
+
state = recordGeneratedTodo(state, iteration, { todoPath: "harness/features/feature-list.json", summary: `${progress.tasksTotal} task(s) planned`, generatedAt: at }, { now });
|
|
152
|
+
}
|
|
153
|
+
if (state.phase === "todo_generated") {
|
|
154
|
+
state = recordWorkerResult(state, iteration, {
|
|
155
|
+
status: progress.tasksDone === progress.tasksTotal ? "done" : "partial",
|
|
156
|
+
summary,
|
|
157
|
+
totalTasks: progress.tasksTotal,
|
|
158
|
+
completedTasks: progress.tasksDone,
|
|
159
|
+
endedAt: at,
|
|
160
|
+
}, { now });
|
|
161
|
+
}
|
|
162
|
+
await store.saveState(state);
|
|
163
|
+
return state;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Judge whether the work meets the goal, and act on the answer.
|
|
167
|
+
*
|
|
168
|
+
* A `complete` verdict ends the run. Anything else opens the next iteration
|
|
169
|
+
* and rewinds the pipeline, because the harness has no other way to do more
|
|
170
|
+
* work: the phase machine is forward-only, so a second pass means starting a
|
|
171
|
+
* second pass, with the remaining work stated up front.
|
|
172
|
+
*/
|
|
173
|
+
export async function reviewGoal(targetDir, input, now) {
|
|
174
|
+
const pointer = readPointer(targetDir);
|
|
175
|
+
if (!pointer)
|
|
176
|
+
throw new Error("No goal is being pursued in this project. Start one with /infinity:goal.");
|
|
177
|
+
const store = storeFor(targetDir, pointer);
|
|
178
|
+
let state = await store.loadState();
|
|
179
|
+
if (state.status !== "running") {
|
|
180
|
+
return { state, terminal: true, message: `The goal loop already finished: ${state.status}.`, rewoundTo: null };
|
|
181
|
+
}
|
|
182
|
+
// A review can legitimately arrive before the pipeline finishes: someone can
|
|
183
|
+
// already see that this pass will not meet the goal, and making them wait
|
|
184
|
+
// for a doomed pipeline to complete first is theatre. The state machine only
|
|
185
|
+
// accepts a verdict on an iteration that has recorded its work, so record it
|
|
186
|
+
// — otherwise the caller gets `Cannot update goal iteration 2 from status
|
|
187
|
+
// pending`, which names an internal phase and helps nobody.
|
|
188
|
+
if (state.phase === "goal_received" || state.phase === "todo_generated") {
|
|
189
|
+
const caught = await recordPipelinePass(targetDir, "reviewed before the pipeline finished", now);
|
|
190
|
+
if (caught)
|
|
191
|
+
state = caught;
|
|
192
|
+
}
|
|
193
|
+
const at = (now ?? new Date()).toISOString();
|
|
194
|
+
const remainingWork = (input.remainingWork ?? []).map((s) => s.trim()).filter(Boolean);
|
|
195
|
+
if (input.decision !== "complete" && remainingWork.length === 0) {
|
|
196
|
+
// "Not done" with nothing named is not a review, it is a shrug — and the
|
|
197
|
+
// next iteration would start with no more information than this one had.
|
|
198
|
+
throw new Error(`A "${input.decision}" verdict must name what is still missing (remainingWork). ` +
|
|
199
|
+
`The next pass is planned from that list.`);
|
|
200
|
+
}
|
|
201
|
+
state = recordReviewerResult(state, state.currentIteration, {
|
|
202
|
+
decision: input.decision,
|
|
203
|
+
complete: input.decision === "complete",
|
|
204
|
+
summary: input.summary?.trim() || input.rationale.trim(),
|
|
205
|
+
rationale: input.rationale.trim(),
|
|
206
|
+
remainingWork,
|
|
207
|
+
reviewedAt: at,
|
|
208
|
+
}, { now });
|
|
209
|
+
if (state.status !== "running") {
|
|
210
|
+
await store.saveState(state);
|
|
211
|
+
await store.initializeResultIfMissing(state);
|
|
212
|
+
return {
|
|
213
|
+
state,
|
|
214
|
+
terminal: true,
|
|
215
|
+
rewoundTo: null,
|
|
216
|
+
message: state.status === "done"
|
|
217
|
+
? `Goal met after ${state.iterations.length} pass(es): ${state.goal}`
|
|
218
|
+
: `Goal loop ended ${state.status}: ${state.completion?.reason ?? input.rationale}`,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
// Not done, and not fatal: go round again — unless a limit says otherwise.
|
|
222
|
+
const stop = goalLoopStopReason(state, { now });
|
|
223
|
+
if (stop) {
|
|
224
|
+
state = cancelGoalLoop(state, stop.message, { now });
|
|
225
|
+
await store.saveState(state);
|
|
226
|
+
await store.initializeResultIfMissing(state);
|
|
227
|
+
return { state, terminal: true, rewoundTo: null, message: `Goal loop stopped: ${stop.message}` };
|
|
228
|
+
}
|
|
229
|
+
state = startGoalIteration(state, { now });
|
|
230
|
+
await store.saveState(state);
|
|
231
|
+
const phase = rewindPipeline(targetDir, state.goal, remainingWork, state.currentIteration, state.limits.maxIterations);
|
|
232
|
+
return {
|
|
233
|
+
state,
|
|
234
|
+
terminal: false,
|
|
235
|
+
rewoundTo: phase,
|
|
236
|
+
message: `Pass ${state.currentIteration - 1} did not meet the goal. Starting pass ${state.currentIteration} at ` +
|
|
237
|
+
`${phase.toUpperCase()} with ${remainingWork.length} item(s) still to do:\n` +
|
|
238
|
+
remainingWork.map((w) => ` - ${w}`).join("\n"),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/** Stop pursuing the goal, on purpose. */
|
|
242
|
+
export async function cancelGoal(targetDir, reason, now) {
|
|
243
|
+
const pointer = readPointer(targetDir);
|
|
244
|
+
if (!pointer)
|
|
245
|
+
return null;
|
|
246
|
+
const store = storeFor(targetDir, pointer);
|
|
247
|
+
let state;
|
|
248
|
+
try {
|
|
249
|
+
state = await store.loadState();
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
if (state.status !== "running")
|
|
255
|
+
return state;
|
|
256
|
+
state = cancelGoalLoop(state, reason, { now });
|
|
257
|
+
await store.saveState(state);
|
|
258
|
+
await store.initializeResultIfMissing(state);
|
|
259
|
+
return state;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Point the pipeline at the goal and send it back to the first phase.
|
|
263
|
+
*
|
|
264
|
+
* The phase machine is forward-only by design — the agent must not be able to
|
|
265
|
+
* decide it is bored of BUILD. Rewinding is therefore not something the agent
|
|
266
|
+
* can do; it happens here, once, when a review says the goal is not met, and
|
|
267
|
+
* it is recorded in the goal trace.
|
|
268
|
+
*/
|
|
269
|
+
function rewindPipeline(targetDir, goal, remainingWork = [], pass = 1, maxPasses = 1) {
|
|
270
|
+
// The goal belongs in the plan, not the config: `harness/features/feature-list.json`
|
|
271
|
+
// is the single source of truth the brief, the widget and the dashboard all
|
|
272
|
+
// read. Writing it anywhere else means a goal nothing displays.
|
|
273
|
+
try {
|
|
274
|
+
writeTaskList(targetDir, { goal });
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
// A plan too broken to accept a goal is a problem the gate will report;
|
|
278
|
+
// it must not stop the goal loop from being recorded.
|
|
279
|
+
}
|
|
280
|
+
const { config, ok } = loadConfig(targetDir);
|
|
281
|
+
if (!ok)
|
|
282
|
+
return "define";
|
|
283
|
+
const order = getPhaseOrder(config.phases?.enabled);
|
|
284
|
+
const first = order[0] ?? "define";
|
|
285
|
+
config.currentPhase = first;
|
|
286
|
+
config.currentRole = PHASE_ROLE[first];
|
|
287
|
+
config.remainingWork = remainingWork;
|
|
288
|
+
config.goalPass = pass;
|
|
289
|
+
config.goalMaxPasses = maxPasses;
|
|
290
|
+
// A new pass starts with fresh retry budgets. The old ones were spent on
|
|
291
|
+
// work that turned out to be insufficient, not on work that was wrong.
|
|
292
|
+
config.taskRetryCount = 0;
|
|
293
|
+
config.featureRetryCount = 0;
|
|
294
|
+
config.phaseRetryCount = 0;
|
|
295
|
+
saveConfig(targetDir, config);
|
|
296
|
+
return first;
|
|
297
|
+
}
|
|
298
|
+
/** The canonical goal specification, if one has been written. */
|
|
299
|
+
export function readGoalSpec(targetDir) {
|
|
300
|
+
const path = canonicalGoalSpecPath(targetDir);
|
|
301
|
+
if (!existsSync(path))
|
|
302
|
+
return null;
|
|
303
|
+
try {
|
|
304
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/** One line for the widget and the status command. */
|
|
311
|
+
export function describeGoal(view) {
|
|
312
|
+
if (view.status !== "running") {
|
|
313
|
+
return `goal ${view.status}: ${view.goal}`;
|
|
314
|
+
}
|
|
315
|
+
return `goal pass ${view.iteration}/${view.maxIterations} · ${view.goal}`;
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=goal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal.js","sourceRoot":"","sources":["../../src/goal.ts"],"names":[],"mappings":"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"}
|