@rasensio/aidlc 1.2.1 → 1.4.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/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/claim.d.ts +15 -0
- package/dist/commands/claim.d.ts.map +1 -0
- package/dist/commands/claim.js +122 -0
- package/dist/commands/claim.js.map +1 -0
- package/dist/commands/cost.d.ts +12 -0
- package/dist/commands/cost.d.ts.map +1 -0
- package/dist/commands/cost.js +409 -0
- package/dist/commands/cost.js.map +1 -0
- package/dist/commands/gate.d.ts.map +1 -1
- package/dist/commands/gate.js +17 -0
- package/dist/commands/gate.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +38 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +59 -2
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/transition.d.ts.map +1 -1
- package/dist/commands/transition.js +30 -0
- package/dist/commands/transition.js.map +1 -1
- package/dist/core/gate.d.ts +7 -0
- package/dist/core/gate.d.ts.map +1 -1
- package/dist/core/gate.js.map +1 -1
- package/dist/core/types.d.ts +18 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/cost/config.d.ts +8 -0
- package/dist/cost/config.d.ts.map +1 -0
- package/dist/cost/config.js +37 -0
- package/dist/cost/config.js.map +1 -0
- package/dist/cost/hooks/claude-code.d.ts +29 -0
- package/dist/cost/hooks/claude-code.d.ts.map +1 -0
- package/dist/cost/hooks/claude-code.js +101 -0
- package/dist/cost/hooks/claude-code.js.map +1 -0
- package/dist/cost/hooks/kiro.d.ts +17 -0
- package/dist/cost/hooks/kiro.d.ts.map +1 -0
- package/dist/cost/hooks/kiro.js +66 -0
- package/dist/cost/hooks/kiro.js.map +1 -0
- package/dist/cost/ledger.d.ts +70 -0
- package/dist/cost/ledger.d.ts.map +1 -0
- package/dist/cost/ledger.js +314 -0
- package/dist/cost/ledger.js.map +1 -0
- package/dist/cost/providers/claude-code.d.ts +20 -0
- package/dist/cost/providers/claude-code.d.ts.map +1 -0
- package/dist/cost/providers/claude-code.js +116 -0
- package/dist/cost/providers/claude-code.js.map +1 -0
- package/dist/cost/providers/kiro.d.ts +19 -0
- package/dist/cost/providers/kiro.d.ts.map +1 -0
- package/dist/cost/providers/kiro.js +147 -0
- package/dist/cost/providers/kiro.js.map +1 -0
- package/dist/cost/providers/provider.d.ts +36 -0
- package/dist/cost/providers/provider.d.ts.map +1 -0
- package/dist/cost/providers/provider.js +21 -0
- package/dist/cost/providers/provider.js.map +1 -0
- package/dist/cost/rates-bundled.d.ts +11 -0
- package/dist/cost/rates-bundled.d.ts.map +1 -0
- package/dist/cost/rates-bundled.js +23 -0
- package/dist/cost/rates-bundled.js.map +1 -0
- package/dist/cost/rates.d.ts +42 -0
- package/dist/cost/rates.d.ts.map +1 -0
- package/dist/cost/rates.js +190 -0
- package/dist/cost/rates.js.map +1 -0
- package/dist/cost/recorder.d.ts +57 -0
- package/dist/cost/recorder.d.ts.map +1 -0
- package/dist/cost/recorder.js +339 -0
- package/dist/cost/recorder.js.map +1 -0
- package/dist/cost/report.d.ts +44 -0
- package/dist/cost/report.d.ts.map +1 -0
- package/dist/cost/report.js +164 -0
- package/dist/cost/report.js.map +1 -0
- package/dist/cost/sessions.d.ts +40 -0
- package/dist/cost/sessions.d.ts.map +1 -0
- package/dist/cost/sessions.js +200 -0
- package/dist/cost/sessions.js.map +1 -0
- package/dist/cost/sync.d.ts +24 -0
- package/dist/cost/sync.d.ts.map +1 -0
- package/dist/cost/sync.js +191 -0
- package/dist/cost/sync.js.map +1 -0
- package/dist/cost/types.d.ts +116 -0
- package/dist/cost/types.d.ts.map +1 -0
- package/dist/cost/types.js +13 -0
- package/dist/cost/types.js.map +1 -0
- package/dist/setup/setup-compute.d.ts +6 -0
- package/dist/setup/setup-compute.d.ts.map +1 -1
- package/dist/setup/setup-compute.js +3 -0
- package/dist/setup/setup-compute.js.map +1 -1
- package/dist/traceability/cache.d.ts +21 -0
- package/dist/traceability/cache.d.ts.map +1 -0
- package/dist/traceability/cache.js +106 -0
- package/dist/traceability/cache.js.map +1 -0
- package/dist/traceability/coverage-block.d.ts +21 -0
- package/dist/traceability/coverage-block.d.ts.map +1 -0
- package/dist/traceability/coverage-block.js +41 -0
- package/dist/traceability/coverage-block.js.map +1 -0
- package/dist/traceability/gate-criterion.d.ts +34 -0
- package/dist/traceability/gate-criterion.d.ts.map +1 -0
- package/dist/traceability/gate-criterion.js +128 -0
- package/dist/traceability/gate-criterion.js.map +1 -0
- package/dist/traceability/matrix.d.ts +35 -0
- package/dist/traceability/matrix.d.ts.map +1 -0
- package/dist/traceability/matrix.js +93 -0
- package/dist/traceability/matrix.js.map +1 -0
- package/dist/traceability/parser.d.ts +27 -0
- package/dist/traceability/parser.d.ts.map +1 -0
- package/dist/traceability/parser.js +101 -0
- package/dist/traceability/parser.js.map +1 -0
- package/dist/traceability/scanner.d.ts +62 -0
- package/dist/traceability/scanner.d.ts.map +1 -0
- package/dist/traceability/scanner.js +198 -0
- package/dist/traceability/scanner.js.map +1 -0
- package/dist/traceability/types.d.ts +77 -0
- package/dist/traceability/types.d.ts.map +1 -0
- package/dist/traceability/types.js +8 -0
- package/dist/traceability/types.js.map +1 -0
- package/package.json +3 -5
- package/dist/commands/setup.d.ts +0 -24
- package/dist/commands/setup.d.ts.map +0 -1
- package/dist/commands/setup.js +0 -262
- package/dist/commands/setup.js.map +0 -1
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-hoc reconciliation: `aidlc cost sync` (FR4).
|
|
3
|
+
*
|
|
4
|
+
* Correlates platform usage records with instances via sessions.ndjson.
|
|
5
|
+
* Platform-id sessions match records by id equality; agent-id sessions
|
|
6
|
+
* match by interval overlap with a strict single-candidate rule. Appends
|
|
7
|
+
* `reconciled` entries only where coverage is not already held at equal or
|
|
8
|
+
* higher fidelity. Idempotent by construction; never guesses — ambiguity
|
|
9
|
+
* goes to the report, unattributable usage to unattributed.ndjson.
|
|
10
|
+
*
|
|
11
|
+
* Design: design.md §4.4
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
import { readEntries, appendEntry, ledgerPath, unattributedPath } from './ledger.js';
|
|
16
|
+
import { sessionsPath, readSessionEvents, resolveIntervals } from './sessions.js';
|
|
17
|
+
import { getProvider } from './providers/provider.js';
|
|
18
|
+
import { transcriptRoot } from './providers/claude-code.js';
|
|
19
|
+
import { phaseWindows } from './recorder.js';
|
|
20
|
+
import { logCapture } from './recorder.js';
|
|
21
|
+
function coveredWindows(entries, sessionId, minRank) {
|
|
22
|
+
const rank = { metered: 3, reconciled: 2, estimated: 1, unknown: 0 };
|
|
23
|
+
return entries
|
|
24
|
+
.filter((e) => e.session_id === sessionId && rank[e.fidelity] >= minRank && e.units !== null)
|
|
25
|
+
.map((e) => ({ from: Date.parse(e.coverage.from), to: Date.parse(e.coverage.to) }));
|
|
26
|
+
}
|
|
27
|
+
function overlapsAny(at, windows) {
|
|
28
|
+
return windows.some((w) => at >= w.from && at <= w.to);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Reconcile one or all instances. Streams platform records session by
|
|
32
|
+
* session; reports everything it skipped and why (FR4.3).
|
|
33
|
+
*/
|
|
34
|
+
export async function syncCosts(projectRoot, instanceFilter, claimTimeoutMinutes, env = { projectRoot }) {
|
|
35
|
+
const report = { attributed: 0, skipped: [], unattributed: 0 };
|
|
36
|
+
const stateDir = join(projectRoot, '.aidlc', 'state');
|
|
37
|
+
if (!existsSync(stateDir))
|
|
38
|
+
return report;
|
|
39
|
+
const instances = readdirSync(stateDir, { withFileTypes: true })
|
|
40
|
+
.filter((d) => d.isDirectory())
|
|
41
|
+
.map((d) => d.name)
|
|
42
|
+
.filter((n) => instanceFilter === null || n === instanceFilter);
|
|
43
|
+
const perInstance = instances.map((instance) => ({
|
|
44
|
+
instance,
|
|
45
|
+
intervals: resolveIntervals(readSessionEvents(sessionsPath(projectRoot, instance)), claimTimeoutMinutes),
|
|
46
|
+
}));
|
|
47
|
+
// Gather every session id seen anywhere.
|
|
48
|
+
const sessions = new Map();
|
|
49
|
+
for (const { intervals } of perInstance) {
|
|
50
|
+
for (const iv of intervals) {
|
|
51
|
+
sessions.set(iv.session_id, { id_source: iv.id_source, agent: iv.agent });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
for (const [sessionId, meta] of sessions) {
|
|
55
|
+
const provider = getProvider(meta.agent);
|
|
56
|
+
if (!provider) {
|
|
57
|
+
report.skipped.push(`${sessionId}: no provider for agent "${meta.agent}"`);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
// Locate the record file.
|
|
61
|
+
let recordPath = null;
|
|
62
|
+
if (meta.id_source === 'platform') {
|
|
63
|
+
recordPath = locateById(provider.name, sessionId, env);
|
|
64
|
+
if (!recordPath) {
|
|
65
|
+
report.skipped.push(`${sessionId}: no local ${provider.name} records found`);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const candidates = locateByInterval(provider.name, sessionId, perInstance, env);
|
|
71
|
+
if (candidates.length === 0) {
|
|
72
|
+
report.skipped.push(`${sessionId}: agent-id session, no overlapping ${provider.name} records`);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (candidates.length > 1) {
|
|
76
|
+
report.skipped.push(`${sessionId}: agent-id session, ${candidates.length} candidate records — ambiguous, not guessing`);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
recordPath = candidates[0];
|
|
80
|
+
}
|
|
81
|
+
let segments;
|
|
82
|
+
try {
|
|
83
|
+
segments = await provider.extract({ provider: provider.name, path: recordPath }, null, env);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
logCapture(projectRoot, 'sync-extract', 'extract-failed');
|
|
87
|
+
report.skipped.push(`${sessionId}: extraction failed`);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
for (const seg of segments) {
|
|
91
|
+
const at = Date.parse(seg.at);
|
|
92
|
+
let target = { instance: null, phase: null };
|
|
93
|
+
for (const { instance, intervals } of perInstance) {
|
|
94
|
+
const mine = intervals.filter((iv) => iv.session_id === sessionId);
|
|
95
|
+
if (mine.some((iv) => at >= Date.parse(iv.from) && at <= Date.parse(iv.to))) {
|
|
96
|
+
const windows = phaseWindows(projectRoot, instance, 'implementation');
|
|
97
|
+
const phase = windows.find((w) => at >= w.from && at < w.to)?.phase ?? null;
|
|
98
|
+
target = { instance, phase };
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const targetPath = target.instance !== null
|
|
103
|
+
? ledgerPath(projectRoot, target.instance)
|
|
104
|
+
: unattributedPath(projectRoot);
|
|
105
|
+
const existing = readEntries(targetPath);
|
|
106
|
+
// Skip segments already covered at reconciled-or-better fidelity.
|
|
107
|
+
if (overlapsAny(at, coveredWindows(existing, sessionId, 2)))
|
|
108
|
+
continue;
|
|
109
|
+
const entry = {
|
|
110
|
+
timestamp: new Date().toISOString(),
|
|
111
|
+
session_id: sessionId,
|
|
112
|
+
phase: target.phase,
|
|
113
|
+
provider: provider.name,
|
|
114
|
+
fidelity: 'reconciled',
|
|
115
|
+
coverage: { from: seg.at, to: seg.at },
|
|
116
|
+
cursor: seg.cursor,
|
|
117
|
+
units: seg.units,
|
|
118
|
+
};
|
|
119
|
+
try {
|
|
120
|
+
appendEntry(targetPath, entry);
|
|
121
|
+
if (target.instance !== null)
|
|
122
|
+
report.attributed++;
|
|
123
|
+
else
|
|
124
|
+
report.unattributed++;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
logCapture(projectRoot, 'sync-append', 'validation-rejected');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return report;
|
|
132
|
+
}
|
|
133
|
+
/** Locate a platform record file by session id equality. */
|
|
134
|
+
function locateById(providerName, sessionId, env) {
|
|
135
|
+
if (providerName === 'claude-code') {
|
|
136
|
+
const root = transcriptRoot(env);
|
|
137
|
+
if (!existsSync(root))
|
|
138
|
+
return null;
|
|
139
|
+
for (const dir of readdirSync(root, { withFileTypes: true })) {
|
|
140
|
+
if (!dir.isDirectory())
|
|
141
|
+
continue;
|
|
142
|
+
const candidate = join(root, dir.name, `${sessionId}.jsonl`);
|
|
143
|
+
if (existsSync(candidate))
|
|
144
|
+
return candidate;
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
if (providerName === 'kiro') {
|
|
149
|
+
const provider = getProvider('kiro');
|
|
150
|
+
const source = provider?.resolveSource({ session_id: sessionId }, env);
|
|
151
|
+
return source?.path ?? null;
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* For agent-id sessions: find record files whose usage overlaps the
|
|
157
|
+
* session's claim intervals. Strict — several candidates means ambiguity.
|
|
158
|
+
*/
|
|
159
|
+
function locateByInterval(providerName, sessionId, perInstance, env) {
|
|
160
|
+
if (providerName !== 'claude-code')
|
|
161
|
+
return [];
|
|
162
|
+
const intervals = perInstance
|
|
163
|
+
.flatMap(({ intervals }) => intervals)
|
|
164
|
+
.filter((iv) => iv.session_id === sessionId);
|
|
165
|
+
if (intervals.length === 0)
|
|
166
|
+
return [];
|
|
167
|
+
const root = transcriptRoot(env);
|
|
168
|
+
if (!existsSync(root))
|
|
169
|
+
return [];
|
|
170
|
+
const matches = [];
|
|
171
|
+
for (const dir of readdirSync(root, { withFileTypes: true })) {
|
|
172
|
+
if (!dir.isDirectory())
|
|
173
|
+
continue;
|
|
174
|
+
for (const f of readdirSync(join(root, dir.name))) {
|
|
175
|
+
if (!f.endsWith('.jsonl'))
|
|
176
|
+
continue;
|
|
177
|
+
const path = join(root, dir.name, f);
|
|
178
|
+
try {
|
|
179
|
+
const mtime = statSync(path).mtimeMs;
|
|
180
|
+
if (intervals.some((iv) => mtime >= Date.parse(iv.from) && mtime <= Date.parse(iv.to) + 60 * 60 * 1000)) {
|
|
181
|
+
matches.push(path);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return matches;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/cost/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cost-tracking domain types.
|
|
3
|
+
*
|
|
4
|
+
* The ledger records raw usage units (tokens, credits) — never dollars.
|
|
5
|
+
* Dollars are computed at report time from a rate table (see rates.ts).
|
|
6
|
+
*
|
|
7
|
+
* Design: .aidlc/state/cost-tracking/design.md §2
|
|
8
|
+
*/
|
|
9
|
+
/** Token usage for a single model within a coverage window. */
|
|
10
|
+
export interface TokenUnits {
|
|
11
|
+
kind: 'tokens';
|
|
12
|
+
model: string;
|
|
13
|
+
input_tokens: number;
|
|
14
|
+
output_tokens: number;
|
|
15
|
+
cache_read_tokens: number;
|
|
16
|
+
cache_write_tokens: number;
|
|
17
|
+
}
|
|
18
|
+
/** Credit usage (Kiro-style metering) within a coverage window. */
|
|
19
|
+
export interface CreditUnits {
|
|
20
|
+
kind: 'credits';
|
|
21
|
+
credits: number;
|
|
22
|
+
model: string | null;
|
|
23
|
+
}
|
|
24
|
+
export type CostUnits = TokenUnits | CreditUnits;
|
|
25
|
+
/** Provenance of a ledger entry's numbers. */
|
|
26
|
+
export type CostFidelity = 'metered' | 'reconciled' | 'estimated' | 'unknown';
|
|
27
|
+
/** One line in costs.ndjson / unattributed.ndjson. */
|
|
28
|
+
export interface CostEntry {
|
|
29
|
+
/** ISO 8601 UTC append time. */
|
|
30
|
+
timestamp: string;
|
|
31
|
+
session_id: string | null;
|
|
32
|
+
/** Phase the usage occurred in; null only in unattributed.ndjson. */
|
|
33
|
+
phase: string | null;
|
|
34
|
+
provider: string;
|
|
35
|
+
fidelity: CostFidelity;
|
|
36
|
+
/** Usage window this entry covers. */
|
|
37
|
+
coverage: {
|
|
38
|
+
from: string;
|
|
39
|
+
to: string;
|
|
40
|
+
};
|
|
41
|
+
/** Provider resume point after this entry (e.g. transcript message uuid). */
|
|
42
|
+
cursor: string | null;
|
|
43
|
+
/** null ⇔ fidelity 'unknown' (attribution interval marker). */
|
|
44
|
+
units: CostUnits | null;
|
|
45
|
+
}
|
|
46
|
+
/** One line in sessions.ndjson. */
|
|
47
|
+
export interface SessionEvent {
|
|
48
|
+
event: 'claim' | 'renew' | 'release';
|
|
49
|
+
session_id: string;
|
|
50
|
+
id_source: 'platform' | 'agent';
|
|
51
|
+
agent: string;
|
|
52
|
+
timestamp: string;
|
|
53
|
+
}
|
|
54
|
+
/** A resolved session↔instance attribution interval. */
|
|
55
|
+
export interface ClaimInterval {
|
|
56
|
+
session_id: string;
|
|
57
|
+
id_source: 'platform' | 'agent';
|
|
58
|
+
agent: string;
|
|
59
|
+
from: string;
|
|
60
|
+
/** Release time, or claim-timeout bound for unreleased claims. */
|
|
61
|
+
to: string;
|
|
62
|
+
/** True when bounded by timeout rather than an explicit release. */
|
|
63
|
+
open: boolean;
|
|
64
|
+
}
|
|
65
|
+
/** Active-session stash entry (.aidlc/cost/active-sessions/<id>.json). */
|
|
66
|
+
export interface ActiveSession {
|
|
67
|
+
session_id: string;
|
|
68
|
+
agent: string;
|
|
69
|
+
cwd: string;
|
|
70
|
+
transcript_path?: string;
|
|
71
|
+
started_at: string;
|
|
72
|
+
}
|
|
73
|
+
/** A usage segment extracted by a provider, pre-attribution. */
|
|
74
|
+
export interface UsageSegment {
|
|
75
|
+
/** ISO 8601 timestamp of the usage event. */
|
|
76
|
+
at: string;
|
|
77
|
+
units: CostUnits;
|
|
78
|
+
/** Provider resume point after this segment. */
|
|
79
|
+
cursor: string;
|
|
80
|
+
}
|
|
81
|
+
/** Validated pointer to a provider's usage records. */
|
|
82
|
+
export interface SourceRef {
|
|
83
|
+
provider: string;
|
|
84
|
+
path: string;
|
|
85
|
+
}
|
|
86
|
+
/** Input to `aidlc cost record` in hook mode (parsed from stdin). */
|
|
87
|
+
export interface RecordInput {
|
|
88
|
+
session_id: string;
|
|
89
|
+
transcript_path?: string;
|
|
90
|
+
cwd?: string;
|
|
91
|
+
}
|
|
92
|
+
/** Per-model (or per-unit) pricing entry. */
|
|
93
|
+
export interface RateEntry {
|
|
94
|
+
input_per_mtok?: number;
|
|
95
|
+
output_per_mtok?: number;
|
|
96
|
+
cache_read_per_mtok?: number;
|
|
97
|
+
cache_write_per_mtok?: number;
|
|
98
|
+
/** For unit-priced providers (e.g. kiro-credit). */
|
|
99
|
+
per_unit?: number;
|
|
100
|
+
}
|
|
101
|
+
/** A rate table snapshot with provenance. */
|
|
102
|
+
export interface RateSnapshot {
|
|
103
|
+
snapshot_version: string;
|
|
104
|
+
effective_date: string;
|
|
105
|
+
rates: Record<string, RateEntry>;
|
|
106
|
+
}
|
|
107
|
+
/** Cost section of .aidlc/config.yaml. */
|
|
108
|
+
export interface CostConfig {
|
|
109
|
+
rates_url?: string;
|
|
110
|
+
rates?: Record<string, RateEntry>;
|
|
111
|
+
}
|
|
112
|
+
/** Session-id format shared by validation and path construction (FR3.9). */
|
|
113
|
+
export declare const SESSION_ID_RE: RegExp;
|
|
114
|
+
/** Model-id format allowed in ledger entries. */
|
|
115
|
+
export declare const MODEL_ID_RE: RegExp;
|
|
116
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cost/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cost-tracking domain types.
|
|
3
|
+
*
|
|
4
|
+
* The ledger records raw usage units (tokens, credits) — never dollars.
|
|
5
|
+
* Dollars are computed at report time from a rate table (see rates.ts).
|
|
6
|
+
*
|
|
7
|
+
* Design: .aidlc/state/cost-tracking/design.md §2
|
|
8
|
+
*/
|
|
9
|
+
/** Session-id format shared by validation and path construction (FR3.9). */
|
|
10
|
+
export const SESSION_ID_RE = /^[A-Za-z0-9_-]{8,64}$/;
|
|
11
|
+
/** Model-id format allowed in ledger entries. */
|
|
12
|
+
export const MODEL_ID_RE = /^[A-Za-z0-9_.:/@-]{1,128}$/;
|
|
13
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cost/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAoHH,4EAA4E;AAC5E,MAAM,CAAC,MAAM,aAAa,GAAG,uBAAuB,CAAC;AAErD,iDAAiD;AACjD,MAAM,CAAC,MAAM,WAAW,GAAG,4BAA4B,CAAC"}
|
|
@@ -34,6 +34,12 @@ export interface SetupConfig {
|
|
|
34
34
|
actions: string[];
|
|
35
35
|
stalled_threshold_days: number;
|
|
36
36
|
claim_timeout_minutes: number;
|
|
37
|
+
/**
|
|
38
|
+
* Sections computeSetup does not own (cost, orchestrator, secret_patterns,
|
|
39
|
+
* anything future) carry through rebuilds untouched — re-running init must
|
|
40
|
+
* never drop a hand-added config section.
|
|
41
|
+
*/
|
|
42
|
+
[key: string]: unknown;
|
|
37
43
|
}
|
|
38
44
|
/**
|
|
39
45
|
* Compute the setup result by merging existing config with new answers.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-compute.d.ts","sourceRoot":"","sources":["../../src/setup/setup-compute.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAMnD,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE;QACR,KAAK,EAAE,UAAU,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qBAAqB,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"setup-compute.d.ts","sourceRoot":"","sources":["../../src/setup/setup-compute.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAMnD,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE;QACR,KAAK,EAAE,UAAU,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qBAAqB,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAkCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,WAAW,GAAG,IAAI,EAC5B,OAAO,EAAE,YAAY,GACpB,WAAW,CAiBb"}
|
|
@@ -52,6 +52,9 @@ function sortedUnion(a, b) {
|
|
|
52
52
|
export function computeSetup(existing, answers) {
|
|
53
53
|
const base = existing ?? DEFAULT_CONFIG;
|
|
54
54
|
return {
|
|
55
|
+
// Unknown keys first so owned fields below always win (DD8: preserve
|
|
56
|
+
// the whole class of hand-added sections, not just known ones).
|
|
57
|
+
...base,
|
|
55
58
|
version: base.version,
|
|
56
59
|
defaults: {
|
|
57
60
|
scope: answers.scope ?? base.defaults.scope,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-compute.js","sourceRoot":"","sources":["../../src/setup/setup-compute.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"setup-compute.js","sourceRoot":"","sources":["../../src/setup/setup-compute.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA2CH,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E,MAAM,cAAc,GAAgB;IAClC,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE;QACR,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,YAAY;KACvB;IACD,SAAS,EAAE,EAAE;IACb,OAAO,EAAE,EAAE;IACX,sBAAsB,EAAE,CAAC;IACzB,qBAAqB,EAAE,EAAE;CAC1B,CAAC;AAEF,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;GAEG;AACH,SAAS,WAAW,CAAC,CAAW,EAAE,CAAW;IAC3C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAC1B,QAA4B,EAC5B,OAAqB;IAErB,MAAM,IAAI,GAAG,QAAQ,IAAI,cAAc,CAAC;IAExC,OAAO;QACL,qEAAqE;QACrE,gEAAgE;QAChE,GAAG,IAAI;QACP,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ,EAAE;YACR,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK;YAC3C,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ;SACrD;QACD,SAAS,EAAE,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;QAC/D,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;QACzD,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;QACnD,qBAAqB,EAAE,IAAI,CAAC,qBAAqB;KAClD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status-column coverage cache (AC-17, NFR2): `aidlc status` must stay
|
|
3
|
+
* filesystem-cheap, so coverage is cached at
|
|
4
|
+
* `.aidlc/cache/traceability/<instance>.json` — outside tracked state
|
|
5
|
+
* (derived data, design F5) — keyed by a stat hash of every input coverage
|
|
6
|
+
* depends on, including ALL instances' requirements.md (the uniqueness rule
|
|
7
|
+
* makes coverage cross-instance, design F2). Cache hit costs stats only;
|
|
8
|
+
* corrupt or absent cache degrades to recompute (fail-soft).
|
|
9
|
+
*
|
|
10
|
+
* Requirements: traceability-ids/AC-17
|
|
11
|
+
*/
|
|
12
|
+
import type { CoverageSummary } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Coverage summary for the status column, cached by input stat hash.
|
|
15
|
+
*
|
|
16
|
+
* @returns null when the criterion does not apply to the instance.
|
|
17
|
+
*/
|
|
18
|
+
export declare function coverageForStatus(projectRoot: string, instanceName: string): CoverageSummary | null;
|
|
19
|
+
/** Format a coverage summary for the status table cell. */
|
|
20
|
+
export declare function formatCoverage(coverage: CoverageSummary): string;
|
|
21
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/traceability/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAyDlD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,eAAe,GAAG,IAAI,CA6BxB;AAED,2DAA2D;AAC3D,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAGhE"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status-column coverage cache (AC-17, NFR2): `aidlc status` must stay
|
|
3
|
+
* filesystem-cheap, so coverage is cached at
|
|
4
|
+
* `.aidlc/cache/traceability/<instance>.json` — outside tracked state
|
|
5
|
+
* (derived data, design F5) — keyed by a stat hash of every input coverage
|
|
6
|
+
* depends on, including ALL instances' requirements.md (the uniqueness rule
|
|
7
|
+
* makes coverage cross-instance, design F2). Cache hit costs stats only;
|
|
8
|
+
* corrupt or absent cache degrades to recompute (fail-soft).
|
|
9
|
+
*
|
|
10
|
+
* Requirements: traceability-ids/AC-17
|
|
11
|
+
*/
|
|
12
|
+
import { createHash } from 'node:crypto';
|
|
13
|
+
import { mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
import { DEFAULT_TEST_GLOBS, discoverTestFiles } from './scanner.js';
|
|
16
|
+
import { evaluateTraceabilityCriterion, loadTraceabilityConfig } from './gate-criterion.js';
|
|
17
|
+
function statLine(path) {
|
|
18
|
+
try {
|
|
19
|
+
const s = statSync(path);
|
|
20
|
+
return `${s.mtimeMs}:${s.size}`;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return 'absent';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Hash every input the coverage matrix depends on (design DD5). */
|
|
27
|
+
function computeInputsHash(projectRoot, instanceName) {
|
|
28
|
+
const stateDir = join(projectRoot, '.aidlc', 'state');
|
|
29
|
+
const hash = createHash('sha256');
|
|
30
|
+
hash.update(statLine(join(stateDir, instanceName, 'requirements.md')) + '\n');
|
|
31
|
+
hash.update(statLine(join(stateDir, instanceName, 'testing.md')) + '\n');
|
|
32
|
+
// Every instance's requirements.md, sorted — bare-ref uniqueness (AC-24).
|
|
33
|
+
let instances = [];
|
|
34
|
+
try {
|
|
35
|
+
instances = readdirSync(stateDir).sort();
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// No state dir — hash stays partial-but-deterministic.
|
|
39
|
+
}
|
|
40
|
+
for (const name of instances) {
|
|
41
|
+
hash.update(`${name}:${statLine(join(stateDir, name, 'requirements.md'))}\n`);
|
|
42
|
+
}
|
|
43
|
+
const globs = loadTraceabilityConfig(projectRoot)?.test_globs ?? DEFAULT_TEST_GLOBS;
|
|
44
|
+
hash.update(globs.join('\0') + '\n');
|
|
45
|
+
const discovery = discoverTestFiles(projectRoot, globs);
|
|
46
|
+
for (const file of discovery.files) {
|
|
47
|
+
hash.update(`${file}:${statLine(join(projectRoot, ...file.split('/')))}\n`);
|
|
48
|
+
}
|
|
49
|
+
return hash.digest('hex');
|
|
50
|
+
}
|
|
51
|
+
function summarize(projectRoot, instanceName) {
|
|
52
|
+
const result = evaluateTraceabilityCriterion(projectRoot, instanceName, 'testing');
|
|
53
|
+
if (result === null || result.entries.length === 0)
|
|
54
|
+
return null;
|
|
55
|
+
const active = result.entries.filter((e) => e.status !== 'retired');
|
|
56
|
+
const stale = result.warnings.filter((w) => w.includes('(stale reference)')).length;
|
|
57
|
+
return {
|
|
58
|
+
covered: active.filter((e) => e.status === 'covered').length,
|
|
59
|
+
total: active.length,
|
|
60
|
+
stale,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Coverage summary for the status column, cached by input stat hash.
|
|
65
|
+
*
|
|
66
|
+
* @returns null when the criterion does not apply to the instance.
|
|
67
|
+
*/
|
|
68
|
+
export function coverageForStatus(projectRoot, instanceName) {
|
|
69
|
+
const cacheDir = join(projectRoot, '.aidlc', 'cache', 'traceability');
|
|
70
|
+
const cachePath = join(cacheDir, `${instanceName}.json`);
|
|
71
|
+
const inputsHash = computeInputsHash(projectRoot, instanceName);
|
|
72
|
+
try {
|
|
73
|
+
const cached = JSON.parse(readFileSync(cachePath, 'utf8'));
|
|
74
|
+
if (cached.inputsHash === inputsHash && cached.coverage)
|
|
75
|
+
return cached.coverage;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Miss — recompute below.
|
|
79
|
+
}
|
|
80
|
+
const coverage = summarize(projectRoot, instanceName);
|
|
81
|
+
if (coverage === null)
|
|
82
|
+
return null;
|
|
83
|
+
try {
|
|
84
|
+
mkdirSync(cacheDir, { recursive: true });
|
|
85
|
+
// Self-ignoring cache dir: derived data must never land in git, even in
|
|
86
|
+
// consumer repos whose .gitignore predates this feature (design F5).
|
|
87
|
+
const ignorePath = join(projectRoot, '.aidlc', 'cache', '.gitignore');
|
|
88
|
+
try {
|
|
89
|
+
readFileSync(ignorePath);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
writeFileSync(ignorePath, '*\n');
|
|
93
|
+
}
|
|
94
|
+
writeFileSync(cachePath, JSON.stringify({ inputsHash, coverage }));
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Cache write failure never breaks status.
|
|
98
|
+
}
|
|
99
|
+
return coverage;
|
|
100
|
+
}
|
|
101
|
+
/** Format a coverage summary for the status table cell. */
|
|
102
|
+
export function formatCoverage(coverage) {
|
|
103
|
+
const base = `${coverage.covered}/${coverage.total}`;
|
|
104
|
+
return coverage.stale > 0 ? `${base} ⚠${coverage.stale}` : base;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/traceability/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ac-coverage` block parser (FR3, D2): a fenced code block in the instance's
|
|
3
|
+
* testing.md whose info string is `ac-coverage`, one `AC-n: evidence` line
|
|
4
|
+
* per entry. The explicit escape hatch for manually or indirectly verified
|
|
5
|
+
* criteria — block entries union with scanned references (AC-9).
|
|
6
|
+
*
|
|
7
|
+
* Requirements: traceability-ids/AC-9, AC-10
|
|
8
|
+
*/
|
|
9
|
+
export interface CoverageBlockEntry {
|
|
10
|
+
acId: number;
|
|
11
|
+
evidence: string;
|
|
12
|
+
/** 1-based line within testing.md. */
|
|
13
|
+
line: number;
|
|
14
|
+
}
|
|
15
|
+
export interface CoverageBlockResult {
|
|
16
|
+
entries: CoverageBlockEntry[];
|
|
17
|
+
warnings: string[];
|
|
18
|
+
}
|
|
19
|
+
/** Parse all `ac-coverage` blocks from testing.md content. */
|
|
20
|
+
export declare function parseCoverageBlock(content: string): CoverageBlockResult;
|
|
21
|
+
//# sourceMappingURL=coverage-block.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-block.d.ts","sourceRoot":"","sources":["../../src/traceability/coverage-block.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;CACd;AAMD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAwBvE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ac-coverage` block parser (FR3, D2): a fenced code block in the instance's
|
|
3
|
+
* testing.md whose info string is `ac-coverage`, one `AC-n: evidence` line
|
|
4
|
+
* per entry. The explicit escape hatch for manually or indirectly verified
|
|
5
|
+
* criteria — block entries union with scanned references (AC-9).
|
|
6
|
+
*
|
|
7
|
+
* Requirements: traceability-ids/AC-9, AC-10
|
|
8
|
+
*/
|
|
9
|
+
const FENCE_OPEN_RE = /^\s*```ac-coverage\s*$/;
|
|
10
|
+
const FENCE_CLOSE_RE = /^\s*```\s*$/;
|
|
11
|
+
const ENTRY_RE = /^\s*AC-([1-9][0-9]*):\s*(.*\S)\s*$/;
|
|
12
|
+
/** Parse all `ac-coverage` blocks from testing.md content. */
|
|
13
|
+
export function parseCoverageBlock(content) {
|
|
14
|
+
const entries = [];
|
|
15
|
+
const warnings = [];
|
|
16
|
+
const lines = content.split('\n');
|
|
17
|
+
let inBlock = false;
|
|
18
|
+
for (let i = 0; i < lines.length; i++) {
|
|
19
|
+
const line = lines[i];
|
|
20
|
+
if (!inBlock) {
|
|
21
|
+
if (FENCE_OPEN_RE.test(line))
|
|
22
|
+
inBlock = true;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (FENCE_CLOSE_RE.test(line)) {
|
|
26
|
+
inBlock = false;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (line.trim() === '')
|
|
30
|
+
continue;
|
|
31
|
+
const m = ENTRY_RE.exec(line);
|
|
32
|
+
if (m) {
|
|
33
|
+
entries.push({ acId: Number(m[1]), evidence: m[2], line: i + 1 });
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
warnings.push(`ac-coverage block line ${i + 1}: unparseable entry "${line.trim()}"`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return { entries, warnings };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=coverage-block.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-block.js","sourceRoot":"","sources":["../../src/traceability/coverage-block.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,MAAM,aAAa,GAAG,wBAAwB,CAAC;AAC/C,MAAM,cAAc,GAAG,aAAa,CAAC;AACrC,MAAM,QAAQ,GAAG,oCAAoC,CAAC;AAOtD,8DAA8D;AAC9D,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO,GAAG,IAAI,CAAC;YAC7C,SAAS;QACX,CAAC;QACD,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,OAAO,GAAG,KAAK,CAAC;YAChB,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAS;QACjC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,wBAAwB,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Traceability gate criterion (FR4): computed live at the command layer
|
|
3
|
+
* after `evaluateGate`, following the knowledge-criterion precedent — it
|
|
4
|
+
* therefore evaluates even when phase state is `complete` (AC-11) and never
|
|
5
|
+
* touches `evaluateGate`'s contract (DD1).
|
|
6
|
+
*
|
|
7
|
+
* Applicability tri-state (DD7):
|
|
8
|
+
* null phase ≠ testing, phase-testing.yaml absent, or
|
|
9
|
+
* zero AC-shaped lines (AC-3, AC-13)
|
|
10
|
+
* result, empty entries only near-misses — warnings surface (AC-22)
|
|
11
|
+
* result with entries ≥1 valid definition — full evaluation
|
|
12
|
+
*
|
|
13
|
+
* Requirements: traceability-ids/AC-3, AC-11..AC-15
|
|
14
|
+
*/
|
|
15
|
+
import type { ParsedRequirements, TraceabilityConfig, TraceabilityResult } from './types.js';
|
|
16
|
+
/** Message template callers use for unsatisfied criteria / violations. */
|
|
17
|
+
export declare function uncoveredMessage(acId: number): string;
|
|
18
|
+
/** Tolerant reader for the optional `traceability:` config section (AC-7). */
|
|
19
|
+
export declare function loadTraceabilityConfig(projectRoot: string): TraceabilityConfig | null;
|
|
20
|
+
/**
|
|
21
|
+
* Parse every instance's requirements.md — the registry backing the bare-
|
|
22
|
+
* reference uniqueness rule (AC-24, D5). Reads by explicit path; the
|
|
23
|
+
* scanner's `.aidlc` exclusion governs test discovery only.
|
|
24
|
+
*/
|
|
25
|
+
export declare function loadRegistry(projectRoot: string): Map<string, ParsedRequirements>;
|
|
26
|
+
/**
|
|
27
|
+
* Evaluate the traceability criterion for one instance.
|
|
28
|
+
*
|
|
29
|
+
* @returns null when the criterion does not evaluate (AC-3, AC-13); otherwise
|
|
30
|
+
* a result whose `uncoveredActive` entries the caller turns into
|
|
31
|
+
* unsatisfied criteria / gate violations via {@link uncoveredMessage}.
|
|
32
|
+
*/
|
|
33
|
+
export declare function evaluateTraceabilityCriterion(projectRoot: string, instanceName: string, phaseName: string): TraceabilityResult | null;
|
|
34
|
+
//# sourceMappingURL=gate-criterion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-criterion.d.ts","sourceRoot":"","sources":["../../src/traceability/gate-criterion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAM7F,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,8EAA8E;AAC9E,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAarF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAkBjF;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,kBAAkB,GAAG,IAAI,CAuD3B"}
|