@principles/core 1.240.16 → 1.240.18

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,25 @@
1
+ /**
2
+ * Diagnostician Output Schema Tests — Core Package
3
+ *
4
+ * Direct TypeBox schema tests for DiagnosticianOutputV1 and its nested schemas.
5
+ *
6
+ * These tests pin the *schema contract* independently of the validator's
7
+ * additional semantic checks — they are the single source of truth for what
8
+ * the TypeBox layer accepts/rejects.
9
+ *
10
+ * Tests verify (PRI-518 / rc-9-no-silent-fallback focus):
11
+ * - DiagnosticianOutputV1Schema.recommendations requires minItems: 1 (the guard
12
+ * that closed the silent zero-candidate root cause).
13
+ * - Nested schemas (evidence, violatedPrinciples, recommendation kinds) are strict.
14
+ * - Confidence interval is closed [0, 1], not open.
15
+ * - Edge cases: empty strings at minLength: 1 boundaries, invalid kind values.
16
+ *
17
+ * ERR checklist:
18
+ * - ERR-088: assertions pin exact behavior, not just "valid/invalid" boolean —
19
+ * for instance, the minItems: 1 assertion reads the schema's minItems value
20
+ * from .properties to detect if someone loosened it to 0.
21
+ * - ERR-089: branch coverage for every schema field — valid AND at least one
22
+ * invalid path exercised.
23
+ */
24
+ export {};
25
+ //# sourceMappingURL=diagnostician-output-schema.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostician-output-schema.test.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/diagnostician-output-schema.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG"}
@@ -0,0 +1,405 @@
1
+ /**
2
+ * Diagnostician Output Schema Tests — Core Package
3
+ *
4
+ * Direct TypeBox schema tests for DiagnosticianOutputV1 and its nested schemas.
5
+ *
6
+ * These tests pin the *schema contract* independently of the validator's
7
+ * additional semantic checks — they are the single source of truth for what
8
+ * the TypeBox layer accepts/rejects.
9
+ *
10
+ * Tests verify (PRI-518 / rc-9-no-silent-fallback focus):
11
+ * - DiagnosticianOutputV1Schema.recommendations requires minItems: 1 (the guard
12
+ * that closed the silent zero-candidate root cause).
13
+ * - Nested schemas (evidence, violatedPrinciples, recommendation kinds) are strict.
14
+ * - Confidence interval is closed [0, 1], not open.
15
+ * - Edge cases: empty strings at minLength: 1 boundaries, invalid kind values.
16
+ *
17
+ * ERR checklist:
18
+ * - ERR-088: assertions pin exact behavior, not just "valid/invalid" boolean —
19
+ * for instance, the minItems: 1 assertion reads the schema's minItems value
20
+ * from .properties to detect if someone loosened it to 0.
21
+ * - ERR-089: branch coverage for every schema field — valid AND at least one
22
+ * invalid path exercised.
23
+ */
24
+ import { describe, it, expect } from 'vitest';
25
+ import { Value } from '@sinclair/typebox/value';
26
+ import { DiagnosticianViolatedPrincipleSchema, DiagnosticianEvidenceSchema, RecommendationKindSchema, DiagnosticianRecommendationSchema, DiagnosticianOutputV1Schema, DiagnosticianInvocationInputSchema, } from '../diagnostician-output.js';
27
+ // ── Minimal valid fixtures (shared, updated for PRI-518 minItems:1) ────────
28
+ function makeValidRecommendation(overrides = {}) {
29
+ return {
30
+ kind: 'defer',
31
+ description: 'No actionable principle identified — defer to next cycle.',
32
+ ...overrides,
33
+ };
34
+ }
35
+ function makeValidOutput(overrides = {}) {
36
+ return {
37
+ valid: true,
38
+ diagnosisId: 'diag-uuid-0001',
39
+ summary: 'Diagnosis summary of observed pain signal.',
40
+ rootCause: 'Assumption: workflow assumed X without validating data shape.',
41
+ violatedPrinciples: [],
42
+ evidence: [],
43
+ recommendations: [makeValidRecommendation()],
44
+ confidence: 0.85,
45
+ ...overrides,
46
+ };
47
+ }
48
+ // ── DiagnosticianViolatedPrincipleSchema ────────────────────────────────────
49
+ describe('DiagnosticianViolatedPrincipleSchema', () => {
50
+ it('accepts object with only required rationale (minLength:1)', () => {
51
+ const v = { rationale: 'Violated because X' };
52
+ expect(Value.Check(DiagnosticianViolatedPrincipleSchema, v)).toBe(true);
53
+ });
54
+ it('accepts all fields filled', () => {
55
+ const v = {
56
+ principleId: 'PRI-001',
57
+ title: 'Broken contract',
58
+ rationale: 'Violated because X',
59
+ };
60
+ expect(Value.Check(DiagnosticianViolatedPrincipleSchema, v)).toBe(true);
61
+ });
62
+ it('rejects empty rationale string (minLength:1)', () => {
63
+ const v = { rationale: '' };
64
+ expect(Value.Check(DiagnosticianViolatedPrincipleSchema, v)).toBe(false);
65
+ });
66
+ it('rejects whitespace-only rationale (minLength:1 does not trim)', () => {
67
+ // Note: TypeBox minLength operates on raw string length, not trimmed.
68
+ // So whitespace passes minLength:1 — this is a known schema gap, the
69
+ // validator's semantic checks handle trimmed empty in step 2 of default-validator.
70
+ const v = { rationale: ' ' };
71
+ expect(Value.Check(DiagnosticianViolatedPrincipleSchema, v)).toBe(true);
72
+ });
73
+ it('rejects missing rationale field (required)', () => {
74
+ const v = { principleId: 'PRI-001' };
75
+ expect(Value.Check(DiagnosticianViolatedPrincipleSchema, v)).toBe(false);
76
+ });
77
+ it('rejects non-string rationale', () => {
78
+ expect(Value.Check(DiagnosticianViolatedPrincipleSchema, { rationale: 42 })).toBe(false);
79
+ expect(Value.Check(DiagnosticianViolatedPrincipleSchema, { rationale: null })).toBe(false);
80
+ });
81
+ });
82
+ // ── DiagnosticianEvidenceSchema ─────────────────────────────────────────────
83
+ describe('DiagnosticianEvidenceSchema', () => {
84
+ it('accepts valid evidence with non-empty sourceRef and note', () => {
85
+ const v = { sourceRef: 'turn-3:tool-call', note: 'User reported error' };
86
+ expect(Value.Check(DiagnosticianEvidenceSchema, v)).toBe(true);
87
+ });
88
+ it('rejects empty sourceRef (minLength:1)', () => {
89
+ expect(Value.Check(DiagnosticianEvidenceSchema, { sourceRef: '', note: 'x' })).toBe(false);
90
+ });
91
+ it('rejects empty note (minLength:1)', () => {
92
+ expect(Value.Check(DiagnosticianEvidenceSchema, { sourceRef: 'x', note: '' })).toBe(false);
93
+ });
94
+ it('rejects missing sourceRef (required)', () => {
95
+ expect(Value.Check(DiagnosticianEvidenceSchema, { note: 'x' })).toBe(false);
96
+ });
97
+ it('rejects missing note (required)', () => {
98
+ expect(Value.Check(DiagnosticianEvidenceSchema, { sourceRef: 'x' })).toBe(false);
99
+ });
100
+ it('rejects non-object evidence', () => {
101
+ expect(Value.Check(DiagnosticianEvidenceSchema, null)).toBe(false);
102
+ expect(Value.Check(DiagnosticianEvidenceSchema, 'source:note')).toBe(false);
103
+ });
104
+ });
105
+ // ── RecommendationKindSchema ───────────────────────────────────────────────
106
+ describe('RecommendationKindSchema (union of 5 literals)', () => {
107
+ it('accepts all 5 valid kinds', () => {
108
+ const valid = ['principle', 'rule', 'implementation', 'prompt', 'defer'];
109
+ for (const k of valid) {
110
+ expect(Value.Check(RecommendationKindSchema, k)).toBe(true);
111
+ }
112
+ });
113
+ it('rejects near-miss strings (case-sensitive, typos)', () => {
114
+ const nearMisses = [
115
+ 'PRINCIPLE', 'Rule', 'IMPLEMENTATION', // case variants
116
+ 'princples', 'rul', 'deferr', // typos
117
+ 'suggest', 'skip', 'noop', 'none', // plausible but not in union
118
+ '', ' defer', 'defer ', // whitespace
119
+ ];
120
+ for (const k of nearMisses) {
121
+ expect(Value.Check(RecommendationKindSchema, k)).toBe(false);
122
+ }
123
+ });
124
+ it('rejects non-string kinds', () => {
125
+ expect(Value.Check(RecommendationKindSchema, 1)).toBe(false);
126
+ expect(Value.Check(RecommendationKindSchema, null)).toBe(false);
127
+ expect(Value.Check(RecommendationKindSchema, undefined)).toBe(false);
128
+ expect(Value.Check(RecommendationKindSchema, ['principle'])).toBe(false);
129
+ });
130
+ });
131
+ // ── DiagnosticianRecommendationSchema ───────────────────────────────────────
132
+ describe('DiagnosticianRecommendationSchema', () => {
133
+ it('accepts minimal defer recommendation (only required fields)', () => {
134
+ const r = makeValidRecommendation({ kind: 'defer', description: 'Defer' });
135
+ expect(Value.Check(DiagnosticianRecommendationSchema, r)).toBe(true);
136
+ });
137
+ it('accepts principle recommendation with abstractedPrinciple (required for kind principle? schema marks it Optional but semantic validator enforces it)', () => {
138
+ // Note: abstractedPrinciple is TypeBox Optional here; the semantic
139
+ // validator (default-validator step 2f) enforces it when kind==='principle'.
140
+ // This test pins that the schema alone is loose on the per-kind requirement.
141
+ const r1 = makeValidRecommendation({
142
+ kind: 'principle',
143
+ description: 'Principle-level insight.',
144
+ abstractedPrinciple: 'Handle tool failures gracefully to preserve trust.',
145
+ });
146
+ expect(Value.Check(DiagnosticianRecommendationSchema, r1)).toBe(true);
147
+ });
148
+ it('accepts rule recommendation with triggerPattern + action', () => {
149
+ const r = makeValidRecommendation({
150
+ kind: 'rule',
151
+ description: 'Block writes to /etc.',
152
+ triggerPattern: 'tool_name=write_file AND path starts with /etc',
153
+ action: 'block',
154
+ });
155
+ expect(Value.Check(DiagnosticianRecommendationSchema, r)).toBe(true);
156
+ });
157
+ it('rejects missing/invalid kind (required union)', () => {
158
+ const noKind = { description: 'x' };
159
+ expect(Value.Check(DiagnosticianRecommendationSchema, noKind)).toBe(false);
160
+ const badKind = { kind: 'suggest', description: 'x' };
161
+ expect(Value.Check(DiagnosticianRecommendationSchema, badKind)).toBe(false);
162
+ });
163
+ it('rejects empty description (minLength:1)', () => {
164
+ const r = makeValidRecommendation({ description: '' });
165
+ expect(Value.Check(DiagnosticianRecommendationSchema, r)).toBe(false);
166
+ });
167
+ it('rejects missing description (required)', () => {
168
+ const r = { kind: 'defer' };
169
+ expect(Value.Check(DiagnosticianRecommendationSchema, r)).toBe(false);
170
+ });
171
+ });
172
+ // ── DiagnosticianOutputV1Schema — PRIMARY FOCUS (PRI-518) ──────────────────
173
+ describe('DiagnosticianOutputV1Schema (PRI-518 — minItems:1 on recommendations)', () => {
174
+ // ── Schema-level assertion: minItems IS 1 (not 0, not undefined) ──────────
175
+ it('PIN: DiagnosticianOutputV1Schema.properties.recommendations has minItems === 1', () => {
176
+ // This is the PRI-518 root-cause guard at the schema level.
177
+ // ERR-088: read the schema's own property, not just behavior via Value.Check.
178
+ // If someone reverts minItems to 0, this test will fail — not just the
179
+ // downstream "empty array rejected" test (which could be fooled by other means).
180
+ const recProp = DiagnosticianOutputV1Schema.properties.recommendations;
181
+ expect(recProp).toBeDefined();
182
+ expect(typeof recProp.minItems).toBe('number');
183
+ expect(recProp.minItems).toBe(1);
184
+ });
185
+ it('PIN: recommendations array type is enforced (not unknown[] fallback)', () => {
186
+ // Sanity — the property has a type we can introspect.
187
+ const recs = DiagnosticianOutputV1Schema.properties.recommendations;
188
+ expect(recs?.kind ?? 'array').toBeTruthy();
189
+ });
190
+ // ── Accept paths ───────────────────────────────────────────────────────────
191
+ it('accepts a minimal valid output with 1 defer recommendation', () => {
192
+ const o = makeValidOutput();
193
+ expect(Value.Check(DiagnosticianOutputV1Schema, o)).toBe(true);
194
+ });
195
+ it('accepts output with 5 recommendations (many, valid kinds)', () => {
196
+ const o = makeValidOutput({
197
+ recommendations: [
198
+ makeValidRecommendation({ kind: 'principle', description: 'P', abstractedPrinciple: 'W' }),
199
+ makeValidRecommendation({ kind: 'rule', description: 'R', triggerPattern: 'p', action: 'b' }),
200
+ makeValidRecommendation({ kind: 'implementation', description: 'I' }),
201
+ makeValidRecommendation({ kind: 'prompt', description: 'P' }),
202
+ makeValidRecommendation({ kind: 'defer', description: 'D' }),
203
+ ],
204
+ });
205
+ expect(Value.Check(DiagnosticianOutputV1Schema, o)).toBe(true);
206
+ });
207
+ it('accepts confidence at exact lower boundary 0', () => {
208
+ const o = makeValidOutput({ confidence: 0 });
209
+ expect(Value.Check(DiagnosticianOutputV1Schema, o)).toBe(true);
210
+ });
211
+ it('accepts confidence at exact upper boundary 1', () => {
212
+ const o = makeValidOutput({ confidence: 1 });
213
+ expect(Value.Check(DiagnosticianOutputV1Schema, o)).toBe(true);
214
+ });
215
+ it('accepts valid:false — diagnosis can explicitly report invalid-with-reasons', () => {
216
+ const o = makeValidOutput({ valid: false });
217
+ expect(Value.Check(DiagnosticianOutputV1Schema, o)).toBe(true);
218
+ });
219
+ it('accepts filled evidence and violatedPrinciples arrays', () => {
220
+ const o = makeValidOutput({
221
+ violatedPrinciples: [
222
+ { principleId: 'PRI-001', rationale: 'Rationale here.' },
223
+ ],
224
+ evidence: [
225
+ { sourceRef: 'turn-1', note: 'User error report' },
226
+ { sourceRef: 'turn-2', note: 'Tool failure trace' },
227
+ ],
228
+ });
229
+ expect(Value.Check(DiagnosticianOutputV1Schema, o)).toBe(true);
230
+ });
231
+ it('accepts optional ambiguityNotes string array', () => {
232
+ const o = makeValidOutput({
233
+ ambiguityNotes: ['Not enough data on X', 'Y may be transient'],
234
+ });
235
+ expect(Value.Check(DiagnosticianOutputV1Schema, o)).toBe(true);
236
+ });
237
+ // ── Reject paths — PRI-518 root cause (silent zero-candidates) ────────────
238
+ it('REJECTS recommendations: [] — empty array (the PRI-518 silent zero-candidate root cause)', () => {
239
+ // This was the exact pattern that caused 4 pain records → 8 leased tasks → 0 candidates.
240
+ // Schema must reject it at the boundary; validator's semantic check is defense-in-depth.
241
+ const o = makeValidOutput({ recommendations: [] });
242
+ expect(Value.Check(DiagnosticianOutputV1Schema, o)).toBe(false);
243
+ });
244
+ it('REJECTS missing recommendations field (required + array with items)', () => {
245
+ const { recommendations: _omit, ...rest } = makeValidOutput();
246
+ expect(Value.Check(DiagnosticianOutputV1Schema, rest)).toBe(false);
247
+ });
248
+ // ── Reject paths — other required fields ───────────────────────────────────
249
+ it('rejects missing diagnosisId (required, minLength:1)', () => {
250
+ const { diagnosisId: _omit, ...rest } = makeValidOutput();
251
+ expect(Value.Check(DiagnosticianOutputV1Schema, rest)).toBe(false);
252
+ });
253
+ it('rejects empty diagnosisId (minLength:1)', () => {
254
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ diagnosisId: '' }))).toBe(false);
255
+ });
256
+ it('rejects missing summary (required, minLength:1)', () => {
257
+ const { summary: _omit, ...rest } = makeValidOutput();
258
+ expect(Value.Check(DiagnosticianOutputV1Schema, rest)).toBe(false);
259
+ });
260
+ it('rejects empty summary (minLength:1)', () => {
261
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ summary: '' }))).toBe(false);
262
+ });
263
+ it('rejects missing rootCause (required, minLength:1)', () => {
264
+ const { rootCause: _omit, ...rest } = makeValidOutput();
265
+ expect(Value.Check(DiagnosticianOutputV1Schema, rest)).toBe(false);
266
+ });
267
+ it('rejects empty rootCause (minLength:1)', () => {
268
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ rootCause: '' }))).toBe(false);
269
+ });
270
+ it('rejects missing valid boolean field (required)', () => {
271
+ const { valid: _omit, ...rest } = makeValidOutput();
272
+ expect(Value.Check(DiagnosticianOutputV1Schema, rest)).toBe(false);
273
+ });
274
+ it('rejects valid as non-boolean (string, number)', () => {
275
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ valid: 'true' }))).toBe(false);
276
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ valid: 1 }))).toBe(false);
277
+ });
278
+ // ── Reject paths — confidence outside [0,1] ────────────────────────────────
279
+ it('rejects confidence slightly below 0', () => {
280
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ confidence: -0.0001 }))).toBe(false);
281
+ });
282
+ it('rejects confidence slightly above 1', () => {
283
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ confidence: 1.0001 }))).toBe(false);
284
+ });
285
+ it('rejects confidence as NaN or Infinity (TypeBox minimum/maximum on number requires finite)', () => {
286
+ // Note: TypeBox number schema with minimum/maximum rejects NaN natively.
287
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ confidence: NaN }))).toBe(false);
288
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ confidence: Infinity }))).toBe(false);
289
+ });
290
+ it('rejects confidence as non-number (string/null)', () => {
291
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ confidence: 'high' }))).toBe(false);
292
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ confidence: null }))).toBe(false);
293
+ });
294
+ // ── Reject paths — non-object / malformed inputs ───────────────────────────
295
+ it('rejects null instead of output object', () => {
296
+ expect(Value.Check(DiagnosticianOutputV1Schema, null)).toBe(false);
297
+ });
298
+ it('rejects undefined instead of output object', () => {
299
+ expect(Value.Check(DiagnosticianOutputV1Schema, undefined)).toBe(false);
300
+ });
301
+ it('rejects string masquerading as output', () => {
302
+ expect(Value.Check(DiagnosticianOutputV1Schema, 'diagnostician-output-v1')).toBe(false);
303
+ });
304
+ it('rejects array instead of output object', () => {
305
+ expect(Value.Check(DiagnosticianOutputV1Schema, [makeValidOutput()])).toBe(false);
306
+ });
307
+ // ── Reject paths — recommendations is not an array ─────────────────────────
308
+ it('rejects recommendations set to a string (not iterable — guards against for...of throw)', () => {
309
+ // Related to default-validator's 2e-bis guard: for...of undefined would throw
310
+ // if the semantic guard missed. Schema rejects non-array at the boundary.
311
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ recommendations: 'not-an-array' })))
312
+ .toBe(false);
313
+ });
314
+ it('rejects recommendations set to null', () => {
315
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ recommendations: null })))
316
+ .toBe(false);
317
+ });
318
+ it('rejects recommendations set to an object (not array)', () => {
319
+ expect(Value.Check(DiagnosticianOutputV1Schema, makeValidOutput({ recommendations: { 0: makeValidRecommendation() } })))
320
+ .toBe(false);
321
+ });
322
+ // ── Reject paths — single invalid recommendation poisons the whole array ───
323
+ it('rejects a 2-item recommendations array when the 2nd item lacks description', () => {
324
+ // Array items are validated against the item schema — a single bad item
325
+ // should cause the whole output to fail schema check.
326
+ const o = makeValidOutput({
327
+ recommendations: [
328
+ makeValidRecommendation(),
329
+ { kind: 'defer' },
330
+ ],
331
+ });
332
+ expect(Value.Check(DiagnosticianOutputV1Schema, o)).toBe(false);
333
+ });
334
+ });
335
+ // ── DiagnosticianInvocationInputSchema ───────────────────────────────────────
336
+ describe('DiagnosticianInvocationInputSchema', () => {
337
+ it('accepts a valid invocation input', () => {
338
+ const input = {
339
+ agentId: 'diagnostician',
340
+ taskId: 'task-0001',
341
+ context: { /* opaque unknown — validated separately via DiagnosticianContextPayload */},
342
+ outputSchemaRef: 'diagnostician-output-v1',
343
+ timeoutMs: 60_000,
344
+ };
345
+ expect(Value.Check(DiagnosticianInvocationInputSchema, input)).toBe(true);
346
+ });
347
+ it('PIN: outputSchemaRef is the literal "diagnostician-output-v1" (not any string)', () => {
348
+ // Pin that the schema only accepts the exact literal, not v2 or other refs.
349
+ const outputRefProp = DiagnosticianInvocationInputSchema.properties.outputSchemaRef;
350
+ expect(outputRefProp?.const ?? outputRefProp?.anyOf?.[0]?.const).toBe('diagnostician-output-v1');
351
+ });
352
+ it('rejects wrong outputSchemaRef (schema drift detection)', () => {
353
+ const input = {
354
+ agentId: 'diagnostician',
355
+ taskId: 'task-0001',
356
+ context: {},
357
+ outputSchemaRef: 'diagnostician-output-v2', // bumped by mistake
358
+ timeoutMs: 60_000,
359
+ };
360
+ expect(Value.Check(DiagnosticianInvocationInputSchema, input)).toBe(false);
361
+ });
362
+ it('rejects negative timeoutMs (minimum: 0)', () => {
363
+ const input = {
364
+ agentId: 'diagnostician',
365
+ taskId: 'task-0001',
366
+ context: {},
367
+ outputSchemaRef: 'diagnostician-output-v1',
368
+ timeoutMs: -1,
369
+ };
370
+ expect(Value.Check(DiagnosticianInvocationInputSchema, input)).toBe(false);
371
+ });
372
+ it('accepts timeoutMs = 0 (fire-and-forget or no-wait is a valid contract)', () => {
373
+ const input = {
374
+ agentId: 'diagnostician',
375
+ taskId: 'task-0001',
376
+ context: {},
377
+ outputSchemaRef: 'diagnostician-output-v1',
378
+ timeoutMs: 0,
379
+ };
380
+ expect(Value.Check(DiagnosticianInvocationInputSchema, input)).toBe(true);
381
+ });
382
+ it('rejects empty agentId / taskId (minLength:1)', () => {
383
+ const base = {
384
+ context: {},
385
+ outputSchemaRef: 'diagnostician-output-v1',
386
+ timeoutMs: 1000,
387
+ };
388
+ expect(Value.Check(DiagnosticianInvocationInputSchema, { ...base, agentId: '', taskId: 't' })).toBe(false);
389
+ expect(Value.Check(DiagnosticianInvocationInputSchema, { ...base, agentId: 'a', taskId: '' })).toBe(false);
390
+ });
391
+ });
392
+ // ── ERR-088 defense-in-depth: schema ↔ validator agreement on recommendations ─
393
+ describe('cross-contract: schema minItems agrees with semantic checks', () => {
394
+ it('schema rejects empty recommendations AND Validator step 2e-bis would also reject', () => {
395
+ // This test does NOT import the validator (keeps this test independent of
396
+ // runtime-v2/runner module graph). Instead it documents the defense-in-depth
397
+ // agreement: both layers MUST reject. We verify schema's behavior here, and
398
+ // the validator's own test file (default-validator.test.ts) asserts the
399
+ // semantic check. When both fail green, the two layers agree.
400
+ const empty = makeValidOutput({ recommendations: [] });
401
+ const schemaRejects = !Value.Check(DiagnosticianOutputV1Schema, empty);
402
+ expect(schemaRejects).toBe(true);
403
+ });
404
+ });
405
+ //# sourceMappingURL=diagnostician-output-schema.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostician-output-schema.test.js","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/diagnostician-output-schema.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Schema Version Tests — Core Package
3
+ *
4
+ * Unit tests for schema-version.ts — centralized versioning for runtime-v2 contracts.
5
+ *
6
+ * Tests verify:
7
+ * - schemaRef() produces correct "kind-vN" format for valid inputs
8
+ * - RUNTIME_V2_SCHEMA_VERSION constant matches expected literal "1.0.0"
9
+ * - RuntimeV2SchemaVersionSchema accepts only "1.0.0" (exact-match literal)
10
+ * - SchemaVersionRefSchema accepts strings (open-ended contract — not a literal)
11
+ * - Edge cases: zero version, large version, non-integer version numbers
12
+ *
13
+ * ERR checklist:
14
+ * - ERR-088: asserts exact value, not merely truthy — a drift from "1.0.0" to "1.0.1"
15
+ * must fail these tests rather than pass with a generic "is string" check.
16
+ * - ERR-089: branch coverage on both accept and reject paths for each check.
17
+ */
18
+ export {};
19
+ //# sourceMappingURL=schema-version.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-version.test.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/schema-version.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG"}