musubix3 0.1.19 → 0.1.21

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.
Files changed (80) hide show
  1. package/.github/plugin/marketplace.json +2 -2
  2. package/.github/skills/sdd-change/SKILL.md +28 -45
  3. package/CHANGELOG.md +126 -0
  4. package/README-ja.md +171 -5
  5. package/README.md +185 -8
  6. package/dist/packages/analysis/src/adapters.d.ts +2 -2
  7. package/dist/packages/analysis/src/adapters.js +33 -3
  8. package/dist/packages/analysis/src/adapters.js.map +1 -1
  9. package/dist/packages/analysis/src/approval-record.js +4 -0
  10. package/dist/packages/analysis/src/approval-record.js.map +1 -1
  11. package/dist/packages/analysis/src/approval.d.ts +51 -0
  12. package/dist/packages/analysis/src/approval.js +341 -2
  13. package/dist/packages/analysis/src/approval.js.map +1 -1
  14. package/dist/packages/analysis/src/attestation.js +4 -0
  15. package/dist/packages/analysis/src/attestation.js.map +1 -1
  16. package/dist/packages/analysis/src/change-evidence.d.ts +65 -8
  17. package/dist/packages/analysis/src/change-evidence.js +173 -46
  18. package/dist/packages/analysis/src/change-evidence.js.map +1 -1
  19. package/dist/packages/analysis/src/change-waiver.d.ts +46 -13
  20. package/dist/packages/analysis/src/change-waiver.js +481 -152
  21. package/dist/packages/analysis/src/change-waiver.js.map +1 -1
  22. package/dist/packages/analysis/src/change.d.ts +1 -0
  23. package/dist/packages/analysis/src/change.js +194 -66
  24. package/dist/packages/analysis/src/change.js.map +1 -1
  25. package/dist/packages/analysis/src/evidence-merge-guard.d.ts +9 -0
  26. package/dist/packages/analysis/src/evidence-merge-guard.js +62 -0
  27. package/dist/packages/analysis/src/evidence-merge-guard.js.map +1 -0
  28. package/dist/packages/analysis/src/evidence-merge.d.ts +55 -0
  29. package/dist/packages/analysis/src/evidence-merge.js +1182 -0
  30. package/dist/packages/analysis/src/evidence-merge.js.map +1 -0
  31. package/dist/packages/analysis/src/evidence-writer-lock.d.ts +189 -0
  32. package/dist/packages/analysis/src/evidence-writer-lock.js +843 -0
  33. package/dist/packages/analysis/src/evidence-writer-lock.js.map +1 -0
  34. package/dist/packages/analysis/src/files.js +11 -0
  35. package/dist/packages/analysis/src/files.js.map +1 -1
  36. package/dist/packages/analysis/src/formal.js +7 -0
  37. package/dist/packages/analysis/src/formal.js.map +1 -1
  38. package/dist/packages/analysis/src/gate.d.ts +1 -1
  39. package/dist/packages/analysis/src/gate.js +23 -6
  40. package/dist/packages/analysis/src/gate.js.map +1 -1
  41. package/dist/packages/analysis/src/graph.js +6 -0
  42. package/dist/packages/analysis/src/graph.js.map +1 -1
  43. package/dist/packages/analysis/src/index.d.ts +3 -0
  44. package/dist/packages/analysis/src/index.js +3 -0
  45. package/dist/packages/analysis/src/index.js.map +1 -1
  46. package/dist/packages/analysis/src/knowledge.js +4 -0
  47. package/dist/packages/analysis/src/knowledge.js.map +1 -1
  48. package/dist/packages/analysis/src/model-correspondence.js +5 -1
  49. package/dist/packages/analysis/src/model-correspondence.js.map +1 -1
  50. package/dist/packages/analysis/src/mutation.js +4 -0
  51. package/dist/packages/analysis/src/mutation.js.map +1 -1
  52. package/dist/packages/analysis/src/order.d.ts +16 -1
  53. package/dist/packages/analysis/src/order.js +10 -0
  54. package/dist/packages/analysis/src/order.js.map +1 -1
  55. package/dist/packages/analysis/src/performance.js +5 -1
  56. package/dist/packages/analysis/src/performance.js.map +1 -1
  57. package/dist/packages/analysis/src/quality-refresh.d.ts +18 -0
  58. package/dist/packages/analysis/src/quality-refresh.js +312 -0
  59. package/dist/packages/analysis/src/quality-refresh.js.map +1 -0
  60. package/dist/packages/analysis/src/tdd.d.ts +86 -3
  61. package/dist/packages/analysis/src/tdd.js +604 -52
  62. package/dist/packages/analysis/src/tdd.js.map +1 -1
  63. package/dist/packages/analysis/src/trace.d.ts +24 -0
  64. package/dist/packages/analysis/src/trace.js +101 -3
  65. package/dist/packages/analysis/src/trace.js.map +1 -1
  66. package/dist/packages/analysis/src/workflow-waiver.d.ts +6 -2
  67. package/dist/packages/analysis/src/workflow-waiver.js +9 -5
  68. package/dist/packages/analysis/src/workflow-waiver.js.map +1 -1
  69. package/dist/packages/analysis/src/workflow.d.ts +1 -1
  70. package/dist/packages/analysis/src/workflow.js +103 -21
  71. package/dist/packages/analysis/src/workflow.js.map +1 -1
  72. package/dist/packages/cli/src/install.js +51 -6
  73. package/dist/packages/cli/src/install.js.map +1 -1
  74. package/dist/packages/cli/src/main.js +252 -79
  75. package/dist/packages/cli/src/main.js.map +1 -1
  76. package/dist/packages/domain/src/design.js +8 -1
  77. package/dist/packages/domain/src/design.js.map +1 -1
  78. package/dist/packages/domain/src/types.d.ts +1 -0
  79. package/package.json +7 -2
  80. package/plugin.json +1 -1
@@ -0,0 +1,312 @@
1
+ import { link, mkdir, open, readFile, readdir, rename, rm, unlink, writeFile } from 'node:fs/promises';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { digest, exists, safePath } from './files.js';
4
+ import { evidenceJournals } from './evidence-merge-guard.js';
5
+ import { withEvidenceWriterLock } from './evidence-writer-lock.js';
6
+ import { validateEvidenceOrderLog } from './order.js';
7
+ import { qualityIdentity, qualityLineage, } from './change-evidence.js';
8
+ const EVIDENCE_DIR = '.musubix/evidence';
9
+ const ORDER_PATH = `${EVIDENCE_DIR}/order.json`;
10
+ const CHANGES_PATH = `${EVIDENCE_DIR}/changes.json`;
11
+ const JOURNAL_PATH = `${EVIDENCE_DIR}/.quality-refresh-transaction.json`;
12
+ const STAGING_PREFIX = `${EVIDENCE_DIR}/.quality-refresh-transaction.`;
13
+ const TARGETS = [ORDER_PATH, CHANGES_PATH];
14
+ function json(value) {
15
+ return `${JSON.stringify(value, null, 2)}\n`;
16
+ }
17
+ async function fsyncFile(path) {
18
+ const handle = await open(path, 'r+');
19
+ try {
20
+ await handle.sync();
21
+ }
22
+ finally {
23
+ await handle.close();
24
+ }
25
+ }
26
+ export async function fsyncQualityRefreshDirectory(path, openDirectory = open) {
27
+ let handle;
28
+ try {
29
+ handle = await openDirectory(path, 'r');
30
+ await handle.sync();
31
+ }
32
+ catch (cause) {
33
+ if (!['EISDIR', 'EPERM', 'EACCES', 'EINVAL'].includes(cause.code ?? ''))
34
+ throw cause;
35
+ }
36
+ finally {
37
+ await handle?.close();
38
+ }
39
+ }
40
+ async function removeIfPresent(path) {
41
+ await rm(path, { force: true });
42
+ }
43
+ async function originalBytes(root, path) {
44
+ const absolute = await safePath(root, path);
45
+ try {
46
+ return { existed: true, bytes: await readFile(absolute, 'utf8') };
47
+ }
48
+ catch (cause) {
49
+ if (cause.code === 'ENOENT')
50
+ return { existed: false, bytes: '' };
51
+ throw cause;
52
+ }
53
+ }
54
+ async function restoreJournal(root, journal) {
55
+ const evidenceDirectory = await safePath(root, EVIDENCE_DIR);
56
+ for (const target of journal.targets) {
57
+ const absolute = await safePath(root, target.path);
58
+ if (target.existed) {
59
+ const staging = `${absolute}.${journal.transactionId}.restore`;
60
+ await writeFile(staging, Buffer.from(target.originalBase64, 'base64'));
61
+ await fsyncFile(staging);
62
+ await rename(staging, absolute);
63
+ }
64
+ else {
65
+ await removeIfPresent(absolute);
66
+ }
67
+ await removeIfPresent(await safePath(root, target.temporaryPath));
68
+ }
69
+ await fsyncQualityRefreshDirectory(evidenceDirectory);
70
+ await removeIfPresent(await safePath(root, JOURNAL_PATH));
71
+ await fsyncQualityRefreshDirectory(evidenceDirectory);
72
+ }
73
+ function validateCandidate(order, changes) {
74
+ if (!validateEvidenceOrderLog(order).valid || changes.schemaVersion !== 2 || !Array.isArray(changes.changes)) {
75
+ throw new Error('candidate evidence is structurally invalid');
76
+ }
77
+ for (const change of changes.changes) {
78
+ if (change.qualityHistory !== undefined
79
+ && (!Array.isArray(change.qualityHistory) || change.qualityHistory.length === 0)) {
80
+ throw new Error(`${change.changeId} has malformed Quality history`);
81
+ }
82
+ const lineage = qualityLineage(change);
83
+ if (!lineage.length)
84
+ continue;
85
+ const identities = new Set();
86
+ for (const [index, checkpoint] of lineage.entries()) {
87
+ const identity = qualityIdentity(index + 1);
88
+ identities.add(identity);
89
+ if (checkpoint.phase !== 'quality' || typeof checkpoint.recordedAt !== 'string'
90
+ || !checkpoint.fingerprints || !Number.isInteger(checkpoint.order)) {
91
+ throw new Error(`${change.changeId}:${identity} is malformed`);
92
+ }
93
+ const matches = order.records.filter((record) => record.kind === 'change' && record.entityId === change.changeId
94
+ && record.phase === identity && record.sequence === checkpoint.order);
95
+ if (matches.length !== 1)
96
+ throw new Error(`${change.changeId}:${identity} is not paired`);
97
+ }
98
+ if (order.records.some((record) => record.kind === 'change' && record.entityId === change.changeId
99
+ && /^quality(?::\d+)?$/.test(record.phase) && !identities.has(record.phase))) {
100
+ throw new Error(`${change.changeId} has an orphan Quality order identity`);
101
+ }
102
+ }
103
+ }
104
+ function validateJournal(journal) {
105
+ if (journal.schemaVersion !== 1 || journal.kind !== 'quality-refresh'
106
+ || typeof journal.transactionId !== 'string' || !journal.transactionId
107
+ || !['prepared', 'committed'].includes(journal.state) || !Array.isArray(journal.targets)) {
108
+ throw new Error('published Quality-refresh journal is invalid');
109
+ }
110
+ const paths = new Set();
111
+ for (const target of journal.targets) {
112
+ if (!TARGETS.includes(target.path) || paths.has(target.path)
113
+ || typeof target.existed !== 'boolean'
114
+ || typeof target.originalBase64 !== 'string' || typeof target.originalSha256 !== 'string'
115
+ || typeof target.candidateBase64 !== 'string' || typeof target.candidateSha256 !== 'string'
116
+ || typeof target.temporaryPath !== 'string'
117
+ || !target.temporaryPath.startsWith(`${target.path}.${journal.transactionId}.`)
118
+ || digest(Buffer.from(target.originalBase64, 'base64')) !== target.originalSha256
119
+ || digest(Buffer.from(target.candidateBase64, 'base64')) !== target.candidateSha256) {
120
+ throw new Error('published Quality-refresh journal target is invalid');
121
+ }
122
+ paths.add(target.path);
123
+ }
124
+ if (paths.size !== TARGETS.length || TARGETS.some((path) => !paths.has(path))) {
125
+ throw new Error('published Quality-refresh journal target inventory is incomplete');
126
+ }
127
+ }
128
+ function unsafe(reason) {
129
+ return new Error(`CHANGE_QUALITY_REFRESH_RECOVERY_UNSAFE: ${reason}`);
130
+ }
131
+ /** @id CODE-CHANGE-QUALITY-REFRESH-002
132
+ * @implements REQ-CHANGE-QUALITY-REFRESH-001 REQ-CHANGE-QUALITY-REFRESH-003
133
+ * @design DES-CHANGE-QUALITY-REFRESH-002
134
+ */
135
+ export async function commitQualityRefresh(root, order, changes, faultAt) {
136
+ const journals = await evidenceJournals(root);
137
+ if (journals.merge)
138
+ throw new Error('EVIDENCE_MERGE_RECOVERY_REQUIRED: run evidence merge --recover.');
139
+ if (journals.qualityRefresh) {
140
+ throw new Error('CHANGE_QUALITY_REFRESH_RECOVERY_REQUIRED: run change quality-recover.');
141
+ }
142
+ validateCandidate(order, changes);
143
+ const transactionId = crypto.randomUUID();
144
+ const candidateBytes = {
145
+ [ORDER_PATH]: json(order),
146
+ [CHANGES_PATH]: json(changes),
147
+ };
148
+ const targets = [];
149
+ for (const path of TARGETS) {
150
+ const original = await originalBytes(root, path);
151
+ const candidate = candidateBytes[path];
152
+ targets.push({
153
+ path,
154
+ existed: original.existed,
155
+ originalBase64: Buffer.from(original.bytes).toString('base64'),
156
+ originalSha256: digest(original.bytes),
157
+ candidateBase64: Buffer.from(candidate).toString('base64'),
158
+ candidateSha256: digest(candidate),
159
+ temporaryPath: `${path}.${transactionId}.quality-refresh`,
160
+ });
161
+ }
162
+ const journal = {
163
+ schemaVersion: 1,
164
+ kind: 'quality-refresh',
165
+ transactionId,
166
+ state: 'prepared',
167
+ targets,
168
+ };
169
+ const journalAbsolute = await safePath(root, JOURNAL_PATH);
170
+ const stagingJournal = await safePath(root, `${STAGING_PREFIX}${transactionId}.json`);
171
+ await mkdir(dirname(journalAbsolute), { recursive: true });
172
+ if (faultAt === 'journal:staging')
173
+ throw new Error('Injected Quality refresh failure at journal:staging.');
174
+ await writeFile(stagingJournal, json(journal), { flag: 'wx' });
175
+ await fsyncFile(stagingJournal);
176
+ if (faultAt === 'journal:publication') {
177
+ throw new Error('CHANGE_QUALITY_REFRESH_RECOVERY_REQUIRED: injected failure at journal:publication.');
178
+ }
179
+ try {
180
+ await link(stagingJournal, journalAbsolute);
181
+ await unlink(stagingJournal);
182
+ }
183
+ catch (cause) {
184
+ await removeIfPresent(stagingJournal);
185
+ if (cause.code === 'EEXIST') {
186
+ throw new Error('CHANGE_QUALITY_REFRESH_RECOVERY_REQUIRED: another Quality refresh was published.');
187
+ }
188
+ throw cause;
189
+ }
190
+ await fsyncQualityRefreshDirectory(dirname(journalAbsolute));
191
+ try {
192
+ for (let index = 0; index < targets.length; index++) {
193
+ if (faultAt === `temporary:${index}`)
194
+ throw new Error(`Injected Quality refresh failure at temporary:${index}.`);
195
+ const target = targets[index];
196
+ const temporary = await safePath(root, target.temporaryPath);
197
+ await writeFile(temporary, Buffer.from(target.candidateBase64, 'base64'), { flag: 'wx' });
198
+ await fsyncFile(temporary);
199
+ }
200
+ for (let index = 0; index < targets.length; index++) {
201
+ if (faultAt === `replace:${index}`)
202
+ throw new Error(`Injected Quality refresh failure at replace:${index}.`);
203
+ const target = targets[index];
204
+ await rename(await safePath(root, target.temporaryPath), await safePath(root, target.path));
205
+ }
206
+ await fsyncQualityRefreshDirectory(dirname(journalAbsolute));
207
+ journal.state = 'committed';
208
+ const commitStaging = await safePath(root, `${STAGING_PREFIX}${transactionId}.commit.json`);
209
+ await writeFile(commitStaging, json(journal), { flag: 'wx' });
210
+ await fsyncFile(commitStaging);
211
+ if (faultAt === 'commit-marker')
212
+ throw new Error('Injected Quality refresh failure at commit-marker.');
213
+ await rename(commitStaging, journalAbsolute);
214
+ await fsyncQualityRefreshDirectory(dirname(journalAbsolute));
215
+ if (faultAt === 'cleanup') {
216
+ throw new Error('CHANGE_QUALITY_REFRESH_RECOVERY_REQUIRED: injected failure at cleanup.');
217
+ }
218
+ await removeIfPresent(journalAbsolute);
219
+ }
220
+ catch (cause) {
221
+ const injected = cause instanceof Error && cause.message.startsWith('Injected Quality refresh failure');
222
+ if (injected && journal.state === 'prepared') {
223
+ await restoreJournal(root, journal);
224
+ throw cause;
225
+ }
226
+ throw new Error(`CHANGE_QUALITY_REFRESH_RECOVERY_REQUIRED: ${cause instanceof Error ? cause.message : String(cause)}`);
227
+ }
228
+ }
229
+ /** @id CODE-CHANGE-QUALITY-REFRESH-003
230
+ * @implements REQ-CHANGE-QUALITY-REFRESH-003
231
+ * @design DES-CHANGE-QUALITY-REFRESH-002
232
+ */
233
+ export async function recoverQualityRefresh(root) {
234
+ return withEvidenceWriterLock(root, 'change quality-recover', async () => {
235
+ const journals = await evidenceJournals(root);
236
+ if (journals.merge && journals.qualityRefresh)
237
+ throw unsafe('merge and Quality-refresh journals coexist.');
238
+ if (journals.merge)
239
+ throw new Error('EVIDENCE_MERGE_RECOVERY_REQUIRED: run evidence merge --recover.');
240
+ const journalAbsolute = await safePath(root, JOURNAL_PATH);
241
+ const evidenceDir = await safePath(root, EVIDENCE_DIR);
242
+ let staging = [];
243
+ try {
244
+ staging = (await readdir(evidenceDir))
245
+ .filter((entry) => entry.startsWith('.quality-refresh-transaction.')
246
+ && entry !== '.quality-refresh-transaction.json');
247
+ }
248
+ catch (cause) {
249
+ if (cause.code !== 'ENOENT')
250
+ throw cause;
251
+ }
252
+ if (!await exists(journalAbsolute)) {
253
+ for (const entry of staging)
254
+ await removeIfPresent(resolve(evidenceDir, entry));
255
+ return { recovered: false, action: 'nothing-to-recover' };
256
+ }
257
+ let journal;
258
+ try {
259
+ journal = JSON.parse(await readFile(journalAbsolute, 'utf8'));
260
+ validateJournal(journal);
261
+ }
262
+ catch (cause) {
263
+ throw unsafe(cause instanceof Error ? cause.message : String(cause));
264
+ }
265
+ if (journal.state === 'prepared') {
266
+ await restoreJournal(root, journal);
267
+ for (const entry of staging)
268
+ await removeIfPresent(resolve(evidenceDir, entry));
269
+ return { recovered: true, action: 'rolled-back' };
270
+ }
271
+ try {
272
+ const values = new Map(journal.targets.map((target) => [
273
+ target.path,
274
+ JSON.parse(Buffer.from(target.candidateBase64, 'base64').toString('utf8')),
275
+ ]));
276
+ validateCandidate(values.get(ORDER_PATH), values.get(CHANGES_PATH));
277
+ for (const target of journal.targets) {
278
+ const absolute = await safePath(root, target.path);
279
+ let actual = '';
280
+ try {
281
+ actual = await readFile(absolute, 'utf8');
282
+ }
283
+ catch (cause) {
284
+ if (cause.code !== 'ENOENT')
285
+ throw cause;
286
+ }
287
+ const actualDigest = digest(actual);
288
+ if (actualDigest !== target.originalSha256 && actualDigest !== target.candidateSha256) {
289
+ throw unsafe(`${target.path} differs from both journaled original and candidate.`);
290
+ }
291
+ if (actualDigest !== target.candidateSha256) {
292
+ const recovery = `${absolute}.${journal.transactionId}.recover`;
293
+ await writeFile(recovery, Buffer.from(target.candidateBase64, 'base64'));
294
+ await fsyncFile(recovery);
295
+ await rename(recovery, absolute);
296
+ }
297
+ }
298
+ }
299
+ catch (cause) {
300
+ if (cause instanceof Error && cause.message.startsWith('CHANGE_QUALITY_REFRESH_RECOVERY_UNSAFE'))
301
+ throw cause;
302
+ throw unsafe(cause instanceof Error ? cause.message : String(cause));
303
+ }
304
+ await fsyncQualityRefreshDirectory(evidenceDir);
305
+ await removeIfPresent(journalAbsolute);
306
+ for (const entry of staging)
307
+ await removeIfPresent(resolve(evidenceDir, entry));
308
+ await fsyncQualityRefreshDirectory(evidenceDir);
309
+ return { recovered: true, action: 'rolled-forward' };
310
+ });
311
+ }
312
+ //# sourceMappingURL=quality-refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-refresh.js","sourceRoot":"","sources":["../../../../packages/analysis/src/quality-refresh.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  import { type Diagnostic } from '../../domain/src/index.js';
2
2
  import { type Runner } from './process.js';
3
3
  import { type TraceNode } from './trace.js';
4
+ import { type validateEvidenceOrderLog } from './order.js';
5
+ import { type ChangeRecord } from './change-evidence.js';
4
6
  import type { MusubixTestReport } from './test-report.js';
5
7
  export type { MusubixTestReport } from './test-report.js';
6
8
  export type TddPhase = 'red' | 'green' | 'refactor';
@@ -23,12 +25,16 @@ export interface TddPhaseEvidence {
23
25
  diagnostics: Diagnostic[];
24
26
  warnings?: Diagnostic[];
25
27
  }
26
- export type TddChainPhase = TddPhase | 'migrate' | 'void';
28
+ export type TddChainPhase = TddPhase | 'migrate' | 'void' | 'archive';
29
+ export type TddMigrationMode = 'fingerprint' | 'identifier';
27
30
  export interface TddMigrationEvidence {
28
31
  phase: 'migrate';
29
32
  fromFingerprint: string;
30
33
  toFingerprint: string;
31
34
  approver: string;
35
+ mode?: TddMigrationMode;
36
+ oldTestId?: string;
37
+ newTestId?: string;
32
38
  order?: number;
33
39
  recordedAt: string;
34
40
  }
@@ -39,6 +45,15 @@ export interface TddVoidEvidence {
39
45
  order?: number;
40
46
  recordedAt: string;
41
47
  }
48
+ export interface TddArchiveEvidence {
49
+ phase: 'archive';
50
+ approver: string;
51
+ reason: string;
52
+ testId: string;
53
+ cycleId: string;
54
+ order?: number;
55
+ recordedAt: string;
56
+ }
42
57
  export interface TddCycle {
43
58
  cycleId?: string;
44
59
  requirementId: string;
@@ -49,7 +64,9 @@ export interface TddCycle {
49
64
  green?: TddPhaseEvidence;
50
65
  refactor?: TddPhaseEvidence;
51
66
  migrate?: TddMigrationEvidence;
67
+ migrateHistory?: TddMigrationEvidence[];
52
68
  void?: TddVoidEvidence;
69
+ archive?: TddArchiveEvidence;
53
70
  }
54
71
  export interface TddChainRecord {
55
72
  sequence: number;
@@ -59,6 +76,9 @@ export interface TddChainRecord {
59
76
  testPath: string;
60
77
  commandName: string;
61
78
  phase: TddChainPhase;
79
+ mode?: TddMigrationMode;
80
+ oldTestId?: string;
81
+ newTestId?: string;
62
82
  phaseEvidenceSha256: string;
63
83
  previousSha256: string | null;
64
84
  recordSha256: string;
@@ -68,6 +88,23 @@ export interface TddEvidence {
68
88
  cycles: TddCycle[];
69
89
  chain?: TddChainRecord[];
70
90
  }
91
+ /** @id CODE-CHANGE-REQUIREMENT-BATCHES-004
92
+ * @implements REQ-CHANGE-REQUIREMENT-BATCHES-005
93
+ * @design DES-CHANGE-REQUIREMENT-BATCHES-002
94
+ */
95
+ export declare function voidedCycleOrdersInCurrentWindow(change: ChangeRecord, requirementId: string, tdd: TddEvidence | null, validlyVoided: ReadonlySet<TddCycle>): number[];
96
+ export declare function hasValidTddCycle(change: ChangeRecord, requirementId: string, tdd: TddEvidence | null, validlyVoided?: ReadonlySet<TddCycle>): boolean;
97
+ export declare function redUnprovenCondition(change: ChangeRecord, requirementId: string, tdd: TddEvidence | null, validlyVoided?: ReadonlySet<TddCycle>): boolean;
98
+ export declare function greenUnprovenCondition(change: ChangeRecord, requirementId: string, tdd: TddEvidence | null, validlyVoided?: ReadonlySet<TddCycle>): boolean;
99
+ export declare function completenessTddUnsatisfiedCondition(change: ChangeRecord, requirementId: string, tdd: TddEvidence | null, validlyVoided?: ReadonlySet<TddCycle>): boolean;
100
+ /** @id CODE-CHANGE-EVIDENCE-WAIVER-028
101
+ * @implements REQ-CHANGE-EVIDENCE-WAIVER-018
102
+ * @design DES-CHANGE-EVIDENCE-WAIVER-006
103
+ * Accepts an optional `validlyArchived` set, mirroring `validlyVoided`, so
104
+ * archived TDD cycles are excluded from both the "lacks order evidence" scan
105
+ * and `currentTddCycle`'s window selection (Issue #64).
106
+ */
107
+ export declare function orderMigrationRequiredRequirementCondition(change: ChangeRecord, requirementId: string, tdd: TddEvidence | null, validlyVoided?: ReadonlySet<TddCycle>, validlyArchived?: ReadonlySet<TddCycle>): boolean;
71
108
  export declare function parseMusubixTestReport(text: string): MusubixTestReport;
72
109
  /** @id CODE-TDD-FINGERPRINT-MIGRATION-001
73
110
  * @implements REQ-TDD-FINGERPRINT-MIGRATION-001
@@ -81,20 +118,57 @@ export interface TddMigrationResult {
81
118
  toFingerprint?: string;
82
119
  reason?: string;
83
120
  }
121
+ export interface TddIdentifierMigrationResult extends TddMigrationResult {
122
+ oldTestId?: string;
123
+ newTestId?: string;
124
+ }
125
+ /** @id CODE-TDD-CYCLE-ARCHIVE-006
126
+ * @implements REQ-TDD-CYCLE-ARCHIVE-012
127
+ * @design DES-TDD-CYCLE-ARCHIVE-005
128
+ */
84
129
  export declare function migrateTddFingerprint(root: string, testId: string, approver: string): Promise<TddMigrationResult>;
130
+ /** @id CODE-TDD-IDENTIFIER-MIGRATION-001
131
+ * @implements REQ-TDD-IDENTIFIER-MIGRATION-001 REQ-TDD-IDENTIFIER-MIGRATION-002 REQ-TDD-IDENTIFIER-MIGRATION-003 REQ-TDD-IDENTIFIER-MIGRATION-004
132
+ * @design DES-TDD-IDENTIFIER-MIGRATION-001 DES-TDD-IDENTIFIER-MIGRATION-002 DES-TDD-IDENTIFIER-MIGRATION-003
133
+ */
134
+ export declare function migrateTddIdentifier(root: string, oldTestId: string, newTestId: string, approver: string): Promise<TddIdentifierMigrationResult>;
85
135
  export declare function loadTddEvidence(root: string): Promise<TddEvidence | null>;
136
+ export declare function validlyVoidedTddCycles(evidence: TddEvidence | null, order: ReturnType<typeof validateEvidenceOrderLog>): ReadonlySet<TddCycle>;
137
+ /** @id CODE-CHANGE-EVIDENCE-WAIVER-027
138
+ * @implements REQ-CHANGE-EVIDENCE-WAIVER-018
139
+ * @design DES-CHANGE-EVIDENCE-WAIVER-006
140
+ * Mirrors `validlyVoidedTddCycles` for archived cycles so callers can exclude
141
+ * validly archived evidence from change order-window checks the same way
142
+ * validly voided evidence is already excluded (Issue #64).
143
+ */
144
+ export declare function validlyArchivedTddCycles(evidence: TddEvidence | null, order: ReturnType<typeof validateEvidenceOrderLog>): ReadonlySet<TddCycle>;
86
145
  export interface TddVoidResult {
87
146
  voided: boolean;
88
147
  testId: string;
89
148
  cycleId?: string;
90
149
  reason?: string;
91
150
  }
151
+ export interface TddArchiveResult {
152
+ archived: boolean;
153
+ testId: string;
154
+ cycleId?: string;
155
+ reason?: string;
156
+ }
92
157
  /** @id CODE-TDD-CYCLE-VOID-001
93
- * @implements REQ-TDD-CYCLE-VOID-001, REQ-TDD-CYCLE-VOID-002, REQ-TDD-CYCLE-VOID-003, REQ-TDD-CYCLE-VOID-004, REQ-TDD-CYCLE-VOID-011
94
- * @design DES-TDD-CYCLE-VOID-001, DES-TDD-CYCLE-VOID-005
158
+ * @implements REQ-TDD-CYCLE-VOID-001, REQ-TDD-CYCLE-VOID-002, REQ-TDD-CYCLE-VOID-003, REQ-TDD-CYCLE-VOID-004, REQ-TDD-CYCLE-VOID-011, REQ-TDD-CYCLE-ARCHIVE-004
159
+ * @design DES-TDD-CYCLE-VOID-001, DES-TDD-CYCLE-VOID-005, DES-TDD-CYCLE-ARCHIVE-002
95
160
  */
96
161
  export declare function voidTddCycle(root: string, testId: string, approver: string, reason: string): Promise<TddVoidResult>;
162
+ /** @id CODE-TDD-CYCLE-ARCHIVE-001
163
+ * @implements REQ-TDD-CYCLE-ARCHIVE-001 REQ-TDD-CYCLE-ARCHIVE-002 REQ-TDD-CYCLE-ARCHIVE-003 REQ-TDD-CYCLE-ARCHIVE-004 REQ-TDD-CYCLE-ARCHIVE-005
164
+ * @design DES-TDD-CYCLE-ARCHIVE-001 DES-TDD-CYCLE-ARCHIVE-002
165
+ */
166
+ export declare function archiveTddCycle(root: string, testId: string, approver: string, reason: string): Promise<TddArchiveResult>;
97
167
  export declare function runTddPhase(root: string, phase: TddPhase, testId: string, requirementId: string, commandName: string, runner?: Runner): Promise<TddPhaseEvidence>;
168
+ /** @id CODE-TDD-CYCLE-ARCHIVE-004
169
+ * @implements REQ-TDD-CYCLE-ARCHIVE-006 REQ-TDD-CYCLE-ARCHIVE-007 REQ-TDD-CYCLE-ARCHIVE-008 REQ-TDD-CYCLE-ARCHIVE-009 REQ-TDD-CYCLE-ARCHIVE-010 REQ-TDD-CYCLE-ARCHIVE-013
170
+ * @design DES-TDD-CYCLE-ARCHIVE-003 DES-TDD-CYCLE-ARCHIVE-004 DES-TDD-CYCLE-ARCHIVE-005
171
+ */
98
172
  export declare function validateTddEvidence(root: string): Promise<{
99
173
  present: boolean;
100
174
  valid: boolean;
@@ -109,4 +183,13 @@ export declare function validateTddEvidence(root: string): Promise<{
109
183
  recordedAt: string;
110
184
  };
111
185
  }>;
186
+ archived: Array<{
187
+ testId: string;
188
+ cycleId: string;
189
+ archive: {
190
+ approver: string;
191
+ reason: string;
192
+ recordedAt: string;
193
+ };
194
+ }>;
112
195
  }>;