@principles/core 1.240.1 → 1.240.3

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.
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Bridge Result Shaper Tests — Core Package
3
+ *
4
+ * Direct unit tests for the pure shapeBridgeResult() function.
5
+ *
6
+ * This module centralizes the status decision tree for PainSignalBridge,
7
+ * used by both the fresh diagnosis path and the existing-task idempotent path.
8
+ *
9
+ * Tests verify every branch in the decision tree:
10
+ * - Fresh path: no candidates → failed
11
+ * - Fresh path: admitted but no ledger → failed
12
+ * - Fresh path: all gated → degraded
13
+ * - Fresh path: partial admission → degraded
14
+ * - Fresh path: success with seed failure note → degraded
15
+ * - Fresh path: clean success → succeeded
16
+ * - Existing path: no candidates → failed
17
+ * - Existing path: no ledger → failed
18
+ * - Existing path: clean success → succeeded
19
+ *
20
+ * ERR checklist:
21
+ * - ERR-007 / EP-02: single source for status decision (unit test proves all branches)
22
+ * - ERR-002 / EP-03: every degraded/failed branch carries a structured message
23
+ * - ERR-004 / ERR-008 / EP-07: lineage fields pass through untouched
24
+ */
25
+ export {};
26
+ //# sourceMappingURL=bridge-result-shaper.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-result-shaper.test.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/bridge-result-shaper.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG"}
@@ -0,0 +1,402 @@
1
+ /**
2
+ * Bridge Result Shaper Tests — Core Package
3
+ *
4
+ * Direct unit tests for the pure shapeBridgeResult() function.
5
+ *
6
+ * This module centralizes the status decision tree for PainSignalBridge,
7
+ * used by both the fresh diagnosis path and the existing-task idempotent path.
8
+ *
9
+ * Tests verify every branch in the decision tree:
10
+ * - Fresh path: no candidates → failed
11
+ * - Fresh path: admitted but no ledger → failed
12
+ * - Fresh path: all gated → degraded
13
+ * - Fresh path: partial admission → degraded
14
+ * - Fresh path: success with seed failure note → degraded
15
+ * - Fresh path: clean success → succeeded
16
+ * - Existing path: no candidates → failed
17
+ * - Existing path: no ledger → failed
18
+ * - Existing path: clean success → succeeded
19
+ *
20
+ * ERR checklist:
21
+ * - ERR-007 / EP-02: single source for status decision (unit test proves all branches)
22
+ * - ERR-002 / EP-03: every degraded/failed branch carries a structured message
23
+ * - ERR-004 / ERR-008 / EP-07: lineage fields pass through untouched
24
+ */
25
+ import { describe, it, expect } from 'vitest';
26
+ import { shapeBridgeResult } from '../bridge-result-shaper.js';
27
+ const PAIN_ID = 'pain-test-001';
28
+ const TASK_ID = 'diagnosis_pain-test-001';
29
+ const RUN_ID = 'run-test-1';
30
+ const ARTIFACT_ID = 'artifact-test-1';
31
+ function makeAdmissionResult(candidateId, decision) {
32
+ return {
33
+ candidateId,
34
+ recommendationKind: 'principle',
35
+ admission: {
36
+ decision,
37
+ reason: decision === 'admitted' ? 'evidence_sufficient' : 'input_evidence_empty',
38
+ nextAction: decision === 'admitted' ? 'none' : 'collect_evidence_before_diagnosis',
39
+ evidenceStatus: 'automatic_hook',
40
+ },
41
+ };
42
+ }
43
+ describe('shapeBridgeResult — fresh path', () => {
44
+ it('returns failed when no candidates produced', () => {
45
+ const input = {
46
+ path: 'fresh',
47
+ painId: PAIN_ID,
48
+ taskId: TASK_ID,
49
+ runId: RUN_ID,
50
+ candidateIds: [],
51
+ ledgerEntryIds: [],
52
+ admissionResults: [],
53
+ seedFailureNote: '',
54
+ autoIntakeEnabled: true,
55
+ };
56
+ const result = shapeBridgeResult(input);
57
+ expect(result.status).toBe('failed');
58
+ expect(result.painId).toBe(PAIN_ID);
59
+ expect(result.taskId).toBe(TASK_ID);
60
+ expect(result.runId).toBe(RUN_ID);
61
+ expect(result.candidateIds).toEqual([]);
62
+ expect(result.ledgerEntryIds).toEqual([]);
63
+ expect(result.admissionResults).toEqual([]);
64
+ expect(result.message).toBe('Diagnostician succeeded but produced no principle candidates');
65
+ });
66
+ it('returns failed when candidates admitted but intake produced no ledger entries', () => {
67
+ const admissionResults = [
68
+ makeAdmissionResult('cand-1', 'admitted'),
69
+ makeAdmissionResult('cand-2', 'admitted'),
70
+ ];
71
+ const input = {
72
+ path: 'fresh',
73
+ painId: PAIN_ID,
74
+ taskId: TASK_ID,
75
+ runId: RUN_ID,
76
+ artifactId: ARTIFACT_ID,
77
+ candidateIds: ['cand-1', 'cand-2'],
78
+ ledgerEntryIds: [],
79
+ admissionResults,
80
+ seedFailureNote: '',
81
+ autoIntakeEnabled: true,
82
+ };
83
+ const result = shapeBridgeResult(input);
84
+ expect(result.status).toBe('failed');
85
+ expect(result.painId).toBe(PAIN_ID);
86
+ expect(result.artifactId).toBe(ARTIFACT_ID);
87
+ expect(result.candidateIds).toEqual(['cand-1', 'cand-2']);
88
+ expect(result.ledgerEntryIds).toEqual([]);
89
+ expect(result.message).toBe('Candidate intake did not produce a ledger entry');
90
+ });
91
+ it('does NOT fail on no-ledger when autoIntake is disabled', () => {
92
+ const admissionResults = [
93
+ makeAdmissionResult('cand-1', 'admitted'),
94
+ ];
95
+ const input = {
96
+ path: 'fresh',
97
+ painId: PAIN_ID,
98
+ taskId: TASK_ID,
99
+ runId: RUN_ID,
100
+ artifactId: ARTIFACT_ID,
101
+ candidateIds: ['cand-1'],
102
+ ledgerEntryIds: [],
103
+ admissionResults,
104
+ seedFailureNote: '',
105
+ autoIntakeEnabled: false,
106
+ };
107
+ const result = shapeBridgeResult(input);
108
+ expect(result.status).toBe('succeeded');
109
+ expect(result.ledgerEntryIds).toEqual([]);
110
+ });
111
+ it('returns degraded when all candidates are gated (none admitted)', () => {
112
+ const admissionResults = [
113
+ makeAdmissionResult('cand-1', 'needs_evidence'),
114
+ makeAdmissionResult('cand-2', 'deferred'),
115
+ ];
116
+ const input = {
117
+ path: 'fresh',
118
+ painId: PAIN_ID,
119
+ taskId: TASK_ID,
120
+ runId: RUN_ID,
121
+ artifactId: ARTIFACT_ID,
122
+ candidateIds: ['cand-1', 'cand-2'],
123
+ ledgerEntryIds: [],
124
+ admissionResults,
125
+ seedFailureNote: '',
126
+ autoIntakeEnabled: true,
127
+ };
128
+ const result = shapeBridgeResult(input);
129
+ expect(result.status).toBe('degraded');
130
+ expect(result.message).toContain('all_candidates_gated');
131
+ expect(result.message).toContain('cand-1=needs_evidence');
132
+ expect(result.message).toContain('cand-2=deferred');
133
+ });
134
+ it('returns degraded with seed failure note appended when all gated + seed failed', () => {
135
+ const admissionResults = [
136
+ makeAdmissionResult('cand-1', 'needs_evidence'),
137
+ ];
138
+ const input = {
139
+ path: 'fresh',
140
+ painId: PAIN_ID,
141
+ taskId: TASK_ID,
142
+ runId: RUN_ID,
143
+ artifactId: ARTIFACT_ID,
144
+ candidateIds: ['cand-1'],
145
+ ledgerEntryIds: [],
146
+ admissionResults,
147
+ seedFailureNote: 'dreamer seed failed: timeout',
148
+ autoIntakeEnabled: true,
149
+ };
150
+ const result = shapeBridgeResult(input);
151
+ expect(result.status).toBe('degraded');
152
+ expect(result.message).toContain('all_candidates_gated');
153
+ expect(result.message).toContain('dreamer seed failed: timeout');
154
+ });
155
+ it('returns degraded when partial admission (some admitted, some gated)', () => {
156
+ const admissionResults = [
157
+ makeAdmissionResult('cand-1', 'admitted'),
158
+ makeAdmissionResult('cand-2', 'needs_evidence'),
159
+ makeAdmissionResult('cand-3', 'deferred'),
160
+ ];
161
+ const input = {
162
+ path: 'fresh',
163
+ painId: PAIN_ID,
164
+ taskId: TASK_ID,
165
+ runId: RUN_ID,
166
+ artifactId: ARTIFACT_ID,
167
+ candidateIds: ['cand-1', 'cand-2', 'cand-3'],
168
+ ledgerEntryIds: ['ledger-1'],
169
+ admissionResults,
170
+ seedFailureNote: '',
171
+ autoIntakeEnabled: true,
172
+ };
173
+ const result = shapeBridgeResult(input);
174
+ expect(result.status).toBe('degraded');
175
+ expect(result.message).toContain('partial_admission');
176
+ expect(result.message).toContain('1_admitted_2_gated');
177
+ });
178
+ it('returns degraded with seed failure note on partial admission', () => {
179
+ const admissionResults = [
180
+ makeAdmissionResult('cand-1', 'admitted'),
181
+ makeAdmissionResult('cand-2', 'needs_evidence'),
182
+ ];
183
+ const input = {
184
+ path: 'fresh',
185
+ painId: PAIN_ID,
186
+ taskId: TASK_ID,
187
+ runId: RUN_ID,
188
+ artifactId: ARTIFACT_ID,
189
+ candidateIds: ['cand-1', 'cand-2'],
190
+ ledgerEntryIds: ['ledger-1'],
191
+ admissionResults,
192
+ seedFailureNote: 'some seeds failed: rate limit',
193
+ autoIntakeEnabled: true,
194
+ };
195
+ const result = shapeBridgeResult(input);
196
+ expect(result.status).toBe('degraded');
197
+ expect(result.message).toContain('partial_admission');
198
+ expect(result.message).toContain('some seeds failed: rate limit');
199
+ });
200
+ it('returns succeeded when all candidates admitted and ledger produced', () => {
201
+ const admissionResults = [
202
+ makeAdmissionResult('cand-1', 'admitted'),
203
+ makeAdmissionResult('cand-2', 'admitted'),
204
+ ];
205
+ const input = {
206
+ path: 'fresh',
207
+ painId: PAIN_ID,
208
+ taskId: TASK_ID,
209
+ runId: RUN_ID,
210
+ artifactId: ARTIFACT_ID,
211
+ candidateIds: ['cand-1', 'cand-2'],
212
+ ledgerEntryIds: ['ledger-1', 'ledger-2'],
213
+ admissionResults,
214
+ seedFailureNote: '',
215
+ autoIntakeEnabled: true,
216
+ };
217
+ const result = shapeBridgeResult(input);
218
+ expect(result.status).toBe('succeeded');
219
+ expect(result.painId).toBe(PAIN_ID);
220
+ expect(result.taskId).toBe(TASK_ID);
221
+ expect(result.runId).toBe(RUN_ID);
222
+ expect(result.artifactId).toBe(ARTIFACT_ID);
223
+ expect(result.candidateIds).toEqual(['cand-1', 'cand-2']);
224
+ expect(result.ledgerEntryIds).toEqual(['ledger-1', 'ledger-2']);
225
+ expect(result.admissionResults).toEqual(admissionResults);
226
+ expect(result.message).toBeUndefined();
227
+ });
228
+ it('returns degraded when seed failure note is present (even with full admission)', () => {
229
+ const admissionResults = [
230
+ makeAdmissionResult('cand-1', 'admitted'),
231
+ ];
232
+ const input = {
233
+ path: 'fresh',
234
+ painId: PAIN_ID,
235
+ taskId: TASK_ID,
236
+ runId: RUN_ID,
237
+ artifactId: ARTIFACT_ID,
238
+ candidateIds: ['cand-1'],
239
+ ledgerEntryIds: ['ledger-1'],
240
+ admissionResults,
241
+ seedFailureNote: 'dreamer seed failed: LLM error',
242
+ autoIntakeEnabled: true,
243
+ };
244
+ const result = shapeBridgeResult(input);
245
+ expect(result.status).toBe('degraded');
246
+ expect(result.message).toBe('dreamer seed failed: LLM error');
247
+ });
248
+ it('passes through lineage fields untouched (fresh path)', () => {
249
+ const admissionResults = [makeAdmissionResult('cand-1', 'admitted')];
250
+ const input = {
251
+ path: 'fresh',
252
+ painId: PAIN_ID,
253
+ taskId: TASK_ID,
254
+ runId: RUN_ID,
255
+ artifactId: ARTIFACT_ID,
256
+ candidateIds: ['cand-1'],
257
+ ledgerEntryIds: ['ledger-1'],
258
+ admissionResults,
259
+ seedFailureNote: '',
260
+ autoIntakeEnabled: true,
261
+ };
262
+ const result = shapeBridgeResult(input);
263
+ expect(result.painId).toBe(PAIN_ID);
264
+ expect(result.taskId).toBe(TASK_ID);
265
+ expect(result.runId).toBe(RUN_ID);
266
+ expect(result.artifactId).toBe(ARTIFACT_ID);
267
+ expect(result.candidateIds).toBe(input.candidateIds);
268
+ expect(result.ledgerEntryIds).toBe(input.ledgerEntryIds);
269
+ expect(result.admissionResults).toBe(input.admissionResults);
270
+ });
271
+ });
272
+ describe('shapeBridgeResult — existing path', () => {
273
+ it('returns failed when no candidates', () => {
274
+ const input = {
275
+ path: 'existing',
276
+ painId: PAIN_ID,
277
+ taskId: TASK_ID,
278
+ runId: RUN_ID,
279
+ candidateIds: [],
280
+ ledgerEntryIds: [],
281
+ autoIntakeEnabled: true,
282
+ };
283
+ const result = shapeBridgeResult(input);
284
+ expect(result.status).toBe('failed');
285
+ expect(result.message).toBe('Task has no principle candidates — treating as failed');
286
+ expect(result.admissionResults).toBeUndefined();
287
+ });
288
+ it('returns failed when candidates exist but no ledger entries (autoIntake enabled)', () => {
289
+ const input = {
290
+ path: 'existing',
291
+ painId: PAIN_ID,
292
+ taskId: TASK_ID,
293
+ runId: RUN_ID,
294
+ artifactId: ARTIFACT_ID,
295
+ candidateIds: ['cand-1', 'cand-2'],
296
+ ledgerEntryIds: [],
297
+ autoIntakeEnabled: true,
298
+ };
299
+ const result = shapeBridgeResult(input);
300
+ expect(result.status).toBe('failed');
301
+ expect(result.message).toBe('Candidate intake did not produce a ledger entry — treating as failed');
302
+ });
303
+ it('returns succeeded when candidates exist but no ledger (autoIntake disabled)', () => {
304
+ const input = {
305
+ path: 'existing',
306
+ painId: PAIN_ID,
307
+ taskId: TASK_ID,
308
+ runId: RUN_ID,
309
+ artifactId: ARTIFACT_ID,
310
+ candidateIds: ['cand-1'],
311
+ ledgerEntryIds: [],
312
+ autoIntakeEnabled: false,
313
+ };
314
+ const result = shapeBridgeResult(input);
315
+ expect(result.status).toBe('succeeded');
316
+ expect(result.message).toBe('Task already succeeded');
317
+ });
318
+ it('returns succeeded when candidates and ledger entries exist', () => {
319
+ const input = {
320
+ path: 'existing',
321
+ painId: PAIN_ID,
322
+ taskId: TASK_ID,
323
+ runId: RUN_ID,
324
+ artifactId: ARTIFACT_ID,
325
+ candidateIds: ['cand-1', 'cand-2'],
326
+ ledgerEntryIds: ['ledger-1', 'ledger-2'],
327
+ autoIntakeEnabled: true,
328
+ };
329
+ const result = shapeBridgeResult(input);
330
+ expect(result.status).toBe('succeeded');
331
+ expect(result.message).toBe('Task already succeeded');
332
+ expect(result.admissionResults).toBeUndefined();
333
+ });
334
+ it('passes through lineage fields untouched (existing path)', () => {
335
+ const input = {
336
+ path: 'existing',
337
+ painId: PAIN_ID,
338
+ taskId: TASK_ID,
339
+ runId: RUN_ID,
340
+ artifactId: ARTIFACT_ID,
341
+ candidateIds: ['cand-1'],
342
+ ledgerEntryIds: ['ledger-1'],
343
+ autoIntakeEnabled: true,
344
+ };
345
+ const result = shapeBridgeResult(input);
346
+ expect(result.painId).toBe(PAIN_ID);
347
+ expect(result.taskId).toBe(TASK_ID);
348
+ expect(result.runId).toBe(RUN_ID);
349
+ expect(result.artifactId).toBe(ARTIFACT_ID);
350
+ expect(result.candidateIds).toBe(input.candidateIds);
351
+ expect(result.ledgerEntryIds).toBe(input.ledgerEntryIds);
352
+ });
353
+ });
354
+ describe('shapeBridgeResult — cross-path consistency', () => {
355
+ it('fresh and existing paths use different messages for same semantic state', () => {
356
+ const freshNoCandidates = shapeBridgeResult({
357
+ path: 'fresh',
358
+ painId: PAIN_ID,
359
+ taskId: TASK_ID,
360
+ candidateIds: [],
361
+ ledgerEntryIds: [],
362
+ admissionResults: [],
363
+ seedFailureNote: '',
364
+ autoIntakeEnabled: true,
365
+ });
366
+ const existingNoCandidates = shapeBridgeResult({
367
+ path: 'existing',
368
+ painId: PAIN_ID,
369
+ taskId: TASK_ID,
370
+ candidateIds: [],
371
+ ledgerEntryIds: [],
372
+ autoIntakeEnabled: true,
373
+ });
374
+ expect(freshNoCandidates.status).toBe('failed');
375
+ expect(existingNoCandidates.status).toBe('failed');
376
+ expect(freshNoCandidates.message).not.toBe(existingNoCandidates.message);
377
+ });
378
+ it('fresh path includes admissionResults, existing path does not', () => {
379
+ const admissionResults = [makeAdmissionResult('cand-1', 'admitted')];
380
+ const freshSuccess = shapeBridgeResult({
381
+ path: 'fresh',
382
+ painId: PAIN_ID,
383
+ taskId: TASK_ID,
384
+ candidateIds: ['cand-1'],
385
+ ledgerEntryIds: ['ledger-1'],
386
+ admissionResults,
387
+ seedFailureNote: '',
388
+ autoIntakeEnabled: true,
389
+ });
390
+ const existingSuccess = shapeBridgeResult({
391
+ path: 'existing',
392
+ painId: PAIN_ID,
393
+ taskId: TASK_ID,
394
+ candidateIds: ['cand-1'],
395
+ ledgerEntryIds: ['ledger-1'],
396
+ autoIntakeEnabled: true,
397
+ });
398
+ expect(freshSuccess.admissionResults).toBeDefined();
399
+ expect(existingSuccess.admissionResults).toBeUndefined();
400
+ });
401
+ });
402
+ //# sourceMappingURL=bridge-result-shaper.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-result-shaper.test.js","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/bridge-result-shaper.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Pruning Mask Tests — Core Package
3
+ *
4
+ * Direct unit tests for the pruning mask module:
5
+ * - buildMaskedPrincipleSet() — pure LWW (Last Write Wins) function
6
+ * - getCachedMaskedPrincipleSet() — TTL-cached wrapper
7
+ * - clearPruningMaskCache() — cache invalidation
8
+ *
9
+ * Tests verify:
10
+ * - Empty/null input → empty set
11
+ * - Single review → correct masking
12
+ * - Multiple reviews for same principle → LWW semantics
13
+ * - Corrupt records → skipped silently
14
+ * - Archive-candidate → masked; keep/defer → not masked
15
+ * - TTL cache: returns cached value within TTL, re-reads after expiry
16
+ * - Cache keyed by workspaceDir
17
+ * - clearPruningMaskCache resets cache state
18
+ *
19
+ * ERR checklist:
20
+ * - ERR-002 / EP-03: corrupt records skipped (fail-safe)
21
+ * - ERR-007 / EP-02: single source for LWW decision
22
+ * - EP-07: cache keyed by workspaceDir prevents cross-workspace leakage
23
+ */
24
+ export {};
25
+ //# sourceMappingURL=pruning-mask.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pruning-mask.test.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/pruning-mask.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG"}
@@ -0,0 +1,281 @@
1
+ /**
2
+ * Pruning Mask Tests — Core Package
3
+ *
4
+ * Direct unit tests for the pruning mask module:
5
+ * - buildMaskedPrincipleSet() — pure LWW (Last Write Wins) function
6
+ * - getCachedMaskedPrincipleSet() — TTL-cached wrapper
7
+ * - clearPruningMaskCache() — cache invalidation
8
+ *
9
+ * Tests verify:
10
+ * - Empty/null input → empty set
11
+ * - Single review → correct masking
12
+ * - Multiple reviews for same principle → LWW semantics
13
+ * - Corrupt records → skipped silently
14
+ * - Archive-candidate → masked; keep/defer → not masked
15
+ * - TTL cache: returns cached value within TTL, re-reads after expiry
16
+ * - Cache keyed by workspaceDir
17
+ * - clearPruningMaskCache resets cache state
18
+ *
19
+ * ERR checklist:
20
+ * - ERR-002 / EP-03: corrupt records skipped (fail-safe)
21
+ * - ERR-007 / EP-02: single source for LWW decision
22
+ * - EP-07: cache keyed by workspaceDir prevents cross-workspace leakage
23
+ */
24
+ /* eslint-disable @typescript-eslint/max-params */
25
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
26
+ import * as fs from 'fs';
27
+ import * as path from 'path';
28
+ import * as os from 'os';
29
+ import { buildMaskedPrincipleSet, getCachedMaskedPrincipleSet, clearPruningMaskCache, } from '../pruning-mask.js';
30
+ function makeReview(principleId, decision, reviewedAt, overrides = {}) {
31
+ return {
32
+ reviewId: `review-${principleId}-${Date.now()}`,
33
+ principleId,
34
+ decision,
35
+ note: 'test note',
36
+ reviewer: 'test-reviewer',
37
+ reviewedAt,
38
+ signalSnapshot: {
39
+ principleId,
40
+ status: 'active',
41
+ createdAt: reviewedAt,
42
+ updatedAt: reviewedAt,
43
+ derivedCandidateIds: [],
44
+ derivedPainCount: 0,
45
+ matchedCandidateCount: 0,
46
+ recentCandidateCount: 0,
47
+ orphanCandidateCount: 0,
48
+ ageDays: 1,
49
+ riskLevel: 'watch',
50
+ reasons: [],
51
+ },
52
+ ...overrides,
53
+ };
54
+ }
55
+ describe('buildMaskedPrincipleSet', () => {
56
+ it('returns empty set for null input', () => {
57
+ const result = buildMaskedPrincipleSet(null);
58
+ expect(result.size).toBe(0);
59
+ });
60
+ it('returns empty set for empty array', () => {
61
+ const result = buildMaskedPrincipleSet([]);
62
+ expect(result.size).toBe(0);
63
+ });
64
+ it('masks principles with archive-candidate decision', () => {
65
+ const reviews = [
66
+ makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z'),
67
+ makeReview('p2', 'keep', '2026-07-01T00:00:00.000Z'),
68
+ makeReview('p3', 'defer', '2026-07-01T00:00:00.000Z'),
69
+ ];
70
+ const result = buildMaskedPrincipleSet(reviews);
71
+ expect(result.size).toBe(1);
72
+ expect(result.has('p1')).toBe(true);
73
+ expect(result.has('p2')).toBe(false);
74
+ expect(result.has('p3')).toBe(false);
75
+ });
76
+ it('applies LWW semantics: later review overrides earlier one', () => {
77
+ const reviews = [
78
+ makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z'),
79
+ makeReview('p1', 'keep', '2026-07-02T00:00:00.000Z'),
80
+ ];
81
+ const result = buildMaskedPrincipleSet(reviews);
82
+ expect(result.size).toBe(0);
83
+ expect(result.has('p1')).toBe(false);
84
+ });
85
+ it('applies LWW semantics: later archive-candidate overrides earlier keep', () => {
86
+ const reviews = [
87
+ makeReview('p1', 'keep', '2026-07-01T00:00:00.000Z'),
88
+ makeReview('p1', 'archive-candidate', '2026-07-02T00:00:00.000Z'),
89
+ ];
90
+ const result = buildMaskedPrincipleSet(reviews);
91
+ expect(result.size).toBe(1);
92
+ expect(result.has('p1')).toBe(true);
93
+ });
94
+ it('handles same timestamp: later array entry wins (stable ordering)', () => {
95
+ const reviews = [
96
+ makeReview('p1', 'keep', '2026-07-01T00:00:00.000Z'),
97
+ makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z'),
98
+ ];
99
+ const result = buildMaskedPrincipleSet(reviews);
100
+ expect(result.has('p1')).toBe(true);
101
+ });
102
+ it('skips corrupt records with missing principleId', () => {
103
+ const reviews = [
104
+ makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z'),
105
+ { ...makeReview('p2', 'archive-candidate', '2026-07-01T00:00:00.000Z'), principleId: '' },
106
+ { ...makeReview('p3', 'archive-candidate', '2026-07-01T00:00:00.000Z'), principleId: undefined },
107
+ ];
108
+ const result = buildMaskedPrincipleSet(reviews);
109
+ expect(result.size).toBe(1);
110
+ expect(result.has('p1')).toBe(true);
111
+ });
112
+ it('skips corrupt records with missing decision', () => {
113
+ const reviews = [
114
+ makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z'),
115
+ { ...makeReview('p2', 'archive-candidate', '2026-07-01T00:00:00.000Z'), decision: '' },
116
+ { ...makeReview('p3', 'archive-candidate', '2026-07-01T00:00:00.000Z'), decision: undefined },
117
+ ];
118
+ const result = buildMaskedPrincipleSet(reviews);
119
+ expect(result.size).toBe(1);
120
+ expect(result.has('p1')).toBe(true);
121
+ });
122
+ it('skips corrupt records with missing reviewedAt', () => {
123
+ const reviews = [
124
+ makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z'),
125
+ { ...makeReview('p2', 'archive-candidate', '2026-07-01T00:00:00.000Z'), reviewedAt: '' },
126
+ { ...makeReview('p3', 'archive-candidate', '2026-07-01T00:00:00.000Z'), reviewedAt: undefined },
127
+ ];
128
+ const result = buildMaskedPrincipleSet(reviews);
129
+ expect(result.size).toBe(1);
130
+ expect(result.has('p1')).toBe(true);
131
+ });
132
+ it('skips null/undefined entries in the array', () => {
133
+ const reviews = [
134
+ makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z'),
135
+ null,
136
+ undefined,
137
+ ];
138
+ const result = buildMaskedPrincipleSet(reviews);
139
+ expect(result.size).toBe(1);
140
+ expect(result.has('p1')).toBe(true);
141
+ });
142
+ it('handles multiple principles with mixed decisions', () => {
143
+ const reviews = [
144
+ makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z'),
145
+ makeReview('p2', 'keep', '2026-07-01T00:00:00.000Z'),
146
+ makeReview('p3', 'defer', '2026-07-01T00:00:00.000Z'),
147
+ makeReview('p4', 'archive-candidate', '2026-07-01T00:00:00.000Z'),
148
+ makeReview('p2', 'archive-candidate', '2026-07-02T00:00:00.000Z'),
149
+ makeReview('p4', 'keep', '2026-07-03T00:00:00.000Z'),
150
+ ];
151
+ const result = buildMaskedPrincipleSet(reviews);
152
+ expect(result.size).toBe(2);
153
+ expect(result.has('p1')).toBe(true);
154
+ expect(result.has('p2')).toBe(true);
155
+ expect(result.has('p3')).toBe(false);
156
+ expect(result.has('p4')).toBe(false);
157
+ });
158
+ it('returns a new Set instance each call (no shared mutable state)', () => {
159
+ const reviews = [makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z')];
160
+ const result1 = buildMaskedPrincipleSet(reviews);
161
+ const result2 = buildMaskedPrincipleSet(reviews);
162
+ expect(result1).not.toBe(result2);
163
+ result1.add('p999');
164
+ expect(result2.has('p999')).toBe(false);
165
+ });
166
+ });
167
+ describe('getCachedMaskedPrincipleSet', () => {
168
+ let tmpDir;
169
+ let stateDir;
170
+ let logPath;
171
+ beforeEach(() => {
172
+ clearPruningMaskCache();
173
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-pruning-mask-test-'));
174
+ stateDir = path.join(tmpDir, '.state');
175
+ fs.mkdirSync(stateDir, { recursive: true });
176
+ logPath = path.join(stateDir, 'pruning_reviews.jsonl');
177
+ });
178
+ afterEach(() => {
179
+ fs.rmSync(tmpDir, { recursive: true, force: true });
180
+ });
181
+ function writeReviews(reviews) {
182
+ const lines = reviews.map(r => JSON.stringify(r));
183
+ fs.writeFileSync(logPath, lines.join('\n') + '\n', 'utf-8');
184
+ }
185
+ it('reads from file and returns correct mask on first call', () => {
186
+ const reviews = [
187
+ makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z'),
188
+ makeReview('p2', 'keep', '2026-07-01T00:00:00.000Z'),
189
+ ];
190
+ writeReviews(reviews);
191
+ const result = getCachedMaskedPrincipleSet(tmpDir);
192
+ expect(result.size).toBe(1);
193
+ expect(result.has('p1')).toBe(true);
194
+ expect(result.has('p2')).toBe(false);
195
+ });
196
+ it('returns cached value within TTL (no re-read)', () => {
197
+ const reviews = [makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z')];
198
+ writeReviews(reviews);
199
+ const result1 = getCachedMaskedPrincipleSet(tmpDir, 60_000);
200
+ const updatedReviews = [makeReview('p1', 'keep', '2026-07-02T00:00:00.000Z')];
201
+ writeReviews(updatedReviews);
202
+ const result2 = getCachedMaskedPrincipleSet(tmpDir, 60_000);
203
+ expect(result2.has('p1')).toBe(true);
204
+ expect(result2).toBe(result1);
205
+ });
206
+ it('re-reads after TTL expires', () => {
207
+ vi.useFakeTimers();
208
+ const reviews = [makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z')];
209
+ writeReviews(reviews);
210
+ const result1 = getCachedMaskedPrincipleSet(tmpDir, 1000);
211
+ expect(result1.has('p1')).toBe(true);
212
+ const updatedReviews = [makeReview('p1', 'keep', '2026-07-02T00:00:00.000Z')];
213
+ writeReviews(updatedReviews);
214
+ vi.advanceTimersByTime(500);
215
+ const result2 = getCachedMaskedPrincipleSet(tmpDir, 1000);
216
+ expect(result2.has('p1')).toBe(true);
217
+ vi.advanceTimersByTime(600);
218
+ const result3 = getCachedMaskedPrincipleSet(tmpDir, 1000);
219
+ expect(result3.has('p1')).toBe(false);
220
+ vi.useRealTimers();
221
+ });
222
+ it('cache is keyed by workspaceDir', () => {
223
+ const otherDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-pruning-mask-other-'));
224
+ const otherStateDir = path.join(otherDir, '.state');
225
+ fs.mkdirSync(otherStateDir, { recursive: true });
226
+ const otherLogPath = path.join(otherStateDir, 'pruning_reviews.jsonl');
227
+ try {
228
+ const reviews1 = [makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z')];
229
+ writeReviews(reviews1);
230
+ const reviews2 = [makeReview('p1', 'keep', '2026-07-01T00:00:00.000Z')];
231
+ fs.writeFileSync(otherLogPath, reviews2.map(r => JSON.stringify(r)).join('\n') + '\n', 'utf-8');
232
+ const result1 = getCachedMaskedPrincipleSet(tmpDir);
233
+ const result2 = getCachedMaskedPrincipleSet(otherDir);
234
+ expect(result1.has('p1')).toBe(true);
235
+ expect(result2.has('p1')).toBe(false);
236
+ }
237
+ finally {
238
+ fs.rmSync(otherDir, { recursive: true, force: true });
239
+ }
240
+ });
241
+ it('returns empty set when no pruning_reviews.jsonl exists', () => {
242
+ fs.rmSync(logPath, { force: true });
243
+ const result = getCachedMaskedPrincipleSet(tmpDir);
244
+ expect(result.size).toBe(0);
245
+ });
246
+ });
247
+ describe('clearPruningMaskCache', () => {
248
+ let tmpDir;
249
+ let stateDir;
250
+ let logPath;
251
+ beforeEach(() => {
252
+ clearPruningMaskCache();
253
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-pruning-mask-clear-'));
254
+ stateDir = path.join(tmpDir, '.state');
255
+ fs.mkdirSync(stateDir, { recursive: true });
256
+ logPath = path.join(stateDir, 'pruning_reviews.jsonl');
257
+ });
258
+ afterEach(() => {
259
+ fs.rmSync(tmpDir, { recursive: true, force: true });
260
+ });
261
+ function writeReviews(reviews) {
262
+ const lines = reviews.map(r => JSON.stringify(r));
263
+ fs.writeFileSync(logPath, lines.join('\n') + '\n', 'utf-8');
264
+ }
265
+ it('clears cache so next call re-reads from disk', () => {
266
+ const reviews = [makeReview('p1', 'archive-candidate', '2026-07-01T00:00:00.000Z')];
267
+ writeReviews(reviews);
268
+ const result1 = getCachedMaskedPrincipleSet(tmpDir);
269
+ expect(result1.has('p1')).toBe(true);
270
+ const updatedReviews = [makeReview('p1', 'keep', '2026-07-02T00:00:00.000Z')];
271
+ writeReviews(updatedReviews);
272
+ clearPruningMaskCache();
273
+ const result2 = getCachedMaskedPrincipleSet(tmpDir);
274
+ expect(result2.has('p1')).toBe(false);
275
+ });
276
+ it('is safe to call when cache is already empty', () => {
277
+ expect(() => clearPruningMaskCache()).not.toThrow();
278
+ expect(() => clearPruningMaskCache()).not.toThrow();
279
+ });
280
+ });
281
+ //# sourceMappingURL=pruning-mask.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pruning-mask.test.js","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/pruning-mask.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * WorkflowFunnelLoader Tests — Core Package
3
+ *
4
+ * Direct unit tests for the WorkflowFunnelLoader class.
5
+ *
6
+ * Tests verify:
7
+ * - Constructor loads workflows.yaml from stateDir
8
+ * - Missing file → empty funnels + warning
9
+ * - Malformed YAML → preserves last known-good config + warning
10
+ * - Invalid schema (missing version/funnels) → preserves last known-good + warning
11
+ * - Invalid funnel entries (missing workflowId/stages) → skipped + warning
12
+ * - getStages returns correct stages for known workflow
13
+ * - getStages returns empty array for unknown workflow
14
+ * - getFunnel returns full funnel with policy for known workflow
15
+ * - getFunnel returns undefined for unknown workflow
16
+ * - getFunnel returns deep clone (mutations don't affect internal state)
17
+ * - getAllFunnels returns deep clone of all stages
18
+ * - getAllFunnelsWithPolicy returns deep clone of all funnels
19
+ * - watch() starts file watching, dispose() cleans up
20
+ * - getWarnings returns warnings from last load
21
+ * - getConfigPath returns correct path
22
+ *
23
+ * ERR checklist:
24
+ * - ERR-002 / EP-03: malformed YAML preserves last known-good (fail-safe)
25
+ * - ERR-007 / EP-02: single source for funnels table
26
+ * - EP-07: deep clones prevent consumer mutation of internal state
27
+ */
28
+ export {};
29
+ //# sourceMappingURL=workflow-funnel-loader.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-funnel-loader.test.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/workflow-funnel-loader.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG"}
@@ -0,0 +1,431 @@
1
+ /**
2
+ * WorkflowFunnelLoader Tests — Core Package
3
+ *
4
+ * Direct unit tests for the WorkflowFunnelLoader class.
5
+ *
6
+ * Tests verify:
7
+ * - Constructor loads workflows.yaml from stateDir
8
+ * - Missing file → empty funnels + warning
9
+ * - Malformed YAML → preserves last known-good config + warning
10
+ * - Invalid schema (missing version/funnels) → preserves last known-good + warning
11
+ * - Invalid funnel entries (missing workflowId/stages) → skipped + warning
12
+ * - getStages returns correct stages for known workflow
13
+ * - getStages returns empty array for unknown workflow
14
+ * - getFunnel returns full funnel with policy for known workflow
15
+ * - getFunnel returns undefined for unknown workflow
16
+ * - getFunnel returns deep clone (mutations don't affect internal state)
17
+ * - getAllFunnels returns deep clone of all stages
18
+ * - getAllFunnelsWithPolicy returns deep clone of all funnels
19
+ * - watch() starts file watching, dispose() cleans up
20
+ * - getWarnings returns warnings from last load
21
+ * - getConfigPath returns correct path
22
+ *
23
+ * ERR checklist:
24
+ * - ERR-002 / EP-03: malformed YAML preserves last known-good (fail-safe)
25
+ * - ERR-007 / EP-02: single source for funnels table
26
+ * - EP-07: deep clones prevent consumer mutation of internal state
27
+ */
28
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
29
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
30
+ import * as fs from 'fs';
31
+ import * as path from 'path';
32
+ import * as os from 'os';
33
+ import * as yamlLib from 'js-yaml';
34
+ import { WorkflowFunnelLoader } from '../../workflow-funnel-loader.js';
35
+ describe('WorkflowFunnelLoader', () => {
36
+ let tmpDir;
37
+ let stateDir;
38
+ let configPath;
39
+ beforeEach(() => {
40
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-workflow-loader-test-'));
41
+ stateDir = path.join(tmpDir, '.state');
42
+ fs.mkdirSync(stateDir, { recursive: true });
43
+ configPath = path.join(stateDir, 'workflows.yaml');
44
+ });
45
+ afterEach(() => {
46
+ fs.rmSync(tmpDir, { recursive: true, force: true });
47
+ });
48
+ function writeConfig(config) {
49
+ const yamlStr = yamlLib.dump(config, { schema: yamlLib.DEFAULT_SCHEMA });
50
+ fs.writeFileSync(configPath, yamlStr, 'utf-8');
51
+ }
52
+ describe('constructor and initial load', () => {
53
+ it('loads valid workflows.yaml on construction', () => {
54
+ writeConfig({
55
+ version: '1.0',
56
+ funnels: [
57
+ {
58
+ workflowId: 'test-funnel',
59
+ stages: [
60
+ { name: 'stage1', eventType: 'created', eventCategory: 'created', statsField: 'test.created' },
61
+ { name: 'stage2', eventType: 'completed', eventCategory: 'completed', statsField: 'test.completed' },
62
+ ],
63
+ },
64
+ ],
65
+ });
66
+ const loader = new WorkflowFunnelLoader(stateDir);
67
+ const stages = loader.getStages('test-funnel');
68
+ expect(stages.length).toBe(2);
69
+ expect(stages[0].name).toBe('stage1');
70
+ expect(stages[1].name).toBe('stage2');
71
+ });
72
+ it('handles missing workflows.yaml with empty funnels + warning', () => {
73
+ fs.rmSync(configPath, { force: true });
74
+ const loader = new WorkflowFunnelLoader(stateDir);
75
+ expect(loader.getStages('any-workflow')).toEqual([]);
76
+ expect(loader.getAllFunnels().size).toBe(0);
77
+ const warnings = loader.getWarnings();
78
+ expect(warnings.length).toBeGreaterThan(0);
79
+ expect(warnings[0]).toContain('not found');
80
+ });
81
+ it('handles malformed YAML with empty funnels + warning', () => {
82
+ fs.writeFileSync(configPath, 'not: valid: yaml: [broken', 'utf-8');
83
+ const loader = new WorkflowFunnelLoader(stateDir);
84
+ expect(loader.getAllFunnels().size).toBe(0);
85
+ const warnings = loader.getWarnings();
86
+ expect(warnings.length).toBeGreaterThan(0);
87
+ expect(warnings[0]).toContain('Failed to parse');
88
+ });
89
+ it('handles missing version field with warning', () => {
90
+ fs.writeFileSync(configPath, 'funnels:\n - workflowId: test\n stages: []\n', 'utf-8');
91
+ const loader = new WorkflowFunnelLoader(stateDir);
92
+ expect(loader.getAllFunnels().size).toBe(0);
93
+ const warnings = loader.getWarnings();
94
+ expect(warnings.some(w => w.includes('validation failed'))).toBe(true);
95
+ });
96
+ it('handles missing funnels array with warning', () => {
97
+ fs.writeFileSync(configPath, 'version: "1.0"\n', 'utf-8');
98
+ const loader = new WorkflowFunnelLoader(stateDir);
99
+ expect(loader.getAllFunnels().size).toBe(0);
100
+ const warnings = loader.getWarnings();
101
+ expect(warnings.some(w => w.includes('validation failed'))).toBe(true);
102
+ });
103
+ });
104
+ describe('getStages', () => {
105
+ it('returns empty array for unknown workflow', () => {
106
+ writeConfig({
107
+ version: '1.0',
108
+ funnels: [
109
+ {
110
+ workflowId: 'known-funnel',
111
+ stages: [{ name: 's1', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' }],
112
+ },
113
+ ],
114
+ });
115
+ const loader = new WorkflowFunnelLoader(stateDir);
116
+ expect(loader.getStages('unknown-funnel')).toEqual([]);
117
+ });
118
+ it('returns stages in order for known workflow', () => {
119
+ writeConfig({
120
+ version: '1.0',
121
+ funnels: [
122
+ {
123
+ workflowId: 'ordered-funnel',
124
+ stages: [
125
+ { name: 'first', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' },
126
+ { name: 'second', eventType: 'e2', eventCategory: 'c2', statsField: 'f2' },
127
+ { name: 'third', eventType: 'e3', eventCategory: 'c3', statsField: 'f3' },
128
+ ],
129
+ },
130
+ ],
131
+ });
132
+ const loader = new WorkflowFunnelLoader(stateDir);
133
+ const stages = loader.getStages('ordered-funnel');
134
+ expect(stages.map(s => s.name)).toEqual(['first', 'second', 'third']);
135
+ });
136
+ });
137
+ describe('getFunnel', () => {
138
+ it('returns undefined for unknown workflow', () => {
139
+ writeConfig({
140
+ version: '1.0',
141
+ funnels: [],
142
+ });
143
+ const loader = new WorkflowFunnelLoader(stateDir);
144
+ expect(loader.getFunnel('nonexistent')).toBeUndefined();
145
+ });
146
+ it('returns full funnel with policy for known workflow', () => {
147
+ writeConfig({
148
+ version: '1.0',
149
+ funnels: [
150
+ {
151
+ workflowId: 'policy-funnel',
152
+ stages: [{ name: 's1', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' }],
153
+ policy: {
154
+ timeoutMs: 30000,
155
+ stageOrder: 'strict',
156
+ runtimeKind: 'pi-ai',
157
+ },
158
+ },
159
+ ],
160
+ });
161
+ const loader = new WorkflowFunnelLoader(stateDir);
162
+ const funnel = loader.getFunnel('policy-funnel');
163
+ expect(funnel).toBeDefined();
164
+ expect(funnel?.workflowId).toBe('policy-funnel');
165
+ expect(funnel?.stages.length).toBe(1);
166
+ expect(funnel?.policy?.timeoutMs).toBe(30000);
167
+ expect(funnel?.policy?.stageOrder).toBe('strict');
168
+ });
169
+ it('returns deep clone — mutations do not affect internal state', () => {
170
+ writeConfig({
171
+ version: '1.0',
172
+ funnels: [
173
+ {
174
+ workflowId: 'clone-test',
175
+ stages: [{ name: 'original', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' }],
176
+ policy: { timeoutMs: 1000 },
177
+ },
178
+ ],
179
+ });
180
+ const loader = new WorkflowFunnelLoader(stateDir);
181
+ const funnel1 = loader.getFunnel('clone-test');
182
+ funnel1.stages[0].name = 'mutated';
183
+ funnel1.policy.timeoutMs = 99999;
184
+ const funnel2 = loader.getFunnel('clone-test');
185
+ expect(funnel2.stages[0].name).toBe('original');
186
+ expect(funnel2.policy?.timeoutMs).toBe(1000);
187
+ });
188
+ });
189
+ describe('getAllFunnels', () => {
190
+ it('returns all funnels as a Map', () => {
191
+ writeConfig({
192
+ version: '1.0',
193
+ funnels: [
194
+ {
195
+ workflowId: 'funnel-a',
196
+ stages: [{ name: 's1', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' }],
197
+ },
198
+ {
199
+ workflowId: 'funnel-b',
200
+ stages: [
201
+ { name: 's2', eventType: 'e2', eventCategory: 'c2', statsField: 'f2' },
202
+ { name: 's3', eventType: 'e3', eventCategory: 'c3', statsField: 'f3' },
203
+ ],
204
+ },
205
+ ],
206
+ });
207
+ const loader = new WorkflowFunnelLoader(stateDir);
208
+ const all = loader.getAllFunnels();
209
+ expect(all.size).toBe(2);
210
+ expect(all.get('funnel-a')?.length).toBe(1);
211
+ expect(all.get('funnel-b')?.length).toBe(2);
212
+ });
213
+ it('returns deep clone — mutations do not affect internal state', () => {
214
+ writeConfig({
215
+ version: '1.0',
216
+ funnels: [
217
+ {
218
+ workflowId: 'mutate-test',
219
+ stages: [{ name: 'original', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' }],
220
+ },
221
+ ],
222
+ });
223
+ const loader = new WorkflowFunnelLoader(stateDir);
224
+ const all1 = loader.getAllFunnels();
225
+ all1.get('mutate-test')[0].name = 'mutated';
226
+ const all2 = loader.getAllFunnels();
227
+ expect(all2.get('mutate-test')[0].name).toBe('original');
228
+ });
229
+ });
230
+ describe('getAllFunnelsWithPolicy', () => {
231
+ it('returns all funnels with policy as a Map', () => {
232
+ writeConfig({
233
+ version: '1.0',
234
+ funnels: [
235
+ {
236
+ workflowId: 'funnel-x',
237
+ stages: [{ name: 's1', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' }],
238
+ policy: { timeoutMs: 5000 },
239
+ },
240
+ ],
241
+ });
242
+ const loader = new WorkflowFunnelLoader(stateDir);
243
+ const all = loader.getAllFunnelsWithPolicy();
244
+ expect(all.size).toBe(1);
245
+ const funnel = all.get('funnel-x');
246
+ expect(funnel.workflowId).toBe('funnel-x');
247
+ expect(funnel.policy?.timeoutMs).toBe(5000);
248
+ });
249
+ it('returns deep clone — policy mutations do not affect internal state', () => {
250
+ writeConfig({
251
+ version: '1.0',
252
+ funnels: [
253
+ {
254
+ workflowId: 'policy-clone',
255
+ stages: [{ name: 's1', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' }],
256
+ policy: {
257
+ timeoutMs: 1000,
258
+ observability: {
259
+ enabled: true,
260
+ emitEvents: ['event1', 'event2'],
261
+ },
262
+ },
263
+ },
264
+ ],
265
+ });
266
+ const loader = new WorkflowFunnelLoader(stateDir);
267
+ const all1 = loader.getAllFunnelsWithPolicy();
268
+ const funnel1 = all1.get('policy-clone');
269
+ funnel1.policy.timeoutMs = 99999;
270
+ funnel1.policy.observability.emitEvents.push('malicious');
271
+ const all2 = loader.getAllFunnelsWithPolicy();
272
+ const funnel2 = all2.get('policy-clone');
273
+ expect(funnel2.policy?.timeoutMs).toBe(1000);
274
+ expect(funnel2.policy?.observability?.emitEvents).toEqual(['event1', 'event2']);
275
+ });
276
+ });
277
+ describe('load() reload', () => {
278
+ it('reloads from disk on explicit load() call', () => {
279
+ writeConfig({
280
+ version: '1.0',
281
+ funnels: [
282
+ {
283
+ workflowId: 'reload-test',
284
+ stages: [{ name: 'v1', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' }],
285
+ },
286
+ ],
287
+ });
288
+ const loader = new WorkflowFunnelLoader(stateDir);
289
+ expect(loader.getStages('reload-test')[0].name).toBe('v1');
290
+ writeConfig({
291
+ version: '1.0',
292
+ funnels: [
293
+ {
294
+ workflowId: 'reload-test',
295
+ stages: [{ name: 'v2', eventType: 'e2', eventCategory: 'c2', statsField: 'f2' }],
296
+ },
297
+ ],
298
+ });
299
+ loader.load();
300
+ expect(loader.getStages('reload-test')[0].name).toBe('v2');
301
+ });
302
+ it('preserves last known-good config on malformed reload', () => {
303
+ writeConfig({
304
+ version: '1.0',
305
+ funnels: [
306
+ {
307
+ workflowId: 'stable-funnel',
308
+ stages: [{ name: 'good', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' }],
309
+ },
310
+ ],
311
+ });
312
+ const loader = new WorkflowFunnelLoader(stateDir);
313
+ expect(loader.getStages('stable-funnel')[0].name).toBe('good');
314
+ fs.writeFileSync(configPath, '::: invalid yaml :::', 'utf-8');
315
+ loader.load();
316
+ expect(loader.getStages('stable-funnel')[0].name).toBe('good');
317
+ expect(loader.getWarnings().some(w => w.includes('Failed to parse'))).toBe(true);
318
+ });
319
+ it('clears funnels when file is deleted and reloaded', () => {
320
+ writeConfig({
321
+ version: '1.0',
322
+ funnels: [
323
+ {
324
+ workflowId: 'will-disappear',
325
+ stages: [{ name: 's1', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' }],
326
+ },
327
+ ],
328
+ });
329
+ const loader = new WorkflowFunnelLoader(stateDir);
330
+ expect(loader.getStages('will-disappear').length).toBe(1);
331
+ fs.rmSync(configPath);
332
+ loader.load();
333
+ expect(loader.getStages('will-disappear')).toEqual([]);
334
+ expect(loader.getAllFunnels().size).toBe(0);
335
+ });
336
+ });
337
+ describe('invalid funnel entries', () => {
338
+ it('skips funnels missing workflowId', () => {
339
+ const yamlContent = `version: "1.0"\nfunnels:\n - stages:\n - name: s1\n eventType: e1\n eventCategory: c1\n statsField: f1\n`;
340
+ fs.writeFileSync(configPath, yamlContent, 'utf-8');
341
+ const loader = new WorkflowFunnelLoader(stateDir);
342
+ expect(loader.getAllFunnels().size).toBe(0);
343
+ expect(loader.getWarnings().some(w => w.includes('Skipping invalid funnel'))).toBe(true);
344
+ });
345
+ it('skips funnels missing stages array', () => {
346
+ const yamlContent = `version: "1.0"\nfunnels:\n - workflowId: no-stages\n`;
347
+ fs.writeFileSync(configPath, yamlContent, 'utf-8');
348
+ const loader = new WorkflowFunnelLoader(stateDir);
349
+ expect(loader.getAllFunnels().size).toBe(0);
350
+ expect(loader.getWarnings().some(w => w.includes('Skipping invalid funnel'))).toBe(true);
351
+ });
352
+ it('keeps valid funnels when some are invalid', () => {
353
+ const yamlContent = `version: "1.0"\nfunnels:\n - workflowId: valid-1\n stages:\n - name: s1\n eventType: e1\n eventCategory: c1\n statsField: f1\n - workflowId: valid-2\n stages:\n - name: s2\n eventType: e2\n eventCategory: c2\n statsField: f2\n - stages: []\n`;
354
+ fs.writeFileSync(configPath, yamlContent, 'utf-8');
355
+ const loader = new WorkflowFunnelLoader(stateDir);
356
+ expect(loader.getAllFunnels().size).toBe(2);
357
+ expect(loader.getStages('valid-1').length).toBe(1);
358
+ expect(loader.getStages('valid-2').length).toBe(1);
359
+ });
360
+ });
361
+ describe('getWarnings', () => {
362
+ it('returns empty array for successful load', () => {
363
+ writeConfig({
364
+ version: '1.0',
365
+ funnels: [{
366
+ workflowId: 'clean',
367
+ stages: [{ name: 's1', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' }],
368
+ }],
369
+ });
370
+ const loader = new WorkflowFunnelLoader(stateDir);
371
+ const warnings = loader.getWarnings();
372
+ expect(Array.isArray(warnings)).toBe(true);
373
+ expect(warnings).toEqual([]);
374
+ });
375
+ it('warnings are cleared and refreshed on each load', () => {
376
+ fs.writeFileSync(configPath, 'bad yaml [[[', 'utf-8');
377
+ const loader = new WorkflowFunnelLoader(stateDir);
378
+ const firstWarnings = loader.getWarnings();
379
+ expect(firstWarnings.length).toBeGreaterThan(0);
380
+ writeConfig({
381
+ version: '1.0',
382
+ funnels: [{
383
+ workflowId: 'clean',
384
+ stages: [{ name: 's1', eventType: 'e1', eventCategory: 'c1', statsField: 'f1' }],
385
+ }],
386
+ });
387
+ loader.load();
388
+ const secondWarnings = loader.getWarnings();
389
+ expect(secondWarnings).toEqual([]);
390
+ });
391
+ });
392
+ describe('getConfigPath', () => {
393
+ it('returns the correct config path', () => {
394
+ const loader = new WorkflowFunnelLoader(stateDir);
395
+ expect(loader.getConfigPath()).toBe(configPath);
396
+ });
397
+ });
398
+ describe('watch and dispose', () => {
399
+ it('watch() does not throw when file does not exist', () => {
400
+ fs.rmSync(configPath, { force: true });
401
+ const loader = new WorkflowFunnelLoader(stateDir);
402
+ expect(() => loader.watch()).not.toThrow();
403
+ loader.dispose();
404
+ });
405
+ it('dispose() is safe to call multiple times', () => {
406
+ writeConfig({
407
+ version: '1.0',
408
+ funnels: [],
409
+ });
410
+ const loader = new WorkflowFunnelLoader(stateDir);
411
+ loader.watch();
412
+ expect(() => loader.dispose()).not.toThrow();
413
+ expect(() => loader.dispose()).not.toThrow();
414
+ });
415
+ });
416
+ describe('stage-level fields', () => {
417
+ it('preserves optional stage fields: timeoutMs, successCriteria, legacyDisabled', () => {
418
+ const yamlContent = `version: "1.0"\nfunnels:\n - workflowId: stage-fields\n stages:\n - name: full-stage\n eventType: ev1\n eventCategory: cat1\n statsField: stats.ev1\n timeoutMs: 5000\n successCriteria: "count > 0"\n legacyDisabled: true\n observability:\n enabled: true\n emitEvents:\n - stage_started\n`;
419
+ fs.writeFileSync(configPath, yamlContent, 'utf-8');
420
+ const loader = new WorkflowFunnelLoader(stateDir);
421
+ const stages = loader.getStages('stage-fields');
422
+ expect(stages.length).toBe(1);
423
+ expect(stages[0].timeoutMs).toBe(5000);
424
+ expect(stages[0].successCriteria).toBe('count > 0');
425
+ expect(stages[0].legacyDisabled).toBe(true);
426
+ expect(stages[0].observability?.enabled).toBe(true);
427
+ expect(stages[0].observability?.emitEvents).toEqual(['stage_started']);
428
+ });
429
+ });
430
+ });
431
+ //# sourceMappingURL=workflow-funnel-loader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-funnel-loader.test.js","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/workflow-funnel-loader.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principles/core",
3
- "version": "1.240.1",
3
+ "version": "1.240.3",
4
4
  "description": "Universal Evolution SDK - framework-agnostic pain signal capture and principle injection",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",