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,337 @@
|
|
|
1
|
+
import { error, ids, validateDesign, validateRequirements } from '../../domain/src/index.js';
|
|
2
|
+
import { digest, exists, files, snapshot, within, writeJson, readText } from './files.js';
|
|
3
|
+
import { loadTddEvidence } from './tdd.js';
|
|
4
|
+
import { buildTrace } from './trace.js';
|
|
5
|
+
import { indexGraph } from './graph.js';
|
|
6
|
+
import { validatePerformanceEvidence } from './performance.js';
|
|
7
|
+
import { appendEvidenceOrder, evidenceOrderRecord, inspectEvidenceOrder } from './order.js';
|
|
8
|
+
export const changePhases = ['impact', 'requirements', 'design', 'red', 'implementation', 'green', 'quality'];
|
|
9
|
+
async function fingerprint(root, paths) {
|
|
10
|
+
return digest(JSON.stringify(await snapshot(root, [...new Set(paths)].sort())));
|
|
11
|
+
}
|
|
12
|
+
async function requirementImplementationFingerprints(root, requirementIds, trace) {
|
|
13
|
+
const graph = await indexGraph(root, false);
|
|
14
|
+
const nodes = new Map(trace.nodes.map((node) => [node.id, node]));
|
|
15
|
+
const testPaths = new Set(trace.nodes.filter((node) => node.kind === 'test').map((node) => node.path));
|
|
16
|
+
const result = {};
|
|
17
|
+
for (const requirementId of requirementIds) {
|
|
18
|
+
const designs = trace.edges
|
|
19
|
+
.filter((edge) => edge.relation === 'satisfies' && edge.to === requirementId && nodes.get(edge.from)?.kind === 'design')
|
|
20
|
+
.map((edge) => edge.from);
|
|
21
|
+
const direct = new Set(trace.edges
|
|
22
|
+
.filter((edge) => edge.relation === 'implements'
|
|
23
|
+
&& (edge.to === requirementId || designs.includes(edge.to))
|
|
24
|
+
&& nodes.get(edge.from)?.kind === 'code')
|
|
25
|
+
.map((edge) => nodes.get(edge.from).path));
|
|
26
|
+
const relevant = new Set([...direct].filter((path) => graph.files.includes(path) && !testPaths.has(path)));
|
|
27
|
+
const queue = [...relevant];
|
|
28
|
+
for (let index = 0; index < queue.length; index++) {
|
|
29
|
+
const current = queue[index];
|
|
30
|
+
for (const edge of graph.imports.filter((entry) => !entry.external && entry.from === current)) {
|
|
31
|
+
if (testPaths.has(edge.to) || relevant.has(edge.to))
|
|
32
|
+
continue;
|
|
33
|
+
relevant.add(edge.to);
|
|
34
|
+
queue.push(edge.to);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const paths = [...relevant].sort();
|
|
38
|
+
result[requirementId] = { paths, fingerprints: await snapshot(root, paths) };
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
async function currentFingerprints(root, changeId, requirementIds) {
|
|
43
|
+
const paths = await files(root);
|
|
44
|
+
const trace = await buildTrace(root);
|
|
45
|
+
const codePaths = trace.nodes.filter((node) => node.kind === 'code').map((node) => node.path);
|
|
46
|
+
const testPaths = trace.nodes.filter((node) => node.kind === 'test').map((node) => node.path);
|
|
47
|
+
const tddPath = '.musubix/evidence/tdd.json';
|
|
48
|
+
return {
|
|
49
|
+
impact: await fingerprint(root, paths.filter((path) => path === `.musubix/changes/${changeId}.md`)),
|
|
50
|
+
requirements: await fingerprint(root, paths.filter((path) => /^\.musubix\/features\/[^/]+\/requirements\.md$/.test(path))),
|
|
51
|
+
design: await fingerprint(root, paths.filter((path) => /^\.musubix\/features\/[^/]+\/design\.md$/.test(path) || /^\.musubix\/decisions\/ADR-\d+\.md$/.test(path))),
|
|
52
|
+
implementation: await fingerprint(root, codePaths),
|
|
53
|
+
tests: await fingerprint(root, testPaths),
|
|
54
|
+
tdd: await fingerprint(root, await exists(within(root, tddPath)) ? [tddPath] : []),
|
|
55
|
+
requirementImplementations: await requirementImplementationFingerprints(root, requirementIds, trace),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export async function loadChangeEvidence(root) {
|
|
59
|
+
const path = '.musubix/evidence/changes.json';
|
|
60
|
+
if (!await exists(within(root, path)))
|
|
61
|
+
return null;
|
|
62
|
+
const value = JSON.parse(await readText(root, path));
|
|
63
|
+
if (value.schemaVersion !== 1 || !Array.isArray(value.changes))
|
|
64
|
+
throw new Error('Invalid change chronology evidence.');
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
export async function recordChangePhase(root, changeId, phase, requirementIds) {
|
|
68
|
+
if (!/^CHANGE-\d+$/.test(changeId))
|
|
69
|
+
throw new Error('Change ID must match CHANGE-<digits>.');
|
|
70
|
+
if (!changePhases.includes(phase))
|
|
71
|
+
throw new Error('Unknown change phase.');
|
|
72
|
+
if (!requirementIds.length || requirementIds.some((id) => !ids.requirement.test(id))) {
|
|
73
|
+
throw new Error('At least one valid REQ-* ID is required.');
|
|
74
|
+
}
|
|
75
|
+
if (phase === 'impact' && !await exists(within(root, `.musubix/changes/${changeId}.md`))) {
|
|
76
|
+
throw new Error(`Missing staged change document: .musubix/changes/${changeId}.md`);
|
|
77
|
+
}
|
|
78
|
+
const evidence = await loadChangeEvidence(root) ?? { schemaVersion: 1, changes: [] };
|
|
79
|
+
if (evidence.changes.some((entry) => changePhases.some((entryPhase) => entry.phases[entryPhase] && !Number.isInteger(entry.phases[entryPhase].order)))) {
|
|
80
|
+
throw new Error('Existing change evidence lacks monotonic order; regenerate it before recording new phases.');
|
|
81
|
+
}
|
|
82
|
+
let change = evidence.changes.find((entry) => entry.changeId === changeId);
|
|
83
|
+
if (!change) {
|
|
84
|
+
if (phase !== 'impact')
|
|
85
|
+
throw new Error('The first recorded change phase must be impact.');
|
|
86
|
+
change = { changeId, requirementIds: [...new Set(requirementIds)].sort(), phases: {} };
|
|
87
|
+
evidence.changes.push(change);
|
|
88
|
+
}
|
|
89
|
+
else if (JSON.stringify(change.requirementIds) !== JSON.stringify([...new Set(requirementIds)].sort())) {
|
|
90
|
+
throw new Error('Every phase must use the same requirement IDs.');
|
|
91
|
+
}
|
|
92
|
+
const index = changePhases.indexOf(phase);
|
|
93
|
+
if (index > 0 && !change.phases[changePhases[index - 1]]) {
|
|
94
|
+
throw new Error(`${phase} requires the preceding ${changePhases[index - 1]} phase.`);
|
|
95
|
+
}
|
|
96
|
+
if (change.phases[phase])
|
|
97
|
+
throw new Error(`${changeId}:${phase} is already recorded.`);
|
|
98
|
+
const order = await appendEvidenceOrder(root, { kind: 'change', entityId: changeId, phase });
|
|
99
|
+
change.phases[phase] = {
|
|
100
|
+
phase,
|
|
101
|
+
order: order.sequence,
|
|
102
|
+
recordedAt: new Date().toISOString(),
|
|
103
|
+
fingerprints: await currentFingerprints(root, changeId, change.requirementIds),
|
|
104
|
+
};
|
|
105
|
+
await writeJson(root, '.musubix/evidence/changes.json', evidence);
|
|
106
|
+
return evidence;
|
|
107
|
+
}
|
|
108
|
+
export async function validateChangeEvidence(root) {
|
|
109
|
+
const evidence = await loadChangeEvidence(root);
|
|
110
|
+
const documents = (await files(root))
|
|
111
|
+
.filter((path) => /^\.musubix\/changes\/CHANGE-\d+\.md$/.test(path))
|
|
112
|
+
.map((path) => path.split('/').at(-1).replace(/\.md$/, ''));
|
|
113
|
+
if (!evidence?.changes.length) {
|
|
114
|
+
return {
|
|
115
|
+
present: documents.length > 0,
|
|
116
|
+
valid: false,
|
|
117
|
+
changes: 0,
|
|
118
|
+
diagnostics: documents.map((changeId) => error('CHANGE_RECORD_MISSING', `${changeId} has a change document but no chronology record.`)),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const diagnostics = [];
|
|
122
|
+
const order = await inspectEvidenceOrder(root);
|
|
123
|
+
diagnostics.push(...order.diagnostics);
|
|
124
|
+
for (const changeId of documents) {
|
|
125
|
+
if (!evidence.changes.some((change) => change.changeId === changeId)) {
|
|
126
|
+
diagnostics.push(error('CHANGE_RECORD_MISSING', `${changeId} has a change document but no chronology record.`));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
for (const change of evidence.changes) {
|
|
130
|
+
if (!documents.includes(change.changeId)) {
|
|
131
|
+
diagnostics.push(error('CHANGE_DOCUMENT_MISSING', `${change.changeId} has chronology evidence but no change document.`));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const tdd = await loadTddEvidence(root);
|
|
135
|
+
for (const change of evidence.changes) {
|
|
136
|
+
const phases = changePhases.map((phase) => change.phases[phase]);
|
|
137
|
+
for (let index = 0; index < phases.length; index++) {
|
|
138
|
+
if (!phases[index])
|
|
139
|
+
diagnostics.push(error('CHANGE_PHASE_MISSING', `${change.changeId} is missing ${changePhases[index]}.`));
|
|
140
|
+
if (phases[index] && !Number.isInteger(phases[index].order)) {
|
|
141
|
+
diagnostics.push(error('CHANGE_ORDER_MIGRATION_REQUIRED', `${change.changeId}:${changePhases[index]} lacks monotonic order evidence; regenerate this change chronology.`));
|
|
142
|
+
}
|
|
143
|
+
else if (phases[index]) {
|
|
144
|
+
const record = evidenceOrderRecord(order.records, 'change', change.changeId, changePhases[index]);
|
|
145
|
+
if (!record || record.sequence !== phases[index].order) {
|
|
146
|
+
diagnostics.push(error('CHANGE_ORDER_MISMATCH', `${change.changeId}:${changePhases[index]} does not match the monotonic evidence order log.`));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (index > 0 && phases[index]?.order !== undefined && phases[index - 1]?.order !== undefined
|
|
150
|
+
&& phases[index].order <= phases[index - 1].order) {
|
|
151
|
+
diagnostics.push(error('CHANGE_PHASE_ORDER', `${change.changeId}:${changePhases[index]} is not after ${changePhases[index - 1]}.`));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const impact = change.phases.impact;
|
|
155
|
+
const requirements = change.phases.requirements;
|
|
156
|
+
const design = change.phases.design;
|
|
157
|
+
const red = change.phases.red;
|
|
158
|
+
const implementation = change.phases.implementation;
|
|
159
|
+
const green = change.phases.green;
|
|
160
|
+
if (impact && requirements && impact.fingerprints.requirements === requirements.fingerprints.requirements) {
|
|
161
|
+
diagnostics.push(error('CHANGE_REQUIREMENTS_UNCHANGED', `${change.changeId} did not change requirements after impact analysis.`));
|
|
162
|
+
}
|
|
163
|
+
if (requirements && design && requirements.fingerprints.design === design.fingerprints.design) {
|
|
164
|
+
diagnostics.push(error('CHANGE_DESIGN_UNCHANGED', `${change.changeId} did not change design after requirements.`));
|
|
165
|
+
}
|
|
166
|
+
if (design && red && design.fingerprints.tests === red.fingerprints.tests) {
|
|
167
|
+
diagnostics.push(error('CHANGE_TESTS_UNCHANGED', `${change.changeId} did not add or change tests before Red.`));
|
|
168
|
+
}
|
|
169
|
+
if (red && implementation && red.fingerprints.implementation === implementation.fingerprints.implementation) {
|
|
170
|
+
diagnostics.push(error('CHANGE_IMPLEMENTATION_UNCHANGED', `${change.changeId} did not change implementation after Red.`));
|
|
171
|
+
}
|
|
172
|
+
if (red && implementation) {
|
|
173
|
+
for (const requirementId of change.requirementIds) {
|
|
174
|
+
const before = red.fingerprints.requirementImplementations?.[requirementId];
|
|
175
|
+
const after = implementation.fingerprints.requirementImplementations?.[requirementId];
|
|
176
|
+
if (!before || !after || (!before.paths.length && !after.paths.length)) {
|
|
177
|
+
diagnostics.push(error('CHANGE_IMPLEMENTATION_SCOPE_MISSING', `${change.changeId} has no Code Graph implementation scope for ${requirementId}.`));
|
|
178
|
+
}
|
|
179
|
+
else if (JSON.stringify(before.fingerprints) === JSON.stringify(after.fingerprints)) {
|
|
180
|
+
diagnostics.push(error('CHANGE_RELEVANT_IMPLEMENTATION_UNCHANGED', `${change.changeId} did not change implementation related to ${requirementId} after Red.`));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (red && green && red.fingerprints.tests !== green.fingerprints.tests) {
|
|
185
|
+
diagnostics.push(error('CHANGE_TEST_CHANGED_AFTER_RED', `${change.changeId} changed tests between Red and Green.`));
|
|
186
|
+
}
|
|
187
|
+
for (const requirementId of change.requirementIds) {
|
|
188
|
+
const cycles = tdd?.cycles.filter((cycle) => cycle.requirementId === requirementId) ?? [];
|
|
189
|
+
const validCycle = cycles.find((cycle) => requirements
|
|
190
|
+
&& red
|
|
191
|
+
&& implementation
|
|
192
|
+
&& green
|
|
193
|
+
&& Number.isInteger(requirements.order)
|
|
194
|
+
&& Number.isInteger(red.order)
|
|
195
|
+
&& Number.isInteger(implementation.order)
|
|
196
|
+
&& Number.isInteger(green.order)
|
|
197
|
+
&& Number.isInteger(cycle.red.order)
|
|
198
|
+
&& Number.isInteger(cycle.green?.order)
|
|
199
|
+
&& cycle.red.valid
|
|
200
|
+
&& cycle.green?.valid
|
|
201
|
+
&& cycle.red.order > requirements.order
|
|
202
|
+
&& cycle.red.order <= red.order
|
|
203
|
+
&& cycle.green.order > implementation.order
|
|
204
|
+
&& cycle.green.order <= green.order);
|
|
205
|
+
if (red && cycles.some((cycle) => !Number.isInteger(cycle.red.order) || !Number.isInteger(cycle.green?.order))) {
|
|
206
|
+
diagnostics.push(error('CHANGE_ORDER_MIGRATION_REQUIRED', `${change.changeId}:${requirementId} references TDD evidence without monotonic order; regenerate the cycle.`));
|
|
207
|
+
}
|
|
208
|
+
if (red && !validCycle) {
|
|
209
|
+
diagnostics.push(error('CHANGE_RED_UNPROVEN', `${change.changeId} has no valid Red evidence for ${requirementId} before its Red phase.`));
|
|
210
|
+
}
|
|
211
|
+
if (green && !validCycle) {
|
|
212
|
+
diagnostics.push(error('CHANGE_GREEN_UNPROVEN', `${change.changeId} has no valid Green evidence for ${requirementId} before its Green phase.`));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return { present: true, valid: !diagnostics.length, changes: evidence.changes.length, diagnostics };
|
|
217
|
+
}
|
|
218
|
+
export async function validateChangeCompleteness(root) {
|
|
219
|
+
const evidence = await loadChangeEvidence(root);
|
|
220
|
+
if (!evidence?.changes.length)
|
|
221
|
+
return { present: false, valid: false, changes: [], diagnostics: [] };
|
|
222
|
+
const diagnostics = [];
|
|
223
|
+
const trace = await buildTrace(root, false);
|
|
224
|
+
const nodes = new Map(trace.nodes.map((node) => [node.id, node]));
|
|
225
|
+
const requirementsById = new Map();
|
|
226
|
+
for (const path of (await files(root)).filter((entry) => /^\.musubix\/features\/[^/]+\/requirements\.md$/.test(entry))) {
|
|
227
|
+
for (const requirement of validateRequirements(await readText(root, path), path).value) {
|
|
228
|
+
requirementsById.set(requirement.id, requirement);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const designsById = new Map();
|
|
232
|
+
for (const path of (await files(root)).filter((entry) => /^\.musubix\/features\/[^/]+\/design\.md$/.test(entry))) {
|
|
233
|
+
for (const component of validateDesign(await readText(root, path), path).value)
|
|
234
|
+
designsById.set(component.id, component);
|
|
235
|
+
}
|
|
236
|
+
const tdd = await loadTddEvidence(root);
|
|
237
|
+
const performance = await validatePerformanceEvidence(root);
|
|
238
|
+
const changes = [];
|
|
239
|
+
for (const change of evidence.changes) {
|
|
240
|
+
const diagnosticStart = diagnostics.length;
|
|
241
|
+
const changePath = `.musubix/changes/${change.changeId}.md`;
|
|
242
|
+
const declaredRequirements = await exists(within(root, changePath))
|
|
243
|
+
? [...new Set((/^Requirements\s*:\s*(.+)$/im.exec(await readText(root, changePath))?.[1] ?? '').match(/\bREQ-[A-Z0-9]+(?:-[A-Z0-9]+)*-\d{3,}\b/g) ?? [])].sort()
|
|
244
|
+
: [];
|
|
245
|
+
if (JSON.stringify(declaredRequirements) !== JSON.stringify([...change.requirementIds].sort())) {
|
|
246
|
+
diagnostics.push(error('CHANGE_REQUIREMENTS_MISMATCH', `${change.changeId} must explicitly enumerate exactly ${change.requirementIds.join(', ')} in its Requirements field.`, changePath));
|
|
247
|
+
}
|
|
248
|
+
let completeRequirements = 0;
|
|
249
|
+
let functionalRequirements = 0;
|
|
250
|
+
let nonFunctionalRequirements = 0;
|
|
251
|
+
for (const requirementId of change.requirementIds) {
|
|
252
|
+
const requirementNode = nodes.get(requirementId);
|
|
253
|
+
const requirement = requirementsById.get(requirementId);
|
|
254
|
+
const type = requirement?.type;
|
|
255
|
+
if (type === 'non-functional')
|
|
256
|
+
nonFunctionalRequirements++;
|
|
257
|
+
else if (type === 'functional')
|
|
258
|
+
functionalRequirements++;
|
|
259
|
+
const designs = trace.edges
|
|
260
|
+
.filter((edge) => edge.relation === 'satisfies' && edge.to === requirementId && nodes.get(edge.from)?.kind === 'design')
|
|
261
|
+
.map((edge) => edge.from);
|
|
262
|
+
const hasAdr = trace.edges.some((edge) => edge.relation === 'decides' && designs.includes(edge.to) && nodes.get(edge.from)?.kind === 'adr');
|
|
263
|
+
const hasCode = trace.edges.some((edge) => edge.relation === 'implements'
|
|
264
|
+
&& (edge.to === requirementId || designs.includes(edge.to))
|
|
265
|
+
&& nodes.get(edge.from)?.kind === 'code');
|
|
266
|
+
const hasTest = trace.edges.some((edge) => edge.relation === 'verifies' && edge.to === requirementId && nodes.get(edge.from)?.kind === 'test');
|
|
267
|
+
const designConcrete = designs.some((id) => {
|
|
268
|
+
const component = designsById.get(id);
|
|
269
|
+
return component
|
|
270
|
+
&& component.requirements.includes(requirementId)
|
|
271
|
+
&& [component.responsibility, component.interfaces, component.constraints]
|
|
272
|
+
.every((value) => value.trim().length >= 8 && !/^(TODO|TBD|N\/A|none|未定)$/i.test(value.trim()));
|
|
273
|
+
});
|
|
274
|
+
let authoritativeTest = false;
|
|
275
|
+
for (const node of trace.nodes.filter((candidate) => candidate.kind === 'test')) {
|
|
276
|
+
if (!trace.edges.some((edge) => edge.from === node.id && edge.to === requirementId && edge.relation === 'verifies'))
|
|
277
|
+
continue;
|
|
278
|
+
const source = await readText(root, node.path);
|
|
279
|
+
if (new RegExp(`@id\\s+${node.id}\\b`).test(source) && new RegExp(`@verifies\\s+${requirementId}\\b`).test(source)) {
|
|
280
|
+
authoritativeTest = true;
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
const measurableAcceptance = !!requirement?.acceptance
|
|
285
|
+
&& requirement.acceptance.trim().length >= 8
|
|
286
|
+
&& !/^(TODO|TBD|N\/A|none|未定)$/i.test(requirement.acceptance.trim())
|
|
287
|
+
&& /(?:\d|test|check|verif|assert|given|when|then|return|status|pass|fail|テスト|確認|検証|以下|以上)/i.test(requirement.acceptance);
|
|
288
|
+
const requirements = change.phases.requirements;
|
|
289
|
+
const red = change.phases.red;
|
|
290
|
+
const implementation = change.phases.implementation;
|
|
291
|
+
const green = change.phases.green;
|
|
292
|
+
const hasTdd = tdd?.cycles.some((cycle) => cycle.requirementId === requirementId
|
|
293
|
+
&& requirements
|
|
294
|
+
&& red
|
|
295
|
+
&& implementation
|
|
296
|
+
&& green
|
|
297
|
+
&& Number.isInteger(requirements.order)
|
|
298
|
+
&& Number.isInteger(red.order)
|
|
299
|
+
&& Number.isInteger(implementation.order)
|
|
300
|
+
&& Number.isInteger(green.order)
|
|
301
|
+
&& Number.isInteger(cycle.red.order)
|
|
302
|
+
&& Number.isInteger(cycle.green?.order)
|
|
303
|
+
&& cycle.red.valid
|
|
304
|
+
&& cycle.green?.valid
|
|
305
|
+
&& cycle.red.order > requirements.order
|
|
306
|
+
&& cycle.red.order <= red.order
|
|
307
|
+
&& cycle.green.order > implementation.order
|
|
308
|
+
&& cycle.green.order <= green.order) ?? false;
|
|
309
|
+
const checks = [
|
|
310
|
+
[!!requirementNode && !!requirement && !!type, 'CHANGE_COMPLETENESS_REQUIREMENT', 'requirement'],
|
|
311
|
+
[measurableAcceptance, 'CHANGE_COMPLETENESS_ACCEPTANCE', 'nonempty measurable Acceptance criteria'],
|
|
312
|
+
[designs.length > 0 && designConcrete, 'CHANGE_COMPLETENESS_DESIGN', 'concrete design responsibilities, interfaces, and constraints'],
|
|
313
|
+
[hasAdr, 'CHANGE_COMPLETENESS_ADR', 'ADR'],
|
|
314
|
+
[hasCode, 'CHANGE_COMPLETENESS_CODE', 'implementation'],
|
|
315
|
+
[hasTest && authoritativeTest, 'CHANGE_COMPLETENESS_TEST', 'authoritative annotated test declaration'],
|
|
316
|
+
[hasTdd, 'CHANGE_COMPLETENESS_TDD', 'bounded Red-Green TDD'],
|
|
317
|
+
[!requirement?.performance || (performance.valid && performance.validRequirements.includes(requirementId)), 'CHANGE_COMPLETENESS_PERFORMANCE', 'provenance-bound deterministic operation-budget evidence'],
|
|
318
|
+
];
|
|
319
|
+
for (const [present, code, artifact] of checks) {
|
|
320
|
+
if (!present)
|
|
321
|
+
diagnostics.push(error(code, `${change.changeId}:${requirementId} lacks ${artifact} evidence.`));
|
|
322
|
+
}
|
|
323
|
+
if (checks.every(([present]) => present))
|
|
324
|
+
completeRequirements++;
|
|
325
|
+
}
|
|
326
|
+
changes.push({
|
|
327
|
+
changeId: change.changeId,
|
|
328
|
+
functionalRequirements,
|
|
329
|
+
nonFunctionalRequirements,
|
|
330
|
+
requirements: change.requirementIds.length,
|
|
331
|
+
completeRequirements,
|
|
332
|
+
valid: completeRequirements === change.requirementIds.length && diagnostics.length === diagnosticStart,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
return { present: true, valid: !diagnostics.length, changes, diagnostics };
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=change.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change.js","sourceRoot":"","sources":["../../../../packages/analysis/src/change.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { type Diagnostic } from '../../domain/src/index.js';
|
|
2
|
+
export interface CommandConfig {
|
|
3
|
+
name: string;
|
|
4
|
+
command: string;
|
|
5
|
+
args: string[];
|
|
6
|
+
tddArgs?: string[];
|
|
7
|
+
tddReport?: {
|
|
8
|
+
format: 'musubix-json';
|
|
9
|
+
path: string;
|
|
10
|
+
};
|
|
11
|
+
testReport?: {
|
|
12
|
+
format: 'musubix-json';
|
|
13
|
+
path: string;
|
|
14
|
+
};
|
|
15
|
+
mutationReport?: {
|
|
16
|
+
format: 'musubix-mutation-json';
|
|
17
|
+
path: string;
|
|
18
|
+
};
|
|
19
|
+
adapter?: 'vitest' | 'jest' | 'pytest' | 'go-test' | 'cargo' | 'junit';
|
|
20
|
+
required: boolean;
|
|
21
|
+
timeoutMs: number;
|
|
22
|
+
}
|
|
23
|
+
export interface ArchitectureRule {
|
|
24
|
+
name: string;
|
|
25
|
+
from: string;
|
|
26
|
+
disallow: string[];
|
|
27
|
+
}
|
|
28
|
+
export interface FormalConfig {
|
|
29
|
+
solver: 'auto' | 'none' | 'z3' | 'lean';
|
|
30
|
+
minModeledFraction: number;
|
|
31
|
+
timeoutMs: number;
|
|
32
|
+
}
|
|
33
|
+
export interface AttestationConfig {
|
|
34
|
+
mode: 'off' | 'local' | 'ci-required';
|
|
35
|
+
repository?: string;
|
|
36
|
+
maxAgeSeconds?: number;
|
|
37
|
+
maxFutureSkewSeconds?: number;
|
|
38
|
+
trustedPublicKeys: Array<{
|
|
39
|
+
id: string;
|
|
40
|
+
publicKey: string;
|
|
41
|
+
}>;
|
|
42
|
+
githubOidc?: GitHubOidcConfig;
|
|
43
|
+
}
|
|
44
|
+
export interface GitHubOidcConfig {
|
|
45
|
+
mode: 'off' | 'strict';
|
|
46
|
+
issuer?: 'https://token.actions.githubusercontent.com';
|
|
47
|
+
audience?: string;
|
|
48
|
+
repository?: string;
|
|
49
|
+
workflow?: string;
|
|
50
|
+
ref?: string;
|
|
51
|
+
keyBinding?: 'public-key' | 'key-id';
|
|
52
|
+
}
|
|
53
|
+
export interface WorkflowConfig {
|
|
54
|
+
mode: 'compatible' | 'strict';
|
|
55
|
+
expectedSessionId?: string;
|
|
56
|
+
maxAgeSeconds?: number;
|
|
57
|
+
maxFutureSkewSeconds?: number;
|
|
58
|
+
}
|
|
59
|
+
export interface CodeGraphConfig {
|
|
60
|
+
mode: 'compatible' | 'strict';
|
|
61
|
+
}
|
|
62
|
+
export interface MutationConfig {
|
|
63
|
+
mode: 'compatible' | 'strict';
|
|
64
|
+
}
|
|
65
|
+
export interface Config {
|
|
66
|
+
schemaVersion: 1;
|
|
67
|
+
language: 'auto' | 'en' | 'ja';
|
|
68
|
+
commands: CommandConfig[];
|
|
69
|
+
requiredChecks: string[];
|
|
70
|
+
thresholds: {
|
|
71
|
+
design: number;
|
|
72
|
+
implementation: number;
|
|
73
|
+
tests: number;
|
|
74
|
+
};
|
|
75
|
+
architecture: {
|
|
76
|
+
forbidCycles: boolean;
|
|
77
|
+
rules: ArchitectureRule[];
|
|
78
|
+
};
|
|
79
|
+
codeGraph: CodeGraphConfig;
|
|
80
|
+
formal: FormalConfig;
|
|
81
|
+
mutation: MutationConfig;
|
|
82
|
+
workflow: WorkflowConfig;
|
|
83
|
+
attestation: AttestationConfig;
|
|
84
|
+
}
|
|
85
|
+
export interface PolicyBaseline {
|
|
86
|
+
schemaVersion: 1;
|
|
87
|
+
requiredChecks: string[];
|
|
88
|
+
thresholds: Config['thresholds'];
|
|
89
|
+
architecture: Config['architecture'];
|
|
90
|
+
codeGraph: Config['codeGraph'];
|
|
91
|
+
formal: Pick<FormalConfig, 'solver' | 'minModeledFraction'>;
|
|
92
|
+
mutation: MutationConfig;
|
|
93
|
+
workflow: WorkflowConfig;
|
|
94
|
+
attestation: AttestationConfig;
|
|
95
|
+
requiredCommands: string[];
|
|
96
|
+
}
|
|
97
|
+
export declare const checkNames: readonly ["requirements", "design", "constitution", "trace", "graph", "formal", "model-correspondence", "mutation", "workflow", "tdd", "change-history", "change-completeness", "performance", "attestation", "test-identities", "commands"];
|
|
98
|
+
export declare const defaultConfig: Config;
|
|
99
|
+
export declare const defaultPolicyBaseline: PolicyBaseline;
|
|
100
|
+
export declare function parseConfig(input: unknown): Config;
|
|
101
|
+
export declare function loadConfig(root: string): Promise<Config>;
|
|
102
|
+
export declare function parsePolicyBaseline(input: unknown): PolicyBaseline;
|
|
103
|
+
export declare function loadPolicyBaseline(root: string): Promise<PolicyBaseline | null>;
|
|
104
|
+
export declare function policyDiagnostics(config: Config, baseline: PolicyBaseline, changed?: string[] | null): Diagnostic[];
|