jev-agent-tools 0.1.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/CHANGELOG.md +106 -1
  2. package/CONTRIBUTING.md +43 -0
  3. package/README.md +58 -17
  4. package/SECURITY.md +43 -0
  5. package/dist/adapters/analysis-context.js +75 -0
  6. package/dist/adapters/ask-files.js +198 -0
  7. package/dist/adapters/ask-proof.js +200 -0
  8. package/dist/adapters/ask-syntax.js +385 -0
  9. package/dist/adapters/canonical-path.js +17 -0
  10. package/dist/adapters/command.js +234 -0
  11. package/dist/adapters/docs.js +192 -0
  12. package/dist/adapters/evidence-context.js +119 -0
  13. package/dist/adapters/exec.js +207 -0
  14. package/dist/adapters/files.js +418 -0
  15. package/dist/adapters/find.js +150 -0
  16. package/dist/adapters/git-base.js +32 -0
  17. package/dist/adapters/git-inventory.js +71 -0
  18. package/dist/adapters/git.js +483 -0
  19. package/dist/adapters/locate-file.js +197 -0
  20. package/dist/adapters/output-lines.js +46 -0
  21. package/dist/adapters/private-storage.js +106 -0
  22. package/dist/adapters/risk-callers.js +429 -0
  23. package/dist/adapters/runner-version.js +78 -0
  24. package/dist/adapters/shell.js +92 -0
  25. package/dist/adapters/syntax.js +187 -0
  26. package/dist/adapters/test-inventory.js +139 -0
  27. package/dist/adapters/usage.js +20 -0
  28. package/dist/adapters/utf8.js +47 -0
  29. package/dist/configuration.js +267 -0
  30. package/dist/constants.js +140 -0
  31. package/dist/core/ask-closure.js +282 -0
  32. package/dist/core/ask-proof.js +1 -0
  33. package/dist/core/ask-references.js +278 -0
  34. package/dist/core/asks.js +507 -0
  35. package/dist/core/batches.js +65 -0
  36. package/dist/core/command-output.js +224 -0
  37. package/dist/core/diff.js +178 -0
  38. package/dist/core/docs.js +302 -0
  39. package/dist/core/find.js +108 -0
  40. package/dist/core/git.js +1 -0
  41. package/dist/core/imports.js +550 -0
  42. package/dist/core/integrity.js +45 -0
  43. package/dist/core/lexical.js +132 -0
  44. package/dist/core/locate.js +169 -0
  45. package/dist/core/output.js +137 -0
  46. package/dist/core/pointer.js +29 -0
  47. package/dist/core/result-report.js +302 -0
  48. package/dist/core/risk-callers.js +851 -0
  49. package/dist/core/runner-version.js +45 -0
  50. package/dist/core/secret-path.js +34 -0
  51. package/dist/core/sections.js +230 -0
  52. package/dist/core/state.js +51 -0
  53. package/dist/core/syntax.js +1 -0
  54. package/dist/core/test-commands.js +334 -0
  55. package/dist/core/test-coverage.js +74 -0
  56. package/dist/core/test-discovery.js +1382 -0
  57. package/dist/core/test-evidence.js +527 -0
  58. package/dist/core/test-state.js +81 -0
  59. package/dist/core/truncate.js +12 -0
  60. package/dist/core/units.js +349 -0
  61. package/dist/describe.js +23 -0
  62. package/dist/guide.js +33 -0
  63. package/dist/host.js +24 -0
  64. package/dist/jev/client.js +456 -0
  65. package/dist/jev/pool.js +54 -0
  66. package/dist/jev/types.js +1 -0
  67. package/dist/mcp/main.js +124 -0
  68. package/dist/mcp/protocol.js +210 -0
  69. package/dist/mcp/tools.js +129 -0
  70. package/dist/presets/docs.js +62 -0
  71. package/dist/presets/risk.js +179 -0
  72. package/dist/presets/spec.js +81 -0
  73. package/dist/presets/witnesses.js +249 -0
  74. package/dist/render.js +114 -0
  75. package/dist/report-schema.js +1356 -0
  76. package/dist/result-types.js +1 -0
  77. package/dist/result.js +3 -0
  78. package/dist/runtime.js +1 -0
  79. package/dist/session.js +147 -0
  80. package/dist/texts/ask-files.js +3 -0
  81. package/dist/texts/ask.js +4 -0
  82. package/dist/texts/check-diff.js +20 -0
  83. package/dist/texts/configuration.js +1 -0
  84. package/dist/texts/find.js +19 -0
  85. package/dist/texts/guide.js +3 -0
  86. package/dist/texts/instructions.js +72 -0
  87. package/dist/texts/locate.js +15 -0
  88. package/dist/texts/select-tests.js +4 -0
  89. package/dist/tools/ask-files.js +450 -0
  90. package/dist/tools/ask-schema.js +70 -0
  91. package/dist/tools/ask.js +1147 -0
  92. package/dist/tools/check-diff.js +594 -0
  93. package/dist/tools/docs-check.js +408 -0
  94. package/dist/tools/find.js +682 -0
  95. package/dist/tools/locate.js +602 -0
  96. package/dist/tools/review-report.js +230 -0
  97. package/dist/tools/select-tests.js +821 -0
  98. package/dist/tools/spec-check.js +263 -0
  99. package/docs/adr/0001-strict-typescript-pure-core-offline-tests.md +31 -0
  100. package/docs/adr/0002-one-http-protocol-across-hosts.md +17 -0
  101. package/docs/adr/0003-explicit-scope-conservative-automation.md +19 -0
  102. package/docs/adr/0004-compiled-typed-intents.md +19 -0
  103. package/docs/adr/0005-evidence-construction-before-judgment.md +19 -0
  104. package/docs/adr/0006-visible-uncertainty-constrained-controls.md +21 -0
  105. package/docs/adr/0007-bounded-evidence-visible-limits.md +21 -0
  106. package/docs/adr/0008-static-test-discovery-conservative-plans.md +19 -0
  107. package/docs/adr/0009-session-cache-requested-model-identity.md +17 -0
  108. package/docs/adr/0010-mcp-server-thin-host.md +23 -0
  109. package/docs/agent-instructions.md +120 -0
  110. package/docs/design.md +16 -4
  111. package/docs/mcp.md +233 -0
  112. package/docs/tools/jev_ask.md +8 -5
  113. package/docs/tools/jev_ask_files.md +2 -1
  114. package/docs/tools/jev_check_diff.md +4 -1
  115. package/docs/tools/jev_find_files.md +2 -1
  116. package/docs/tools/jev_locate_in_file.md +5 -0
  117. package/docs/tools/jev_select_tests.md +4 -1
  118. package/package.json +19 -4
  119. package/rules/jev-ask.md +22 -1
  120. package/server.json +57 -0
  121. package/src/adapters/ask-files.ts +11 -3
  122. package/src/adapters/ask-proof.ts +69 -11
  123. package/src/adapters/canonical-path.ts +18 -0
  124. package/src/adapters/command.ts +102 -36
  125. package/src/adapters/docs.ts +33 -14
  126. package/src/adapters/evidence-context.ts +169 -0
  127. package/src/adapters/exec.ts +226 -0
  128. package/src/adapters/files.ts +146 -16
  129. package/src/adapters/find.ts +37 -7
  130. package/src/adapters/git-base.ts +7 -1
  131. package/src/adapters/git.ts +61 -8
  132. package/src/adapters/locate-file.ts +51 -9
  133. package/src/adapters/private-storage.ts +155 -0
  134. package/src/adapters/risk-callers.ts +7 -2
  135. package/src/adapters/shell.ts +113 -0
  136. package/src/adapters/test-inventory.ts +12 -4
  137. package/src/configuration.ts +55 -14
  138. package/src/constants.ts +37 -5
  139. package/src/core/ask-references.ts +262 -146
  140. package/src/core/asks.ts +79 -7
  141. package/src/core/command-output.ts +17 -1
  142. package/src/core/import-boundaries.ts +8 -3
  143. package/src/core/locate.ts +8 -5
  144. package/src/core/output.ts +34 -0
  145. package/src/core/result-report.ts +410 -0
  146. package/src/core/secret-path.ts +37 -0
  147. package/src/core/state.ts +8 -1
  148. package/src/core/units.ts +3 -2
  149. package/src/host.ts +11 -0
  150. package/src/index.ts +3 -0
  151. package/src/jev/client.ts +66 -16
  152. package/src/jev/types.ts +24 -3
  153. package/src/mcp/main.ts +135 -0
  154. package/src/mcp/protocol.ts +332 -0
  155. package/src/mcp/tools.ts +179 -0
  156. package/src/render.ts +109 -0
  157. package/src/report-schema.ts +1380 -0
  158. package/src/result-types.ts +234 -0
  159. package/src/result.ts +4 -1
  160. package/src/runtime.ts +6 -0
  161. package/src/session.ts +59 -0
  162. package/src/setup.ts +13 -5
  163. package/src/texts/ask-files.ts +4 -1
  164. package/src/texts/ask.ts +8 -1
  165. package/src/texts/check-diff.ts +7 -4
  166. package/src/texts/find.ts +8 -2
  167. package/src/texts/guide.ts +8 -16
  168. package/src/texts/instructions.ts +98 -0
  169. package/src/texts/locate.ts +8 -2
  170. package/src/texts/run-end.ts +2 -2
  171. package/src/texts/select-tests.ts +4 -1
  172. package/src/tools/ask-files.ts +311 -18
  173. package/src/tools/ask.ts +722 -95
  174. package/src/tools/check-diff.ts +337 -31
  175. package/src/tools/docs-check.ts +241 -38
  176. package/src/tools/find.ts +389 -29
  177. package/src/tools/locate.ts +387 -25
  178. package/src/tools/review-report.ts +308 -0
  179. package/src/tools/select-tests.ts +484 -23
  180. package/src/tools/spec-check.ts +194 -19
@@ -0,0 +1,1380 @@
1
+ import { validateResultReport } from "./core/result-report.ts";
2
+ import type { McpStructuredResultV1, ResultReportV1 } from "./result-types.ts";
3
+
4
+ /** Self-contained public JSON Schema; semantic ID/count checks live in result-report. */
5
+ const definitions = {
6
+ KnowledgeString: {
7
+ oneOf: [
8
+ {
9
+ type: "object",
10
+ properties: {
11
+ status: {
12
+ const: "known",
13
+ },
14
+ value: {
15
+ type: "string",
16
+ },
17
+ },
18
+ required: ["status", "value"],
19
+ additionalProperties: false,
20
+ },
21
+ {
22
+ type: "object",
23
+ properties: {
24
+ status: {
25
+ type: "string",
26
+ enum: ["unknown", "not_applicable", "not_collected"],
27
+ },
28
+ reason: {
29
+ type: "string",
30
+ },
31
+ },
32
+ required: ["status", "reason"],
33
+ additionalProperties: false,
34
+ },
35
+ ],
36
+ },
37
+ KnowledgeNumber: {
38
+ oneOf: [
39
+ {
40
+ type: "object",
41
+ properties: {
42
+ status: {
43
+ const: "known",
44
+ },
45
+ value: {
46
+ type: "integer",
47
+ minimum: 0,
48
+ },
49
+ },
50
+ required: ["status", "value"],
51
+ additionalProperties: false,
52
+ },
53
+ {
54
+ type: "object",
55
+ properties: {
56
+ status: {
57
+ type: "string",
58
+ enum: ["unknown", "not_applicable", "not_collected"],
59
+ },
60
+ reason: {
61
+ type: "string",
62
+ },
63
+ },
64
+ required: ["status", "reason"],
65
+ additionalProperties: false,
66
+ },
67
+ ],
68
+ },
69
+ KnowledgeBoolean: {
70
+ oneOf: [
71
+ {
72
+ type: "object",
73
+ properties: {
74
+ status: {
75
+ const: "known",
76
+ },
77
+ value: {
78
+ type: "boolean",
79
+ },
80
+ },
81
+ required: ["status", "value"],
82
+ additionalProperties: false,
83
+ },
84
+ {
85
+ type: "object",
86
+ properties: {
87
+ status: {
88
+ type: "string",
89
+ enum: ["unknown", "not_applicable", "not_collected"],
90
+ },
91
+ reason: {
92
+ type: "string",
93
+ },
94
+ },
95
+ required: ["status", "reason"],
96
+ additionalProperties: false,
97
+ },
98
+ ],
99
+ },
100
+ KnowledgeNullableNumber: {
101
+ oneOf: [
102
+ {
103
+ type: "object",
104
+ properties: {
105
+ status: {
106
+ const: "known",
107
+ },
108
+ value: {
109
+ type: ["number", "null"],
110
+ },
111
+ },
112
+ required: ["status", "value"],
113
+ additionalProperties: false,
114
+ },
115
+ {
116
+ type: "object",
117
+ properties: {
118
+ status: {
119
+ type: "string",
120
+ enum: ["unknown", "not_applicable", "not_collected"],
121
+ },
122
+ reason: {
123
+ type: "string",
124
+ },
125
+ },
126
+ required: ["status", "reason"],
127
+ additionalProperties: false,
128
+ },
129
+ ],
130
+ },
131
+ KnowledgeAuthority: {
132
+ oneOf: [
133
+ {
134
+ type: "object",
135
+ properties: {
136
+ status: {
137
+ const: "known",
138
+ },
139
+ value: {
140
+ $ref: "#/$defs/Authority",
141
+ },
142
+ },
143
+ required: ["status", "value"],
144
+ additionalProperties: false,
145
+ },
146
+ {
147
+ type: "object",
148
+ properties: {
149
+ status: {
150
+ type: "string",
151
+ enum: ["unknown", "not_applicable", "not_collected"],
152
+ },
153
+ reason: {
154
+ type: "string",
155
+ },
156
+ },
157
+ required: ["status", "reason"],
158
+ additionalProperties: false,
159
+ },
160
+ ],
161
+ },
162
+ KnowledgeEffectiveRoot: {
163
+ oneOf: [
164
+ {
165
+ type: "object",
166
+ properties: {
167
+ status: {
168
+ const: "known",
169
+ },
170
+ value: {
171
+ $ref: "#/$defs/EffectiveRoot",
172
+ },
173
+ },
174
+ required: ["status", "value"],
175
+ additionalProperties: false,
176
+ },
177
+ {
178
+ type: "object",
179
+ properties: {
180
+ status: {
181
+ type: "string",
182
+ enum: ["unknown", "not_applicable", "not_collected"],
183
+ },
184
+ reason: {
185
+ type: "string",
186
+ },
187
+ },
188
+ required: ["status", "reason"],
189
+ additionalProperties: false,
190
+ },
191
+ ],
192
+ },
193
+ KnowledgeProbability: {
194
+ oneOf: [
195
+ {
196
+ type: "object",
197
+ properties: {
198
+ status: {
199
+ const: "known",
200
+ },
201
+ value: {
202
+ type: "number",
203
+ minimum: 0,
204
+ maximum: 1,
205
+ },
206
+ },
207
+ required: ["status", "value"],
208
+ additionalProperties: false,
209
+ },
210
+ {
211
+ type: "object",
212
+ properties: {
213
+ status: {
214
+ type: "string",
215
+ enum: ["unknown", "not_applicable", "not_collected"],
216
+ },
217
+ reason: {
218
+ type: "string",
219
+ },
220
+ },
221
+ required: ["status", "reason"],
222
+ additionalProperties: false,
223
+ },
224
+ ],
225
+ },
226
+ KnowledgeCost: {
227
+ oneOf: [
228
+ {
229
+ type: "object",
230
+ properties: {
231
+ status: {
232
+ const: "known",
233
+ },
234
+ value: {
235
+ type: "number",
236
+ minimum: 0,
237
+ },
238
+ },
239
+ required: ["status", "value"],
240
+ additionalProperties: false,
241
+ },
242
+ {
243
+ type: "object",
244
+ properties: {
245
+ status: {
246
+ type: "string",
247
+ enum: ["unknown", "not_applicable", "not_collected"],
248
+ },
249
+ reason: {
250
+ type: "string",
251
+ },
252
+ },
253
+ required: ["status", "reason"],
254
+ additionalProperties: false,
255
+ },
256
+ ],
257
+ },
258
+ Authority: {
259
+ type: "object",
260
+ properties: {
261
+ path: {
262
+ type: "string",
263
+ },
264
+ origin: {
265
+ type: "string",
266
+ enum: ["host", "server"],
267
+ },
268
+ },
269
+ required: ["path", "origin"],
270
+ additionalProperties: false,
271
+ },
272
+ EffectiveRoot: {
273
+ type: "object",
274
+ properties: {
275
+ path: {
276
+ type: "string",
277
+ },
278
+ origin: {
279
+ type: "string",
280
+ enum: ["host", "server", "override"],
281
+ },
282
+ commonDir: {
283
+ $ref: "#/$defs/KnowledgeString",
284
+ },
285
+ },
286
+ required: ["path", "origin", "commonDir"],
287
+ additionalProperties: false,
288
+ },
289
+ Scope: {
290
+ oneOf: [
291
+ {
292
+ type: "object",
293
+ properties: {
294
+ kind: {
295
+ const: "call",
296
+ },
297
+ },
298
+ required: ["kind"],
299
+ additionalProperties: false,
300
+ },
301
+ {
302
+ type: "object",
303
+ properties: {
304
+ kind: {
305
+ const: "group",
306
+ },
307
+ groupIds: {
308
+ type: "array",
309
+ items: {
310
+ type: "string",
311
+ },
312
+ },
313
+ },
314
+ required: ["kind", "groupIds"],
315
+ additionalProperties: false,
316
+ },
317
+ {
318
+ type: "object",
319
+ properties: {
320
+ kind: {
321
+ const: "item",
322
+ },
323
+ itemIds: {
324
+ type: "array",
325
+ items: {
326
+ type: "string",
327
+ },
328
+ },
329
+ },
330
+ required: ["kind", "itemIds"],
331
+ additionalProperties: false,
332
+ },
333
+ {
334
+ type: "object",
335
+ properties: {
336
+ kind: {
337
+ const: "inventory",
338
+ },
339
+ inventoryIds: {
340
+ type: "array",
341
+ items: {
342
+ type: "string",
343
+ },
344
+ },
345
+ },
346
+ required: ["kind", "inventoryIds"],
347
+ additionalProperties: false,
348
+ },
349
+ ],
350
+ },
351
+ Criterion: {
352
+ type: "object",
353
+ properties: {
354
+ criterion: {
355
+ type: "string",
356
+ },
357
+ matches: {
358
+ $ref: "#/$defs/KnowledgeNumber",
359
+ },
360
+ outcome: {
361
+ type: "string",
362
+ enum: ["matched", "no_match", "outside_inventory", "not_evaluated"],
363
+ },
364
+ diagnosticIds: {
365
+ type: "array",
366
+ items: {
367
+ type: "string",
368
+ },
369
+ },
370
+ },
371
+ required: ["criterion", "matches", "outcome", "diagnosticIds"],
372
+ additionalProperties: false,
373
+ },
374
+ Inventory: {
375
+ type: "object",
376
+ properties: {
377
+ id: {
378
+ type: "string",
379
+ },
380
+ kind: {
381
+ type: "string",
382
+ enum: ["repository", "tests", "sections", "units"],
383
+ },
384
+ rules: {
385
+ type: "array",
386
+ items: {
387
+ type: "string",
388
+ },
389
+ },
390
+ restrictions: {
391
+ type: "array",
392
+ items: {
393
+ type: "string",
394
+ },
395
+ },
396
+ discovered: {
397
+ $ref: "#/$defs/KnowledgeNumber",
398
+ },
399
+ considered: {
400
+ $ref: "#/$defs/KnowledgeNumber",
401
+ },
402
+ scopeRestricted: {
403
+ type: "boolean",
404
+ },
405
+ criteria: {
406
+ type: "array",
407
+ items: {
408
+ $ref: "#/$defs/Criterion",
409
+ },
410
+ },
411
+ },
412
+ required: [
413
+ "id",
414
+ "kind",
415
+ "rules",
416
+ "restrictions",
417
+ "discovered",
418
+ "considered",
419
+ "scopeRestricted",
420
+ "criteria",
421
+ ],
422
+ additionalProperties: false,
423
+ },
424
+ Command: {
425
+ type: "object",
426
+ properties: {
427
+ execution: {
428
+ type: "string",
429
+ enum: [
430
+ "not_requested",
431
+ "unknown",
432
+ "not_started",
433
+ "started",
434
+ "finished",
435
+ ],
436
+ },
437
+ cwd: {
438
+ $ref: "#/$defs/KnowledgeString",
439
+ },
440
+ exitCode: {
441
+ $ref: "#/$defs/KnowledgeNullableNumber",
442
+ },
443
+ timedOut: {
444
+ $ref: "#/$defs/KnowledgeBoolean",
445
+ },
446
+ },
447
+ required: ["execution", "cwd", "exitCode", "timedOut"],
448
+ additionalProperties: false,
449
+ },
450
+ Context: {
451
+ type: "object",
452
+ properties: {
453
+ authority: {
454
+ $ref: "#/$defs/KnowledgeAuthority",
455
+ },
456
+ requestedRoot: {
457
+ $ref: "#/$defs/KnowledgeString",
458
+ },
459
+ effectiveRoot: {
460
+ $ref: "#/$defs/KnowledgeEffectiveRoot",
461
+ },
462
+ requestedBase: {
463
+ $ref: "#/$defs/KnowledgeString",
464
+ },
465
+ resolvedBase: {
466
+ $ref: "#/$defs/KnowledgeString",
467
+ },
468
+ inventories: {
469
+ type: "array",
470
+ items: {
471
+ $ref: "#/$defs/Inventory",
472
+ },
473
+ },
474
+ command: {
475
+ $ref: "#/$defs/Command",
476
+ },
477
+ },
478
+ required: [
479
+ "authority",
480
+ "requestedRoot",
481
+ "effectiveRoot",
482
+ "requestedBase",
483
+ "resolvedBase",
484
+ "inventories",
485
+ "command",
486
+ ],
487
+ additionalProperties: false,
488
+ },
489
+ Cause: {
490
+ type: "string",
491
+ enum: [
492
+ "invalid_arguments",
493
+ "internal_error",
494
+ "file_unavailable",
495
+ "git_failure",
496
+ "evidence_limit",
497
+ "invalid_root",
498
+ "invalid_base",
499
+ "forbidden_path",
500
+ "ignored_path",
501
+ "secret_pattern",
502
+ "symlink",
503
+ "binary_or_non_utf8",
504
+ "missing_required",
505
+ "empty_required",
506
+ "ambiguous_reference",
507
+ "reserved_key",
508
+ "evidence_too_large",
509
+ "group_too_large",
510
+ "call_budget",
511
+ "session_budget",
512
+ "provider_context_refusal",
513
+ "not_configured",
514
+ "service_unavailable",
515
+ "transport_failure",
516
+ "invalid_response",
517
+ "cancelled",
518
+ "collection_empty",
519
+ "no_changed_units",
520
+ "criteria_no_match",
521
+ "outside_inventory",
522
+ "collection_omitted",
523
+ "unsupported_syntax",
524
+ "unresolved_runner",
525
+ "dynamic_dependency",
526
+ "conservative_widening",
527
+ "control_failure",
528
+ "evidence_disagreement",
529
+ ],
530
+ },
531
+ Diagnostic: {
532
+ type: "object",
533
+ properties: {
534
+ id: {
535
+ type: "string",
536
+ },
537
+ cause: {
538
+ $ref: "#/$defs/Cause",
539
+ },
540
+ fact: {
541
+ type: "string",
542
+ },
543
+ target: {
544
+ $ref: "#/$defs/KnowledgeString",
545
+ },
546
+ origin: {
547
+ type: "string",
548
+ enum: [
549
+ "input",
550
+ "note",
551
+ "ask",
552
+ "control",
553
+ "collection",
554
+ "closure",
555
+ "runner",
556
+ "provider",
557
+ "budget",
558
+ ],
559
+ },
560
+ scope: {
561
+ $ref: "#/$defs/Scope",
562
+ },
563
+ effect: {
564
+ type: "string",
565
+ enum: ["blocking", "reservation"],
566
+ },
567
+ material: {
568
+ type: "boolean",
569
+ },
570
+ omittedMembers: {
571
+ type: "array",
572
+ items: {
573
+ type: "string",
574
+ },
575
+ },
576
+ memberCount: {
577
+ $ref: "#/$defs/KnowledgeNumber",
578
+ },
579
+ actionIds: {
580
+ type: "array",
581
+ items: {
582
+ type: "string",
583
+ },
584
+ },
585
+ },
586
+ required: [
587
+ "id",
588
+ "cause",
589
+ "fact",
590
+ "target",
591
+ "origin",
592
+ "scope",
593
+ "effect",
594
+ "material",
595
+ "omittedMembers",
596
+ "memberCount",
597
+ "actionIds",
598
+ ],
599
+ additionalProperties: false,
600
+ },
601
+ Action: {
602
+ type: "object",
603
+ properties: {
604
+ id: {
605
+ type: "string",
606
+ },
607
+ code: {
608
+ type: "string",
609
+ enum: [
610
+ "correct_context",
611
+ "correct_reference",
612
+ "provide_evidence",
613
+ "narrow_evidence",
614
+ "inspect_native",
615
+ "execute_plan",
616
+ "configure_client",
617
+ "recover_service",
618
+ "continue_without_judgment",
619
+ "none",
620
+ ],
621
+ },
622
+ target: {
623
+ $ref: "#/$defs/KnowledgeString",
624
+ },
625
+ scope: {
626
+ $ref: "#/$defs/Scope",
627
+ },
628
+ condition: {
629
+ type: "string",
630
+ },
631
+ instruction: {
632
+ type: "string",
633
+ },
634
+ repeatUnchanged: {
635
+ const: false,
636
+ },
637
+ },
638
+ required: [
639
+ "id",
640
+ "code",
641
+ "target",
642
+ "scope",
643
+ "condition",
644
+ "instruction",
645
+ "repeatUnchanged",
646
+ ],
647
+ additionalProperties: false,
648
+ },
649
+ RawValue: {
650
+ type: "object",
651
+ properties: {
652
+ label: {
653
+ type: "string",
654
+ },
655
+ value: {
656
+ type: ["string", "number", "boolean"],
657
+ },
658
+ probability: {
659
+ $ref: "#/$defs/KnowledgeProbability",
660
+ },
661
+ },
662
+ required: ["label", "value", "probability"],
663
+ additionalProperties: false,
664
+ },
665
+ Control: {
666
+ type: "object",
667
+ properties: {
668
+ id: {
669
+ type: "string",
670
+ },
671
+ kind: {
672
+ type: "string",
673
+ enum: ["cross_check", "order", "witness", "attribution", "integrity"],
674
+ },
675
+ source: {
676
+ type: "string",
677
+ enum: ["fresh", "cache", "static"],
678
+ },
679
+ outcome: {
680
+ type: "string",
681
+ },
682
+ rawValues: {
683
+ type: "array",
684
+ items: {
685
+ $ref: "#/$defs/RawValue",
686
+ },
687
+ },
688
+ },
689
+ required: ["id", "kind", "source", "outcome", "rawValues"],
690
+ additionalProperties: false,
691
+ },
692
+ Judgment: {
693
+ type: "object",
694
+ properties: {
695
+ band: {
696
+ type: "string",
697
+ enum: ["verdict", "unsure", "abstain"],
698
+ },
699
+ result: {
700
+ type: ["string", "number", "boolean"],
701
+ },
702
+ measure: {
703
+ type: "object",
704
+ properties: {
705
+ kind: {
706
+ type: "string",
707
+ enum: ["probability", "confidence"],
708
+ },
709
+ value: {
710
+ $ref: "#/$defs/KnowledgeProbability",
711
+ },
712
+ },
713
+ required: ["kind", "value"],
714
+ additionalProperties: false,
715
+ },
716
+ reason: {
717
+ type: "string",
718
+ },
719
+ uncalibrated: {
720
+ type: "boolean",
721
+ },
722
+ rawValues: {
723
+ type: "array",
724
+ items: {
725
+ $ref: "#/$defs/RawValue",
726
+ },
727
+ },
728
+ controls: {
729
+ type: "array",
730
+ items: {
731
+ $ref: "#/$defs/Control",
732
+ },
733
+ },
734
+ },
735
+ required: [
736
+ "band",
737
+ "result",
738
+ "measure",
739
+ "reason",
740
+ "uncalibrated",
741
+ "rawValues",
742
+ "controls",
743
+ ],
744
+ additionalProperties: false,
745
+ },
746
+ Evidence: {
747
+ type: "object",
748
+ properties: {
749
+ target: {
750
+ type: "string",
751
+ },
752
+ canonicalPath: {
753
+ $ref: "#/$defs/KnowledgeString",
754
+ },
755
+ aliases: {
756
+ type: "array",
757
+ items: {
758
+ type: "string",
759
+ },
760
+ },
761
+ side: {
762
+ type: "string",
763
+ enum: ["current", "before", "output", "state"],
764
+ },
765
+ revision: {
766
+ $ref: "#/$defs/KnowledgeString",
767
+ },
768
+ },
769
+ required: ["target", "canonicalPath", "aliases", "side", "revision"],
770
+ additionalProperties: false,
771
+ },
772
+ ItemCommon: {
773
+ type: "object",
774
+ properties: {
775
+ id: {
776
+ type: "string",
777
+ },
778
+ kind: {
779
+ type: "string",
780
+ enum: [
781
+ "claim",
782
+ "question",
783
+ "file_question",
784
+ "unit",
785
+ "section",
786
+ "requirement",
787
+ "scenario",
788
+ "entry",
789
+ "pointer",
790
+ ],
791
+ },
792
+ label: {
793
+ type: "string",
794
+ },
795
+ groupId: {
796
+ type: "string",
797
+ },
798
+ evidence: {
799
+ type: "array",
800
+ items: {
801
+ $ref: "#/$defs/Evidence",
802
+ },
803
+ },
804
+ diagnosticIds: {
805
+ type: "array",
806
+ items: {
807
+ type: "string",
808
+ },
809
+ },
810
+ actionIds: {
811
+ type: "array",
812
+ items: {
813
+ type: "string",
814
+ },
815
+ },
816
+ selection: {
817
+ type: "object",
818
+ properties: {
819
+ selected: {
820
+ type: "boolean",
821
+ },
822
+ reason: {
823
+ type: "string",
824
+ },
825
+ },
826
+ required: ["selected", "reason"],
827
+ additionalProperties: false,
828
+ },
829
+ },
830
+ required: [
831
+ "id",
832
+ "kind",
833
+ "label",
834
+ "groupId",
835
+ "evidence",
836
+ "diagnosticIds",
837
+ "actionIds",
838
+ ],
839
+ additionalProperties: false,
840
+ },
841
+ Item: {
842
+ oneOf: [
843
+ {
844
+ type: "object",
845
+ properties: {
846
+ id: {
847
+ type: "string",
848
+ },
849
+ kind: {
850
+ type: "string",
851
+ enum: [
852
+ "claim",
853
+ "question",
854
+ "file_question",
855
+ "unit",
856
+ "section",
857
+ "requirement",
858
+ "scenario",
859
+ "entry",
860
+ "pointer",
861
+ ],
862
+ },
863
+ label: {
864
+ type: "string",
865
+ },
866
+ groupId: {
867
+ type: "string",
868
+ },
869
+ evidence: {
870
+ type: "array",
871
+ items: {
872
+ $ref: "#/$defs/Evidence",
873
+ },
874
+ },
875
+ diagnosticIds: {
876
+ type: "array",
877
+ items: {
878
+ type: "string",
879
+ },
880
+ },
881
+ actionIds: {
882
+ type: "array",
883
+ items: {
884
+ type: "string",
885
+ },
886
+ },
887
+ selection: {
888
+ type: "object",
889
+ properties: {
890
+ selected: {
891
+ type: "boolean",
892
+ },
893
+ reason: {
894
+ type: "string",
895
+ },
896
+ },
897
+ required: ["selected", "reason"],
898
+ additionalProperties: false,
899
+ },
900
+ treatment: {
901
+ const: "judged",
902
+ },
903
+ source: {
904
+ type: "string",
905
+ enum: ["fresh", "cache"],
906
+ },
907
+ judgment: {
908
+ $ref: "#/$defs/Judgment",
909
+ },
910
+ },
911
+ required: [
912
+ "id",
913
+ "kind",
914
+ "label",
915
+ "groupId",
916
+ "evidence",
917
+ "diagnosticIds",
918
+ "actionIds",
919
+ "treatment",
920
+ "source",
921
+ "judgment",
922
+ ],
923
+ additionalProperties: false,
924
+ },
925
+ {
926
+ type: "object",
927
+ properties: {
928
+ id: {
929
+ type: "string",
930
+ },
931
+ kind: {
932
+ type: "string",
933
+ enum: [
934
+ "claim",
935
+ "question",
936
+ "file_question",
937
+ "unit",
938
+ "section",
939
+ "requirement",
940
+ "scenario",
941
+ "entry",
942
+ "pointer",
943
+ ],
944
+ },
945
+ label: {
946
+ type: "string",
947
+ },
948
+ groupId: {
949
+ type: "string",
950
+ },
951
+ evidence: {
952
+ type: "array",
953
+ items: {
954
+ $ref: "#/$defs/Evidence",
955
+ },
956
+ },
957
+ diagnosticIds: {
958
+ type: "array",
959
+ items: {
960
+ type: "string",
961
+ },
962
+ },
963
+ actionIds: {
964
+ type: "array",
965
+ items: {
966
+ type: "string",
967
+ },
968
+ },
969
+ selection: {
970
+ type: "object",
971
+ properties: {
972
+ selected: {
973
+ type: "boolean",
974
+ },
975
+ reason: {
976
+ type: "string",
977
+ },
978
+ },
979
+ required: ["selected", "reason"],
980
+ additionalProperties: false,
981
+ },
982
+ treatment: {
983
+ const: "not_judged",
984
+ },
985
+ source: {
986
+ const: "none",
987
+ },
988
+ },
989
+ required: [
990
+ "id",
991
+ "kind",
992
+ "label",
993
+ "groupId",
994
+ "evidence",
995
+ "diagnosticIds",
996
+ "actionIds",
997
+ "treatment",
998
+ "source",
999
+ ],
1000
+ additionalProperties: false,
1001
+ },
1002
+ {
1003
+ type: "object",
1004
+ properties: {
1005
+ id: {
1006
+ type: "string",
1007
+ },
1008
+ kind: {
1009
+ type: "string",
1010
+ enum: [
1011
+ "claim",
1012
+ "question",
1013
+ "file_question",
1014
+ "unit",
1015
+ "section",
1016
+ "requirement",
1017
+ "scenario",
1018
+ "entry",
1019
+ "pointer",
1020
+ ],
1021
+ },
1022
+ label: {
1023
+ type: "string",
1024
+ },
1025
+ groupId: {
1026
+ type: "string",
1027
+ },
1028
+ evidence: {
1029
+ type: "array",
1030
+ items: {
1031
+ $ref: "#/$defs/Evidence",
1032
+ },
1033
+ },
1034
+ diagnosticIds: {
1035
+ type: "array",
1036
+ items: {
1037
+ type: "string",
1038
+ },
1039
+ },
1040
+ actionIds: {
1041
+ type: "array",
1042
+ items: {
1043
+ type: "string",
1044
+ },
1045
+ },
1046
+ selection: {
1047
+ type: "object",
1048
+ properties: {
1049
+ selected: {
1050
+ type: "boolean",
1051
+ },
1052
+ reason: {
1053
+ type: "string",
1054
+ },
1055
+ },
1056
+ required: ["selected", "reason"],
1057
+ additionalProperties: false,
1058
+ },
1059
+ treatment: {
1060
+ const: "static",
1061
+ },
1062
+ source: {
1063
+ const: "none",
1064
+ },
1065
+ staticReason: {
1066
+ type: "string",
1067
+ },
1068
+ },
1069
+ required: [
1070
+ "id",
1071
+ "kind",
1072
+ "label",
1073
+ "groupId",
1074
+ "evidence",
1075
+ "diagnosticIds",
1076
+ "actionIds",
1077
+ "treatment",
1078
+ "source",
1079
+ "staticReason",
1080
+ ],
1081
+ additionalProperties: false,
1082
+ },
1083
+ ],
1084
+ },
1085
+ Accounting: {
1086
+ type: "object",
1087
+ properties: {
1088
+ toolInvocations: {
1089
+ const: 1,
1090
+ },
1091
+ httpAttempts: {
1092
+ type: "integer",
1093
+ minimum: 0,
1094
+ },
1095
+ questionsSent: {
1096
+ type: "integer",
1097
+ minimum: 0,
1098
+ },
1099
+ cacheHits: {
1100
+ type: "integer",
1101
+ minimum: 0,
1102
+ },
1103
+ cacheRequests: {
1104
+ type: "integer",
1105
+ minimum: 0,
1106
+ },
1107
+ requestedResults: {
1108
+ type: "object",
1109
+ properties: {
1110
+ total: {
1111
+ $ref: "#/$defs/KnowledgeNumber",
1112
+ },
1113
+ fresh: {
1114
+ type: "integer",
1115
+ minimum: 0,
1116
+ },
1117
+ cache: {
1118
+ type: "integer",
1119
+ minimum: 0,
1120
+ },
1121
+ notJudged: {
1122
+ type: "integer",
1123
+ minimum: 0,
1124
+ },
1125
+ static: {
1126
+ type: "integer",
1127
+ minimum: 0,
1128
+ },
1129
+ },
1130
+ required: ["total", "fresh", "cache", "notJudged", "static"],
1131
+ additionalProperties: false,
1132
+ },
1133
+ auxiliary: {
1134
+ type: "object",
1135
+ properties: {
1136
+ controls: {
1137
+ type: "object",
1138
+ properties: {
1139
+ fresh: {
1140
+ type: "integer",
1141
+ minimum: 0,
1142
+ },
1143
+ cache: {
1144
+ type: "integer",
1145
+ minimum: 0,
1146
+ },
1147
+ notJudged: {
1148
+ type: "integer",
1149
+ minimum: 0,
1150
+ },
1151
+ static: {
1152
+ type: "integer",
1153
+ minimum: 0,
1154
+ },
1155
+ },
1156
+ required: ["fresh", "cache", "notJudged", "static"],
1157
+ additionalProperties: false,
1158
+ },
1159
+ passages: {
1160
+ type: "object",
1161
+ properties: {
1162
+ fresh: {
1163
+ type: "integer",
1164
+ minimum: 0,
1165
+ },
1166
+ cache: {
1167
+ type: "integer",
1168
+ minimum: 0,
1169
+ },
1170
+ notJudged: {
1171
+ type: "integer",
1172
+ minimum: 0,
1173
+ },
1174
+ },
1175
+ required: ["fresh", "cache", "notJudged"],
1176
+ additionalProperties: false,
1177
+ },
1178
+ },
1179
+ required: ["controls", "passages"],
1180
+ additionalProperties: false,
1181
+ },
1182
+ costUsd: {
1183
+ $ref: "#/$defs/KnowledgeCost",
1184
+ },
1185
+ elapsedMs: {
1186
+ type: "number",
1187
+ minimum: 0,
1188
+ },
1189
+ },
1190
+ required: [
1191
+ "toolInvocations",
1192
+ "httpAttempts",
1193
+ "questionsSent",
1194
+ "cacheHits",
1195
+ "cacheRequests",
1196
+ "requestedResults",
1197
+ "auxiliary",
1198
+ "costUsd",
1199
+ "elapsedMs",
1200
+ ],
1201
+ additionalProperties: false,
1202
+ },
1203
+ Tool: {
1204
+ type: "string",
1205
+ enum: [
1206
+ "jev_ask",
1207
+ "jev_ask_files",
1208
+ "jev_check_diff",
1209
+ "jev_select_tests",
1210
+ "jev_find_files",
1211
+ "jev_locate_in_file",
1212
+ ],
1213
+ },
1214
+ Execution: {
1215
+ type: "string",
1216
+ enum: ["complete", "partial", "not_judged", "refused"],
1217
+ },
1218
+ ResultReportV1: {
1219
+ type: "object",
1220
+ properties: {
1221
+ schemaVersion: {
1222
+ const: 1,
1223
+ },
1224
+ tool: {
1225
+ $ref: "#/$defs/Tool",
1226
+ },
1227
+ execution: {
1228
+ $ref: "#/$defs/Execution",
1229
+ },
1230
+ context: {
1231
+ $ref: "#/$defs/Context",
1232
+ },
1233
+ items: {
1234
+ type: "array",
1235
+ items: {
1236
+ $ref: "#/$defs/Item",
1237
+ },
1238
+ },
1239
+ diagnostics: {
1240
+ type: "array",
1241
+ items: {
1242
+ $ref: "#/$defs/Diagnostic",
1243
+ },
1244
+ },
1245
+ actions: {
1246
+ type: "array",
1247
+ items: {
1248
+ $ref: "#/$defs/Action",
1249
+ },
1250
+ },
1251
+ accounting: {
1252
+ $ref: "#/$defs/Accounting",
1253
+ },
1254
+ },
1255
+ required: [
1256
+ "schemaVersion",
1257
+ "tool",
1258
+ "execution",
1259
+ "context",
1260
+ "items",
1261
+ "diagnostics",
1262
+ "actions",
1263
+ "accounting",
1264
+ ],
1265
+ additionalProperties: false,
1266
+ },
1267
+ McpStructuredResultV1: {
1268
+ type: "object",
1269
+ properties: {
1270
+ result: {
1271
+ $ref: "#/$defs/ResultReportV1",
1272
+ },
1273
+ },
1274
+ required: ["result"],
1275
+ additionalProperties: false,
1276
+ },
1277
+ } as const;
1278
+
1279
+ export const resultReportSchema = {
1280
+ ...definitions.ResultReportV1,
1281
+ $defs: definitions,
1282
+ } as const;
1283
+ export const mcpStructuredResultSchema = {
1284
+ ...definitions.McpStructuredResultV1,
1285
+ $defs: definitions,
1286
+ } as const;
1287
+
1288
+ type Schema = { readonly [key: string]: unknown };
1289
+ /** Validator for the closed, local-reference JSON Schema vocabulary emitted above. */
1290
+ function conforms(schema: Schema, value: unknown, root: Schema): boolean {
1291
+ if (typeof schema.$ref === "string") {
1292
+ if (!schema.$ref.startsWith("#/$defs/")) return false;
1293
+ const definitions = root.$defs as Record<string, Schema>;
1294
+ const name = schema.$ref.slice("#/$defs/".length);
1295
+ const definition = Object.hasOwn(definitions, name)
1296
+ ? definitions[name]
1297
+ : undefined;
1298
+ return definition !== undefined && conforms(definition, value, root);
1299
+ }
1300
+ if (schema.oneOf)
1301
+ return (
1302
+ (schema.oneOf as readonly Schema[]).filter((branch) =>
1303
+ conforms(branch, value, root),
1304
+ ).length === 1
1305
+ );
1306
+ if (Object.hasOwn(schema, "const") && value !== schema.const) return false;
1307
+ if (schema.enum && !(schema.enum as readonly unknown[]).includes(value))
1308
+ return false;
1309
+ const types = Array.isArray(schema.type)
1310
+ ? schema.type
1311
+ : schema.type
1312
+ ? [schema.type]
1313
+ : [];
1314
+ if (
1315
+ types.length &&
1316
+ !types.some((type) =>
1317
+ type === "null"
1318
+ ? value === null
1319
+ : type === "array"
1320
+ ? Array.isArray(value)
1321
+ : type === "object"
1322
+ ? value !== null &&
1323
+ typeof value === "object" &&
1324
+ !Array.isArray(value)
1325
+ : type === "integer"
1326
+ ? typeof value === "number" && Number.isInteger(value)
1327
+ : typeof value === type,
1328
+ )
1329
+ )
1330
+ return false;
1331
+ if (
1332
+ typeof value === "number" &&
1333
+ (!Number.isFinite(value) ||
1334
+ (typeof schema.minimum === "number" && value < schema.minimum) ||
1335
+ (typeof schema.maximum === "number" && value > schema.maximum))
1336
+ )
1337
+ return false;
1338
+ if (Array.isArray(value) && schema.items)
1339
+ return value.every((v) => conforms(schema.items as Schema, v, root));
1340
+ if (
1341
+ value !== null &&
1342
+ typeof value === "object" &&
1343
+ !Array.isArray(value) &&
1344
+ schema.properties
1345
+ ) {
1346
+ const properties = schema.properties as Record<string, Schema>;
1347
+ const record = value as Record<string, unknown>;
1348
+ if (
1349
+ (schema.required as readonly string[]).some(
1350
+ (key) => !Object.hasOwn(record, key),
1351
+ )
1352
+ )
1353
+ return false;
1354
+ return Object.entries(record).every(([key, v]) => {
1355
+ const property = Object.hasOwn(properties, key)
1356
+ ? properties[key]
1357
+ : undefined;
1358
+ return property !== undefined
1359
+ ? conforms(property, v, root)
1360
+ : schema.additionalProperties !== false;
1361
+ });
1362
+ }
1363
+ return true;
1364
+ }
1365
+
1366
+ export function isResultReport(value: unknown): value is ResultReportV1 {
1367
+ return (
1368
+ conforms(resultReportSchema, value, resultReportSchema) &&
1369
+ validateResultReport(value as ResultReportV1).length === 0
1370
+ );
1371
+ }
1372
+ export function isMcpStructuredResult(
1373
+ value: unknown,
1374
+ ): value is McpStructuredResultV1 {
1375
+ if (!conforms(mcpStructuredResultSchema, value, mcpStructuredResultSchema))
1376
+ return false;
1377
+ // The schema above established the complete closed wrapper before this cast.
1378
+ const structured = value as McpStructuredResultV1;
1379
+ return validateResultReport(structured.result).length === 0;
1380
+ }