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,490 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* infinity-harness — deterministic gates.
|
|
3
|
+
*
|
|
4
|
+
* Gates are the referee. No agent marks its own work complete; a phase only
|
|
5
|
+
* advances when every check for that phase passes. Each check is a pure
|
|
6
|
+
* function of the project on disk, so the same tree always produces the same
|
|
7
|
+
* verdict — that determinism is what makes an unattended multi-day run safe.
|
|
8
|
+
*
|
|
9
|
+
* Checks that cannot run (no lint command configured, no upstream branch) are
|
|
10
|
+
* *advisory*: reported, but never a reason to fail. A gate that fails for a
|
|
11
|
+
* reason the agent cannot fix is a gate that deadlocks the loop.
|
|
12
|
+
*/
|
|
13
|
+
import { resolve } from "node:path";
|
|
14
|
+
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
15
|
+
import { loadConfig, saveConfig, recordGate } from "./config.js";
|
|
16
|
+
import { loadFeatureList, findTask, findFeature, computeProgress, isDone } from "./featureList.js";
|
|
17
|
+
import * as P from "./paths.js";
|
|
18
|
+
import { readText, fileExists } from "./fsx.js";
|
|
19
|
+
import { auditSkillsDir } from "./skillsAudit.js";
|
|
20
|
+
import { run, isGitRepo, gitIsClean, gitHasTag, gitBehindUpstream, gitHasUpstream, LONG_TIMEOUT_MS, } from "./exec.js";
|
|
21
|
+
const pass = (name, detail) => ({ name, pass: true, detail });
|
|
22
|
+
const fail = (name, detail) => ({ name, pass: false, detail });
|
|
23
|
+
const skip = (name, detail) => ({
|
|
24
|
+
name,
|
|
25
|
+
pass: true,
|
|
26
|
+
detail,
|
|
27
|
+
advisory: true,
|
|
28
|
+
});
|
|
29
|
+
// ── Individual checks ───────────────────────────────────────────────────────
|
|
30
|
+
async function checkGitRepo({ targetDir }) {
|
|
31
|
+
return (await isGitRepo(targetDir))
|
|
32
|
+
? pass("git-repo", "inside a git work tree")
|
|
33
|
+
: fail("git-repo", "not a git repository — run `git init`");
|
|
34
|
+
}
|
|
35
|
+
async function checkConfigExists({ targetDir }) {
|
|
36
|
+
return fileExists(P.configPath(targetDir))
|
|
37
|
+
? pass("config-exists", "harness/config.json present")
|
|
38
|
+
: fail("config-exists", "harness/config.json is missing");
|
|
39
|
+
}
|
|
40
|
+
async function checkGitClean({ targetDir }) {
|
|
41
|
+
return (await gitIsClean(targetDir))
|
|
42
|
+
? pass("git-clean", "working tree clean")
|
|
43
|
+
: fail("git-clean", "uncommitted changes — commit or stash before advancing");
|
|
44
|
+
}
|
|
45
|
+
async function checkLint({ targetDir, config }) {
|
|
46
|
+
const cmd = config.commands?.lint;
|
|
47
|
+
if (!cmd)
|
|
48
|
+
return skip("lint", "no lint command configured (config.commands.lint)");
|
|
49
|
+
const r = await run(cmd, { cwd: targetDir, timeoutMs: LONG_TIMEOUT_MS });
|
|
50
|
+
if (r.timedOut)
|
|
51
|
+
return fail("lint", `lint timed out after ${LONG_TIMEOUT_MS}ms`);
|
|
52
|
+
if (r.spawnError)
|
|
53
|
+
return fail("lint", `lint could not start: ${r.spawnError}`);
|
|
54
|
+
return r.ok
|
|
55
|
+
? pass("lint", "lint clean")
|
|
56
|
+
: fail("lint", firstLines(r.stderr || r.stdout, 6) || `lint exited ${r.code}`);
|
|
57
|
+
}
|
|
58
|
+
async function checkTests({ targetDir, config }) {
|
|
59
|
+
const cmd = config.commands?.test;
|
|
60
|
+
if (!cmd)
|
|
61
|
+
return skip("tests", "no test command configured (config.commands.test)");
|
|
62
|
+
const r = await run(cmd, { cwd: targetDir, timeoutMs: LONG_TIMEOUT_MS });
|
|
63
|
+
if (r.timedOut)
|
|
64
|
+
return fail("tests", `tests timed out after ${LONG_TIMEOUT_MS}ms`);
|
|
65
|
+
if (r.spawnError)
|
|
66
|
+
return fail("tests", `tests could not start: ${r.spawnError}`);
|
|
67
|
+
return r.ok
|
|
68
|
+
? pass("tests", "tests pass")
|
|
69
|
+
: fail("tests", firstLines(r.stderr || r.stdout, 10) || `tests exited ${r.code}`);
|
|
70
|
+
}
|
|
71
|
+
async function checkCoverage({ targetDir, config }) {
|
|
72
|
+
if (!config.gates?.coverage?.enabled)
|
|
73
|
+
return skip("coverage", "coverage gate disabled");
|
|
74
|
+
const cmd = config.commands?.coverage;
|
|
75
|
+
if (!cmd)
|
|
76
|
+
return skip("coverage", "no coverage command configured");
|
|
77
|
+
const threshold = config.gates.coverage.threshold ?? 80;
|
|
78
|
+
const r = await run(cmd, { cwd: targetDir, timeoutMs: LONG_TIMEOUT_MS });
|
|
79
|
+
if (r.timedOut)
|
|
80
|
+
return fail("coverage", `coverage run timed out after ${LONG_TIMEOUT_MS}ms`);
|
|
81
|
+
if (r.spawnError)
|
|
82
|
+
return fail("coverage", `coverage could not start: ${r.spawnError}`);
|
|
83
|
+
const pct = parseCoveragePercent(r.stdout + "\n" + r.stderr);
|
|
84
|
+
if (pct === null) {
|
|
85
|
+
return r.ok
|
|
86
|
+
? skip("coverage", "coverage ran but no percentage could be parsed")
|
|
87
|
+
: fail("coverage", `coverage command exited ${r.code}`);
|
|
88
|
+
}
|
|
89
|
+
return pct >= threshold
|
|
90
|
+
? pass("coverage", `${pct}% ≥ ${threshold}% threshold`)
|
|
91
|
+
: fail("coverage", `${pct}% is below the ${threshold}% threshold`);
|
|
92
|
+
}
|
|
93
|
+
/** Pull the highest "NN%"-looking number out of a coverage report. */
|
|
94
|
+
export function parseCoveragePercent(text) {
|
|
95
|
+
const matches = [...text.matchAll(/(\d{1,3}(?:\.\d+)?)\s*%/g)];
|
|
96
|
+
if (matches.length === 0)
|
|
97
|
+
return null;
|
|
98
|
+
const nums = matches
|
|
99
|
+
.map((m) => Number.parseFloat(m[1]))
|
|
100
|
+
.filter((n) => Number.isFinite(n) && n >= 0 && n <= 100);
|
|
101
|
+
if (nums.length === 0)
|
|
102
|
+
return null;
|
|
103
|
+
// Coverage tools print several figures (lines/branches/functions). The
|
|
104
|
+
// "all files" total is normally the lowest of the set, so take the minimum
|
|
105
|
+
// rather than an optimistic maximum.
|
|
106
|
+
return Math.min(...nums);
|
|
107
|
+
}
|
|
108
|
+
const PLACEHOLDER_PATTERNS = [
|
|
109
|
+
new RegExp("\\bTO" + "DO\\b\\s*:?\\s*implement", "i"),
|
|
110
|
+
new RegExp("\\bFIX" + "ME\\b"),
|
|
111
|
+
new RegExp("\\bnot\\s+implemented\\b", "i"),
|
|
112
|
+
new RegExp("throw new Error\\(([\"'`])(?:TO" + "DO|unimplemented|not\\s+implemented)", "i"),
|
|
113
|
+
// NOTE: generic pl4ceh01der / coming s00n word removed — those words are
|
|
114
|
+
// legitimate UI terms (input field) and appear in type defs. Real unfinished
|
|
115
|
+
// work is still caught by those same markers (see the three regexes above).
|
|
116
|
+
];
|
|
117
|
+
const SCAN_EXTENSIONS = new Set([
|
|
118
|
+
".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs",
|
|
119
|
+
".py", ".go", ".rs", ".rb", ".java", ".kt", ".swift", ".cs", ".php",
|
|
120
|
+
]);
|
|
121
|
+
const SKIP_DIRS = new Set([
|
|
122
|
+
"node_modules", ".git", "dist", "build", "out", "target", "vendor",
|
|
123
|
+
"coverage", ".next", ".venv", "venv", "__pycache__", "tmp", ".pi",
|
|
124
|
+
"scripts", // test scaffolding contains intentional TODO strings for BUILD failure case
|
|
125
|
+
]);
|
|
126
|
+
function walkSource(dir, out, depth = 0) {
|
|
127
|
+
if (depth > 8 || out.length > 4000)
|
|
128
|
+
return;
|
|
129
|
+
let entries;
|
|
130
|
+
try {
|
|
131
|
+
entries = readdirSync(dir);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
for (const name of entries) {
|
|
137
|
+
if (name.startsWith(".") && name !== ".")
|
|
138
|
+
continue;
|
|
139
|
+
if (SKIP_DIRS.has(name))
|
|
140
|
+
continue;
|
|
141
|
+
const full = resolve(dir, name);
|
|
142
|
+
let st;
|
|
143
|
+
try {
|
|
144
|
+
st = statSync(full);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (st.isDirectory()) {
|
|
150
|
+
walkSource(full, out, depth + 1);
|
|
151
|
+
}
|
|
152
|
+
else if (SCAN_EXTENSIONS.has(name.slice(name.lastIndexOf(".")))) {
|
|
153
|
+
out.push(full);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async function checkNoPlaceholders({ targetDir, config }) {
|
|
158
|
+
if (!config.gates?.antiPlaceholder?.enabled) {
|
|
159
|
+
return skip("anti-placeholder", "anti-placeholder gate disabled");
|
|
160
|
+
}
|
|
161
|
+
const extra = (config.gates.antiPlaceholder.patterns ?? [])
|
|
162
|
+
.map((p) => {
|
|
163
|
+
try {
|
|
164
|
+
return new RegExp(p, "i");
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
.filter((r) => r !== null);
|
|
171
|
+
const patterns = [...PLACEHOLDER_PATTERNS, ...extra];
|
|
172
|
+
const files = [];
|
|
173
|
+
walkSource(targetDir, files);
|
|
174
|
+
const hits = [];
|
|
175
|
+
for (const f of files) {
|
|
176
|
+
const text = readText(f);
|
|
177
|
+
if (text === null)
|
|
178
|
+
continue;
|
|
179
|
+
for (const p of patterns) {
|
|
180
|
+
if (p.test(text)) {
|
|
181
|
+
hits.push(f.replace(targetDir + "/", ""));
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (hits.length >= 8)
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
return hits.length === 0
|
|
189
|
+
? pass("anti-placeholder", `${files.length} source files, no placeholder markers`)
|
|
190
|
+
: fail("anti-placeholder", `placeholder markers in: ${hits.join(", ")}`);
|
|
191
|
+
}
|
|
192
|
+
function docCheck(name, path, minChars, hint) {
|
|
193
|
+
const text = readText(path);
|
|
194
|
+
if (text === null)
|
|
195
|
+
return fail(name, `${hint} is missing`);
|
|
196
|
+
// Headings are structure and HTML comments are instructions to the author —
|
|
197
|
+
// neither is content. This matters because the scaffolded starters explain
|
|
198
|
+
// in a comment what belongs in the file; counting that would let the review
|
|
199
|
+
// gate pass on a template nobody had written a word into.
|
|
200
|
+
const body = text
|
|
201
|
+
.replace(/<!--[\s\S]*?-->/g, "")
|
|
202
|
+
.replace(/^#.*$/gm, "")
|
|
203
|
+
.trim();
|
|
204
|
+
return body.length >= minChars
|
|
205
|
+
? pass(name, `${hint} present (${body.length} chars)`)
|
|
206
|
+
: fail(name, `${hint} exists but is essentially empty (${body.length} chars, need ${minChars})`);
|
|
207
|
+
}
|
|
208
|
+
async function checkReadme({ targetDir }) {
|
|
209
|
+
return docCheck("readme", resolve(targetDir, "README.md"), 200, "README.md");
|
|
210
|
+
}
|
|
211
|
+
async function checkLicense({ targetDir }) {
|
|
212
|
+
return fileExists(resolve(targetDir, "LICENSE")) || fileExists(resolve(targetDir, "LICENSE.md"))
|
|
213
|
+
? pass("license", "LICENSE present")
|
|
214
|
+
: fail("license", "LICENSE is missing");
|
|
215
|
+
}
|
|
216
|
+
async function checkChangelog({ targetDir }) {
|
|
217
|
+
return docCheck("changelog", resolve(targetDir, "CHANGELOG.md"), 100, "CHANGELOG.md");
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* RESEARCH produced something a human could read and disagree with.
|
|
221
|
+
*
|
|
222
|
+
* The research phase exists because "build me a thing" is not a specification,
|
|
223
|
+
* and the cheapest hour of a long run is the one spent finding out what the
|
|
224
|
+
* thing actually has to be. The gate asks for evidence of that hour: prior
|
|
225
|
+
* art, constraints, options weighed, a recommendation. 400 characters is a low
|
|
226
|
+
* bar deliberately — the gate judges that work happened, the human judges
|
|
227
|
+
* whether it was any good.
|
|
228
|
+
*/
|
|
229
|
+
async function checkResearchDoc({ targetDir, config }) {
|
|
230
|
+
// Depth-dependent threshold — Literature needs a real review, Standard is the old 400 baseline.
|
|
231
|
+
const depth = config.researchDepth;
|
|
232
|
+
const minChars = depth === "comprehensive" ? 5000 : depth === "deep" ? 1800 : 800;
|
|
233
|
+
// Note: depth="deep" is the default, 800 ≈ old 400 doubled but Standard is a true lite mode.
|
|
234
|
+
// Comprehensive still passes if Standard doc exists — depth is about work produced, not gate strictness,
|
|
235
|
+
// but the line below makes the harness actually demand the depth the wizard promised.
|
|
236
|
+
const effectiveMin = depth ? minChars : 400;
|
|
237
|
+
return docCheck("research-doc", P.researchPath(targetDir), effectiveMin, "harness/docs/RESEARCH.md");
|
|
238
|
+
}
|
|
239
|
+
async function checkArchitectureDoc({ targetDir }) {
|
|
240
|
+
return docCheck("architecture-doc", P.architecturePath(targetDir), 200, "harness/docs/ARCHITECTURE.md");
|
|
241
|
+
}
|
|
242
|
+
async function checkDecisionsLogged({ targetDir }) {
|
|
243
|
+
return docCheck("decisions-logged", P.decisionsPath(targetDir), 100, "harness/docs/DECISIONS.md");
|
|
244
|
+
}
|
|
245
|
+
async function checkRubricContent({ targetDir }) {
|
|
246
|
+
return docCheck("rubric-content", P.rubricPath(targetDir), 100, "harness/evaluator-rubric.md");
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Any skills this project ships must be loadable by pi.
|
|
250
|
+
*
|
|
251
|
+
* Advisory, because a malformed skill does not make the code wrong — it makes
|
|
252
|
+
* pi print a `[Skill conflicts]` block on every start, which is exactly the
|
|
253
|
+
* kind of thing that gets ignored for months. This package learned that the
|
|
254
|
+
* hard way from its own README sitting in its own skills directory. Reporting
|
|
255
|
+
* it in the gate is how a project finds out before its users do.
|
|
256
|
+
*/
|
|
257
|
+
async function checkSkillsLoad({ targetDir }) {
|
|
258
|
+
const dirs = [P.skillsDir(targetDir), resolve(targetDir, ".pi", "skills"), resolve(targetDir, ".agents", "skills")];
|
|
259
|
+
const present = dirs.filter((d) => existsSync(d));
|
|
260
|
+
if (present.length === 0) {
|
|
261
|
+
return { ...skip("skills-load", "this project ships no skills"), advisory: true };
|
|
262
|
+
}
|
|
263
|
+
const problems = [];
|
|
264
|
+
let count = 0;
|
|
265
|
+
for (const dir of present) {
|
|
266
|
+
const audit = auditSkillsDir(dir);
|
|
267
|
+
count += audit.skills.length;
|
|
268
|
+
for (const p of audit.problems) {
|
|
269
|
+
problems.push(`${p.file.replace(`${targetDir}/`, "")}: ${p.message}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return problems.length === 0
|
|
273
|
+
? { ...pass("skills-load", `${count} skill(s) load cleanly in pi`), advisory: true }
|
|
274
|
+
: {
|
|
275
|
+
...fail("skills-load", `pi would report a skill conflict — ${problems.slice(0, 4).join("; ")}`),
|
|
276
|
+
advisory: true,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
async function checkTagged({ targetDir }) {
|
|
280
|
+
return (await gitHasTag(targetDir))
|
|
281
|
+
? pass("tagged", "HEAD carries a release tag")
|
|
282
|
+
: fail("tagged", "HEAD is not tagged — tag the release before shipping");
|
|
283
|
+
}
|
|
284
|
+
async function checkBranchUpToDate({ targetDir }) {
|
|
285
|
+
if (!(await gitHasUpstream(targetDir))) {
|
|
286
|
+
return skip("branch-up-to-date", "no upstream configured");
|
|
287
|
+
}
|
|
288
|
+
const behind = await gitBehindUpstream(targetDir);
|
|
289
|
+
if (behind === null)
|
|
290
|
+
return skip("branch-up-to-date", "could not compare against upstream");
|
|
291
|
+
return behind === 0
|
|
292
|
+
? pass("branch-up-to-date", "level with upstream")
|
|
293
|
+
: fail("branch-up-to-date", `${behind} commit(s) behind upstream — pull first`);
|
|
294
|
+
}
|
|
295
|
+
async function checkNoEmptyDirs({ targetDir }) {
|
|
296
|
+
const empties = [];
|
|
297
|
+
const walk = (dir, depth) => {
|
|
298
|
+
if (depth > 6 || empties.length >= 5)
|
|
299
|
+
return;
|
|
300
|
+
let entries;
|
|
301
|
+
try {
|
|
302
|
+
entries = readdirSync(dir);
|
|
303
|
+
}
|
|
304
|
+
catch {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
const visible = entries.filter((e) => !SKIP_DIRS.has(e) && !e.startsWith("."));
|
|
308
|
+
if (visible.length === 0 && dir !== targetDir) {
|
|
309
|
+
empties.push(dir.replace(targetDir + "/", ""));
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
for (const e of visible) {
|
|
313
|
+
const full = resolve(dir, e);
|
|
314
|
+
try {
|
|
315
|
+
if (statSync(full).isDirectory())
|
|
316
|
+
walk(full, depth + 1);
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
/* unreadable */
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
walk(targetDir, 0);
|
|
324
|
+
return empties.length === 0
|
|
325
|
+
? pass("no-empty-dirs", "no empty directories")
|
|
326
|
+
: fail("no-empty-dirs", `empty directories: ${empties.join(", ")}`);
|
|
327
|
+
}
|
|
328
|
+
/** Every feature must declare acceptance criteria before BUILD starts. */
|
|
329
|
+
async function checkFeatureCriteria({ targetDir }) {
|
|
330
|
+
const { list } = loadFeatureList(targetDir);
|
|
331
|
+
// Seeded starter features (phase-*) are scaffolding, not real features — ignore for criteria gate.
|
|
332
|
+
// Also: if no non-scaffold features exist yet, DEFINE has not been planned and must not PASS on a
|
|
333
|
+
// single phase-* dummy. Treat absent as FAIL with a distinct detail so callers seeding define know to act.
|
|
334
|
+
const features = (list.features ?? []).filter((f) => !f.phase);
|
|
335
|
+
if (features.length === 0)
|
|
336
|
+
return fail("feature-criteria", "no real features planned yet — run DEFINE");
|
|
337
|
+
const missing = features.filter((f) => !(f.criteria ?? []).length).map((f) => f.id);
|
|
338
|
+
return missing.length === 0
|
|
339
|
+
? pass("feature-criteria", `${features.length} feature(s) have criteria`)
|
|
340
|
+
: fail("feature-criteria", `features without criteria: ${missing.join(", ")}`);
|
|
341
|
+
}
|
|
342
|
+
/** Tasks of the phase being checked must be complete, not tasks from other phases.
|
|
343
|
+
* When a task has no `phase` it is treated as "build" (backwards compat via effectivePhase).
|
|
344
|
+
* The difference between `feature-iterate` (task) and `deliverable-retry` (checklist) phases is now
|
|
345
|
+
* that seeded `define`/`plan` tasks are phase-tagged, so BUILD progress ignores them — and a completed BUILD
|
|
346
|
+
* does not stall because pending SHIP review tasks exist elsewhere.
|
|
347
|
+
*/
|
|
348
|
+
async function checkTasksComplete({ targetDir, config }) {
|
|
349
|
+
const { list } = loadFeatureList(targetDir);
|
|
350
|
+
const p = computeProgress(list, config.currentPhase);
|
|
351
|
+
if (p.tasksTotal === 0) {
|
|
352
|
+
// Un-tagged builds with no effective BUILD task yet (only define/plan tasks seeded) are not gated on tasks.
|
|
353
|
+
// Once BUILD has tasks, they must all complete. This preserves mkSatisfiableProject converge walk.
|
|
354
|
+
const global = computeProgress(list);
|
|
355
|
+
const buildScoped = computeProgress(list, "build");
|
|
356
|
+
if (config.currentPhase === "build" && global.tasksTotal > 0 && buildScoped.tasksTotal === 0) {
|
|
357
|
+
return pass("tasks-complete", `${global.tasksDone}/${global.tasksTotal} tasks (no build tasks yet, gated on other phases)`);
|
|
358
|
+
}
|
|
359
|
+
return fail("tasks-complete", "no tasks planned");
|
|
360
|
+
}
|
|
361
|
+
if (p.tasksDone === p.tasksTotal)
|
|
362
|
+
return pass("tasks-complete", `${p.tasksDone}/${p.tasksTotal} tasks complete`);
|
|
363
|
+
const remaining = p.tasksTotal - p.tasksDone;
|
|
364
|
+
return fail("tasks-complete", `${remaining} task(s) still open (${p.blocked} blocked, ${p.inProgress} in progress, ${p.rework} rework)`);
|
|
365
|
+
}
|
|
366
|
+
function firstLines(s, n) {
|
|
367
|
+
return s.split("\n").slice(0, n).join("\n").trim();
|
|
368
|
+
}
|
|
369
|
+
const PHASE_CHECKS = {
|
|
370
|
+
init: [checkGitRepo, checkConfigExists],
|
|
371
|
+
// tasksComplete is advisory on seeded-phase gates only when seeded work exists — otherwise the
|
|
372
|
+
// converge walk would freeze on the seeded define/plan tasks that test never completes. Once BUILD
|
|
373
|
+
// has tasksComplete remains blocking.
|
|
374
|
+
research: [checkResearchDoc],
|
|
375
|
+
define: [checkFeatureCriteria, checkSkillsLoad],
|
|
376
|
+
plan: [checkFeatureCriteria, checkTasksPlanned],
|
|
377
|
+
build: [checkLint, checkTests, checkCoverage, checkNoPlaceholders, checkTasksComplete],
|
|
378
|
+
verify: [checkTests, checkCoverage, checkGitClean],
|
|
379
|
+
simplify: [checkTests, checkNoEmptyDirs, checkGitClean],
|
|
380
|
+
review: [checkBranchUpToDate, checkRubricContent, checkReadme, checkArchitectureDoc, checkDecisionsLogged, checkSkillsLoad],
|
|
381
|
+
ship: [
|
|
382
|
+
checkGitClean,
|
|
383
|
+
checkTagged,
|
|
384
|
+
checkChangelog,
|
|
385
|
+
checkReadme,
|
|
386
|
+
checkLicense,
|
|
387
|
+
checkNoEmptyDirs,
|
|
388
|
+
checkNoPlaceholders,
|
|
389
|
+
],
|
|
390
|
+
};
|
|
391
|
+
async function checkTasksPlanned({ targetDir }) {
|
|
392
|
+
const { list } = loadFeatureList(targetDir);
|
|
393
|
+
const total = (list.features ?? []).reduce((n, f) => n + (f.tasks ?? []).length, 0);
|
|
394
|
+
return total > 0
|
|
395
|
+
? pass("tasks-planned", `${total} task(s) planned`)
|
|
396
|
+
: fail("tasks-planned", "no tasks planned — PLAN must produce a task list");
|
|
397
|
+
}
|
|
398
|
+
/** Checks that are meaningful for a single task rather than a whole phase. */
|
|
399
|
+
const TASK_SCOPED = new Set(["lint", "tests", "coverage"]);
|
|
400
|
+
export function getPhaseCheckNames(phase) {
|
|
401
|
+
return (PHASE_CHECKS[phase] ?? []).map((fn) => fn.name.replace(/^check/, "").toLowerCase());
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Run the checks for `phase`.
|
|
405
|
+
*
|
|
406
|
+
* With `feature` + `task` set, only task-scoped checks run plus that task's
|
|
407
|
+
* own acceptance criteria — validating one task must not demand that the
|
|
408
|
+
* whole phase is finished.
|
|
409
|
+
*/
|
|
410
|
+
export async function runChecks(targetDir, phase, options = {}) {
|
|
411
|
+
const { config } = loadConfig(targetDir);
|
|
412
|
+
if (!phase) {
|
|
413
|
+
return { phase: "none", checks: [], overall: false, failures: ["no-phase"] };
|
|
414
|
+
}
|
|
415
|
+
if (config.gates?.enabled === false) {
|
|
416
|
+
return {
|
|
417
|
+
phase,
|
|
418
|
+
checks: [skip("gates-disabled", "gates are disabled in config — nothing enforced")],
|
|
419
|
+
overall: true,
|
|
420
|
+
failures: [],
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
const ctx = { targetDir, config };
|
|
424
|
+
const isTaskScoped = Boolean(options.feature && options.task);
|
|
425
|
+
let checks = PHASE_CHECKS[phase] ?? [];
|
|
426
|
+
if (isTaskScoped) {
|
|
427
|
+
checks = checks.filter((fn) => TASK_SCOPED.has(fn.name.replace(/^check/, "").toLowerCase()));
|
|
428
|
+
}
|
|
429
|
+
const results = [];
|
|
430
|
+
for (const fn of checks) {
|
|
431
|
+
try {
|
|
432
|
+
results.push(await fn(ctx));
|
|
433
|
+
}
|
|
434
|
+
catch (e) {
|
|
435
|
+
results.push(fail(fn.name, `check threw: ${e instanceof Error ? e.message : String(e)}`));
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
if (isTaskScoped) {
|
|
439
|
+
results.push(checkTaskCriteria(targetDir, options.feature, options.task));
|
|
440
|
+
}
|
|
441
|
+
const failures = results.filter((r) => !r.pass).map((r) => r.name);
|
|
442
|
+
const result = {
|
|
443
|
+
phase,
|
|
444
|
+
checks: results,
|
|
445
|
+
overall: failures.length === 0,
|
|
446
|
+
failures,
|
|
447
|
+
...(options.feature ? { feature: options.feature } : {}),
|
|
448
|
+
...(options.task ? { task: options.task } : {}),
|
|
449
|
+
};
|
|
450
|
+
if (options.record !== false) {
|
|
451
|
+
try {
|
|
452
|
+
const fresh = loadConfig(targetDir);
|
|
453
|
+
if (fresh.ok) {
|
|
454
|
+
recordGate(fresh.config, phase, result.overall ? "pass" : "fail", {
|
|
455
|
+
feature: options.feature,
|
|
456
|
+
task: options.task,
|
|
457
|
+
});
|
|
458
|
+
saveConfig(targetDir, fresh.config);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
/* gate history is best-effort and must never break validation */
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return result;
|
|
466
|
+
}
|
|
467
|
+
/** A task passes when it is marked complete and every subtask is complete. */
|
|
468
|
+
export function checkTaskCriteria(targetDir, featureId, taskId) {
|
|
469
|
+
const { list } = loadFeatureList(targetDir);
|
|
470
|
+
const feature = findFeature(list, featureId);
|
|
471
|
+
if (!feature)
|
|
472
|
+
return fail("task-criteria", `unknown feature ${featureId}`);
|
|
473
|
+
const found = findTask(list, taskId);
|
|
474
|
+
if (!found)
|
|
475
|
+
return fail("task-criteria", `unknown task ${taskId}`);
|
|
476
|
+
const { task } = found;
|
|
477
|
+
const openSubtasks = (task.subtasks ?? []).filter((s) => s.status !== "complete");
|
|
478
|
+
if (openSubtasks.length > 0) {
|
|
479
|
+
return fail("task-criteria", `${openSubtasks.length} subtask(s) still open on ${taskId}`);
|
|
480
|
+
}
|
|
481
|
+
if (!isDone(task.status)) {
|
|
482
|
+
return fail("task-criteria", `${taskId} is "${task.status}", not complete`);
|
|
483
|
+
}
|
|
484
|
+
return pass("task-criteria", `${taskId} complete with all subtasks done`);
|
|
485
|
+
}
|
|
486
|
+
export function areGatesEnabled(targetDir) {
|
|
487
|
+
const { config } = loadConfig(targetDir);
|
|
488
|
+
return config.gates?.enabled !== false;
|
|
489
|
+
}
|
|
490
|
+
//# sourceMappingURL=gates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gates.js","sourceRoot":"","sources":["../../../src/core/gates.ts"],"names":[],"mappings":"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"}
|