@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.
Files changed (83) hide show
  1. package/dist/commands/archive.js +57 -3
  2. package/dist/commands/archive.js.map +1 -1
  3. package/dist/commands/close-out.d.ts +2 -0
  4. package/dist/commands/close-out.js +167 -0
  5. package/dist/commands/close-out.js.map +1 -0
  6. package/dist/commands/conformance.js +20 -1
  7. package/dist/commands/conformance.js.map +1 -1
  8. package/dist/commands/create.js +25 -4
  9. package/dist/commands/create.js.map +1 -1
  10. package/dist/commands/metrics.js +15 -0
  11. package/dist/commands/metrics.js.map +1 -1
  12. package/dist/commands/run.d.ts +10 -0
  13. package/dist/commands/run.js +230 -0
  14. package/dist/commands/run.js.map +1 -0
  15. package/dist/commands/validate.d.ts +7 -0
  16. package/dist/commands/validate.js +46 -7
  17. package/dist/commands/validate.js.map +1 -1
  18. package/dist/commands/walkthrough.d.ts +2 -0
  19. package/dist/commands/walkthrough.js +76 -0
  20. package/dist/commands/walkthrough.js.map +1 -0
  21. package/dist/index.d.ts +1 -0
  22. package/dist/index.js +15 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/lib/ai-call.d.ts +12 -0
  25. package/dist/lib/ai-call.js +6 -0
  26. package/dist/lib/ai-call.js.map +1 -1
  27. package/dist/lib/closeout-core.d.ts +46 -0
  28. package/dist/lib/closeout-core.js +34 -0
  29. package/dist/lib/closeout-core.js.map +1 -0
  30. package/dist/lib/closeout-predicate.d.ts +36 -0
  31. package/dist/lib/closeout-predicate.js +130 -0
  32. package/dist/lib/closeout-predicate.js.map +1 -0
  33. package/dist/lib/cost.js +7 -0
  34. package/dist/lib/cost.js.map +1 -1
  35. package/dist/lib/events.d.ts +15 -1
  36. package/dist/lib/events.js.map +1 -1
  37. package/dist/lib/frontmatter.d.ts +38 -0
  38. package/dist/lib/frontmatter.js +76 -0
  39. package/dist/lib/frontmatter.js.map +1 -1
  40. package/dist/lib/gate-executor.d.ts +80 -0
  41. package/dist/lib/gate-executor.js +311 -0
  42. package/dist/lib/gate-executor.js.map +1 -0
  43. package/dist/lib/llm-health.d.ts +28 -0
  44. package/dist/lib/llm-health.js +46 -0
  45. package/dist/lib/llm-health.js.map +1 -0
  46. package/dist/lib/metrics.d.ts +26 -0
  47. package/dist/lib/metrics.js +35 -0
  48. package/dist/lib/metrics.js.map +1 -1
  49. package/dist/lib/next-action.d.ts +10 -4
  50. package/dist/lib/next-action.js +10 -4
  51. package/dist/lib/next-action.js.map +1 -1
  52. package/dist/lib/ollama-embed.d.ts +5 -0
  53. package/dist/lib/ollama-embed.js +5 -0
  54. package/dist/lib/ollama-embed.js.map +1 -1
  55. package/dist/lib/output.d.ts +3 -0
  56. package/dist/lib/output.js +3 -0
  57. package/dist/lib/output.js.map +1 -1
  58. package/dist/lib/pipeline-config.js +10 -0
  59. package/dist/lib/pipeline-config.js.map +1 -1
  60. package/dist/lib/pipeline-map.js +9 -0
  61. package/dist/lib/pipeline-map.js.map +1 -1
  62. package/dist/lib/precedent-search.d.ts +1 -0
  63. package/dist/lib/precedent-search.js +19 -2
  64. package/dist/lib/precedent-search.js.map +1 -1
  65. package/dist/lib/predicate-registry.js +7 -0
  66. package/dist/lib/predicate-registry.js.map +1 -1
  67. package/dist/lib/run-pipeline.d.ts +118 -0
  68. package/dist/lib/run-pipeline.js +106 -0
  69. package/dist/lib/run-pipeline.js.map +1 -0
  70. package/dist/lib/scorecard.js +9 -0
  71. package/dist/lib/scorecard.js.map +1 -1
  72. package/dist/lib/spec-pure.d.ts +69 -4
  73. package/dist/lib/spec-pure.js +125 -15
  74. package/dist/lib/spec-pure.js.map +1 -1
  75. package/dist/lib/specs.d.ts +3 -3
  76. package/dist/lib/specs.js +43 -20
  77. package/dist/lib/specs.js.map +1 -1
  78. package/dist/lib/version.d.ts +1 -1
  79. package/dist/lib/version.js +1 -1
  80. package/dist/lib/walkthrough-coverage.d.ts +81 -0
  81. package/dist/lib/walkthrough-coverage.js +111 -0
  82. package/dist/lib/walkthrough-coverage.js.map +1 -0
  83. 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 { findSpec, listSpecs } from '../lib/specs.js';
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
- const spec = findSpec(repoRoot, options.spec);
58
- if (!spec) {
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 = validateSpecFromIndex(spec.id, buildSpecIndex([spec]));
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: spec.id, issues },
88
+ data: { spec: matches[0].id, issues },
89
+ error: dupError,
70
90
  text: issues.length === 0
71
- ? `validate: ${spec.id} OK`
72
- : `validate: ${spec.id} — ${issues.length} issue(s)\n${formatIssues(issues)}`,
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":"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"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerWalkthrough(program: Command): void;
@@ -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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"}
@@ -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). */
@@ -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
@@ -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;AAYvC;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;KACnB,CAAC,CAAC;AACL,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"}