caveat-cli 0.20.2 → 0.21.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.
@@ -0,0 +1,1078 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __caveat_createRequire } from 'node:module';
3
+ const require = __caveat_createRequire(import.meta.url);
4
+ import "../chunk-TWJDSUZ4.js";
5
+
6
+ // src/privateEvidence/validation.ts
7
+ import { createHash } from "node:crypto";
8
+ import { TextDecoder, isDeepStrictEqual } from "node:util";
9
+ import { Ajv2020 } from "ajv/dist/2020.js";
10
+ import { visit } from "jsonc-parser";
11
+
12
+ // src/contracts/factory-private-evidence/capability.v1.schema.json
13
+ var capability_v1_schema_default = {
14
+ $schema: "https://json-schema.org/draft/2020-12/schema",
15
+ $id: "urn:caveat:factory-private-evidence-capability:v1",
16
+ title: "Draft: Caveat official private evidence capability v1",
17
+ type: "object",
18
+ additionalProperties: false,
19
+ required: [
20
+ "schema",
21
+ "product",
22
+ "package_version",
23
+ "public_diagnostic_schema",
24
+ "private_protocol",
25
+ "transports",
26
+ "max_channel_bytes",
27
+ "operation_receipt"
28
+ ],
29
+ properties: {
30
+ schema: {
31
+ const: "caveat.factory_private_evidence_capability.v1"
32
+ },
33
+ product: {
34
+ const: "caveat"
35
+ },
36
+ package_version: {
37
+ type: "string",
38
+ pattern: "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$",
39
+ maxLength: 128
40
+ },
41
+ public_diagnostic_schema: {
42
+ const: "caveat.native_factory_diagnostics.v1"
43
+ },
44
+ private_protocol: {
45
+ const: "caveat.factory_private_evidence.v1"
46
+ },
47
+ transports: {
48
+ type: "array",
49
+ maxItems: 2,
50
+ uniqueItems: true,
51
+ items: {
52
+ oneOf: [
53
+ {
54
+ type: "object",
55
+ additionalProperties: false,
56
+ required: [
57
+ "id",
58
+ "platforms",
59
+ "launch_paths"
60
+ ],
61
+ properties: {
62
+ id: {
63
+ const: "posix-fd-v1"
64
+ },
65
+ platforms: {
66
+ type: "array",
67
+ minItems: 1,
68
+ maxItems: 2,
69
+ uniqueItems: true,
70
+ items: {
71
+ enum: [
72
+ "linux",
73
+ "darwin"
74
+ ]
75
+ }
76
+ },
77
+ launch_paths: {
78
+ type: "array",
79
+ minItems: 1,
80
+ maxItems: 1,
81
+ uniqueItems: true,
82
+ items: {
83
+ enum: [
84
+ "direct_node_entry"
85
+ ]
86
+ }
87
+ }
88
+ }
89
+ },
90
+ {
91
+ type: "object",
92
+ additionalProperties: false,
93
+ required: [
94
+ "id",
95
+ "platforms",
96
+ "launch_paths"
97
+ ],
98
+ properties: {
99
+ id: {
100
+ const: "windows-named-pipe-v1"
101
+ },
102
+ platforms: {
103
+ type: "array",
104
+ minItems: 1,
105
+ maxItems: 1,
106
+ uniqueItems: true,
107
+ items: {
108
+ enum: [
109
+ "win32"
110
+ ]
111
+ }
112
+ },
113
+ launch_paths: {
114
+ type: "array",
115
+ minItems: 1,
116
+ maxItems: 2,
117
+ uniqueItems: true,
118
+ items: {
119
+ enum: [
120
+ "native_exe",
121
+ "powershell_standard_shim"
122
+ ]
123
+ }
124
+ }
125
+ }
126
+ }
127
+ ]
128
+ },
129
+ allOf: [
130
+ {
131
+ contains: {
132
+ type: "object",
133
+ required: [
134
+ "id"
135
+ ],
136
+ properties: {
137
+ id: {
138
+ const: "posix-fd-v1"
139
+ }
140
+ }
141
+ },
142
+ minContains: 0,
143
+ maxContains: 1
144
+ },
145
+ {
146
+ contains: {
147
+ type: "object",
148
+ required: [
149
+ "id"
150
+ ],
151
+ properties: {
152
+ id: {
153
+ const: "windows-named-pipe-v1"
154
+ }
155
+ }
156
+ },
157
+ minContains: 0,
158
+ maxContains: 1
159
+ }
160
+ ]
161
+ },
162
+ max_channel_bytes: {
163
+ const: 16384
164
+ },
165
+ operation_receipt: {
166
+ const: "not_supported"
167
+ }
168
+ }
169
+ };
170
+
171
+ // src/contracts/factory-private-evidence/private-frame.v1.schema.json
172
+ var private_frame_v1_schema_default = {
173
+ $schema: "https://json-schema.org/draft/2020-12/schema",
174
+ $id: "urn:caveat:factory-private-evidence:v1",
175
+ title: "Draft: Caveat official private evidence NDJSON frame v1",
176
+ oneOf: [
177
+ {
178
+ type: "object",
179
+ additionalProperties: false,
180
+ required: [
181
+ "schema",
182
+ "collection_id",
183
+ "nonce",
184
+ "execution_id",
185
+ "type",
186
+ "product",
187
+ "product_version",
188
+ "public_diagnostic_schema",
189
+ "transport",
190
+ "process"
191
+ ],
192
+ properties: {
193
+ schema: {
194
+ const: "caveat.factory_private_evidence.v1"
195
+ },
196
+ collection_id: {
197
+ type: "string",
198
+ pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
199
+ },
200
+ nonce: {
201
+ type: "string",
202
+ pattern: "^[0-9a-f]{64}$"
203
+ },
204
+ execution_id: {
205
+ type: "string",
206
+ pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
207
+ },
208
+ type: {
209
+ const: "hello"
210
+ },
211
+ product: {
212
+ const: "caveat"
213
+ },
214
+ product_version: {
215
+ type: "string",
216
+ pattern: "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$",
217
+ maxLength: 128
218
+ },
219
+ public_diagnostic_schema: {
220
+ const: "caveat.native_factory_diagnostics.v1"
221
+ },
222
+ transport: {
223
+ enum: [
224
+ "posix-fd-v1",
225
+ "windows-named-pipe-v1"
226
+ ]
227
+ },
228
+ process: {
229
+ type: "object",
230
+ additionalProperties: false,
231
+ required: [
232
+ "pid",
233
+ "parent_pid",
234
+ "start_identity",
235
+ "identity",
236
+ "exec_path",
237
+ "entry_realpath",
238
+ "package_version",
239
+ "build_id",
240
+ "missing_reasons"
241
+ ],
242
+ properties: {
243
+ pid: {
244
+ type: "integer",
245
+ minimum: 1,
246
+ maximum: 9007199254740991
247
+ },
248
+ parent_pid: {
249
+ anyOf: [
250
+ {
251
+ type: "integer",
252
+ minimum: 0,
253
+ maximum: 9007199254740991
254
+ },
255
+ {
256
+ type: "null"
257
+ }
258
+ ]
259
+ },
260
+ start_identity: {
261
+ type: "object",
262
+ additionalProperties: false,
263
+ required: [
264
+ "source",
265
+ "value"
266
+ ],
267
+ properties: {
268
+ source: {
269
+ enum: [
270
+ "linux_proc_start",
271
+ "windows_process_creation",
272
+ "os_process_start",
273
+ "unavailable"
274
+ ]
275
+ },
276
+ value: {
277
+ anyOf: [
278
+ {
279
+ type: "string",
280
+ minLength: 1,
281
+ maxLength: 256
282
+ },
283
+ {
284
+ type: "null"
285
+ }
286
+ ]
287
+ }
288
+ },
289
+ allOf: [
290
+ {
291
+ if: {
292
+ properties: {
293
+ source: {
294
+ const: "unavailable"
295
+ }
296
+ }
297
+ },
298
+ then: {
299
+ properties: {
300
+ value: {
301
+ type: "null"
302
+ }
303
+ }
304
+ },
305
+ else: {
306
+ properties: {
307
+ value: {
308
+ type: "string"
309
+ }
310
+ }
311
+ }
312
+ }
313
+ ]
314
+ },
315
+ identity: {
316
+ type: "object",
317
+ additionalProperties: false,
318
+ required: [
319
+ "kind",
320
+ "uid",
321
+ "gid",
322
+ "sid"
323
+ ],
324
+ properties: {
325
+ kind: {
326
+ enum: [
327
+ "uid_gid",
328
+ "windows_sid",
329
+ "unknown"
330
+ ]
331
+ },
332
+ uid: {
333
+ anyOf: [
334
+ {
335
+ type: "integer",
336
+ minimum: 0,
337
+ maximum: 9007199254740991
338
+ },
339
+ {
340
+ type: "null"
341
+ }
342
+ ]
343
+ },
344
+ gid: {
345
+ anyOf: [
346
+ {
347
+ type: "integer",
348
+ minimum: 0,
349
+ maximum: 9007199254740991
350
+ },
351
+ {
352
+ type: "null"
353
+ }
354
+ ]
355
+ },
356
+ sid: {
357
+ anyOf: [
358
+ {
359
+ type: "string",
360
+ pattern: "^S-1-[0-9]+(?:-[0-9]+)+$",
361
+ maxLength: 256
362
+ },
363
+ {
364
+ type: "null"
365
+ }
366
+ ]
367
+ }
368
+ },
369
+ allOf: [
370
+ {
371
+ if: {
372
+ properties: {
373
+ kind: {
374
+ const: "uid_gid"
375
+ }
376
+ }
377
+ },
378
+ then: {
379
+ properties: {
380
+ uid: {
381
+ type: "integer"
382
+ },
383
+ gid: {
384
+ type: "integer"
385
+ },
386
+ sid: {
387
+ type: "null"
388
+ }
389
+ }
390
+ }
391
+ },
392
+ {
393
+ if: {
394
+ properties: {
395
+ kind: {
396
+ const: "windows_sid"
397
+ }
398
+ }
399
+ },
400
+ then: {
401
+ properties: {
402
+ uid: {
403
+ type: "null"
404
+ },
405
+ gid: {
406
+ type: "null"
407
+ },
408
+ sid: {
409
+ type: "string"
410
+ }
411
+ }
412
+ }
413
+ },
414
+ {
415
+ if: {
416
+ properties: {
417
+ kind: {
418
+ const: "unknown"
419
+ }
420
+ }
421
+ },
422
+ then: {
423
+ properties: {
424
+ uid: {
425
+ type: "null"
426
+ },
427
+ gid: {
428
+ type: "null"
429
+ },
430
+ sid: {
431
+ type: "null"
432
+ }
433
+ }
434
+ }
435
+ }
436
+ ]
437
+ },
438
+ exec_path: {
439
+ anyOf: [
440
+ {
441
+ type: "string",
442
+ minLength: 1,
443
+ maxLength: 4096
444
+ },
445
+ {
446
+ type: "null"
447
+ }
448
+ ]
449
+ },
450
+ entry_realpath: {
451
+ anyOf: [
452
+ {
453
+ type: "string",
454
+ minLength: 1,
455
+ maxLength: 4096
456
+ },
457
+ {
458
+ type: "null"
459
+ }
460
+ ]
461
+ },
462
+ package_version: {
463
+ type: "string",
464
+ pattern: "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$",
465
+ maxLength: 128
466
+ },
467
+ build_id: {
468
+ anyOf: [
469
+ {
470
+ type: "string",
471
+ minLength: 1,
472
+ maxLength: 256
473
+ },
474
+ {
475
+ type: "null"
476
+ }
477
+ ]
478
+ },
479
+ missing_reasons: {
480
+ type: "array",
481
+ uniqueItems: true,
482
+ items: {
483
+ enum: [
484
+ "parent_identity_unavailable",
485
+ "start_identity_unavailable",
486
+ "actor_identity_unavailable",
487
+ "exec_path_unavailable",
488
+ "entry_path_unavailable",
489
+ "build_id_unavailable"
490
+ ]
491
+ }
492
+ }
493
+ }
494
+ }
495
+ }
496
+ },
497
+ {
498
+ type: "object",
499
+ additionalProperties: false,
500
+ required: [
501
+ "schema",
502
+ "collection_id",
503
+ "nonce",
504
+ "execution_id",
505
+ "type",
506
+ "public_output",
507
+ "public_result",
508
+ "sync_observation",
509
+ "operation_receipt"
510
+ ],
511
+ properties: {
512
+ schema: {
513
+ const: "caveat.factory_private_evidence.v1"
514
+ },
515
+ collection_id: {
516
+ type: "string",
517
+ pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
518
+ },
519
+ nonce: {
520
+ type: "string",
521
+ pattern: "^[0-9a-f]{64}$"
522
+ },
523
+ execution_id: {
524
+ type: "string",
525
+ pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
526
+ },
527
+ type: {
528
+ const: "diagnostic_result"
529
+ },
530
+ public_output: {
531
+ type: "object",
532
+ additionalProperties: false,
533
+ required: [
534
+ "bytes",
535
+ "sha256"
536
+ ],
537
+ properties: {
538
+ bytes: {
539
+ type: "integer",
540
+ minimum: 0,
541
+ maximum: 9007199254740991
542
+ },
543
+ sha256: {
544
+ type: "string",
545
+ pattern: "^[0-9a-f]{64}$"
546
+ }
547
+ }
548
+ },
549
+ public_result: {
550
+ type: "object",
551
+ additionalProperties: false,
552
+ required: [
553
+ "schema",
554
+ "overall_status",
555
+ "planned_exit_code"
556
+ ],
557
+ properties: {
558
+ schema: {
559
+ const: "caveat.native_factory_diagnostics.v1"
560
+ },
561
+ overall_status: {
562
+ enum: [
563
+ "ready",
564
+ "not_ready",
565
+ "unverified"
566
+ ]
567
+ },
568
+ planned_exit_code: {
569
+ enum: [
570
+ 0,
571
+ 1
572
+ ]
573
+ }
574
+ },
575
+ allOf: [
576
+ {
577
+ if: {
578
+ properties: {
579
+ overall_status: {
580
+ const: "ready"
581
+ }
582
+ }
583
+ },
584
+ then: {
585
+ properties: {
586
+ planned_exit_code: {
587
+ const: 0
588
+ }
589
+ }
590
+ },
591
+ else: {
592
+ properties: {
593
+ planned_exit_code: {
594
+ const: 1
595
+ }
596
+ }
597
+ }
598
+ }
599
+ ]
600
+ },
601
+ sync_observation: {
602
+ type: "object",
603
+ additionalProperties: false,
604
+ required: [
605
+ "status",
606
+ "reason_code",
607
+ "repo_identity",
608
+ "local_head",
609
+ "remote_head",
610
+ "comparison",
611
+ "relation_counts"
612
+ ],
613
+ properties: {
614
+ status: {
615
+ enum: [
616
+ "ready",
617
+ "not_ready",
618
+ "unverified"
619
+ ]
620
+ },
621
+ reason_code: {
622
+ type: "string",
623
+ pattern: "^[a-z][a-z0-9_]{0,63}$"
624
+ },
625
+ repo_identity: {
626
+ type: "object",
627
+ additionalProperties: false,
628
+ required: [
629
+ "status",
630
+ "algorithm",
631
+ "digest",
632
+ "reason"
633
+ ],
634
+ properties: {
635
+ status: {
636
+ enum: [
637
+ "available",
638
+ "not_observed",
639
+ "unverified"
640
+ ]
641
+ },
642
+ algorithm: {
643
+ anyOf: [
644
+ {
645
+ const: "origin-descriptor-sha256-v1"
646
+ },
647
+ {
648
+ type: "null"
649
+ }
650
+ ]
651
+ },
652
+ digest: {
653
+ anyOf: [
654
+ {
655
+ type: "string",
656
+ pattern: "^[0-9a-f]{64}$"
657
+ },
658
+ {
659
+ type: "null"
660
+ }
661
+ ]
662
+ },
663
+ reason: {
664
+ enum: [
665
+ "origin_descriptor_observed",
666
+ "origin_not_reached",
667
+ "origin_capture_unverified",
668
+ "origin_syntax_unsupported",
669
+ "origin_semantics_ambiguous"
670
+ ]
671
+ }
672
+ },
673
+ allOf: [
674
+ {
675
+ if: {
676
+ properties: {
677
+ status: {
678
+ const: "available"
679
+ }
680
+ }
681
+ },
682
+ then: {
683
+ properties: {
684
+ algorithm: {
685
+ const: "origin-descriptor-sha256-v1"
686
+ },
687
+ digest: {
688
+ type: "string",
689
+ pattern: "^[0-9a-f]{64}$"
690
+ },
691
+ reason: {
692
+ const: "origin_descriptor_observed"
693
+ }
694
+ }
695
+ },
696
+ else: {
697
+ properties: {
698
+ algorithm: {
699
+ type: "null"
700
+ },
701
+ digest: {
702
+ type: "null"
703
+ }
704
+ }
705
+ }
706
+ },
707
+ {
708
+ if: {
709
+ properties: {
710
+ status: {
711
+ const: "not_observed"
712
+ }
713
+ }
714
+ },
715
+ then: {
716
+ properties: {
717
+ reason: {
718
+ const: "origin_not_reached"
719
+ }
720
+ }
721
+ }
722
+ },
723
+ {
724
+ if: {
725
+ properties: {
726
+ status: {
727
+ const: "unverified"
728
+ }
729
+ }
730
+ },
731
+ then: {
732
+ properties: {
733
+ reason: {
734
+ enum: [
735
+ "origin_capture_unverified",
736
+ "origin_syntax_unsupported",
737
+ "origin_semantics_ambiguous"
738
+ ]
739
+ }
740
+ }
741
+ }
742
+ }
743
+ ]
744
+ },
745
+ local_head: {
746
+ type: "object",
747
+ additionalProperties: false,
748
+ required: [
749
+ "status",
750
+ "value",
751
+ "reason"
752
+ ],
753
+ properties: {
754
+ status: {
755
+ enum: [
756
+ "observed",
757
+ "not_observed",
758
+ "unverified"
759
+ ]
760
+ },
761
+ value: {
762
+ anyOf: [
763
+ {
764
+ type: "string",
765
+ pattern: "^[0-9a-f]{40}$"
766
+ },
767
+ {
768
+ type: "null"
769
+ }
770
+ ]
771
+ },
772
+ reason: {
773
+ type: "string",
774
+ pattern: "^[a-z][a-z0-9_]{0,63}$"
775
+ }
776
+ },
777
+ allOf: [
778
+ {
779
+ if: {
780
+ properties: {
781
+ status: {
782
+ const: "observed"
783
+ }
784
+ }
785
+ },
786
+ then: {
787
+ properties: {
788
+ value: {
789
+ type: "string",
790
+ pattern: "^[0-9a-f]{40}$"
791
+ }
792
+ }
793
+ },
794
+ else: {
795
+ properties: {
796
+ value: {
797
+ type: "null"
798
+ }
799
+ }
800
+ }
801
+ }
802
+ ]
803
+ },
804
+ remote_head: {
805
+ type: "object",
806
+ additionalProperties: false,
807
+ required: [
808
+ "status",
809
+ "value",
810
+ "reason"
811
+ ],
812
+ properties: {
813
+ status: {
814
+ enum: [
815
+ "observed",
816
+ "not_observed",
817
+ "unverified"
818
+ ]
819
+ },
820
+ value: {
821
+ anyOf: [
822
+ {
823
+ type: "string",
824
+ pattern: "^[0-9a-f]{40}$"
825
+ },
826
+ {
827
+ type: "null"
828
+ }
829
+ ]
830
+ },
831
+ reason: {
832
+ type: "string",
833
+ pattern: "^[a-z][a-z0-9_]{0,63}$"
834
+ }
835
+ },
836
+ allOf: [
837
+ {
838
+ if: {
839
+ properties: {
840
+ status: {
841
+ const: "observed"
842
+ }
843
+ }
844
+ },
845
+ then: {
846
+ properties: {
847
+ value: {
848
+ type: "string",
849
+ pattern: "^[0-9a-f]{40}$"
850
+ }
851
+ }
852
+ },
853
+ else: {
854
+ properties: {
855
+ value: {
856
+ type: "null"
857
+ }
858
+ }
859
+ }
860
+ }
861
+ ]
862
+ },
863
+ comparison: {
864
+ enum: [
865
+ "equal",
866
+ "different",
867
+ "not_evaluated"
868
+ ]
869
+ },
870
+ relation_counts: {
871
+ type: "object",
872
+ additionalProperties: false,
873
+ required: [
874
+ "status",
875
+ "behind",
876
+ "ahead"
877
+ ],
878
+ properties: {
879
+ status: {
880
+ const: "not_supported"
881
+ },
882
+ behind: {
883
+ type: "null"
884
+ },
885
+ ahead: {
886
+ type: "null"
887
+ }
888
+ }
889
+ }
890
+ }
891
+ },
892
+ operation_receipt: {
893
+ type: "object",
894
+ additionalProperties: false,
895
+ required: [
896
+ "status",
897
+ "receipt"
898
+ ],
899
+ properties: {
900
+ status: {
901
+ const: "not_supported"
902
+ },
903
+ receipt: {
904
+ type: "null"
905
+ }
906
+ }
907
+ }
908
+ }
909
+ }
910
+ ]
911
+ };
912
+
913
+ // src/contracts/factory-private-evidence/windows-channel.v1.schema.json
914
+ var windows_channel_v1_schema_default = {
915
+ $schema: "https://json-schema.org/draft/2020-12/schema",
916
+ $id: "urn:caveat:factory-private-evidence-windows-channel:v1",
917
+ title: "Draft: local Windows private channel descriptor",
918
+ type: "object",
919
+ additionalProperties: false,
920
+ required: [
921
+ "transport",
922
+ "path",
923
+ "server_pid",
924
+ "server_start_identity",
925
+ "owner_sid"
926
+ ],
927
+ properties: {
928
+ transport: {
929
+ const: "windows-named-pipe-v1"
930
+ },
931
+ path: {
932
+ type: "string",
933
+ pattern: "^\\\\\\\\\\.\\\\pipe\\\\caveat-evidence-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
934
+ },
935
+ server_pid: {
936
+ type: "integer",
937
+ minimum: 1,
938
+ maximum: 9007199254740991
939
+ },
940
+ server_start_identity: {
941
+ type: "string",
942
+ minLength: 1,
943
+ maxLength: 256
944
+ },
945
+ owner_sid: {
946
+ type: "string",
947
+ pattern: "^S-1-[0-9]+(?:-[0-9]+)+$",
948
+ maxLength: 256
949
+ }
950
+ }
951
+ };
952
+
953
+ // src/privateEvidence/validation.ts
954
+ var ajv = new Ajv2020({ strict: true, strictRequired: false });
955
+ var validateCapability = ajv.compile(capability_v1_schema_default);
956
+ var validateFrame = ajv.compile(private_frame_v1_schema_default);
957
+ var validateWindowsDescriptor = ajv.compile(windows_channel_v1_schema_default);
958
+ var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
959
+ var NONCE = /^[0-9a-f]{64}$/;
960
+ var MAX_CHANNEL_BYTES = 16384;
961
+ function strictJson(bytes, limit = MAX_CHANNEL_BYTES) {
962
+ if (bytes.byteLength === 0 || bytes.byteLength > limit) throw new Error("json_budget");
963
+ const text = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
964
+ const objects = [];
965
+ let depth = 0, invalid = false;
966
+ visit(text, {
967
+ onObjectBegin() {
968
+ if (++depth > 32) throw new Error("json_depth");
969
+ objects.push(/* @__PURE__ */ new Set());
970
+ },
971
+ onObjectProperty(key) {
972
+ const keys = objects.at(-1);
973
+ if (keys.has(key)) invalid = true;
974
+ keys.add(key);
975
+ },
976
+ onObjectEnd() {
977
+ objects.pop();
978
+ depth--;
979
+ },
980
+ onArrayBegin() {
981
+ if (++depth > 32) throw new Error("json_depth");
982
+ },
983
+ onArrayEnd() {
984
+ depth--;
985
+ },
986
+ onError() {
987
+ invalid = true;
988
+ }
989
+ }, { disallowComments: true, allowTrailingComma: false, allowEmptyContent: false });
990
+ if (invalid || depth !== 0 || objects.length !== 0) throw new Error("json_invalid");
991
+ return JSON.parse(text);
992
+ }
993
+ function validateRequest(env) {
994
+ if (env.CAVEAT_FACTORY_PRIVATE_EVIDENCE !== "v1") return { status: "off" };
995
+ const collection = env.CAVEAT_FACTORY_PRIVATE_COLLECTION_ID;
996
+ const nonce = env.CAVEAT_FACTORY_PRIVATE_NONCE;
997
+ const channel = env.CAVEAT_FACTORY_PRIVATE_CHANNEL;
998
+ if (!collection || !UUID.test(collection) || !nonce || !NONCE.test(nonce) || !channel || channel.length > MAX_CHANNEL_BYTES)
999
+ return { status: "unverified", reason: "request_invalid" };
1000
+ if (channel === "fd:3") return { status: "valid", collection_id: collection, nonce, transport: "posix-fd-v1" };
1001
+ try {
1002
+ const descriptor = strictJson(Buffer.from(channel));
1003
+ if (validateWindowsDescriptor(descriptor))
1004
+ return { status: "valid", collection_id: collection, nonce, transport: "windows-named-pipe-v1" };
1005
+ } catch {
1006
+ }
1007
+ return { status: "unverified", reason: "request_invalid" };
1008
+ }
1009
+ function selectCapability(request, capability, expectedVersion, platform, launchPath) {
1010
+ if (request.status === "off") return { status: "off" };
1011
+ if (request.status !== "valid") return { status: "unverified", reason: "request_invalid" };
1012
+ if (capability == null) return { status: "not_supported", reason: "capability_absent" };
1013
+ if (!validateCapability(capability) || capability.package_version !== expectedVersion)
1014
+ return { status: "unverified", reason: "capability_invalid" };
1015
+ const common = capability.transports.some((t) => t.id === request.transport && t.platforms.includes(platform) && t.launch_paths.includes(launchPath));
1016
+ return common ? { status: "candidate_requires_os_verification" } : { status: "not_supported", reason: "transport_unsupported" };
1017
+ }
1018
+ function validateExchange(input) {
1019
+ const bad = (reason) => ({ status: "unverified", reason });
1020
+ try {
1021
+ if (input.request.status !== "valid" || input.eof !== true || input.peerVerified !== true) return bad("channel_incomplete");
1022
+ if (!validateCapability(input.capability) || input.capability.package_version !== input.expectedVersion)
1023
+ return bad("capability_invalid");
1024
+ if (input.channelBytes.byteLength > MAX_CHANNEL_BYTES) return bad("channel_budget");
1025
+ const bytes = Buffer.from(input.channelBytes);
1026
+ if (bytes.at(-1) !== 10) return bad("frame_framing");
1027
+ const lines = bytes.toString("latin1").split("\n");
1028
+ if (lines.length !== 3 || lines[2] !== "") return bad("frame_framing");
1029
+ const frames = lines.slice(0, 2).map((line) => strictJson(Buffer.from(line, "latin1")));
1030
+ if (frames.some((frame) => !validateFrame(frame))) return bad("frame_schema");
1031
+ const [hello, result] = frames;
1032
+ if (hello.type !== "hello" || result.type !== "diagnostic_result") return bad("frame_order");
1033
+ if (!UUID.test(hello.execution_id)) return bad("frame_identity");
1034
+ for (const key of ["schema", "collection_id", "nonce", "execution_id"])
1035
+ if (hello[key] !== result[key]) return bad("frame_identity");
1036
+ if (hello.collection_id !== input.request.collection_id || hello.nonce !== input.request.nonce || hello.product_version !== input.expectedVersion || hello.process.package_version !== input.expectedVersion || hello.transport !== input.request.transport) return bad("frame_identity");
1037
+ if (selectCapability(input.request, input.capability, input.expectedVersion, input.platform, input.launchPath).status !== "candidate_requires_os_verification") return bad("transport_unsupported");
1038
+ const p = hello.process;
1039
+ if (!input.expectedProcess || !isDeepStrictEqual(p, input.expectedProcess)) return bad("peer_identity");
1040
+ const needed = [];
1041
+ for (const [key, reason] of [
1042
+ ["parent_pid", "parent_identity_unavailable"],
1043
+ ["exec_path", "exec_path_unavailable"],
1044
+ ["entry_realpath", "entry_path_unavailable"],
1045
+ ["build_id", "build_id_unavailable"]
1046
+ ])
1047
+ if (p[key] === null) needed.push(reason);
1048
+ if (p.start_identity.source === "unavailable") needed.push("start_identity_unavailable");
1049
+ if (p.identity.kind === "unknown") needed.push("actor_identity_unavailable");
1050
+ if (!isDeepStrictEqual([...needed].sort(), [...p.missing_reasons].sort())) return bad("process_missing_reason");
1051
+ if (input.publicBytes.at(-1) !== 10 || input.publicBytes.subarray(0, -1).includes(10)) return bad("public_framing");
1052
+ const pub = strictJson(input.publicBytes, 65536);
1053
+ if (pub.schema !== hello.public_diagnostic_schema || pub.product !== "caveat" || pub.version !== input.expectedVersion || pub.overall?.status !== result.public_result.overall_status || pub.sync?.status !== result.sync_observation.status || pub.sync?.reason_code !== result.sync_observation.reason_code) return bad("public_mismatch");
1054
+ if (result.public_output.bytes !== input.publicBytes.byteLength || result.public_output.sha256 !== createHash("sha256").update(input.publicBytes).digest("hex")) return bad("public_bytes_mismatch");
1055
+ const sync = result.sync_observation;
1056
+ const both = sync.local_head.status === "observed" && sync.remote_head.status === "observed";
1057
+ const comparison = both ? sync.local_head.value === sync.remote_head.value ? "equal" : "different" : "not_evaluated";
1058
+ if (sync.comparison !== comparison) return bad("head_comparison");
1059
+ const repo = sync.repo_identity;
1060
+ const allowed = repo.status === "available" ? ["origin_descriptor_observed"] : repo.status === "not_observed" ? ["origin_not_reached"] : ["origin_capture_unverified", "origin_syntax_unsupported", "origin_semantics_ambiguous"];
1061
+ if (!allowed.includes(repo.reason)) return bad("origin_reason");
1062
+ return { status: "valid", reason: "complete_synthetic_exchange" };
1063
+ } catch {
1064
+ return bad("exchange_invalid");
1065
+ }
1066
+ }
1067
+ export {
1068
+ MAX_CHANNEL_BYTES,
1069
+ UUID,
1070
+ selectCapability,
1071
+ strictJson,
1072
+ validateCapability,
1073
+ validateExchange,
1074
+ validateFrame,
1075
+ validateRequest,
1076
+ validateWindowsDescriptor
1077
+ };
1078
+ //# sourceMappingURL=validation.js.map