@encore-os/eos-spec 0.8.0 → 0.10.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 +1 -1
- 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/complete.js +81 -4
- package/dist/commands/complete.js.map +1 -1
- package/dist/commands/conformance.js +20 -1
- package/dist/commands/conformance.js.map +1 -1
- package/dist/commands/create.js +6 -6
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/funnel.js +7 -0
- package/dist/commands/funnel.js.map +1 -1
- package/dist/commands/metrics.js +15 -0
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/next.d.ts +10 -4
- package/dist/commands/next.js +23 -12
- package/dist/commands/next.js.map +1 -1
- package/dist/commands/proceed.d.ts +48 -0
- package/dist/commands/proceed.js +144 -0
- package/dist/commands/proceed.js.map +1 -0
- package/dist/commands/reconcile.js +7 -1
- package/dist/commands/reconcile.js.map +1 -1
- package/dist/commands/run.d.ts +13 -0
- package/dist/commands/run.js +238 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/scorecard.d.ts +24 -0
- package/dist/commands/scorecard.js +49 -3
- package/dist/commands/scorecard.js.map +1 -1
- package/dist/commands/signoff.js +3 -2
- package/dist/commands/signoff.js.map +1 -1
- package/dist/commands/status.js +7 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/tasks.d.ts +7 -0
- package/dist/commands/tasks.js +13 -1
- package/dist/commands/tasks.js.map +1 -1
- 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/index.js +19 -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/config.d.ts +10 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/cost.js +7 -0
- package/dist/lib/cost.js.map +1 -1
- package/dist/lib/coverage-gate.d.ts +43 -0
- package/dist/lib/coverage-gate.js +54 -0
- package/dist/lib/coverage-gate.js.map +1 -0
- package/dist/lib/events.d.ts +12 -0
- package/dist/lib/events.js +8 -1
- package/dist/lib/events.js.map +1 -1
- package/dist/lib/frontmatter.d.ts +23 -1
- package/dist/lib/frontmatter.js +37 -0
- package/dist/lib/frontmatter.js.map +1 -1
- package/dist/lib/funnel.d.ts +5 -0
- package/dist/lib/funnel.js +2 -1
- package/dist/lib/funnel.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.d.ts +24 -0
- package/dist/lib/pipeline-map.js +54 -5
- package/dist/lib/pipeline-map.js.map +1 -1
- package/dist/lib/predicate-registry.js +7 -0
- package/dist/lib/predicate-registry.js.map +1 -1
- package/dist/lib/reconcile-core.d.ts +20 -3
- package/dist/lib/reconcile-core.js +16 -6
- package/dist/lib/reconcile-core.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.d.ts +5 -0
- package/dist/lib/scorecard.js +1 -0
- package/dist/lib/scorecard.js.map +1 -1
- package/dist/lib/spec-pure.d.ts +69 -4
- package/dist/lib/spec-pure.js +129 -15
- package/dist/lib/spec-pure.js.map +1 -1
- package/dist/lib/specs.d.ts +9 -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/version.js.map +1 -1
- package/dist/lib/with-event-log.js +17 -3
- package/dist/lib/with-event-log.js.map +1 -1
- package/package.json +1 -1
|
@@ -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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"}
|
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';
|
|
@@ -21,9 +22,11 @@ import { registerList } from './commands/list.js';
|
|
|
21
22
|
import { registerMetrics } from './commands/metrics.js';
|
|
22
23
|
import { registerNext } from './commands/next.js';
|
|
23
24
|
import { registerPrecedent } from './commands/precedent.js';
|
|
25
|
+
import { registerProceed } from './commands/proceed.js';
|
|
24
26
|
import { registerProfile } from './commands/profile.js';
|
|
25
27
|
import { registerReady } from './commands/ready.js';
|
|
26
28
|
import { registerReconcile } from './commands/reconcile.js';
|
|
29
|
+
import { registerRun } from './commands/run.js';
|
|
27
30
|
import { registerReadinessRollup } from './commands/rollup.js';
|
|
28
31
|
import { registerScorecard } from './commands/scorecard.js';
|
|
29
32
|
import { registerSignoff } from './commands/signoff.js';
|
|
@@ -96,11 +99,13 @@ registerNext(program);
|
|
|
96
99
|
registerReady(program);
|
|
97
100
|
registerClaim(program);
|
|
98
101
|
registerPrecedent(program);
|
|
102
|
+
registerProceed(program);
|
|
99
103
|
registerStatus(program);
|
|
100
104
|
registerList(program);
|
|
101
105
|
registerCreate(program);
|
|
102
106
|
registerTasks(program);
|
|
103
107
|
registerComplete(program);
|
|
108
|
+
registerCloseOut(program);
|
|
104
109
|
registerArchive(program);
|
|
105
110
|
registerDeferred(program);
|
|
106
111
|
registerDelta(program);
|
|
@@ -115,6 +120,7 @@ registerVerifyRollout(program);
|
|
|
115
120
|
registerCheckPlacement(program);
|
|
116
121
|
registerCheckArtifacts(program);
|
|
117
122
|
registerReconcile(program);
|
|
123
|
+
registerRun(program);
|
|
118
124
|
registerSignoff(program);
|
|
119
125
|
registerWalkthrough(program);
|
|
120
126
|
registerVerifyAcs(program);
|
|
@@ -128,6 +134,8 @@ Examples:
|
|
|
128
134
|
$ eos-spec validate --core cl --json # Validate CL specs, JSON output
|
|
129
135
|
$ eos-spec next --core hr # Show next recommended action for HR (blocker-aware)
|
|
130
136
|
$ eos-spec next --spec FA-12 --strict # Also enforce mid-pipeline parity gates as BLOCKING
|
|
137
|
+
$ eos-spec run --spec LO-50 --autonomy suggest # Print the planned gate sequence; execute nothing
|
|
138
|
+
$ eos-spec run --spec LO-50 --strict-local # Drive to tasks_generated on the LOCAL model (no cloud fallback)
|
|
131
139
|
$ eos-spec complete --spec CE-58 --enforce # Hard-block completion until docshots + heal exist (UI-bearing)
|
|
132
140
|
$ eos-spec ready --core lo # List LO specs whose blockers are all Complete
|
|
133
141
|
$ eos-spec ready --propose --core lo # Propose blocked_by entries from legacy dependencies
|
|
@@ -137,6 +145,8 @@ Examples:
|
|
|
137
145
|
$ eos-spec create PF-99 "Foo Feature" # Scaffold spec/plan/tasks files (stubs)
|
|
138
146
|
$ eos-spec tasks PF-99 # Generate or refresh TASKS file
|
|
139
147
|
$ eos-spec complete --spec PF-37 --update-registry
|
|
148
|
+
$ eos-spec close-out --spec LO-50 # Verified close-out: promote status->complete when ACs are verified at tasks_generated
|
|
149
|
+
$ eos-spec close-out --spec LO-50 --dry-run # Preview the close-out promotion without writing
|
|
140
150
|
$ eos-spec archive --spec PF-37 # Archive a completed spec
|
|
141
151
|
$ eos-spec deferred --sync # Sync deferred dashboard
|
|
142
152
|
$ eos-spec scorecard --core fm # Per-spec readiness; headline: claimed-complete-but-unverified
|
|
@@ -150,6 +160,15 @@ Documentation:
|
|
|
150
160
|
specs/_templates/SPEC_GUIDE.md # Spec authoring decision tree
|
|
151
161
|
specs/_templates/TEMPLATE_INDEX.md # Template selection
|
|
152
162
|
AI_GUIDE.md # Spec workflow process
|
|
163
|
+
|
|
164
|
+
Environment:
|
|
165
|
+
EOS_SPEC_EVENTS_PATH Override the telemetry sink file. By default events are
|
|
166
|
+
written to <repo-root>/.claude/tmp/eos-spec-events.jsonl,
|
|
167
|
+
where <repo-root> honors --repo-root (falling back to
|
|
168
|
+
git rev-parse --show-toplevel). Set an absolute path to
|
|
169
|
+
redirect the log; set it to /dev/null to discard events.
|
|
170
|
+
EOS_SPEC_RUN_ID Externally-supplied opaque run id to correlate events
|
|
171
|
+
across CLI invocations (defaults to a per-process UUID).
|
|
153
172
|
`);
|
|
154
173
|
export async function run(argv) {
|
|
155
174
|
await program.parseAsync(argv);
|
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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type CloseoutDecision, type CloseoutOptions } from './closeout-predicate.js';
|
|
2
|
+
import { type ReconcileRow } from './reconcile-core.js';
|
|
3
|
+
import type { SpecFile } from './specs.js';
|
|
4
|
+
/**
|
|
5
|
+
* The per-spec close-out core (issue #30, TOOL-06 terminal complement), extracted
|
|
6
|
+
* so the `close-out` command stays a thin adapter and the verified status: ->
|
|
7
|
+
* complete write lives in ONE place the engine owns
|
|
8
|
+
* (docs/adr/0001-engine-owns-verified-close-out-status-promotion.md). fs-bound
|
|
9
|
+
* (reads + writes the spec markdown, delegates to the fs-bound reconcileSpec) — stays
|
|
10
|
+
* behind the package main entry, never `/pure`.
|
|
11
|
+
*
|
|
12
|
+
* close-out composes the three pipeline-tail steps the issue names, reusing their
|
|
13
|
+
* lib functions rather than shelling the CLI:
|
|
14
|
+
* 1. reconcile — heal `pipeline_status` from the on-disk artifacts so the gate
|
|
15
|
+
* sees the TRUE stage, not a stale frontmatter value (reconcileSpec).
|
|
16
|
+
* 2. verify-acs — the conservative gate reads the per-AC `status` that
|
|
17
|
+
* `verify-acs --write` has already promoted to `verified`
|
|
18
|
+
* (decideCloseout mirrors the `hasVerifiedAcceptanceCriteria` signal;
|
|
19
|
+
* close-out does NOT re-run the test harness — that is verify-acs's job).
|
|
20
|
+
* 3. complete — when (and only when) the gate says so, the engine writes
|
|
21
|
+
* `status: complete` (markSpecComplete). An optional `--update-registry`
|
|
22
|
+
* delegation to a consumer audit script remains a separate, explicit
|
|
23
|
+
* opt-in handled by the command layer.
|
|
24
|
+
*/
|
|
25
|
+
export type CloseoutRow = {
|
|
26
|
+
id: string;
|
|
27
|
+
core: string;
|
|
28
|
+
/** The conservative gate's verdict (decideCloseout). */
|
|
29
|
+
decision: CloseoutDecision;
|
|
30
|
+
/** The status value written, or that WOULD be written in a dry-run, or null. */
|
|
31
|
+
status: 'complete' | 'in_progress' | null;
|
|
32
|
+
/** True only when this run actually wrote a new `status:` to the spec file. */
|
|
33
|
+
written: boolean;
|
|
34
|
+
/** The reconcile divergence row (pipeline_status recompute) computed as step 1. */
|
|
35
|
+
reconcile: ReconcileRow;
|
|
36
|
+
};
|
|
37
|
+
export type CloseoutSpecOptions = CloseoutOptions & {
|
|
38
|
+
/** When false (dry-run), compute the decision + reconcile divergence but write nothing. */
|
|
39
|
+
write: boolean;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Close out a single spec: reconcile, decide, and (when `write`) materialize the
|
|
43
|
+
* verified `status:` promotion. The decision is computed against the
|
|
44
|
+
* artifact-recomputed stage so a dry-run preview and a real write always agree.
|
|
45
|
+
*/
|
|
46
|
+
export declare function closeOutSpec(repoRoot: string, spec: SpecFile, opts: CloseoutSpecOptions): CloseoutRow;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { decideCloseout } from './closeout-predicate.js';
|
|
3
|
+
import { markSpecComplete, readFrontmatter, setStatus } from './frontmatter.js';
|
|
4
|
+
import { reconcileSpec } from './reconcile-core.js';
|
|
5
|
+
/**
|
|
6
|
+
* Close out a single spec: reconcile, decide, and (when `write`) materialize the
|
|
7
|
+
* verified `status:` promotion. The decision is computed against the
|
|
8
|
+
* artifact-recomputed stage so a dry-run preview and a real write always agree.
|
|
9
|
+
*/
|
|
10
|
+
export function closeOutSpec(repoRoot, spec, opts) {
|
|
11
|
+
const { write, ...decisionOpts } = opts;
|
|
12
|
+
// Step 1 — reconcile. In a real run this writes the artifact-computed
|
|
13
|
+
// `pipeline_status` back; in a dry-run nothing is written, but we still capture the
|
|
14
|
+
// computed stage and feed it to the gate below so dry-run == apply.
|
|
15
|
+
const reconcile = reconcileSpec(repoRoot, spec, write);
|
|
16
|
+
// Step 2 — decide. Read the (possibly just-reconciled) frontmatter and overlay the
|
|
17
|
+
// artifact-computed stage so the gate keys on reality, not a stale/lagging value.
|
|
18
|
+
const text = readFileSync(spec.path, 'utf8');
|
|
19
|
+
const fm = readFrontmatter(text);
|
|
20
|
+
const effectiveFm = { ...fm, pipeline_status: reconcile.computed ?? fm.pipeline_status };
|
|
21
|
+
const decision = decideCloseout(effectiveFm, decisionOpts);
|
|
22
|
+
// Step 3 — promote. The engine OWNS the verified status write; it happens only when
|
|
23
|
+
// the gate returned a status AND --write (non-dry-run) was requested.
|
|
24
|
+
let written = false;
|
|
25
|
+
if (write && decision.nextStatus) {
|
|
26
|
+
const next = decision.nextStatus === 'complete' ? markSpecComplete(text) : setStatus(text, decision.nextStatus);
|
|
27
|
+
if (next !== text) {
|
|
28
|
+
writeFileSync(spec.path, next, 'utf8');
|
|
29
|
+
written = true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return { id: spec.id, core: spec.core, decision, status: decision.nextStatus, written, reconcile };
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=closeout-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"closeout-core.js","sourceRoot":"","sources":["../../src/lib/closeout-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAA+C,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACtG,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAqB,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA2CvE;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,IAAc,EAAE,IAAyB;IACtF,MAAM,EAAE,KAAK,EAAE,GAAG,YAAY,EAAE,GAAG,IAAI,CAAC;IAExC,sEAAsE;IACtE,oFAAoF;IACpF,oEAAoE;IACpE,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IAEvD,mFAAmF;IACnF,kFAAkF;IAClF,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,EAAE,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,EAAE,eAAe,EAAE,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC,eAAe,EAAE,CAAC;IACzF,MAAM,QAAQ,GAAG,cAAc,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAE3D,oFAAoF;IACpF,sEAAsE;IACtE,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,KAAK,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;QAChH,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YACvC,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AACrG,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { SpecFrontmatter } from './frontmatter.js';
|
|
2
|
+
import { type RequirementStatus } from './requirements.js';
|
|
3
|
+
/** The pipeline stage a spec must have reached before close-out will promote it.
|
|
4
|
+
* It is the terminal stage of BOTH built-in layouts — `ENCORE1_PIPELINE_SCHEMA` and
|
|
5
|
+
* `BUILDER_PIPELINE_SCHEMA` `statusOrder` both end on it — kept as a named constant
|
|
6
|
+
* so the canonical predicate carries no magic string. A consumer on a custom layout
|
|
7
|
+
* can override it via {@link CloseoutOptions.terminalStage}. */
|
|
8
|
+
export declare const CLOSEOUT_TERMINAL_STAGE = "tasks_generated";
|
|
9
|
+
/** The default closeable AC vocabulary: encoreos's binary planned->verified model.
|
|
10
|
+
* A consumer on the builder/Switchboard model passes `['verified', 'hand_closed']`
|
|
11
|
+
* (and may add `'deferred'`) via {@link CloseoutOptions.closeableStatuses}. */
|
|
12
|
+
export declare const DEFAULT_CLOSEABLE_AC_STATUSES: readonly RequirementStatus[];
|
|
13
|
+
/** Pre-work `status:` values that close-out may UPGRADE to `in_progress` once work
|
|
14
|
+
* has demonstrably started (>=1 closeable AC) but the spec is not yet closeable. An
|
|
15
|
+
* empty/absent status is also treated as pre-work. Conservative: a status OUTSIDE
|
|
16
|
+
* this set is human-meaningful and is left untouched (we never clobber it). */
|
|
17
|
+
export declare const DEFAULT_PRE_WORK_STATUSES: readonly string[];
|
|
18
|
+
export type CloseoutOptions = {
|
|
19
|
+
/** AC statuses that count as terminally closed (default `['verified']`). */
|
|
20
|
+
closeableStatuses?: readonly string[];
|
|
21
|
+
/** The pipeline stage gating promotion (default `'tasks_generated'`). */
|
|
22
|
+
terminalStage?: string;
|
|
23
|
+
/** Pre-work statuses eligible for the in_progress nudge (default {@link DEFAULT_PRE_WORK_STATUSES}). */
|
|
24
|
+
preWorkStatuses?: readonly string[];
|
|
25
|
+
};
|
|
26
|
+
export type CloseoutDecision = {
|
|
27
|
+
/** `'complete'` => promote; `'in_progress'` => nudge a pre-work status; `null` => leave unchanged. */
|
|
28
|
+
nextStatus: 'complete' | 'in_progress' | null;
|
|
29
|
+
/** Human-readable justification — surfaced in `--json` output and per-spec telemetry. */
|
|
30
|
+
reason: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Decide whether the spec described by `fm` may be closed out. Pure over parsed
|
|
34
|
+
* frontmatter; see the module header for the canonical predicate and invariants.
|
|
35
|
+
*/
|
|
36
|
+
export declare function decideCloseout(fm: SpecFrontmatter, opts?: CloseoutOptions): CloseoutDecision;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The conservative close-out gate (issue #30, TOOL-06 terminal complement).
|
|
3
|
+
*
|
|
4
|
+
* `decideCloseout` is the single source of truth for whether a spec's
|
|
5
|
+
* org-lifecycle `status:` may be promoted to `complete` — the verified close-out
|
|
6
|
+
* the engine now OWNS rather than delegating to a consumer audit script
|
|
7
|
+
* (docs/adr/0001-engine-owns-verified-close-out-status-promotion.md). It is a PURE
|
|
8
|
+
* leaf: it reads ONLY already-parsed frontmatter (no node:fs, no child_process, no
|
|
9
|
+
* network), so it sits behind the package main entry yet stays as cheap and
|
|
10
|
+
* side-effect-free as the predicate registry it mirrors. (Deliberately NOT wired
|
|
11
|
+
* into `/pure` — see CLAUDE.md; it is importable from the main graph.)
|
|
12
|
+
*
|
|
13
|
+
* The canonical predicate (deliberately conservative — never blind-stamp):
|
|
14
|
+
* closeable(spec) <=>
|
|
15
|
+
* nonEmpty(acceptance_criteria)
|
|
16
|
+
* AND acceptance_criteria.every(ac => ac.status in closeableStatuses)
|
|
17
|
+
* AND pipeline_status === terminalStage (default 'tasks_generated')
|
|
18
|
+
* => status: complete
|
|
19
|
+
* else: leave unchanged (null) — or nudge a *pre-work* status to in_progress once
|
|
20
|
+
* some ACs are terminal but the spec is not yet closeable.
|
|
21
|
+
*
|
|
22
|
+
* Two invariants the verb must never break:
|
|
23
|
+
* 1. NEVER downgrade an already complete / archived / superseded / deferred spec —
|
|
24
|
+
* those are terminal org-lifecycle states; close-out returns `null` for them.
|
|
25
|
+
* 2. NEVER promote past the evidence — a single `planned` AC, or a pipeline_status
|
|
26
|
+
* short of the terminal stage, blocks `complete`.
|
|
27
|
+
*
|
|
28
|
+
* The terminal AC vocabulary is PARAMETRIZED so both consuming layouts pass:
|
|
29
|
+
* - encoreos: the binary planned->verified model => closeableStatuses ['verified'].
|
|
30
|
+
* - Switchboard/builder: verified + hand_closed => ['verified', 'hand_closed'].
|
|
31
|
+
* It mirrors the existing `hasVerifiedAcceptanceCriteria` signal (which keys on
|
|
32
|
+
* `allAcceptanceCriteriaTerminal`) but is STRICTER by default: only `verified`
|
|
33
|
+
* closes a spec unless the consumer opts `hand_closed`/`deferred` in.
|
|
34
|
+
*/
|
|
35
|
+
import { isCompleteStatus, isTerminalStatus } from './blockers.js';
|
|
36
|
+
import { normalizeAcceptanceCriteria } from './requirements.js';
|
|
37
|
+
/** The pipeline stage a spec must have reached before close-out will promote it.
|
|
38
|
+
* It is the terminal stage of BOTH built-in layouts — `ENCORE1_PIPELINE_SCHEMA` and
|
|
39
|
+
* `BUILDER_PIPELINE_SCHEMA` `statusOrder` both end on it — kept as a named constant
|
|
40
|
+
* so the canonical predicate carries no magic string. A consumer on a custom layout
|
|
41
|
+
* can override it via {@link CloseoutOptions.terminalStage}. */
|
|
42
|
+
export const CLOSEOUT_TERMINAL_STAGE = 'tasks_generated';
|
|
43
|
+
/** The default closeable AC vocabulary: encoreos's binary planned->verified model.
|
|
44
|
+
* A consumer on the builder/Switchboard model passes `['verified', 'hand_closed']`
|
|
45
|
+
* (and may add `'deferred'`) via {@link CloseoutOptions.closeableStatuses}. */
|
|
46
|
+
export const DEFAULT_CLOSEABLE_AC_STATUSES = ['verified'];
|
|
47
|
+
/** Pre-work `status:` values that close-out may UPGRADE to `in_progress` once work
|
|
48
|
+
* has demonstrably started (>=1 closeable AC) but the spec is not yet closeable. An
|
|
49
|
+
* empty/absent status is also treated as pre-work. Conservative: a status OUTSIDE
|
|
50
|
+
* this set is human-meaningful and is left untouched (we never clobber it). */
|
|
51
|
+
export const DEFAULT_PRE_WORK_STATUSES = [
|
|
52
|
+
'draft',
|
|
53
|
+
'todo',
|
|
54
|
+
'backlog',
|
|
55
|
+
'planned',
|
|
56
|
+
'not started',
|
|
57
|
+
'not_started',
|
|
58
|
+
'stub',
|
|
59
|
+
'new',
|
|
60
|
+
'open',
|
|
61
|
+
];
|
|
62
|
+
/** True when `status` is empty/absent or one of the pre-work values (eligible for the nudge). */
|
|
63
|
+
function isPreWork(status, set) {
|
|
64
|
+
if (status === undefined)
|
|
65
|
+
return true;
|
|
66
|
+
const norm = status.trim().toLowerCase();
|
|
67
|
+
if (norm === '')
|
|
68
|
+
return true;
|
|
69
|
+
return set.includes(norm);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Decide whether the spec described by `fm` may be closed out. Pure over parsed
|
|
73
|
+
* frontmatter; see the module header for the canonical predicate and invariants.
|
|
74
|
+
*/
|
|
75
|
+
export function decideCloseout(fm, opts = {}) {
|
|
76
|
+
const closeable = opts.closeableStatuses ?? DEFAULT_CLOSEABLE_AC_STATUSES;
|
|
77
|
+
const terminalStage = opts.terminalStage ?? CLOSEOUT_TERMINAL_STAGE;
|
|
78
|
+
const preWork = opts.preWorkStatuses ?? DEFAULT_PRE_WORK_STATUSES;
|
|
79
|
+
// (1) Terminal-state guard: NEVER downgrade. An already complete/implemented spec,
|
|
80
|
+
// or an archived/superseded/blocked/deferred one, is left exactly as-is. Keys on the
|
|
81
|
+
// org-lifecycle `status` axis (+ the `superseded_by` pointer), mirroring the
|
|
82
|
+
// navigator's own terminal checks (isCompleteStatus / isTerminalStatus in blockers.ts).
|
|
83
|
+
if (isCompleteStatus(fm.status)) {
|
|
84
|
+
return { nextStatus: null, reason: `already complete (status: ${fm.status}); never downgrade` };
|
|
85
|
+
}
|
|
86
|
+
if (isTerminalStatus(fm.status, fm.superseded_by)) {
|
|
87
|
+
const why = fm.superseded_by ? `superseded_by: ${fm.superseded_by}` : `status: ${fm.status}`;
|
|
88
|
+
return { nextStatus: null, reason: `terminal org-lifecycle state (${why}); never downgrade` };
|
|
89
|
+
}
|
|
90
|
+
// (2) ACs are the unit of evidence. No well-formed AC => nothing to close out.
|
|
91
|
+
// (Malformed/id-less entries are dropped by normalizeAcceptanceCriteria — `validate`
|
|
92
|
+
// flags them separately — so they never silently satisfy the gate.)
|
|
93
|
+
const acs = normalizeAcceptanceCriteria(fm.acceptance_criteria).acs;
|
|
94
|
+
if (acs.length === 0) {
|
|
95
|
+
return { nextStatus: null, reason: 'no acceptance criteria — nothing to close out' };
|
|
96
|
+
}
|
|
97
|
+
const closeableSet = new Set(closeable);
|
|
98
|
+
const remaining = acs.filter((ac) => !closeableSet.has(ac.status));
|
|
99
|
+
const allCloseable = remaining.length === 0;
|
|
100
|
+
const someClosed = acs.some((ac) => closeableSet.has(ac.status));
|
|
101
|
+
const pipelineReady = fm.pipeline_status === terminalStage;
|
|
102
|
+
// (3) Closeable => promote to complete (the verified close-out the engine owns).
|
|
103
|
+
if (allCloseable && pipelineReady) {
|
|
104
|
+
return {
|
|
105
|
+
nextStatus: 'complete',
|
|
106
|
+
reason: `all ${acs.length} AC(s) in {${closeable.join(', ')}} and pipeline_status=${terminalStage}`,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// (4) Not closeable. Offer a conservative in_progress UPGRADE only when work has
|
|
110
|
+
// demonstrably started (>=1 closeable AC) AND the current status is pre-work — never
|
|
111
|
+
// a no-op restamp, never a clobber of a human-meaningful status, never a downgrade.
|
|
112
|
+
if (someClosed && !allCloseable && isPreWork(fm.status, preWork)) {
|
|
113
|
+
return {
|
|
114
|
+
nextStatus: 'in_progress',
|
|
115
|
+
reason: `work in progress — ${acs.length - remaining.length}/${acs.length} AC(s) closed, ${remaining.length} still open`,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
// (5) Otherwise leave unchanged, with a precise reason for the no-op.
|
|
119
|
+
if (!allCloseable) {
|
|
120
|
+
return {
|
|
121
|
+
nextStatus: null,
|
|
122
|
+
reason: `${remaining.length}/${acs.length} AC(s) not in {${closeable.join(', ')}} (e.g. ${remaining[0].id})`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
nextStatus: null,
|
|
127
|
+
reason: `ACs closeable but pipeline_status=${fm.pipeline_status ?? '(none)'} != ${terminalStage}`,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=closeout-predicate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"closeout-predicate.js","sourceRoot":"","sources":["../../src/lib/closeout-predicate.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -70,6 +70,16 @@ export type SpecConfig = {
|
|
|
70
70
|
pipeline?: {
|
|
71
71
|
layout?: 'encore1' | 'builder';
|
|
72
72
|
};
|
|
73
|
+
/** D2: opt-in verification-coverage gate on `eos-spec complete`. Absent (the
|
|
74
|
+
* whole block, or the `verification_coverage_min` key) ⇒ no gate — fully
|
|
75
|
+
* backward-compatible. `per_core` overrides win over the repo-wide default;
|
|
76
|
+
* see `resolveCoverageThreshold` in `lib/coverage-gate.ts`. Distinct from
|
|
77
|
+
* `defaults.test_coverage_target` (test-LINE coverage, 0–100): this is the
|
|
78
|
+
* requirement-VERIFICATION ratio (0–1), i.e. requirementsVerified/requirementsTotal. */
|
|
79
|
+
gate_thresholds?: {
|
|
80
|
+
verification_coverage_min?: number;
|
|
81
|
+
per_core?: Record<string, number>;
|
|
82
|
+
};
|
|
73
83
|
};
|
|
74
84
|
export declare function loadConfig(repoRoot: string, configOverride?: string): SpecConfig;
|
|
75
85
|
export declare function resetConfigCache(): void;
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,+BAA+B,EAC/B,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/cost.js
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
* Cross-package import is blocked by tools/eos-spec's tsconfig rootDir; tests assert parity. */
|
|
3
3
|
export const MODEL_RATES = {
|
|
4
4
|
'anthropic/claude-sonnet-4': { promptPer1m: 3, completionPer1m: 15 },
|
|
5
|
+
// TOOL-06 local models (`eos-spec run` default offload, Ollama): self-hosted, so
|
|
6
|
+
// their marginal token cost is $0. Listing them with zero rates makes a
|
|
7
|
+
// strict-local run report $0.0000 (an honest "free"), rather than `(unknown)`
|
|
8
|
+
// which a missing rate would yield. An unknown local model still returns null
|
|
9
|
+
// (handled in metrics) — only these named defaults are pinned to zero.
|
|
10
|
+
'qwen3-coder:30b': { promptPer1m: 0, completionPer1m: 0 },
|
|
11
|
+
'gpt-oss:20b': { promptPer1m: 0, completionPer1m: 0 },
|
|
5
12
|
};
|
|
6
13
|
export function computeCostUsd(model, tokens) {
|
|
7
14
|
const rate = MODEL_RATES[model];
|
package/dist/lib/cost.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../../src/lib/cost.ts"],"names":[],"mappings":"AAAA;iGACiG;AACjG,MAAM,CAAC,MAAM,WAAW,GAAqE;IAC3F,2BAA2B,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../../src/lib/cost.ts"],"names":[],"mappings":"AAAA;iGACiG;AACjG,MAAM,CAAC,MAAM,WAAW,GAAqE;IAC3F,2BAA2B,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE;IACpE,iFAAiF;IACjF,wEAAwE;IACxE,8EAA8E;IAC9E,8EAA8E;IAC9E,uEAAuE;IACvE,iBAAiB,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE;IACzD,aAAa,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE;CACtD,CAAC;AAIF,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,MAAgB;IAC5D,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,SAAS,CAAC;AACnG,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { SpecConfig } from './config.js';
|
|
2
|
+
/** Verdicts a single `eos-spec complete` invocation can reach for the D2
|
|
3
|
+
* verification-coverage gate. `no-gate` means the consuming repo never opted
|
|
4
|
+
* in (`gate_thresholds` absent from `specs/config.yaml`) — behavior is
|
|
5
|
+
* unchanged from before this gate existed. */
|
|
6
|
+
export type CoverageGateVerdict = 'no-gate' | 'pass' | 'waived' | 'blocked';
|
|
7
|
+
/**
|
|
8
|
+
* Resolve the verification-coverage threshold (a 0–1 ratio) for a core, per the
|
|
9
|
+
* D2 design: a `per_core` override wins, then the repo-wide
|
|
10
|
+
* `verification_coverage_min`, else `null` — meaning no gate is configured at
|
|
11
|
+
* all. `null` is load-bearing: it is how the gate stays fully opt-in (a repo
|
|
12
|
+
* that never sets `gate_thresholds` sees zero behavior change). Pure.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveCoverageThreshold(config: SpecConfig, core: string): number | null;
|
|
15
|
+
/**
|
|
16
|
+
* Evaluate the coverage gate's verdict from a computed ratio, the resolved
|
|
17
|
+
* threshold, and whether the spec carries a `coverage-waived` sign-off marker.
|
|
18
|
+
* Pure — the CLI wires the real coverage/threshold/waiver lookups.
|
|
19
|
+
*/
|
|
20
|
+
export declare function evaluateCoverageGate(input: {
|
|
21
|
+
ratio: number;
|
|
22
|
+
threshold: number | null;
|
|
23
|
+
hasWaiver: boolean;
|
|
24
|
+
}): {
|
|
25
|
+
gate: CoverageGateVerdict;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* A single spec's verification coverage — `requirementsVerified/requirementsTotal`
|
|
29
|
+
* from the same machinery `eos-spec scorecard` runs (`scanVerifies` +
|
|
30
|
+
* `buildScorecardForCore`), mirroring `spec-debt.ts`'s
|
|
31
|
+
* `isClaimedCompleteUnverified` so `scorecard`/`complete`/this gate never drift.
|
|
32
|
+
* `total === 0` (no declared AC/US/FR) is vacuously fully covered (`ratio: 1`) —
|
|
33
|
+
* there is nothing left un-backed, though a caller may still want to treat an
|
|
34
|
+
* all-zero "complete" spec as advisory-suspicious. An unknown spec id (no
|
|
35
|
+
* scorecard row) also reads as `{ verified: 0, total: 0, ratio: 1 }`; callers
|
|
36
|
+
* that gate on this should have already confirmed the spec exists (e.g. via
|
|
37
|
+
* `findSpec`) before calling in.
|
|
38
|
+
*/
|
|
39
|
+
export declare function verificationCoverage(repoRoot: string, specId: string): {
|
|
40
|
+
verified: number;
|
|
41
|
+
total: number;
|
|
42
|
+
ratio: number;
|
|
43
|
+
};
|