@rasensio/aidlc 1.3.0 → 1.5.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/claim.d.ts +8 -6
- package/dist/commands/claim.d.ts.map +1 -1
- package/dist/commands/claim.js +49 -41
- package/dist/commands/claim.js.map +1 -1
- 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.js +13 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +145 -4
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +109 -3
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/transition.d.ts.map +1 -1
- package/dist/commands/transition.js +39 -2
- package/dist/commands/transition.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +13 -0
- package/dist/commands/update.js.map +1 -1
- package/dist/concurrency/claim-store.d.ts +44 -0
- package/dist/concurrency/claim-store.d.ts.map +1 -0
- package/dist/concurrency/claim-store.js +273 -0
- package/dist/concurrency/claim-store.js.map +1 -0
- package/dist/concurrency/common-dir.d.ts +25 -0
- package/dist/concurrency/common-dir.d.ts.map +1 -0
- package/dist/concurrency/common-dir.js +81 -0
- package/dist/concurrency/common-dir.js.map +1 -0
- package/dist/concurrency/detect.d.ts +23 -0
- package/dist/concurrency/detect.d.ts.map +1 -0
- package/dist/concurrency/detect.js +59 -0
- package/dist/concurrency/detect.js.map +1 -0
- package/dist/concurrency/gitattributes.d.ts +23 -0
- package/dist/concurrency/gitattributes.d.ts.map +1 -0
- package/dist/concurrency/gitattributes.js +52 -0
- package/dist/concurrency/gitattributes.js.map +1 -0
- package/dist/concurrency/registry.d.ts +48 -0
- package/dist/concurrency/registry.d.ts.map +1 -0
- package/dist/concurrency/registry.js +163 -0
- package/dist/concurrency/registry.js.map +1 -0
- package/dist/concurrency/session-id.d.ts +22 -0
- package/dist/concurrency/session-id.d.ts.map +1 -0
- package/dist/concurrency/session-id.js +35 -0
- package/dist/concurrency/session-id.js.map +1 -0
- package/dist/concurrency/types.d.ts +39 -0
- package/dist/concurrency/types.d.ts.map +1 -0
- package/dist/concurrency/types.js +12 -0
- package/dist/concurrency/types.js.map +1 -0
- package/dist/concurrency/worktree.d.ts +49 -0
- package/dist/concurrency/worktree.d.ts.map +1 -0
- package/dist/concurrency/worktree.js +169 -0
- package/dist/concurrency/worktree.js.map +1 -0
- 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 +16 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/cost/ledger.d.ts.map +1 -1
- package/dist/cost/ledger.js +6 -0
- package/dist/cost/ledger.js.map +1 -1
- package/dist/cost/sessions.d.ts +6 -1
- package/dist/cost/sessions.d.ts.map +1 -1
- package/dist/cost/sessions.js +10 -1
- package/dist/cost/sessions.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 +2 -2
- 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,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage matrix builder: resolves references against the cross-instance
|
|
3
|
+
* registry (uniqueness rule, D5) and unions scan ∪ block coverage per AC.
|
|
4
|
+
*
|
|
5
|
+
* Bare `AC-n` counts only when exactly one AC-bearing instance defines id n
|
|
6
|
+
* (AC-24); qualified `<instance>/AC-n` always resolves to that instance
|
|
7
|
+
* (AC-25). Retired ACs never require coverage; references to them warn
|
|
8
|
+
* (AC-14). Only `uncoveredActive` fails gates — warnings are data (DD6).
|
|
9
|
+
*
|
|
10
|
+
* Requirements: traceability-ids/AC-9..AC-15, AC-24, AC-25
|
|
11
|
+
*/
|
|
12
|
+
import type { AcCoverageEntry, AcReference, ParsedRequirements } from './types.js';
|
|
13
|
+
import type { CoverageBlockEntry } from './coverage-block.js';
|
|
14
|
+
export interface MatrixInput {
|
|
15
|
+
/** Target instance name. */
|
|
16
|
+
instance: string;
|
|
17
|
+
/** Target instance's parsed requirements. */
|
|
18
|
+
parsed: ParsedRequirements;
|
|
19
|
+
/** All instances' parsed requirements (registry, keyed by instance). */
|
|
20
|
+
registry: Map<string, ParsedRequirements>;
|
|
21
|
+
/** Scanned references from test files. */
|
|
22
|
+
refs: AcReference[];
|
|
23
|
+
/** Entries from the target instance's ac-coverage block. */
|
|
24
|
+
blockEntries: CoverageBlockEntry[];
|
|
25
|
+
/** Posix-relative path of the target instance's testing.md. */
|
|
26
|
+
testingPath: string;
|
|
27
|
+
}
|
|
28
|
+
export interface MatrixOutput {
|
|
29
|
+
entries: AcCoverageEntry[];
|
|
30
|
+
warnings: string[];
|
|
31
|
+
uncoveredActive: number[];
|
|
32
|
+
}
|
|
33
|
+
/** Build the coverage matrix for one instance. */
|
|
34
|
+
export declare function buildMatrix(input: MatrixInput): MatrixOutput;
|
|
35
|
+
//# sourceMappingURL=matrix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../../src/traceability/matrix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACV,eAAe,EAEf,WAAW,EACX,kBAAkB,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,MAAM,EAAE,kBAAkB,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC1C,0CAA0C;IAC1C,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,4DAA4D;IAC5D,YAAY,EAAE,kBAAkB,EAAE,CAAC;IACnC,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAWD,kDAAkD;AAClD,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CA+E5D"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage matrix builder: resolves references against the cross-instance
|
|
3
|
+
* registry (uniqueness rule, D5) and unions scan ∪ block coverage per AC.
|
|
4
|
+
*
|
|
5
|
+
* Bare `AC-n` counts only when exactly one AC-bearing instance defines id n
|
|
6
|
+
* (AC-24); qualified `<instance>/AC-n` always resolves to that instance
|
|
7
|
+
* (AC-25). Retired ACs never require coverage; references to them warn
|
|
8
|
+
* (AC-14). Only `uncoveredActive` fails gates — warnings are data (DD6).
|
|
9
|
+
*
|
|
10
|
+
* Requirements: traceability-ids/AC-9..AC-15, AC-24, AC-25
|
|
11
|
+
*/
|
|
12
|
+
/** Instances (other than possibly the target) defining a given AC id. */
|
|
13
|
+
function definersOf(registry, acId) {
|
|
14
|
+
const definers = [];
|
|
15
|
+
for (const [name, parsed] of registry) {
|
|
16
|
+
if (parsed.defs.some((d) => d.id === acId))
|
|
17
|
+
definers.push(name);
|
|
18
|
+
}
|
|
19
|
+
return definers.sort();
|
|
20
|
+
}
|
|
21
|
+
/** Build the coverage matrix for one instance. */
|
|
22
|
+
export function buildMatrix(input) {
|
|
23
|
+
const { instance, parsed, registry, refs, blockEntries, testingPath } = input;
|
|
24
|
+
const warnings = [];
|
|
25
|
+
const byId = new Map(parsed.defs.map((d) => [d.id, d]));
|
|
26
|
+
const coverage = new Map();
|
|
27
|
+
const addRef = (acId, path, source) => {
|
|
28
|
+
let paths = coverage.get(acId);
|
|
29
|
+
if (!paths)
|
|
30
|
+
coverage.set(acId, (paths = new Map()));
|
|
31
|
+
if (!paths.has(path))
|
|
32
|
+
paths.set(path, source);
|
|
33
|
+
};
|
|
34
|
+
// Resolve scanned references.
|
|
35
|
+
for (const ref of refs) {
|
|
36
|
+
if (ref.instance !== null) {
|
|
37
|
+
// Qualified (AC-25): counts only for the named instance.
|
|
38
|
+
const target = registry.get(ref.instance);
|
|
39
|
+
if (!target || !target.defs.some((d) => d.id === ref.acId)) {
|
|
40
|
+
warnings.push(`${ref.path}:${ref.line}: ${ref.instance}/AC-${ref.acId} references unknown instance/id`);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (ref.instance !== instance)
|
|
44
|
+
continue; // another instance's coverage
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// Bare (AC-24): counts only when exactly one instance defines the id.
|
|
48
|
+
const definers = definersOf(registry, ref.acId);
|
|
49
|
+
if (definers.length === 0)
|
|
50
|
+
continue; // unknown id — not ours to warn about
|
|
51
|
+
if (definers.length > 1) {
|
|
52
|
+
warnings.push(`${ref.path}:${ref.line}: bare AC-${ref.acId} is ambiguous (defined by ${definers.join(', ')}); qualify as <instance>/AC-${ref.acId}`);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (definers[0] !== instance)
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const def = byId.get(ref.acId);
|
|
59
|
+
if (def?.status === 'retired') {
|
|
60
|
+
warnings.push(`${ref.path}:${ref.line}: AC-${ref.acId} is retired (stale reference)`);
|
|
61
|
+
}
|
|
62
|
+
addRef(ref.acId, ref.path, 'scan');
|
|
63
|
+
}
|
|
64
|
+
// Union in block entries (AC-9); unknown/retired ids warn, never fail (AC-10).
|
|
65
|
+
for (const entry of blockEntries) {
|
|
66
|
+
const def = byId.get(entry.acId);
|
|
67
|
+
if (!def) {
|
|
68
|
+
warnings.push(`${testingPath}:${entry.line}: ac-coverage entry AC-${entry.acId} references unknown id`);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (def.status === 'retired') {
|
|
72
|
+
warnings.push(`${testingPath}:${entry.line}: ac-coverage entry AC-${entry.acId} is retired (stale reference)`);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
addRef(entry.acId, testingPath, 'block');
|
|
76
|
+
}
|
|
77
|
+
// Assemble entries sorted by id; refs sorted by path (NFR4).
|
|
78
|
+
const entries = [...parsed.defs]
|
|
79
|
+
.sort((a, b) => a.id - b.id)
|
|
80
|
+
.map((def) => {
|
|
81
|
+
const paths = coverage.get(def.id);
|
|
82
|
+
const refList = paths
|
|
83
|
+
? [...paths.entries()]
|
|
84
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
85
|
+
.map(([path, source]) => ({ path, source }))
|
|
86
|
+
: [];
|
|
87
|
+
const status = def.status === 'retired' ? 'retired' : refList.length > 0 ? 'covered' : 'uncovered';
|
|
88
|
+
return { id: def.id, status, refs: refList };
|
|
89
|
+
});
|
|
90
|
+
const uncoveredActive = entries.filter((e) => e.status === 'uncovered').map((e) => e.id);
|
|
91
|
+
return { entries, warnings, uncoveredActive };
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=matrix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matrix.js","sourceRoot":"","sources":["../../src/traceability/matrix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AC definition parser: closed grammar over requirements.md (FR1).
|
|
3
|
+
*
|
|
4
|
+
* Accepted forms (dash bullets only; emphasis coupled — unbalanced bold is a
|
|
5
|
+
* near-miss, AC-22/design F13):
|
|
6
|
+
* - AC-n: text
|
|
7
|
+
* - **AC-n**: text
|
|
8
|
+
* - **AC-n:** text
|
|
9
|
+
* - AC-n (retired YYYY-MM-DD[, superseded by AC-m]): text
|
|
10
|
+
* - **AC-n** (retired ...): text
|
|
11
|
+
* - **AC-n (retired ...):** text
|
|
12
|
+
* - **AC-n (retired ...)**: text
|
|
13
|
+
*
|
|
14
|
+
* Anything AC-shaped that fails the strict grammar warns rather than silently
|
|
15
|
+
* dropping out of required coverage (AC-22).
|
|
16
|
+
*
|
|
17
|
+
* Requirements: traceability-ids/AC-1, AC-2, AC-4, AC-22, AC-23
|
|
18
|
+
*/
|
|
19
|
+
import type { ParsedRequirements } from './types.js';
|
|
20
|
+
/**
|
|
21
|
+
* Parse one requirements.md for AC definitions.
|
|
22
|
+
*
|
|
23
|
+
* @param content - File content (UTF-8).
|
|
24
|
+
* @param instance - Owning instance name, recorded on each definition.
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseRequirements(content: string, instance: string): ParsedRequirements;
|
|
27
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/traceability/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAgB,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA0BnE;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAiEvF"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AC definition parser: closed grammar over requirements.md (FR1).
|
|
3
|
+
*
|
|
4
|
+
* Accepted forms (dash bullets only; emphasis coupled — unbalanced bold is a
|
|
5
|
+
* near-miss, AC-22/design F13):
|
|
6
|
+
* - AC-n: text
|
|
7
|
+
* - **AC-n**: text
|
|
8
|
+
* - **AC-n:** text
|
|
9
|
+
* - AC-n (retired YYYY-MM-DD[, superseded by AC-m]): text
|
|
10
|
+
* - **AC-n** (retired ...): text
|
|
11
|
+
* - **AC-n (retired ...):** text
|
|
12
|
+
* - **AC-n (retired ...)**: text
|
|
13
|
+
*
|
|
14
|
+
* Anything AC-shaped that fails the strict grammar warns rather than silently
|
|
15
|
+
* dropping out of required coverage (AC-22).
|
|
16
|
+
*
|
|
17
|
+
* Requirements: traceability-ids/AC-1, AC-2, AC-4, AC-22, AC-23
|
|
18
|
+
*/
|
|
19
|
+
// Active: the three bold/colon variants, coupled emphasis, non-empty text.
|
|
20
|
+
const ACTIVE_RE = /^\s*-\s+(?:AC-([1-9][0-9]*):|\*\*AC-([1-9][0-9]*)\*\*:|\*\*AC-([1-9][0-9]*):\*\*)\s+\S/;
|
|
21
|
+
// Retired: `R` = retired marker with optional supersession.
|
|
22
|
+
const R = String.raw `\(retired\s+(\d{4}-\d{2}-\d{2})(?:,\s*superseded by AC-([1-9][0-9]*))?\)`;
|
|
23
|
+
const RETIRED_RE = new RegExp(String.raw `^\s*-\s+(?:` +
|
|
24
|
+
String.raw `AC-([1-9][0-9]*)\s+${R}:|` +
|
|
25
|
+
String.raw `\*\*AC-([1-9][0-9]*)\*\*\s+${R}:|` +
|
|
26
|
+
String.raw `\*\*AC-([1-9][0-9]*)\s+${R}:\*\*|` +
|
|
27
|
+
String.raw `\*\*AC-([1-9][0-9]*)\s+${R}\*\*:` +
|
|
28
|
+
String.raw `)`);
|
|
29
|
+
// Loose pattern for the near-miss lint (AC-22): any bullet style, so `*`/`+`
|
|
30
|
+
// bullets and numbered items warn instead of vanishing (design F13).
|
|
31
|
+
const AC_SHAPED_RE = /^\s*(?:[-*+]|\d+\.)\s+\**AC-\d+/;
|
|
32
|
+
function excerpt(line) {
|
|
33
|
+
const trimmed = line.trim();
|
|
34
|
+
return trimmed.length > 60 ? `${trimmed.slice(0, 57)}...` : trimmed;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parse one requirements.md for AC definitions.
|
|
38
|
+
*
|
|
39
|
+
* @param content - File content (UTF-8).
|
|
40
|
+
* @param instance - Owning instance name, recorded on each definition.
|
|
41
|
+
*/
|
|
42
|
+
export function parseRequirements(content, instance) {
|
|
43
|
+
const defs = [];
|
|
44
|
+
const warnings = [];
|
|
45
|
+
const byId = new Map();
|
|
46
|
+
let acShapedLines = 0;
|
|
47
|
+
const lines = content.split('\n');
|
|
48
|
+
for (let i = 0; i < lines.length; i++) {
|
|
49
|
+
const line = lines[i];
|
|
50
|
+
const lineNo = i + 1;
|
|
51
|
+
if (!AC_SHAPED_RE.test(line))
|
|
52
|
+
continue;
|
|
53
|
+
acShapedLines++;
|
|
54
|
+
let def = null;
|
|
55
|
+
const active = ACTIVE_RE.exec(line);
|
|
56
|
+
if (active) {
|
|
57
|
+
const id = Number(active[1] ?? active[2] ?? active[3]);
|
|
58
|
+
def = { id, instance, line: lineNo, status: 'active' };
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const retired = RETIRED_RE.exec(line);
|
|
62
|
+
if (retired) {
|
|
63
|
+
// Four alternatives × (id, date, supersededBy) capture triplets.
|
|
64
|
+
for (let g = 1; g <= 10; g += 3) {
|
|
65
|
+
if (retired[g] !== undefined) {
|
|
66
|
+
def = {
|
|
67
|
+
id: Number(retired[g]),
|
|
68
|
+
instance,
|
|
69
|
+
line: lineNo,
|
|
70
|
+
status: 'retired',
|
|
71
|
+
retiredDate: retired[g + 1],
|
|
72
|
+
...(retired[g + 2] !== undefined && { supersededBy: Number(retired[g + 2]) }),
|
|
73
|
+
};
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (!def) {
|
|
80
|
+
warnings.push(`line ${lineNo}: "${excerpt(line)}" resembles an AC definition but does not match the grammar`);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const existing = byId.get(def.id);
|
|
84
|
+
if (existing) {
|
|
85
|
+
warnings.push(`duplicate AC-${def.id}: lines ${existing.line} and ${lineNo} (first occurrence wins)`);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
byId.set(def.id, def);
|
|
89
|
+
defs.push(def);
|
|
90
|
+
}
|
|
91
|
+
// Sequence gaps (AC-23), computed over active ∪ retired ids.
|
|
92
|
+
if (byId.size > 0) {
|
|
93
|
+
const maxId = Math.max(...byId.keys());
|
|
94
|
+
for (let n = 1; n <= maxId; n++) {
|
|
95
|
+
if (!byId.has(n))
|
|
96
|
+
warnings.push(`AC-${n} is never defined (sequence gap)`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { defs, warnings, acShapedLines };
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/traceability/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-file discovery and AC-reference scanning (FR2).
|
|
3
|
+
*
|
|
4
|
+
* Own walker + glob translator instead of `fs.globSync`: stdlib glob
|
|
5
|
+
* semantics are release-dependent while the Node floor is 22.13; the pinned
|
|
6
|
+
* semantics here are enforced by this module's tests (NFR1, design DD2).
|
|
7
|
+
*
|
|
8
|
+
* Pinned semantics (design Data Flow 4):
|
|
9
|
+
* - `**` matches zero or more path segments
|
|
10
|
+
* - `*` / `?` match within a segment, never a leading dot
|
|
11
|
+
* - dot-files and dot-directories are never traversed
|
|
12
|
+
* - exclusions (node_modules, .git, dist, build, .aidlc) prune before
|
|
13
|
+
* descent at any depth, regardless of glob source (AC-6/AC-7, DD4)
|
|
14
|
+
* - symlinks are never followed (AC-8, NFR3)
|
|
15
|
+
* - emitted paths are posix-separated and project-root-relative (design F7)
|
|
16
|
+
*
|
|
17
|
+
* Requirements: traceability-ids/AC-5..AC-8, AC-24, AC-25
|
|
18
|
+
*/
|
|
19
|
+
import type { AcReference } from './types.js';
|
|
20
|
+
/** D1 default test globs. */
|
|
21
|
+
export declare const DEFAULT_TEST_GLOBS: string[];
|
|
22
|
+
/** Scan caps (NFR2, AC-8). */
|
|
23
|
+
export declare const MAX_SCANNED_FILES = 10000;
|
|
24
|
+
/**
|
|
25
|
+
* Translate one glob into a RegExp over posix relative paths, or null when
|
|
26
|
+
* the pattern uses unsupported syntax (braces, extglobs, character classes).
|
|
27
|
+
*/
|
|
28
|
+
export declare function translateGlob(pattern: string): RegExp | null;
|
|
29
|
+
/**
|
|
30
|
+
* Validate configured globs (AC-7): absolute or `..`-containing patterns and
|
|
31
|
+
* unsupported syntax are rejected with a warning naming the glob.
|
|
32
|
+
*/
|
|
33
|
+
export declare function validateGlobs(patterns: string[]): {
|
|
34
|
+
matchers: RegExp[];
|
|
35
|
+
warnings: string[];
|
|
36
|
+
};
|
|
37
|
+
export interface DiscoveryResult {
|
|
38
|
+
/** Posix-separated project-root-relative paths, sorted. */
|
|
39
|
+
files: string[];
|
|
40
|
+
warnings: string[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Discover test files by glob against the project root.
|
|
44
|
+
*
|
|
45
|
+
* @param projectRoot - Directory containing `.aidlc/`.
|
|
46
|
+
* @param globs - Effective glob list (defaults or config).
|
|
47
|
+
*/
|
|
48
|
+
export declare function discoverTestFiles(projectRoot: string, globs: string[]): DiscoveryResult;
|
|
49
|
+
export interface ScanResult {
|
|
50
|
+
refs: AcReference[];
|
|
51
|
+
warnings: string[];
|
|
52
|
+
}
|
|
53
|
+
/** Scan one file's content for AC reference tokens (qualified, then bare). */
|
|
54
|
+
export declare function scanContent(content: string, path: string): AcReference[];
|
|
55
|
+
/**
|
|
56
|
+
* Scan discovered files, skipping unreadable/oversize/binary files with a
|
|
57
|
+
* warning (AC-8). Never throws.
|
|
58
|
+
*/
|
|
59
|
+
export declare function scanFiles(projectRoot: string, files: string[]): ScanResult;
|
|
60
|
+
/** Convert a native relative path to the canonical posix form (design F7). */
|
|
61
|
+
export declare function toPosix(relPath: string): string;
|
|
62
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/traceability/scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,6BAA6B;AAC7B,eAAO,MAAM,kBAAkB,UAA8D,CAAC;AAK9F,8BAA8B;AAC9B,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAgBxC;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAyB5D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAoB5F;AAMD,MAAM,WAAW,eAAe;IAC9B,2DAA2D;IAC3D,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAsBD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,eAAe,CAYvF;AAMD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAexE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CA8B1E;AAED,8EAA8E;AAC9E,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/C"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-file discovery and AC-reference scanning (FR2).
|
|
3
|
+
*
|
|
4
|
+
* Own walker + glob translator instead of `fs.globSync`: stdlib glob
|
|
5
|
+
* semantics are release-dependent while the Node floor is 22.13; the pinned
|
|
6
|
+
* semantics here are enforced by this module's tests (NFR1, design DD2).
|
|
7
|
+
*
|
|
8
|
+
* Pinned semantics (design Data Flow 4):
|
|
9
|
+
* - `**` matches zero or more path segments
|
|
10
|
+
* - `*` / `?` match within a segment, never a leading dot
|
|
11
|
+
* - dot-files and dot-directories are never traversed
|
|
12
|
+
* - exclusions (node_modules, .git, dist, build, .aidlc) prune before
|
|
13
|
+
* descent at any depth, regardless of glob source (AC-6/AC-7, DD4)
|
|
14
|
+
* - symlinks are never followed (AC-8, NFR3)
|
|
15
|
+
* - emitted paths are posix-separated and project-root-relative (design F7)
|
|
16
|
+
*
|
|
17
|
+
* Requirements: traceability-ids/AC-5..AC-8, AC-24, AC-25
|
|
18
|
+
*/
|
|
19
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
|
20
|
+
import { isAbsolute, join, sep } from 'node:path';
|
|
21
|
+
/** D1 default test globs. */
|
|
22
|
+
export const DEFAULT_TEST_GLOBS = ['**/*.test.*', '**/*.spec.*', '**/test/**', '**/tests/**'];
|
|
23
|
+
/** Unconditional exclusions — directory-name filters applied before descent. */
|
|
24
|
+
const EXCLUDED_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.aidlc']);
|
|
25
|
+
/** Scan caps (NFR2, AC-8). */
|
|
26
|
+
export const MAX_SCANNED_FILES = 10_000;
|
|
27
|
+
const MAX_FILE_BYTES = 1024 * 1024;
|
|
28
|
+
const BINARY_SNIFF_BYTES = 8 * 1024;
|
|
29
|
+
// Reference tokens (AC-5, AC-24, AC-25): case-sensitive, literal digits,
|
|
30
|
+
// symmetric boundaries — `AC-1-bis` is not a reference to AC-1 (design F8);
|
|
31
|
+
// `https://example.com/AC-6` is not a qualified reference (design F9).
|
|
32
|
+
const QUALIFIED_RE = /(?<![\w./:-])([a-z0-9-]+)\/AC-([1-9][0-9]*)(?![\w-])/g;
|
|
33
|
+
const BARE_RE = /(?<![\w/-])AC-([1-9][0-9]*)(?![\w-])/g;
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Glob translation
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
const GLOB_UNSUPPORTED = /[{}()!+@]|\[/;
|
|
38
|
+
/**
|
|
39
|
+
* Translate one glob into a RegExp over posix relative paths, or null when
|
|
40
|
+
* the pattern uses unsupported syntax (braces, extglobs, character classes).
|
|
41
|
+
*/
|
|
42
|
+
export function translateGlob(pattern) {
|
|
43
|
+
if (GLOB_UNSUPPORTED.test(pattern))
|
|
44
|
+
return null;
|
|
45
|
+
const segments = pattern.split('/').filter((s) => s.length > 0);
|
|
46
|
+
const parts = [];
|
|
47
|
+
for (const seg of segments) {
|
|
48
|
+
if (seg === '**') {
|
|
49
|
+
// Zero or more whole segments (each not starting with a dot).
|
|
50
|
+
parts.push('(?:[^./][^/]*/)*');
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
let re = '';
|
|
54
|
+
for (const ch of seg) {
|
|
55
|
+
if (ch === '*')
|
|
56
|
+
re += '[^/]*';
|
|
57
|
+
else if (ch === '?')
|
|
58
|
+
re += '[^/]';
|
|
59
|
+
else
|
|
60
|
+
re += ch.replace(/[.\\^$|#+()[\]{}]/g, '\\$&');
|
|
61
|
+
}
|
|
62
|
+
// `*`/`?` never match a leading dot.
|
|
63
|
+
if (seg.startsWith('*') || seg.startsWith('?'))
|
|
64
|
+
re = `(?!\\.)${re}`;
|
|
65
|
+
parts.push(`${re}/`);
|
|
66
|
+
}
|
|
67
|
+
let source = parts.join('');
|
|
68
|
+
if (source.endsWith('/'))
|
|
69
|
+
source = source.slice(0, -1);
|
|
70
|
+
// A trailing `**` also matches files in any subdirectory.
|
|
71
|
+
if (segments[segments.length - 1] === '**')
|
|
72
|
+
source += '[^/]*(?:/[^/]+)*';
|
|
73
|
+
return new RegExp(`^${source}$`);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Validate configured globs (AC-7): absolute or `..`-containing patterns and
|
|
77
|
+
* unsupported syntax are rejected with a warning naming the glob.
|
|
78
|
+
*/
|
|
79
|
+
export function validateGlobs(patterns) {
|
|
80
|
+
const matchers = [];
|
|
81
|
+
const warnings = [];
|
|
82
|
+
for (const pattern of patterns) {
|
|
83
|
+
if (isAbsolute(pattern)) {
|
|
84
|
+
warnings.push(`glob "${pattern}" rejected: absolute`);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (pattern.split('/').includes('..')) {
|
|
88
|
+
warnings.push(`glob "${pattern}" rejected: escapes project root`);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const matcher = translateGlob(pattern);
|
|
92
|
+
if (!matcher) {
|
|
93
|
+
warnings.push(`glob "${pattern}" rejected: unsupported syntax`);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
matchers.push(matcher);
|
|
97
|
+
}
|
|
98
|
+
return { matchers, warnings };
|
|
99
|
+
}
|
|
100
|
+
/** Recursively collect candidate files under root (pinned semantics above). */
|
|
101
|
+
function walk(root, relDir, out) {
|
|
102
|
+
let entries;
|
|
103
|
+
try {
|
|
104
|
+
entries = readdirSync(relDir === '' ? root : join(root, ...relDir.split('/')), {
|
|
105
|
+
withFileTypes: true,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
112
|
+
for (const entry of entries) {
|
|
113
|
+
if (entry.name.startsWith('.') || EXCLUDED_DIRS.has(entry.name))
|
|
114
|
+
continue;
|
|
115
|
+
const rel = relDir === '' ? entry.name : `${relDir}/${entry.name}`;
|
|
116
|
+
// Dirent type checks never follow symlinks (lstat semantics).
|
|
117
|
+
if (entry.isDirectory())
|
|
118
|
+
walk(root, rel, out);
|
|
119
|
+
else if (entry.isFile())
|
|
120
|
+
out.push(rel);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Discover test files by glob against the project root.
|
|
125
|
+
*
|
|
126
|
+
* @param projectRoot - Directory containing `.aidlc/`.
|
|
127
|
+
* @param globs - Effective glob list (defaults or config).
|
|
128
|
+
*/
|
|
129
|
+
export function discoverTestFiles(projectRoot, globs) {
|
|
130
|
+
const { matchers, warnings } = validateGlobs(globs);
|
|
131
|
+
const all = [];
|
|
132
|
+
walk(projectRoot, '', all);
|
|
133
|
+
const files = all.filter((f) => matchers.some((m) => m.test(f)));
|
|
134
|
+
if (files.length > MAX_SCANNED_FILES) {
|
|
135
|
+
warnings.push(`scanning truncated at ${MAX_SCANNED_FILES} files; coverage may be under-reported`);
|
|
136
|
+
files.length = MAX_SCANNED_FILES;
|
|
137
|
+
}
|
|
138
|
+
return { files, warnings };
|
|
139
|
+
}
|
|
140
|
+
/** Scan one file's content for AC reference tokens (qualified, then bare). */
|
|
141
|
+
export function scanContent(content, path) {
|
|
142
|
+
const refs = [];
|
|
143
|
+
const lines = content.split('\n');
|
|
144
|
+
for (let i = 0; i < lines.length; i++) {
|
|
145
|
+
const line = lines[i];
|
|
146
|
+
for (const m of line.matchAll(QUALIFIED_RE)) {
|
|
147
|
+
refs.push({ acId: Number(m[2]), instance: m[1], path, line: i + 1, source: 'scan' });
|
|
148
|
+
}
|
|
149
|
+
// Bare tokens inside qualified ones are blocked by `/` in the lookbehind
|
|
150
|
+
// — that guard, not token consumption, prevents double-counting (F8).
|
|
151
|
+
for (const m of line.matchAll(BARE_RE)) {
|
|
152
|
+
refs.push({ acId: Number(m[1]), instance: null, path, line: i + 1, source: 'scan' });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return refs;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Scan discovered files, skipping unreadable/oversize/binary files with a
|
|
159
|
+
* warning (AC-8). Never throws.
|
|
160
|
+
*/
|
|
161
|
+
export function scanFiles(projectRoot, files) {
|
|
162
|
+
const refs = [];
|
|
163
|
+
const warnings = [];
|
|
164
|
+
for (const rel of files) {
|
|
165
|
+
const abs = join(projectRoot, ...rel.split('/'));
|
|
166
|
+
let size;
|
|
167
|
+
try {
|
|
168
|
+
size = statSync(abs).size;
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
warnings.push(`skipped ${rel}: unreadable`);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (size > MAX_FILE_BYTES) {
|
|
175
|
+
warnings.push(`skipped ${rel}: too large`);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
let buf;
|
|
179
|
+
try {
|
|
180
|
+
buf = readFileSync(abs);
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
warnings.push(`skipped ${rel}: unreadable`);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (buf.subarray(0, BINARY_SNIFF_BYTES).includes(0)) {
|
|
187
|
+
warnings.push(`skipped ${rel}: binary`);
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
refs.push(...scanContent(buf.toString('utf8'), rel));
|
|
191
|
+
}
|
|
192
|
+
return { refs, warnings };
|
|
193
|
+
}
|
|
194
|
+
/** Convert a native relative path to the canonical posix form (design F7). */
|
|
195
|
+
export function toPosix(relPath) {
|
|
196
|
+
return sep === '/' ? relPath : relPath.split(sep).join('/');
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/traceability/scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAGlD,6BAA6B;AAC7B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;AAE9F,gFAAgF;AAChF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEnF,8BAA8B;AAC9B,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACxC,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAAC;AACnC,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,CAAC;AAEpC,yEAAyE;AACzE,4EAA4E;AAC5E,uEAAuE;AACvE,MAAM,YAAY,GAAG,uDAAuD,CAAC;AAC7E,MAAM,OAAO,GAAG,uCAAuC,CAAC;AAExD,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAExC;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,IAAI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,8DAA8D;YAC9D,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAC/B,SAAS;QACX,CAAC;QACD,IAAI,EAAE,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,IAAI,EAAE,KAAK,GAAG;gBAAE,EAAE,IAAI,OAAO,CAAC;iBACzB,IAAI,EAAE,KAAK,GAAG;gBAAE,EAAE,IAAI,MAAM,CAAC;;gBAC7B,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QACtD,CAAC;QACD,qCAAqC;QACrC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,EAAE,GAAG,UAAU,EAAE,EAAE,CAAC;QACpE,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5B,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvD,0DAA0D;IAC1D,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI;QAAE,MAAM,IAAI,kBAAkB,CAAC;IACzE,OAAO,IAAI,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,QAAkB;IAC9C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,SAAS,OAAO,sBAAsB,CAAC,CAAC;YACtD,SAAS;QACX,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,QAAQ,CAAC,IAAI,CAAC,SAAS,OAAO,kCAAkC,CAAC,CAAC;YAClE,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,SAAS,OAAO,gCAAgC,CAAC,CAAC;YAChE,SAAS;QACX,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAChC,CAAC;AAYD,+EAA+E;AAC/E,SAAS,IAAI,CAAC,IAAY,EAAE,MAAc,EAAE,GAAa;IACvD,IAAI,OAAO,CAAC;IACZ,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE;YAC7E,aAAa,EAAE,IAAI;SACpB,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QAC1E,MAAM,GAAG,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QACnE,8DAA8D;QAC9D,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;aACzC,IAAI,KAAK,CAAC,MAAM,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB,EAAE,KAAe;IACpE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,IAAI,KAAK,CAAC,MAAM,GAAG,iBAAiB,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,CACX,yBAAyB,iBAAiB,wCAAwC,CACnF,CAAC;QACF,KAAK,CAAC,MAAM,GAAG,iBAAiB,CAAC;IACnC,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC;AAWD,8EAA8E;AAC9E,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,IAAY;IACvD,MAAM,IAAI,GAAkB,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,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,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,yEAAyE;QACzE,sEAAsE;QACtE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,WAAmB,EAAE,KAAe;IAC5D,MAAM,IAAI,GAAkB,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC,CAAC;YAC5C,SAAS;QACX,CAAC;QACD,IAAI,IAAI,GAAG,cAAc,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,aAAa,CAAC,CAAC;YAC3C,SAAS;QACX,CAAC;QACD,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC,CAAC;YAC5C,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,CAAC;YACxC,SAAS;QACX,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Traceability types: AC definitions, references, and the coverage matrix
|
|
3
|
+
* exposed via `aidlc gate --json` (traceability-ids AC-15).
|
|
4
|
+
*
|
|
5
|
+
* Design: design.md (traceability-ids) §Interfaces
|
|
6
|
+
*/
|
|
7
|
+
/** A single acceptance-criterion definition parsed from requirements.md. */
|
|
8
|
+
export interface AcDefinition {
|
|
9
|
+
/** n in AC-n (≥1, no leading zeros). */
|
|
10
|
+
id: number;
|
|
11
|
+
/** Owning instance name. */
|
|
12
|
+
instance: string;
|
|
13
|
+
/** 1-based line number in requirements.md. */
|
|
14
|
+
line: number;
|
|
15
|
+
status: 'active' | 'retired';
|
|
16
|
+
/** YYYY-MM-DD, present when retired. */
|
|
17
|
+
retiredDate?: string;
|
|
18
|
+
/** AC number this criterion was superseded by, when stated. */
|
|
19
|
+
supersededBy?: number;
|
|
20
|
+
}
|
|
21
|
+
/** Parse result for one instance's requirements.md. */
|
|
22
|
+
export interface ParsedRequirements {
|
|
23
|
+
/** First occurrence wins on duplicates (AC-4). */
|
|
24
|
+
defs: AcDefinition[];
|
|
25
|
+
/** Duplicates, near-misses, sequence gaps (AC-4, AC-22, AC-23). */
|
|
26
|
+
warnings: string[];
|
|
27
|
+
/**
|
|
28
|
+
* Lines matching the loose AC pattern (defs + near-misses). Drives the
|
|
29
|
+
* applicability tri-state (DD7): 0 → criterion silent; >0 with no defs →
|
|
30
|
+
* warnings-only result.
|
|
31
|
+
*/
|
|
32
|
+
acShapedLines: number;
|
|
33
|
+
}
|
|
34
|
+
/** One AC reference found in a test file or coverage block. */
|
|
35
|
+
export interface AcReference {
|
|
36
|
+
acId: number;
|
|
37
|
+
/** Qualified instance name, or null for a bare token. */
|
|
38
|
+
instance: string | null;
|
|
39
|
+
/** Posix-separated, project-root-relative path. */
|
|
40
|
+
path: string;
|
|
41
|
+
/** 1-based line number. */
|
|
42
|
+
line: number;
|
|
43
|
+
source: 'scan' | 'block';
|
|
44
|
+
}
|
|
45
|
+
/** Per-AC row of the coverage matrix (AC-15). */
|
|
46
|
+
export interface AcCoverageEntry {
|
|
47
|
+
id: number;
|
|
48
|
+
status: 'covered' | 'uncovered' | 'retired';
|
|
49
|
+
/** Sorted by path (NFR4). */
|
|
50
|
+
refs: {
|
|
51
|
+
path: string;
|
|
52
|
+
source: 'scan' | 'block';
|
|
53
|
+
}[];
|
|
54
|
+
}
|
|
55
|
+
/** Full traceability result attached to GateCheckResult (AC-15). */
|
|
56
|
+
export interface TraceabilityResult {
|
|
57
|
+
/** Posix-separated, project-root-relative requirements.md path. */
|
|
58
|
+
requirementsPath: string;
|
|
59
|
+
/** Sorted by id (NFR4). */
|
|
60
|
+
entries: AcCoverageEntry[];
|
|
61
|
+
/** Ordered by phase, then path, then line (NFR4). */
|
|
62
|
+
warnings: string[];
|
|
63
|
+
/** Active AC ids with zero references — drives gate failure (AC-11). */
|
|
64
|
+
uncoveredActive: number[];
|
|
65
|
+
}
|
|
66
|
+
/** Coverage summary for the `aidlc status` column (AC-17). */
|
|
67
|
+
export interface CoverageSummary {
|
|
68
|
+
covered: number;
|
|
69
|
+
total: number;
|
|
70
|
+
stale: number;
|
|
71
|
+
}
|
|
72
|
+
/** Tolerantly-read `traceability:` section of .aidlc/config.yaml. */
|
|
73
|
+
export interface TraceabilityConfig {
|
|
74
|
+
/** Replaces the default test globs when present (AC-7). */
|
|
75
|
+
test_globs?: string[];
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/traceability/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC7B,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,uDAAuD;AACvD,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;IAC5C,6BAA6B;IAC7B,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,EAAE,CAAC;CACpD;AAED,oEAAoE;AACpE,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,gBAAgB,EAAE,MAAM,CAAC;IACzB,2BAA2B;IAC3B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,qDAAqD;IACrD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,wEAAwE;IACxE,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,8DAA8D;AAC9D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/traceability/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|