musubix3 0.1.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/.github/plugin/marketplace.json +16 -0
- package/.github/skills/sdd-change/SKILL.md +78 -0
- package/.github/skills/sdd-design/SKILL.md +26 -0
- package/.github/skills/sdd-formal-codegraph/SKILL.md +53 -0
- package/.github/skills/sdd-implementation/SKILL.md +54 -0
- package/.github/skills/sdd-knowledge/SKILL.md +24 -0
- package/.github/skills/sdd-quality/SKILL.md +69 -0
- package/.github/skills/sdd-requirements/SKILL.md +42 -0
- package/.github/skills/sdd-traceability/SKILL.md +28 -0
- package/CHANGELOG.md +152 -0
- package/LICENSE +21 -0
- package/README-ja.md +573 -0
- package/README.md +639 -0
- package/assets/ADR-0001.md +15 -0
- package/assets/constitution.md +17 -0
- package/assets/design.md +13 -0
- package/assets/requirements.md +15 -0
- package/dist/packages/analysis/src/adapters.d.ts +12 -0
- package/dist/packages/analysis/src/adapters.js +167 -0
- package/dist/packages/analysis/src/adapters.js.map +1 -0
- package/dist/packages/analysis/src/attestation.d.ts +50 -0
- package/dist/packages/analysis/src/attestation.js +474 -0
- package/dist/packages/analysis/src/attestation.js.map +1 -0
- package/dist/packages/analysis/src/change.d.ts +53 -0
- package/dist/packages/analysis/src/change.js +337 -0
- package/dist/packages/analysis/src/change.js.map +1 -0
- package/dist/packages/analysis/src/config.d.ts +104 -0
- package/dist/packages/analysis/src/config.js +456 -0
- package/dist/packages/analysis/src/config.js.map +1 -0
- package/dist/packages/analysis/src/files.d.ts +13 -0
- package/dist/packages/analysis/src/files.js +103 -0
- package/dist/packages/analysis/src/files.js.map +1 -0
- package/dist/packages/analysis/src/formal.d.ts +82 -0
- package/dist/packages/analysis/src/formal.js +579 -0
- package/dist/packages/analysis/src/formal.js.map +1 -0
- package/dist/packages/analysis/src/gate.d.ts +56 -0
- package/dist/packages/analysis/src/gate.js +484 -0
- package/dist/packages/analysis/src/gate.js.map +1 -0
- package/dist/packages/analysis/src/graph.d.ts +52 -0
- package/dist/packages/analysis/src/graph.js +737 -0
- package/dist/packages/analysis/src/graph.js.map +1 -0
- package/dist/packages/analysis/src/index.d.ts +17 -0
- package/dist/packages/analysis/src/index.js +18 -0
- package/dist/packages/analysis/src/index.js.map +1 -0
- package/dist/packages/analysis/src/knowledge.d.ts +29 -0
- package/dist/packages/analysis/src/knowledge.js +95 -0
- package/dist/packages/analysis/src/knowledge.js.map +1 -0
- package/dist/packages/analysis/src/model-correspondence.d.ts +45 -0
- package/dist/packages/analysis/src/model-correspondence.js +310 -0
- package/dist/packages/analysis/src/model-correspondence.js.map +1 -0
- package/dist/packages/analysis/src/mutation.d.ts +54 -0
- package/dist/packages/analysis/src/mutation.js +299 -0
- package/dist/packages/analysis/src/mutation.js.map +1 -0
- package/dist/packages/analysis/src/order.d.ts +23 -0
- package/dist/packages/analysis/src/order.js +89 -0
- package/dist/packages/analysis/src/order.js.map +1 -0
- package/dist/packages/analysis/src/performance.d.ts +65 -0
- package/dist/packages/analysis/src/performance.js +319 -0
- package/dist/packages/analysis/src/performance.js.map +1 -0
- package/dist/packages/analysis/src/process.d.ts +14 -0
- package/dist/packages/analysis/src/process.js +79 -0
- package/dist/packages/analysis/src/process.js.map +1 -0
- package/dist/packages/analysis/src/tdd.d.ts +65 -0
- package/dist/packages/analysis/src/tdd.js +353 -0
- package/dist/packages/analysis/src/tdd.js.map +1 -0
- package/dist/packages/analysis/src/trace.d.ts +45 -0
- package/dist/packages/analysis/src/trace.js +242 -0
- package/dist/packages/analysis/src/trace.js.map +1 -0
- package/dist/packages/analysis/src/workflow.d.ts +59 -0
- package/dist/packages/analysis/src/workflow.js +405 -0
- package/dist/packages/analysis/src/workflow.js.map +1 -0
- package/dist/packages/cli/src/install.d.ts +15 -0
- package/dist/packages/cli/src/install.js +71 -0
- package/dist/packages/cli/src/install.js.map +1 -0
- package/dist/packages/cli/src/main.d.ts +3 -0
- package/dist/packages/cli/src/main.js +364 -0
- package/dist/packages/cli/src/main.js.map +1 -0
- package/dist/packages/domain/src/constitution.d.ts +3 -0
- package/dist/packages/domain/src/constitution.js +46 -0
- package/dist/packages/domain/src/constitution.js.map +1 -0
- package/dist/packages/domain/src/design.d.ts +8 -0
- package/dist/packages/domain/src/design.js +59 -0
- package/dist/packages/domain/src/design.js.map +1 -0
- package/dist/packages/domain/src/index.d.ts +5 -0
- package/dist/packages/domain/src/index.js +6 -0
- package/dist/packages/domain/src/index.js.map +1 -0
- package/dist/packages/domain/src/markdown.d.ts +16 -0
- package/dist/packages/domain/src/markdown.js +72 -0
- package/dist/packages/domain/src/markdown.js.map +1 -0
- package/dist/packages/domain/src/requirements.d.ts +3 -0
- package/dist/packages/domain/src/requirements.js +195 -0
- package/dist/packages/domain/src/requirements.js.map +1 -0
- package/dist/packages/domain/src/types.d.ts +100 -0
- package/dist/packages/domain/src/types.js +14 -0
- package/dist/packages/domain/src/types.js.map +1 -0
- package/package.json +59 -0
- package/plugin.json +9 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { unlink } from 'node:fs/promises';
|
|
2
|
+
import ts from 'typescript';
|
|
3
|
+
import { error } from '../../domain/src/index.js';
|
|
4
|
+
import { loadConfig } from './config.js';
|
|
5
|
+
import { digest, exists, files, isSource, readText, safePath, snapshot, within, writeJson } from './files.js';
|
|
6
|
+
import { runProcess } from './process.js';
|
|
7
|
+
import { buildTrace } from './trace.js';
|
|
8
|
+
import { adapterInvocation, clearAdapterOutput, normalizeAdapterReport, readAdapterOutput } from './adapters.js';
|
|
9
|
+
import { appendEvidenceOrder, evidenceOrderRecord, inspectEvidenceOrder } from './order.js';
|
|
10
|
+
function render(value, testId, testPath, reportPath) {
|
|
11
|
+
return value.replaceAll('{testId}', testId).replaceAll('{testPath}', testPath).replaceAll('{reportPath}', reportPath);
|
|
12
|
+
}
|
|
13
|
+
export function parseMusubixTestReport(text) {
|
|
14
|
+
const value = JSON.parse(text);
|
|
15
|
+
if (value.schemaVersion !== 1 || !Array.isArray(value.tests))
|
|
16
|
+
throw new Error('Invalid structured TDD report.');
|
|
17
|
+
for (const test of value.tests) {
|
|
18
|
+
if (!test || typeof test.id !== 'string' || !['passed', 'failed', 'skipped', 'error'].includes(test.status)) {
|
|
19
|
+
throw new Error('Invalid structured TDD test result.');
|
|
20
|
+
}
|
|
21
|
+
if (test.operations !== undefined && (!test.operations || typeof test.operations !== 'object' || Array.isArray(test.operations)
|
|
22
|
+
|| Object.entries(test.operations).some(([name, count]) => !/^[\p{L}_][\p{L}\p{N}_.:-]{0,127}$/u.test(name)
|
|
23
|
+
|| typeof count !== 'number' || !Number.isSafeInteger(count) || count < 0))) {
|
|
24
|
+
throw new Error('Structured test operations must be nonnegative integer counters.');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
function chainRecordSha256(record) {
|
|
30
|
+
return digest(JSON.stringify(record));
|
|
31
|
+
}
|
|
32
|
+
function appendChainRecord(evidence, cycle, phase, phaseEvidence) {
|
|
33
|
+
if (!cycle.cycleId)
|
|
34
|
+
throw new Error('TDD cycle ID is required for append-only evidence.');
|
|
35
|
+
if (!evidence.chain) {
|
|
36
|
+
if (evidence.cycles.some((entry) => entry !== cycle)) {
|
|
37
|
+
throw new Error('Existing TDD evidence lacks an append-only hash chain; regenerate it before recording new phases.');
|
|
38
|
+
}
|
|
39
|
+
evidence.chain = [];
|
|
40
|
+
}
|
|
41
|
+
const previous = evidence.chain.at(-1);
|
|
42
|
+
const payload = {
|
|
43
|
+
sequence: evidence.chain.length + 1,
|
|
44
|
+
cycleId: cycle.cycleId,
|
|
45
|
+
requirementId: cycle.requirementId,
|
|
46
|
+
testId: cycle.testId,
|
|
47
|
+
testPath: cycle.testPath,
|
|
48
|
+
commandName: cycle.commandName,
|
|
49
|
+
phase,
|
|
50
|
+
phaseEvidenceSha256: digest(JSON.stringify(phaseEvidence)),
|
|
51
|
+
previousSha256: previous?.recordSha256 ?? null,
|
|
52
|
+
};
|
|
53
|
+
evidence.chain.push({ ...payload, recordSha256: chainRecordSha256(payload) });
|
|
54
|
+
}
|
|
55
|
+
async function sourceFingerprint(root, testPath, excludedPaths = []) {
|
|
56
|
+
const excluded = new Set(excludedPaths);
|
|
57
|
+
const paths = (await files(root)).filter((path) => path !== testPath
|
|
58
|
+
&& !excluded.has(path)
|
|
59
|
+
&& !/^\.musubix\/features\/[^/]+\/trace\.json$/.test(path)
|
|
60
|
+
&& !path.endsWith('.tgz')
|
|
61
|
+
&& !/(?:^|\/)(?:logs?|session-logs)\//.test(path)
|
|
62
|
+
&& !/\.jsonl$/.test(path));
|
|
63
|
+
return digest(JSON.stringify(await snapshot(root, paths)));
|
|
64
|
+
}
|
|
65
|
+
async function testFingerprint(root, test) {
|
|
66
|
+
const text = await readText(root, test.path);
|
|
67
|
+
const lines = text.split(/\r?\n/);
|
|
68
|
+
const start = lines.slice(0, Math.max(0, test.line - 1)).join('\n').length + (test.line > 1 ? 1 : 0);
|
|
69
|
+
if (isSource(test.path)) {
|
|
70
|
+
const source = ts.createSourceFile(test.path, text, ts.ScriptTarget.Latest, true);
|
|
71
|
+
const declaration = source.statements.find((statement) => statement.getStart(source) >= start);
|
|
72
|
+
if (declaration)
|
|
73
|
+
return digest(text.slice(start, declaration.end).trim());
|
|
74
|
+
}
|
|
75
|
+
const next = text.slice(start + 1).search(/^[ \t]*(?:\/\*+|\/\/|#).*?@id\s+TEST-/m);
|
|
76
|
+
return digest(text.slice(start, next < 0 ? text.length : start + 1 + next).trim());
|
|
77
|
+
}
|
|
78
|
+
export async function loadTddEvidence(root) {
|
|
79
|
+
const path = '.musubix/evidence/tdd.json';
|
|
80
|
+
if (!await exists(within(root, path)))
|
|
81
|
+
return null;
|
|
82
|
+
const value = JSON.parse(await readText(root, path));
|
|
83
|
+
if (value.schemaVersion !== 1 || !Array.isArray(value.cycles))
|
|
84
|
+
throw new Error('Invalid TDD evidence.');
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
export async function runTddPhase(root, phase, testId, requirementId, commandName, runner = runProcess) {
|
|
88
|
+
const config = await loadConfig(root);
|
|
89
|
+
const command = config.commands.find((entry) => entry.name === commandName);
|
|
90
|
+
if (!command)
|
|
91
|
+
throw new Error(`Configured command not found: ${commandName}`);
|
|
92
|
+
if ((!command.tddArgs?.length || !command.tddReport) && !command.adapter) {
|
|
93
|
+
throw new Error(`Configured command ${commandName} needs tddArgs and a structured tddReport.`);
|
|
94
|
+
}
|
|
95
|
+
const trace = await buildTrace(root);
|
|
96
|
+
const test = trace.nodes.find((node) => node.kind === 'test' && node.id === testId);
|
|
97
|
+
if (!test)
|
|
98
|
+
throw new Error(`Annotated test ID not found: ${testId}`);
|
|
99
|
+
if (!trace.edges.some((edge) => edge.from === testId && edge.to === requirementId && edge.relation === 'verifies')) {
|
|
100
|
+
throw new Error(`${testId} does not verify ${requirementId}.`);
|
|
101
|
+
}
|
|
102
|
+
const currentFingerprint = await testFingerprint(root, test);
|
|
103
|
+
const evidence = await loadTddEvidence(root) ?? { schemaVersion: 1, cycles: [], chain: [] };
|
|
104
|
+
if (evidence.cycles.some((cycle) => [cycle.red, cycle.green, cycle.refactor].some((item) => item && !Number.isInteger(item.order)))) {
|
|
105
|
+
throw new Error('Existing TDD evidence lacks monotonic order; regenerate it before recording new phases.');
|
|
106
|
+
}
|
|
107
|
+
const previous = evidence.cycles.filter((cycle) => cycle.testId === testId).at(-1);
|
|
108
|
+
if (phase !== 'red') {
|
|
109
|
+
if (!previous?.red.valid)
|
|
110
|
+
throw new Error(`A valid Red phase is required before ${phase}.`);
|
|
111
|
+
if (previous.red.testFingerprint !== currentFingerprint)
|
|
112
|
+
throw new Error('The test changed after Red; run the Red phase again.');
|
|
113
|
+
if (phase === 'refactor' && !previous.green?.valid)
|
|
114
|
+
throw new Error('A valid Green phase is required before Refactor.');
|
|
115
|
+
}
|
|
116
|
+
const adapter = command.adapter ? adapterInvocation(command.adapter, command.name, testId, test.path) : null;
|
|
117
|
+
const reportPath = command.tddReport
|
|
118
|
+
? render(command.tddReport.path, testId, test.path, '')
|
|
119
|
+
: adapter.reportPath;
|
|
120
|
+
const reportAbsolute = await safePath(root, reportPath);
|
|
121
|
+
if (adapter)
|
|
122
|
+
await clearAdapterOutput(adapter, reportAbsolute);
|
|
123
|
+
else if (await exists(reportAbsolute))
|
|
124
|
+
await unlink(reportAbsolute);
|
|
125
|
+
const targetedArgs = command.tddArgs
|
|
126
|
+
? command.tddArgs.map((arg) => render(arg, testId, test.path, reportPath))
|
|
127
|
+
: adapter.args;
|
|
128
|
+
const args = [
|
|
129
|
+
...command.args.map((arg) => render(arg, testId, test.path, reportPath)),
|
|
130
|
+
...targetedArgs,
|
|
131
|
+
];
|
|
132
|
+
const execution = await runner(command.command, args, { cwd: root, timeoutMs: command.timeoutMs });
|
|
133
|
+
const output = `${execution.stdout}\n${execution.stderr}`;
|
|
134
|
+
const diagnostics = [];
|
|
135
|
+
let reportText = null;
|
|
136
|
+
let testStatus;
|
|
137
|
+
if (adapter) {
|
|
138
|
+
reportText = await readAdapterOutput(adapter, reportAbsolute, execution.stdout);
|
|
139
|
+
}
|
|
140
|
+
else if (await exists(reportAbsolute)) {
|
|
141
|
+
reportText = await readText(root, reportPath);
|
|
142
|
+
}
|
|
143
|
+
if (reportText === null) {
|
|
144
|
+
diagnostics.push(error('TDD_REPORT_MISSING', `${testId} did not produce a fresh structured TDD report.`, reportPath));
|
|
145
|
+
}
|
|
146
|
+
if (reportText !== null) {
|
|
147
|
+
try {
|
|
148
|
+
const report = command.tddReport
|
|
149
|
+
? parseMusubixTestReport(reportText)
|
|
150
|
+
: normalizeAdapterReport(command.adapter, reportText, testId);
|
|
151
|
+
if (report.tests.length !== 1 || report.tests[0]?.id !== testId) {
|
|
152
|
+
diagnostics.push(error('TDD_REPORT_NOT_SCOPED', `${testId} must be the only test result in the structured report.`, reportPath));
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
testStatus = report.tests[0].status;
|
|
156
|
+
const expectedStatus = phase === 'red' ? 'failed' : 'passed';
|
|
157
|
+
if (testStatus !== expectedStatus) {
|
|
158
|
+
diagnostics.push(error('TDD_TARGET_RESULT', `${phase} requires ${testId} to report ${expectedStatus}, observed ${testStatus}.`, reportPath));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (cause) {
|
|
163
|
+
diagnostics.push(error('TDD_REPORT_INVALID', cause instanceof Error ? cause.message : String(cause), reportPath));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const expectedExit = phase === 'red' ? 'nonzero' : 'zero';
|
|
167
|
+
const exitValid = execution.status === 'completed' && (phase === 'red' ? execution.exitCode !== 0 : execution.exitCode === 0);
|
|
168
|
+
if (!exitValid)
|
|
169
|
+
diagnostics.push(error('TDD_PHASE_RESULT', `${phase} requires a completed command with ${expectedExit} exit status.`));
|
|
170
|
+
const currentSourceFingerprint = await sourceFingerprint(root, test.path, [reportPath]);
|
|
171
|
+
if (phase === 'green' && previous?.red.sourceFingerprint === currentSourceFingerprint) {
|
|
172
|
+
diagnostics.push(error('TDD_GREEN_WITHOUT_SOURCE_CHANGE', `${testId} has no non-test project change between Red and Green.`, test.path));
|
|
173
|
+
}
|
|
174
|
+
const cycleId = phase === 'red' ? crypto.randomUUID() : previous?.cycleId;
|
|
175
|
+
if (!cycleId)
|
|
176
|
+
throw new Error(`A cycle ID is required before recording ${phase}.`);
|
|
177
|
+
const result = {
|
|
178
|
+
phase,
|
|
179
|
+
valid: !diagnostics.length,
|
|
180
|
+
scoped: true,
|
|
181
|
+
resultObserved: testStatus === (phase === 'red' ? 'failed' : 'passed'),
|
|
182
|
+
...(testStatus ? { testStatus } : {}),
|
|
183
|
+
...(reportText === null ? {} : { reportSha256: digest(reportText) }),
|
|
184
|
+
commandSha256: digest(JSON.stringify([command.command, args])),
|
|
185
|
+
outputSha256: digest(output),
|
|
186
|
+
exitCode: execution.exitCode,
|
|
187
|
+
durationMs: execution.durationMs,
|
|
188
|
+
testFingerprint: currentFingerprint,
|
|
189
|
+
sourceFingerprint: currentSourceFingerprint,
|
|
190
|
+
executionId: crypto.randomUUID(),
|
|
191
|
+
recordedAt: new Date().toISOString(),
|
|
192
|
+
diagnostics,
|
|
193
|
+
};
|
|
194
|
+
result.order = (await appendEvidenceOrder(root, {
|
|
195
|
+
kind: 'tdd',
|
|
196
|
+
entityId: cycleId,
|
|
197
|
+
phase,
|
|
198
|
+
})).sequence;
|
|
199
|
+
if (phase === 'red') {
|
|
200
|
+
const cycle = { cycleId, requirementId, testId, testPath: test.path, commandName, red: result };
|
|
201
|
+
evidence.cycles.push(cycle);
|
|
202
|
+
appendChainRecord(evidence, cycle, phase, result);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
if (!previous || previous.requirementId !== requirementId || previous.commandName !== commandName) {
|
|
206
|
+
throw new Error(`${phase} must use the same requirement and command as Red.`);
|
|
207
|
+
}
|
|
208
|
+
previous[phase] = result;
|
|
209
|
+
appendChainRecord(evidence, previous, phase, result);
|
|
210
|
+
}
|
|
211
|
+
await writeJson(root, '.musubix/evidence/tdd.json', evidence);
|
|
212
|
+
return result;
|
|
213
|
+
}
|
|
214
|
+
export async function validateTddEvidence(root) {
|
|
215
|
+
const evidence = await loadTddEvidence(root);
|
|
216
|
+
if (!evidence?.cycles.length)
|
|
217
|
+
return { present: false, valid: false, diagnostics: [], cycles: 0 };
|
|
218
|
+
const diagnostics = [];
|
|
219
|
+
const order = await inspectEvidenceOrder(root);
|
|
220
|
+
diagnostics.push(...order.diagnostics);
|
|
221
|
+
if (!evidence.chain) {
|
|
222
|
+
diagnostics.push(error('TDD_CHAIN_MISSING', 'TDD evidence lacks the append-only hash chain.'));
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
const records = new Map();
|
|
226
|
+
for (const [index, record] of evidence.chain.entries()) {
|
|
227
|
+
const expectedSequence = index + 1;
|
|
228
|
+
const expectedPrevious = index === 0 ? null : evidence.chain[index - 1].recordSha256;
|
|
229
|
+
const { recordSha256, ...payload } = record;
|
|
230
|
+
if (record.sequence !== expectedSequence) {
|
|
231
|
+
diagnostics.push(error('TDD_CHAIN_SEQUENCE', `TDD chain record ${record.sequence} is out of order; expected ${expectedSequence}.`));
|
|
232
|
+
}
|
|
233
|
+
if (record.previousSha256 !== expectedPrevious) {
|
|
234
|
+
diagnostics.push(error('TDD_CHAIN_LINK', `TDD chain record ${record.sequence} does not link to the preceding record.`));
|
|
235
|
+
}
|
|
236
|
+
if (recordSha256 !== chainRecordSha256(payload)) {
|
|
237
|
+
diagnostics.push(error('TDD_CHAIN_HASH_MISMATCH', `TDD chain record ${record.sequence} has an invalid SHA-256.`));
|
|
238
|
+
}
|
|
239
|
+
const key = `${record.cycleId}:${record.phase}`;
|
|
240
|
+
if (records.has(key))
|
|
241
|
+
diagnostics.push(error('TDD_CHAIN_PHASE_DUPLICATE', `${key} appears more than once in the TDD chain.`));
|
|
242
|
+
records.set(key, record);
|
|
243
|
+
}
|
|
244
|
+
for (const cycle of evidence.cycles) {
|
|
245
|
+
for (const phase of ['red', 'green', 'refactor']) {
|
|
246
|
+
const phaseEvidence = cycle[phase];
|
|
247
|
+
if (!phaseEvidence)
|
|
248
|
+
continue;
|
|
249
|
+
const key = `${cycle.cycleId ?? 'missing'}:${phase}`;
|
|
250
|
+
const record = records.get(key);
|
|
251
|
+
if (!record) {
|
|
252
|
+
diagnostics.push(error('TDD_CHAIN_PHASE_MISSING', `${cycle.testId}:${phase} is absent from the TDD hash chain.`, cycle.testPath));
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (record.requirementId !== cycle.requirementId
|
|
256
|
+
|| record.testId !== cycle.testId
|
|
257
|
+
|| record.testPath !== cycle.testPath
|
|
258
|
+
|| record.commandName !== cycle.commandName
|
|
259
|
+
|| record.phaseEvidenceSha256 !== digest(JSON.stringify(phaseEvidence))) {
|
|
260
|
+
diagnostics.push(error('TDD_CHAIN_PAYLOAD_MISMATCH', `${cycle.testId}:${phase} does not match its immutable TDD chain record.`, cycle.testPath));
|
|
261
|
+
}
|
|
262
|
+
records.delete(key);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
for (const record of records.values()) {
|
|
266
|
+
diagnostics.push(error('TDD_CHAIN_ORPHAN', `TDD chain record ${record.sequence} has no matching cycle phase.`));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const latestCycles = new Map();
|
|
270
|
+
for (const cycle of evidence.cycles)
|
|
271
|
+
latestCycles.set(cycle.testId, cycle);
|
|
272
|
+
const trace = await buildTrace(root, false);
|
|
273
|
+
for (const requirement of trace.nodes.filter((node) => node.kind === 'requirement' && node.mandatory)) {
|
|
274
|
+
const verifiedTests = trace.edges
|
|
275
|
+
.filter((edge) => edge.relation === 'verifies' && edge.to === requirement.id)
|
|
276
|
+
.map((edge) => edge.from);
|
|
277
|
+
const covered = evidence.cycles.some((cycle) => cycle.requirementId === requirement.id
|
|
278
|
+
&& verifiedTests.includes(cycle.testId)
|
|
279
|
+
&& cycle.red.valid
|
|
280
|
+
&& cycle.green?.valid);
|
|
281
|
+
if (!covered) {
|
|
282
|
+
diagnostics.push(error('TDD_REQUIREMENT_UNCOVERED', `${requirement.id} has no valid Red-Green cycle from an authoritative verifying test.`, requirement.path, requirement.line));
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
for (const cycle of evidence.cycles) {
|
|
286
|
+
for (const phase of ['red', 'green', 'refactor']) {
|
|
287
|
+
const item = cycle[phase];
|
|
288
|
+
if (!item)
|
|
289
|
+
continue;
|
|
290
|
+
if (!cycle.cycleId || !Number.isInteger(item.order)) {
|
|
291
|
+
diagnostics.push(error('TDD_ORDER_MIGRATION_REQUIRED', `${cycle.testId}:${phase} lacks monotonic order evidence; regenerate this TDD cycle.`, cycle.testPath));
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
const record = evidenceOrderRecord(order.records, 'tdd', cycle.cycleId, phase);
|
|
295
|
+
if (!record || record.sequence !== item.order) {
|
|
296
|
+
diagnostics.push(error('TDD_ORDER_MISMATCH', `${cycle.testId}:${phase} does not match the monotonic evidence order log.`, cycle.testPath));
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
if (cycle.green?.order !== undefined && cycle.red.order !== undefined && cycle.green.order <= cycle.red.order) {
|
|
300
|
+
diagnostics.push(error('TDD_ORDER_SEQUENCE', `${cycle.testId}:green is not after Red in monotonic evidence order.`, cycle.testPath));
|
|
301
|
+
}
|
|
302
|
+
if (cycle.refactor?.order !== undefined && cycle.green?.order !== undefined && cycle.refactor.order <= cycle.green.order) {
|
|
303
|
+
diagnostics.push(error('TDD_ORDER_SEQUENCE', `${cycle.testId}:refactor is not after Green in monotonic evidence order.`, cycle.testPath));
|
|
304
|
+
}
|
|
305
|
+
if (!cycle.red.scoped || !cycle.red.resultObserved || cycle.red.testStatus !== 'failed' || !cycle.red.reportSha256 || !cycle.red.sourceFingerprint || !cycle.red.executionId) {
|
|
306
|
+
diagnostics.push(error('TDD_LEGACY_OR_UNSCOPED_EVIDENCE', `${cycle.testId} lacks test-scoped execution provenance.`, cycle.testPath));
|
|
307
|
+
}
|
|
308
|
+
if (!cycle.red.valid)
|
|
309
|
+
diagnostics.push(error('TDD_RED_MISSING', `${cycle.testId} has no valid failing Red phase.`, cycle.testPath));
|
|
310
|
+
if (!cycle.green?.valid)
|
|
311
|
+
diagnostics.push(error('TDD_GREEN_MISSING', `${cycle.testId} has no valid passing Green phase.`, cycle.testPath));
|
|
312
|
+
if (cycle.green?.valid) {
|
|
313
|
+
if (!cycle.green.scoped || !cycle.green.resultObserved || cycle.green.testStatus !== 'passed' || !cycle.green.reportSha256 || !cycle.green.sourceFingerprint || !cycle.green.executionId) {
|
|
314
|
+
diagnostics.push(error('TDD_LEGACY_OR_UNSCOPED_EVIDENCE', `${cycle.testId} Green lacks test-scoped execution provenance.`, cycle.testPath));
|
|
315
|
+
}
|
|
316
|
+
if (latestCycles.get(cycle.testId) === cycle) {
|
|
317
|
+
const test = trace.nodes.find((node) => node.kind === 'test' && node.id === cycle.testId);
|
|
318
|
+
const current = test ? await testFingerprint(root, test) : undefined;
|
|
319
|
+
const latest = cycle.refactor?.valid ? cycle.refactor : cycle.green;
|
|
320
|
+
if (current !== latest.testFingerprint)
|
|
321
|
+
diagnostics.push(error('TDD_TEST_STALE', `${cycle.testId} changed after its latest passing TDD phase.`, cycle.testPath));
|
|
322
|
+
}
|
|
323
|
+
if (cycle.red.sourceFingerprint === cycle.green.sourceFingerprint) {
|
|
324
|
+
diagnostics.push(error('TDD_GREEN_WITHOUT_SOURCE_CHANGE', `${cycle.testId} has no non-test project change between Red and Green.`, cycle.testPath));
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (cycle.green && cycle.green.commandSha256 !== cycle.red.commandSha256) {
|
|
328
|
+
diagnostics.push(error('TDD_COMMAND_CHANGED', `${cycle.testId} used a different command between Red and Green.`, cycle.testPath));
|
|
329
|
+
}
|
|
330
|
+
if (cycle.refactor && cycle.refactor.commandSha256 !== cycle.red.commandSha256) {
|
|
331
|
+
diagnostics.push(error('TDD_COMMAND_CHANGED', `${cycle.testId} used a different command during Refactor.`, cycle.testPath));
|
|
332
|
+
}
|
|
333
|
+
if (cycle.refactor?.valid && (!cycle.refactor.scoped || !cycle.refactor.resultObserved || cycle.refactor.testStatus !== 'passed' || !cycle.refactor.reportSha256 || !cycle.refactor.sourceFingerprint || !cycle.refactor.executionId)) {
|
|
334
|
+
diagnostics.push(error('TDD_LEGACY_OR_UNSCOPED_EVIDENCE', `${cycle.testId} Refactor lacks test-scoped execution provenance.`, cycle.testPath));
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
for (const phase of ['red', 'green', 'refactor']) {
|
|
338
|
+
const hashes = new Map();
|
|
339
|
+
for (const cycle of evidence.cycles) {
|
|
340
|
+
const item = cycle[phase];
|
|
341
|
+
if (!item)
|
|
342
|
+
continue;
|
|
343
|
+
const previous = hashes.get(item.outputSha256);
|
|
344
|
+
if (previous && previous.testId !== cycle.testId) {
|
|
345
|
+
diagnostics.push(error('TDD_EVIDENCE_REUSED', `${previous.testId} and ${cycle.testId} reuse identical ${phase} output evidence.`, cycle.testPath));
|
|
346
|
+
}
|
|
347
|
+
else
|
|
348
|
+
hashes.set(item.outputSha256, cycle);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return { present: true, valid: !diagnostics.length, diagnostics, cycles: evidence.cycles.length };
|
|
352
|
+
}
|
|
353
|
+
//# sourceMappingURL=tdd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tdd.js","sourceRoot":"","sources":["../../../../packages/analysis/src/tdd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type Diagnostic } from '../../domain/src/index.js';
|
|
2
|
+
export interface TraceNode {
|
|
3
|
+
id: string;
|
|
4
|
+
kind: 'requirement' | 'design' | 'code' | 'test' | 'adr';
|
|
5
|
+
path: string;
|
|
6
|
+
line: number;
|
|
7
|
+
mandatory?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface TraceEdge {
|
|
10
|
+
from: string;
|
|
11
|
+
to: string;
|
|
12
|
+
relation: 'satisfies' | 'implements' | 'verifies' | 'decides' | 'depends-on';
|
|
13
|
+
}
|
|
14
|
+
export interface TraceGraph {
|
|
15
|
+
schemaVersion: 1;
|
|
16
|
+
generatedAt: string;
|
|
17
|
+
nodes: TraceNode[];
|
|
18
|
+
edges: TraceEdge[];
|
|
19
|
+
diagnostics: Diagnostic[];
|
|
20
|
+
fingerprints: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
export declare function traceInputs(root: string): Promise<string[]>;
|
|
23
|
+
export declare function buildTrace(root: string, persist?: boolean): Promise<TraceGraph>;
|
|
24
|
+
export declare function loadTrace(root: string): Promise<TraceGraph>;
|
|
25
|
+
export interface TraceCheck {
|
|
26
|
+
valid: boolean;
|
|
27
|
+
diagnostics: Diagnostic[];
|
|
28
|
+
coverageKind: 'link-coverage';
|
|
29
|
+
mandatoryRequirements: number;
|
|
30
|
+
coverage: {
|
|
31
|
+
design: number | null;
|
|
32
|
+
implementation: number | null;
|
|
33
|
+
tests: number | null;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export declare function checkTrace(root: string, graph: TraceGraph, strict?: boolean, thresholds?: {
|
|
37
|
+
design: number;
|
|
38
|
+
implementation: number;
|
|
39
|
+
tests: number;
|
|
40
|
+
}): Promise<TraceCheck>;
|
|
41
|
+
export interface Impact {
|
|
42
|
+
id: string;
|
|
43
|
+
paths: string[][];
|
|
44
|
+
}
|
|
45
|
+
export declare function traceImpact(graph: TraceGraph, query: string): Impact[];
|