@encore-os/eos-spec 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/archive.js +57 -3
- package/dist/commands/archive.js.map +1 -1
- package/dist/commands/close-out.d.ts +2 -0
- package/dist/commands/close-out.js +167 -0
- package/dist/commands/close-out.js.map +1 -0
- package/dist/commands/conformance.js +20 -1
- package/dist/commands/conformance.js.map +1 -1
- package/dist/commands/create.js +25 -4
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/metrics.js +15 -0
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/run.d.ts +10 -0
- package/dist/commands/run.js +230 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/validate.d.ts +7 -0
- package/dist/commands/validate.js +46 -7
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/walkthrough.d.ts +2 -0
- package/dist/commands/walkthrough.js +76 -0
- package/dist/commands/walkthrough.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/ai-call.d.ts +12 -0
- package/dist/lib/ai-call.js +6 -0
- package/dist/lib/ai-call.js.map +1 -1
- package/dist/lib/closeout-core.d.ts +46 -0
- package/dist/lib/closeout-core.js +34 -0
- package/dist/lib/closeout-core.js.map +1 -0
- package/dist/lib/closeout-predicate.d.ts +36 -0
- package/dist/lib/closeout-predicate.js +130 -0
- package/dist/lib/closeout-predicate.js.map +1 -0
- package/dist/lib/cost.js +7 -0
- package/dist/lib/cost.js.map +1 -1
- package/dist/lib/events.d.ts +15 -1
- package/dist/lib/events.js.map +1 -1
- package/dist/lib/frontmatter.d.ts +38 -0
- package/dist/lib/frontmatter.js +76 -0
- package/dist/lib/frontmatter.js.map +1 -1
- package/dist/lib/gate-executor.d.ts +80 -0
- package/dist/lib/gate-executor.js +311 -0
- package/dist/lib/gate-executor.js.map +1 -0
- package/dist/lib/llm-health.d.ts +28 -0
- package/dist/lib/llm-health.js +46 -0
- package/dist/lib/llm-health.js.map +1 -0
- package/dist/lib/metrics.d.ts +26 -0
- package/dist/lib/metrics.js +35 -0
- package/dist/lib/metrics.js.map +1 -1
- package/dist/lib/next-action.d.ts +10 -4
- package/dist/lib/next-action.js +10 -4
- package/dist/lib/next-action.js.map +1 -1
- package/dist/lib/ollama-embed.d.ts +5 -0
- package/dist/lib/ollama-embed.js +5 -0
- package/dist/lib/ollama-embed.js.map +1 -1
- package/dist/lib/output.d.ts +3 -0
- package/dist/lib/output.js +3 -0
- package/dist/lib/output.js.map +1 -1
- package/dist/lib/pipeline-config.js +10 -0
- package/dist/lib/pipeline-config.js.map +1 -1
- package/dist/lib/pipeline-map.js +9 -0
- package/dist/lib/pipeline-map.js.map +1 -1
- package/dist/lib/precedent-search.d.ts +1 -0
- package/dist/lib/precedent-search.js +19 -2
- package/dist/lib/precedent-search.js.map +1 -1
- package/dist/lib/predicate-registry.js +7 -0
- package/dist/lib/predicate-registry.js.map +1 -1
- package/dist/lib/run-pipeline.d.ts +118 -0
- package/dist/lib/run-pipeline.js +106 -0
- package/dist/lib/run-pipeline.js.map +1 -0
- package/dist/lib/scorecard.js +9 -0
- package/dist/lib/scorecard.js.map +1 -1
- package/dist/lib/spec-pure.d.ts +69 -4
- package/dist/lib/spec-pure.js +125 -15
- package/dist/lib/spec-pure.js.map +1 -1
- package/dist/lib/specs.d.ts +3 -3
- package/dist/lib/specs.js +43 -20
- package/dist/lib/specs.js.map +1 -1
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/lib/walkthrough-coverage.d.ts +81 -0
- package/dist/lib/walkthrough-coverage.js +111 -0
- package/dist/lib/walkthrough-coverage.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { basename } from 'node:path';
|
|
3
|
+
import { addClaim, DEFAULT_TTL_MINUTES, releaseClaim } from '../lib/claims.js';
|
|
4
|
+
import { DEFAULT_LLM_BASE_URL, DEFAULT_LOCAL_MODEL, directModelExecutor, } from '../lib/gate-executor.js';
|
|
5
|
+
import { ErrorCode, emit, getGlobalOptions } from '../lib/output.js';
|
|
6
|
+
import { computeStage, PIPELINE, rank, stageApplies } from '../lib/pipeline-map.js';
|
|
7
|
+
import { reconcileSpec } from '../lib/reconcile-core.js';
|
|
8
|
+
import { getRepoRoot } from '../lib/repo.js';
|
|
9
|
+
import { runPipeline } from '../lib/run-pipeline.js';
|
|
10
|
+
import { diagnoseMissingSpec, findSpec } from '../lib/specs.js';
|
|
11
|
+
import { withEventLog } from '../lib/with-event-log.js';
|
|
12
|
+
import { recommendAction } from './next.js';
|
|
13
|
+
/** The cloud model used when a gate escalates off an unhealthy local endpoint —
|
|
14
|
+
* the same resolution ac-backfill uses (gateway via the `ai` SDK). */
|
|
15
|
+
function resolveCloudModel() {
|
|
16
|
+
return process.env.AC_DRAFT_MODEL ?? process.env.JUDGE_MODEL ?? 'anthropic/claude-sonnet-4';
|
|
17
|
+
}
|
|
18
|
+
/** The default LOCAL model — overridable via EOS_SPEC_LLM_MODEL. */
|
|
19
|
+
function resolveLocalModel() {
|
|
20
|
+
return process.env.EOS_SPEC_LLM_MODEL ?? DEFAULT_LOCAL_MODEL;
|
|
21
|
+
}
|
|
22
|
+
/** The LOCAL OpenAI-compatible base URL (Ollama). */
|
|
23
|
+
function resolveBaseUrl() {
|
|
24
|
+
return process.env.EOS_SPEC_LLM_BASE_URL ?? DEFAULT_LLM_BASE_URL;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The planned document-gate sequence from a spec's current state to `until`.
|
|
28
|
+
* Walks the SAME PIPELINE the navigator uses (optional + strictOnly + already-done
|
|
29
|
+
* gates skipped), stopping once the gate that completes `until` is included. Used
|
|
30
|
+
* by `--autonomy suggest` (executes nothing) and surfaced on the drive payload.
|
|
31
|
+
*/
|
|
32
|
+
export function planGates(spec, until) {
|
|
33
|
+
const out = [];
|
|
34
|
+
for (const t of PIPELINE) {
|
|
35
|
+
if (t.optional || t.strictOnly)
|
|
36
|
+
continue;
|
|
37
|
+
if (!stageApplies(t, spec))
|
|
38
|
+
continue;
|
|
39
|
+
if (t.isDone(spec))
|
|
40
|
+
continue;
|
|
41
|
+
out.push(t.id);
|
|
42
|
+
if (t.completesStatus && rank(t.completesStatus) >= rank(until))
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
/** Offline/test executor seam: when EOS_SPEC_LLM_FAKE=1 the gate executor skips
|
|
48
|
+
* the network entirely (probe reports healthy, the model returns canned text) so
|
|
49
|
+
* a drive can be exercised end-to-end without a live model. The REAL artifact
|
|
50
|
+
* writers + telemetry still run, so the recommend→execute→reconcile loop is
|
|
51
|
+
* genuinely exercised. */
|
|
52
|
+
function fakeExecutorDeps() {
|
|
53
|
+
return {
|
|
54
|
+
probe: async () => ({ healthy: true, status: 200, ms: 0 }),
|
|
55
|
+
callModel: async ({ endpoint, model }) => ({
|
|
56
|
+
text: `[fake ${endpoint} output from ${model}]`,
|
|
57
|
+
tokens: { prompt: 1, completion: 1, total: 2 },
|
|
58
|
+
}),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** Reasons that count as a clean, expected outcome (exit 0). */
|
|
62
|
+
const SUCCESS_REASONS = new Set(['suggested', 'reached-target', 'halt-before-implement']);
|
|
63
|
+
export function registerRun(program) {
|
|
64
|
+
program
|
|
65
|
+
.command('run')
|
|
66
|
+
.description('Autonomously drive a spec next→execute-gate→reconcile to tasks_generated, HALTING before implement. Routes each gate to a LOCAL model (Ollama) by default, escalating to the cloud gateway unless --strict-local.')
|
|
67
|
+
.requiredOption('--spec <id>', 'Spec id to drive (e.g. LO-50)')
|
|
68
|
+
.option('--autonomy <mode>', 'suggest (plan only, write nothing) | drive (advance the spec)', 'drive')
|
|
69
|
+
.option('--until <stage>', 'Stop once the computed stage reaches this status', 'tasks_generated')
|
|
70
|
+
.option('--max-gates <n>', 'Hard bound on executed gates', '8')
|
|
71
|
+
.option('--strict-local', 'Require the local model; HALT (no cloud fallback) if it is unhealthy', false)
|
|
72
|
+
.action(withEventLog('run', async (options, cmd) => {
|
|
73
|
+
const global = getGlobalOptions(cmd);
|
|
74
|
+
const repoRoot = getRepoRoot(global.repoRoot);
|
|
75
|
+
const autonomy = String(options.autonomy);
|
|
76
|
+
if (autonomy !== 'suggest' && autonomy !== 'drive') {
|
|
77
|
+
emit(global, {
|
|
78
|
+
ok: false,
|
|
79
|
+
error: {
|
|
80
|
+
code: ErrorCode.INVALID_ARGUMENT,
|
|
81
|
+
message: `run: --autonomy must be 'suggest' or 'drive' (got "${autonomy}")`,
|
|
82
|
+
},
|
|
83
|
+
data: null,
|
|
84
|
+
text: `run: --autonomy must be 'suggest' or 'drive' (got "${autonomy}")`,
|
|
85
|
+
});
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const until = String(options.until);
|
|
89
|
+
if (rank(until) < 0) {
|
|
90
|
+
emit(global, {
|
|
91
|
+
ok: false,
|
|
92
|
+
error: {
|
|
93
|
+
code: ErrorCode.INVALID_ARGUMENT,
|
|
94
|
+
message: `run: --until "${until}" is not a known pipeline status`,
|
|
95
|
+
},
|
|
96
|
+
data: null,
|
|
97
|
+
text: `run: --until "${until}" is not a known pipeline status`,
|
|
98
|
+
});
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const maxGates = Number.parseInt(String(options.maxGates), 10);
|
|
102
|
+
if (!Number.isFinite(maxGates) || maxGates < 0) {
|
|
103
|
+
emit(global, {
|
|
104
|
+
ok: false,
|
|
105
|
+
error: {
|
|
106
|
+
code: ErrorCode.INVALID_ARGUMENT,
|
|
107
|
+
message: `run: --max-gates must be a non-negative integer (got "${options.maxGates}")`,
|
|
108
|
+
},
|
|
109
|
+
data: null,
|
|
110
|
+
text: `run: --max-gates must be a non-negative integer (got "${options.maxGates}")`,
|
|
111
|
+
});
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const spec0 = findSpec(repoRoot, String(options.spec));
|
|
115
|
+
if (!spec0) {
|
|
116
|
+
const diag = diagnoseMissingSpec(repoRoot, String(options.spec));
|
|
117
|
+
emit(global, {
|
|
118
|
+
ok: false,
|
|
119
|
+
error: { code: ErrorCode.SPEC_NOT_FOUND, message: `run: spec ${options.spec} not found (${diag.reason})` },
|
|
120
|
+
data: null,
|
|
121
|
+
text: `run: spec ${options.spec} not found (${diag.reason})`,
|
|
122
|
+
});
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const specId = spec0.id;
|
|
126
|
+
const strictLocal = Boolean(options.strictLocal);
|
|
127
|
+
const baseURL = resolveBaseUrl();
|
|
128
|
+
const localModel = resolveLocalModel();
|
|
129
|
+
const cloudModel = resolveCloudModel();
|
|
130
|
+
const fake = process.env.EOS_SPEC_LLM_FAKE === '1';
|
|
131
|
+
const execDeps = fake ? fakeExecutorDeps() : {};
|
|
132
|
+
// ── suggest: plan only, NO claim, NO writes (AC-7) ───────────────────
|
|
133
|
+
if (autonomy === 'suggest') {
|
|
134
|
+
const result = await runPipeline({
|
|
135
|
+
recommend: () => recommendAction(findSpec(repoRoot, specId), null, repoRoot),
|
|
136
|
+
stage: () => computeStage(findSpec(repoRoot, specId)),
|
|
137
|
+
rank,
|
|
138
|
+
execute: async () => ({ ok: true, executor: 'noop' }),
|
|
139
|
+
reconcile: () => { },
|
|
140
|
+
plan: () => planGates(spec0, until),
|
|
141
|
+
}, { autonomy, until, maxGates });
|
|
142
|
+
emit(global, {
|
|
143
|
+
ok: true,
|
|
144
|
+
data: { specId, autonomy, until, plan: result.plan, finalStage: result.finalStage, reason: result.reason },
|
|
145
|
+
text: `run (suggest) ${specId}: ${result.plan?.length ? result.plan.join(' → ') : '(already at/past target — nothing to do)'}\n` +
|
|
146
|
+
` from stage: ${result.finalStage} target: ${until} (executes nothing)`,
|
|
147
|
+
});
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
// ── drive: claim, then loop recommend→execute→reconcile ──────────────
|
|
151
|
+
addClaim(repoRoot, specId, {
|
|
152
|
+
by: process.env.EOS_SPEC_CLAIMED_BY ?? basename(repoRoot),
|
|
153
|
+
ttlMinutes: DEFAULT_TTL_MINUTES,
|
|
154
|
+
});
|
|
155
|
+
const execute = async (action) => {
|
|
156
|
+
const fresh = findSpec(repoRoot, specId);
|
|
157
|
+
const specText = readFileSync(fresh.path, 'utf8');
|
|
158
|
+
const r = await directModelExecutor({
|
|
159
|
+
gate: action.type,
|
|
160
|
+
spec: fresh,
|
|
161
|
+
repoRoot,
|
|
162
|
+
specText,
|
|
163
|
+
baseURL,
|
|
164
|
+
localModel,
|
|
165
|
+
cloudModel,
|
|
166
|
+
strictLocal,
|
|
167
|
+
autonomy,
|
|
168
|
+
}, execDeps);
|
|
169
|
+
return {
|
|
170
|
+
ok: r.ok,
|
|
171
|
+
executor: r.executor,
|
|
172
|
+
model: r.model,
|
|
173
|
+
escalatedToCloud: r.escalatedToCloud,
|
|
174
|
+
artifacts: r.artifacts,
|
|
175
|
+
error: r.error,
|
|
176
|
+
halt: r.halt,
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
let result;
|
|
180
|
+
try {
|
|
181
|
+
result = await runPipeline({
|
|
182
|
+
recommend: () => recommendAction(findSpec(repoRoot, specId), null, repoRoot),
|
|
183
|
+
stage: () => computeStage(findSpec(repoRoot, specId)),
|
|
184
|
+
rank,
|
|
185
|
+
execute,
|
|
186
|
+
reconcile: () => {
|
|
187
|
+
reconcileSpec(repoRoot, findSpec(repoRoot, specId), true);
|
|
188
|
+
},
|
|
189
|
+
plan: () => planGates(spec0, until),
|
|
190
|
+
}, { autonomy, until, maxGates });
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
// Always release the lease, even if the loop threw — emit() never returns.
|
|
194
|
+
releaseClaim(repoRoot, specId);
|
|
195
|
+
}
|
|
196
|
+
const ok = SUCCESS_REASONS.has(result.reason);
|
|
197
|
+
const localGates = result.events.filter((e) => !e.escalatedToCloud).length;
|
|
198
|
+
const cloudGates = result.events.length - localGates;
|
|
199
|
+
const artifacts = result.events.flatMap((e) => e.artifacts ?? []);
|
|
200
|
+
const lines = [
|
|
201
|
+
`run (drive) ${specId}: ${result.reason} at stage ${result.finalStage}`,
|
|
202
|
+
` gates executed: ${result.events.length} (local=${localGates}, cloud=${cloudGates})`,
|
|
203
|
+
...result.events.map((e) => ` - ${e.gate}: ${e.ok ? 'ok' : `FAILED (${e.error ?? 'unknown'})`}${e.escalatedToCloud ? ' [escalated→cloud]' : ''}`),
|
|
204
|
+
...(result.resumeHint ? [` resume: ${result.resumeHint}`] : []),
|
|
205
|
+
...(artifacts.length ? [` wrote: ${artifacts.join(', ')}`] : []),
|
|
206
|
+
];
|
|
207
|
+
emit(global, {
|
|
208
|
+
ok,
|
|
209
|
+
data: {
|
|
210
|
+
specId,
|
|
211
|
+
autonomy,
|
|
212
|
+
until,
|
|
213
|
+
strictLocal,
|
|
214
|
+
reason: result.reason,
|
|
215
|
+
finalStage: result.finalStage,
|
|
216
|
+
haltedAt: result.haltedAt ?? null,
|
|
217
|
+
resumeHint: result.resumeHint ?? null,
|
|
218
|
+
gatesExecuted: result.events.length,
|
|
219
|
+
localGates,
|
|
220
|
+
cloudGates,
|
|
221
|
+
events: result.events,
|
|
222
|
+
artifacts,
|
|
223
|
+
},
|
|
224
|
+
exitCode: ok ? 0 : 1,
|
|
225
|
+
text: lines.join('\n'),
|
|
226
|
+
...(ok ? {} : { error: { code: ErrorCode.SUBPROCESS_ERROR, message: `run halted: ${result.reason}` } }),
|
|
227
|
+
});
|
|
228
|
+
}));
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,13 @@ export type ValidateIssue = {
|
|
|
5
5
|
rule: string;
|
|
6
6
|
message: string;
|
|
7
7
|
};
|
|
8
|
+
/**
|
|
9
|
+
* Build the `ValidateIssue`s for any spec id claimed by more than one primary spec
|
|
10
|
+
* (issue #27, mode b). One issue per colliding id, naming every offending path, so the
|
|
11
|
+
* old silent lowest-path-wins drop becomes a loud, actionable failure. Pure over the
|
|
12
|
+
* already-listed corpus — `findDuplicateSpecIds` does the fs-free grouping.
|
|
13
|
+
*/
|
|
14
|
+
export declare function duplicateIdIssues(specs: SpecFile[]): ValidateIssue[];
|
|
8
15
|
export type TemplateValidatorDecision = {
|
|
9
16
|
run: true;
|
|
10
17
|
} | {
|
|
@@ -3,7 +3,20 @@ import { join } from 'node:path';
|
|
|
3
3
|
import { runScript } from '../lib/exec.js';
|
|
4
4
|
import { ErrorCode, emit, emitContinuing, getGlobalOptions } from '../lib/output.js';
|
|
5
5
|
import { getRepoRoot } from '../lib/repo.js';
|
|
6
|
-
import {
|
|
6
|
+
import { findDuplicateSpecIds, findSpecsById, listSpecs } from '../lib/specs.js';
|
|
7
|
+
/**
|
|
8
|
+
* Build the `ValidateIssue`s for any spec id claimed by more than one primary spec
|
|
9
|
+
* (issue #27, mode b). One issue per colliding id, naming every offending path, so the
|
|
10
|
+
* old silent lowest-path-wins drop becomes a loud, actionable failure. Pure over the
|
|
11
|
+
* already-listed corpus — `findDuplicateSpecIds` does the fs-free grouping.
|
|
12
|
+
*/
|
|
13
|
+
export function duplicateIdIssues(specs) {
|
|
14
|
+
return findDuplicateSpecIds(specs).map((dup) => ({
|
|
15
|
+
file: dup.paths.join(', '),
|
|
16
|
+
rule: 'duplicate-spec-id',
|
|
17
|
+
message: `Duplicate spec id ${dup.id}: ${dup.paths.length} files resolve to it — ${dup.paths.join(', ')}`,
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
7
20
|
/** Decide whether to invoke the consumer-local template-structure validator.
|
|
8
21
|
* Skips when `--no-templates` is passed (commander maps it to options.templates ===
|
|
9
22
|
* false) OR when scripts/audit/validate-specs-templates.ts is absent (builder has
|
|
@@ -54,8 +67,10 @@ export function registerValidate(program) {
|
|
|
54
67
|
const global = getGlobalOptions(cmd);
|
|
55
68
|
const repoRoot = getRepoRoot(global.repoRoot);
|
|
56
69
|
if (options.spec) {
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
// Use findSpecsById (not findSpec) so a duplicate id surfaces as a hard error
|
|
71
|
+
// here too, instead of findSpec's silent lowest-path-wins pick (#27).
|
|
72
|
+
const matches = findSpecsById(repoRoot, options.spec);
|
|
73
|
+
if (matches.length === 0) {
|
|
59
74
|
emit(global, {
|
|
60
75
|
ok: false,
|
|
61
76
|
error: { code: ErrorCode.SPEC_NOT_FOUND, message: `validate: spec ${options.spec} not found` },
|
|
@@ -63,13 +78,18 @@ export function registerValidate(program) {
|
|
|
63
78
|
text: `validate: spec ${options.spec} not found`,
|
|
64
79
|
});
|
|
65
80
|
}
|
|
66
|
-
const issues =
|
|
81
|
+
const issues = [
|
|
82
|
+
...validateSpecFromIndex(matches[0].id, buildSpecIndex(matches)),
|
|
83
|
+
...duplicateIdIssues(matches),
|
|
84
|
+
];
|
|
85
|
+
const dupError = duplicateError(issues);
|
|
67
86
|
emit(global, {
|
|
68
87
|
ok: issues.length === 0,
|
|
69
|
-
data: { spec:
|
|
88
|
+
data: { spec: matches[0].id, issues },
|
|
89
|
+
error: dupError,
|
|
70
90
|
text: issues.length === 0
|
|
71
|
-
? `validate: ${
|
|
72
|
-
: `validate: ${
|
|
91
|
+
? `validate: ${matches[0].id} OK`
|
|
92
|
+
: `validate: ${matches[0].id} — ${issues.length} issue(s)\n${formatIssues(issues)}`,
|
|
73
93
|
exitCode: issues.length === 0 ? 0 : 1,
|
|
74
94
|
});
|
|
75
95
|
}
|
|
@@ -79,6 +99,9 @@ export function registerValidate(program) {
|
|
|
79
99
|
for (const s of specs) {
|
|
80
100
|
allIssues.push(...validateSpecFromIndex(s.id, index));
|
|
81
101
|
}
|
|
102
|
+
// Duplicate spec ids: a hard loader error (issue #27, mode b), not the old
|
|
103
|
+
// silent dedupe. Detected over the already-listed corpus (no extra fs work).
|
|
104
|
+
allIssues.push(...duplicateIdIssues(specs));
|
|
82
105
|
// Run the repo-wide template-structure validator, gated by --no-templates and a
|
|
83
106
|
// root-cause existence guard (a repo without the script is not a `templates` issue).
|
|
84
107
|
const tplDecision = templateValidatorDecision(repoRoot, options);
|
|
@@ -103,6 +126,7 @@ export function registerValidate(program) {
|
|
|
103
126
|
emit(global, {
|
|
104
127
|
ok: allIssues.length === 0,
|
|
105
128
|
data: { specCount: specs.length, issues: allIssues },
|
|
129
|
+
error: duplicateError(allIssues),
|
|
106
130
|
text: allIssues.length === 0
|
|
107
131
|
? `validate: OK (${specs.length} specs)`
|
|
108
132
|
: `validate: ${allIssues.length} issue(s) across ${specs.length} specs\n${formatIssues(allIssues)}`,
|
|
@@ -110,6 +134,21 @@ export function registerValidate(program) {
|
|
|
110
134
|
});
|
|
111
135
|
});
|
|
112
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Promote any duplicate-spec-id issues to the machine-actionable top-level error
|
|
139
|
+
* envelope (issue #27): a headless agent switches on `error.code === DUPLICATE_SPEC_ID`
|
|
140
|
+
* rather than scraping the human text. Returns undefined when there are no collisions,
|
|
141
|
+
* leaving other rule failures (spec-exists, templates) to the issues list + nonzero exit.
|
|
142
|
+
*/
|
|
143
|
+
function duplicateError(issues) {
|
|
144
|
+
const dups = issues.filter((i) => i.rule === 'duplicate-spec-id');
|
|
145
|
+
if (dups.length === 0)
|
|
146
|
+
return undefined;
|
|
147
|
+
return {
|
|
148
|
+
code: ErrorCode.DUPLICATE_SPEC_ID,
|
|
149
|
+
message: `${dups.length} duplicate spec id(s) — ${dups.map((d) => d.message).join('; ')}`,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
113
152
|
function formatIssues(issues) {
|
|
114
153
|
return issues.map((i) => ` - ${i.file} [${i.rule}] ${i.message.split('\n')[0]}`).join('\n');
|
|
115
154
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { ErrorCode, emit, getGlobalOptions } from '../lib/output.js';
|
|
4
|
+
import { getRepoRoot } from '../lib/repo.js';
|
|
5
|
+
import { diagnoseMissingSpec, findSpec } from '../lib/specs.js';
|
|
6
|
+
import { checkWalkthroughCoverage, specRequirementIds } from '../lib/walkthrough-coverage.js';
|
|
7
|
+
import { withEventLog } from '../lib/with-event-log.js';
|
|
8
|
+
/** Repo-relative path to a spec's walkthrough manifest. */
|
|
9
|
+
function manifestPath(repoRoot, specId) {
|
|
10
|
+
return join(repoRoot, 'docs', 'walkthroughs', specId.toLowerCase(), 'manifest.json');
|
|
11
|
+
}
|
|
12
|
+
export function registerWalkthrough(program) {
|
|
13
|
+
program
|
|
14
|
+
.command('walkthrough')
|
|
15
|
+
.description('Walkthrough filmed-coverage gate: with --check, verify every in-spec AC is filmed (non-empty clip + numeric chapterStartMs) and every user story is covered by a filmed AC, reporting STALE when the manifest specSha no longer matches the spec. Reads docs/walkthroughs/<spec>/manifest.json (regenerated, gitignored) — a local/post-record gate, not a corpus CI sweep.')
|
|
16
|
+
.requiredOption('--spec <id>', 'Spec id (e.g. CL-02)')
|
|
17
|
+
.option('--check', 'Run the coverage gate (the only mode today)')
|
|
18
|
+
.action(withEventLog('walkthrough', async (options, cmd) => {
|
|
19
|
+
const global = getGlobalOptions(cmd);
|
|
20
|
+
const repoRoot = getRepoRoot(global.repoRoot);
|
|
21
|
+
const spec = findSpec(repoRoot, options.spec);
|
|
22
|
+
if (!spec) {
|
|
23
|
+
const diag = diagnoseMissingSpec(repoRoot, options.spec);
|
|
24
|
+
const msg = `walkthrough: spec ${options.spec} not found (${diag.reason})`;
|
|
25
|
+
emit(global, { ok: false, error: { code: ErrorCode.SPEC_NOT_FOUND, message: msg }, data: null, text: msg });
|
|
26
|
+
process.exitCode = 2;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const mPath = manifestPath(repoRoot, spec.id);
|
|
30
|
+
if (!existsSync(mPath)) {
|
|
31
|
+
const msg = `walkthrough: no manifest for ${spec.id} — record it first ` +
|
|
32
|
+
`(\`npm run walkthrough -- --grep "${spec.id}"\` then \`walkthrough:build\`)`;
|
|
33
|
+
emit(global, {
|
|
34
|
+
ok: false,
|
|
35
|
+
error: { code: ErrorCode.IO_ERROR, message: msg },
|
|
36
|
+
data: { specId: spec.id, manifest: false },
|
|
37
|
+
text: `✖ ${msg}`,
|
|
38
|
+
});
|
|
39
|
+
process.exitCode = 1;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
let manifest;
|
|
43
|
+
try {
|
|
44
|
+
manifest = JSON.parse(readFileSync(mPath, 'utf8'));
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
const msg = `walkthrough: manifest for ${spec.id} is not valid JSON (${err instanceof Error ? err.message : String(err)})`;
|
|
48
|
+
emit(global, { ok: false, error: { code: ErrorCode.IO_ERROR, message: msg }, data: null, text: `✖ ${msg}` });
|
|
49
|
+
process.exitCode = 1;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const verdict = checkWalkthroughCoverage(manifest, specRequirementIds(readFileSync(spec.path, 'utf8')));
|
|
53
|
+
const lines = [
|
|
54
|
+
`Walkthrough filmed-coverage — ${spec.id}`,
|
|
55
|
+
verdict.stale ? ' ⚠️ STALE: manifest specSha ≠ current spec — re-record (spec changed since filming)' : '',
|
|
56
|
+
` ACs filmed: ${verdict.acFilmed}/${verdict.acTotal}`,
|
|
57
|
+
...verdict.unfilmed.map((u) => ` ✖ ${u.id}: ${u.reason}`),
|
|
58
|
+
` Stories covered: ${verdict.storiesCovered}/${verdict.storiesTotal}`,
|
|
59
|
+
...verdict.uncovered.map((s) => ` ✖ ${s}: no filmed AC covers it`),
|
|
60
|
+
verdict.ok ? ' ✅ PASS — every AC filmed, every story covered' : ' ✖ FAIL — see above',
|
|
61
|
+
].filter(Boolean);
|
|
62
|
+
emit(global, {
|
|
63
|
+
ok: verdict.ok,
|
|
64
|
+
...(verdict.ok
|
|
65
|
+
? {}
|
|
66
|
+
: {
|
|
67
|
+
error: { code: ErrorCode.VALIDATION_FAILED, message: `walkthrough coverage incomplete for ${spec.id}` },
|
|
68
|
+
}),
|
|
69
|
+
data: { specId: spec.id, manifest: true, ...verdict },
|
|
70
|
+
text: lines.join('\n'),
|
|
71
|
+
});
|
|
72
|
+
if (!verdict.ok)
|
|
73
|
+
process.exitCode = 1;
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=walkthrough.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walkthrough.js","sourceRoot":"","sources":["../../src/commands/walkthrough.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export { deriveCodeEvidence } from './lib/code-evidence.js';
|
|
|
13
13
|
export { computeStage, PIPELINE, buildPipeline, stageApplies, isComplianceGated, isSupersededGate, SUPERSEDE_SOFT_GATES, rank, type ActorType, type Transition, } from './lib/pipeline-map.js';
|
|
14
14
|
export { isCompleteStatus, collectSpecIds } from './lib/blockers.js';
|
|
15
15
|
export { uiEvidenceGate } from './lib/completion-gate.js';
|
|
16
|
+
export { type AcFilmStatus, type WalkthroughAc, type WalkthroughManifest, type WalkthroughVerdict, type WalkthroughVideo, acFilmStatus, checkWalkthroughCoverage, computeSpecSha, coveredStoryIds, specRequirementIds, } from './lib/walkthrough-coverage.js';
|
|
16
17
|
export { parseComplianceSignoff } from './lib/compliance-signoff.js';
|
|
17
18
|
export { loadEnforcementAllowlist, type EnforcementAllowlist } from './lib/enforcement-allowlist.js';
|
|
18
19
|
export type { SessionState } from './lib/session-state.js';
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { registerBackfill } from './commands/backfill.js';
|
|
|
7
7
|
import { registerCheckArtifacts } from './commands/checkArtifacts.js';
|
|
8
8
|
import { registerCheckPlacement } from './commands/checkPlacement.js';
|
|
9
9
|
import { registerClaim } from './commands/claim.js';
|
|
10
|
+
import { registerCloseOut } from './commands/close-out.js';
|
|
10
11
|
import { registerComplete } from './commands/complete.js';
|
|
11
12
|
import { registerConformance } from './commands/conformance.js';
|
|
12
13
|
import { registerCreate } from './commands/create.js';
|
|
@@ -24,9 +25,11 @@ import { registerPrecedent } from './commands/precedent.js';
|
|
|
24
25
|
import { registerProfile } from './commands/profile.js';
|
|
25
26
|
import { registerReady } from './commands/ready.js';
|
|
26
27
|
import { registerReconcile } from './commands/reconcile.js';
|
|
28
|
+
import { registerRun } from './commands/run.js';
|
|
27
29
|
import { registerReadinessRollup } from './commands/rollup.js';
|
|
28
30
|
import { registerScorecard } from './commands/scorecard.js';
|
|
29
31
|
import { registerSignoff } from './commands/signoff.js';
|
|
32
|
+
import { registerWalkthrough } from './commands/walkthrough.js';
|
|
30
33
|
import { registerStatus } from './commands/status.js';
|
|
31
34
|
import { registerTasks } from './commands/tasks.js';
|
|
32
35
|
import { registerValidate } from './commands/validate.js';
|
|
@@ -59,6 +62,11 @@ export { deriveCodeEvidence } from './lib/code-evidence.js';
|
|
|
59
62
|
export { computeStage, PIPELINE, buildPipeline, stageApplies, isComplianceGated, isSupersededGate, SUPERSEDE_SOFT_GATES, rank, } from './lib/pipeline-map.js';
|
|
60
63
|
export { isCompleteStatus, collectSpecIds } from './lib/blockers.js';
|
|
61
64
|
export { uiEvidenceGate } from './lib/completion-gate.js';
|
|
65
|
+
// Canonical walkthrough filmed-coverage contract — encoreos repoints its repo-local
|
|
66
|
+
// copy (scripts/specs/check-walkthrough-coverage.ts, tests/e2e/utils/walkthrough-manifest.ts)
|
|
67
|
+
// to these (REPOINT.md / encoreos#12). `computeSpecSha` MUST stay byte-stable: the
|
|
68
|
+
// encoreos manifest's specSha is computed against this implementation.
|
|
69
|
+
export { acFilmStatus, checkWalkthroughCoverage, computeSpecSha, coveredStoryIds, specRequirementIds, } from './lib/walkthrough-coverage.js';
|
|
62
70
|
export { parseComplianceSignoff } from './lib/compliance-signoff.js';
|
|
63
71
|
// Shared with encoreos's validate-pipeline-status: the core-enforcement allowlist
|
|
64
72
|
// reader (block/warn cores), so the gate's escalation policy lives in ONE place.
|
|
@@ -95,6 +103,7 @@ registerList(program);
|
|
|
95
103
|
registerCreate(program);
|
|
96
104
|
registerTasks(program);
|
|
97
105
|
registerComplete(program);
|
|
106
|
+
registerCloseOut(program);
|
|
98
107
|
registerArchive(program);
|
|
99
108
|
registerDeferred(program);
|
|
100
109
|
registerDelta(program);
|
|
@@ -109,7 +118,9 @@ registerVerifyRollout(program);
|
|
|
109
118
|
registerCheckPlacement(program);
|
|
110
119
|
registerCheckArtifacts(program);
|
|
111
120
|
registerReconcile(program);
|
|
121
|
+
registerRun(program);
|
|
112
122
|
registerSignoff(program);
|
|
123
|
+
registerWalkthrough(program);
|
|
113
124
|
registerVerifyAcs(program);
|
|
114
125
|
registerGenTests(program);
|
|
115
126
|
registerAudit(program);
|
|
@@ -121,6 +132,8 @@ Examples:
|
|
|
121
132
|
$ eos-spec validate --core cl --json # Validate CL specs, JSON output
|
|
122
133
|
$ eos-spec next --core hr # Show next recommended action for HR (blocker-aware)
|
|
123
134
|
$ eos-spec next --spec FA-12 --strict # Also enforce mid-pipeline parity gates as BLOCKING
|
|
135
|
+
$ eos-spec run --spec LO-50 --autonomy suggest # Print the planned gate sequence; execute nothing
|
|
136
|
+
$ eos-spec run --spec LO-50 --strict-local # Drive to tasks_generated on the LOCAL model (no cloud fallback)
|
|
124
137
|
$ eos-spec complete --spec CE-58 --enforce # Hard-block completion until docshots + heal exist (UI-bearing)
|
|
125
138
|
$ eos-spec ready --core lo # List LO specs whose blockers are all Complete
|
|
126
139
|
$ eos-spec ready --propose --core lo # Propose blocked_by entries from legacy dependencies
|
|
@@ -130,6 +143,8 @@ Examples:
|
|
|
130
143
|
$ eos-spec create PF-99 "Foo Feature" # Scaffold spec/plan/tasks files (stubs)
|
|
131
144
|
$ eos-spec tasks PF-99 # Generate or refresh TASKS file
|
|
132
145
|
$ eos-spec complete --spec PF-37 --update-registry
|
|
146
|
+
$ eos-spec close-out --spec LO-50 # Verified close-out: promote status->complete when ACs are verified at tasks_generated
|
|
147
|
+
$ eos-spec close-out --spec LO-50 --dry-run # Preview the close-out promotion without writing
|
|
133
148
|
$ eos-spec archive --spec PF-37 # Archive a completed spec
|
|
134
149
|
$ eos-spec deferred --sync # Sync deferred dashboard
|
|
135
150
|
$ eos-spec scorecard --core fm # Per-spec readiness; headline: claimed-complete-but-unverified
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/ai-call.d.ts
CHANGED
|
@@ -7,6 +7,18 @@ export type LogAiCallInput = {
|
|
|
7
7
|
tokens?: AiTokens;
|
|
8
8
|
error?: string;
|
|
9
9
|
ts?: string;
|
|
10
|
+
/** Optional CLI context, threaded onto the event for per-spec/-core metrics. */
|
|
11
|
+
specId?: string;
|
|
12
|
+
core?: string;
|
|
13
|
+
/** TOOL-06 gate-offload context (`eos-spec run`): the pipeline gate this call
|
|
14
|
+
* drove, the executor that ran it, the run's autonomy mode, and whether it
|
|
15
|
+
* escalated to the cloud. All optional so existing callers are unaffected; when
|
|
16
|
+
* present they let `metrics` roll the call up by gate/executor/autonomy and into
|
|
17
|
+
* the local-vs-cloud ratio. */
|
|
18
|
+
gate?: string;
|
|
19
|
+
executor?: string;
|
|
20
|
+
autonomy?: string;
|
|
21
|
+
escalatedToCloud?: boolean;
|
|
10
22
|
};
|
|
11
23
|
/** Log a single AI gateway call as an eos-spec event, computing USD cost from token counts.
|
|
12
24
|
* Shared by every AI-calling command so token/cost capture is uniform (DRY). */
|
package/dist/lib/ai-call.js
CHANGED
|
@@ -12,6 +12,12 @@ export function logAiCall(input) {
|
|
|
12
12
|
tokens: input.tokens,
|
|
13
13
|
costUsd: input.tokens ? computeCostUsd(input.model, input.tokens) : undefined,
|
|
14
14
|
error: input.error,
|
|
15
|
+
specId: input.specId,
|
|
16
|
+
core: input.core,
|
|
17
|
+
gate: input.gate,
|
|
18
|
+
executor: input.executor,
|
|
19
|
+
autonomy: input.autonomy,
|
|
20
|
+
escalatedToCloud: input.escalatedToCloud,
|
|
15
21
|
});
|
|
16
22
|
}
|
|
17
23
|
//# sourceMappingURL=ai-call.js.map
|
package/dist/lib/ai-call.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-call.js","sourceRoot":"","sources":["../../src/lib/ai-call.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,cAAc,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ai-call.js","sourceRoot":"","sources":["../../src/lib/ai-call.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,cAAc,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAwBvC;iFACiF;AACjF,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,QAAQ,CAAC;QACP,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACxC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;QAC7E,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;KACzC,CAAC,CAAC;AACL,CAAC"}
|