@behavproof/cli 0.0.0-stage → 0.1.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 (67) hide show
  1. package/README.md +14 -2
  2. package/dist/api.d.ts +6 -0
  3. package/dist/api.d.ts.map +1 -0
  4. package/dist/api.js +5 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/check.d.ts +272 -0
  7. package/dist/check.d.ts.map +1 -0
  8. package/dist/check.js +220 -0
  9. package/dist/check.js.map +1 -0
  10. package/dist/formal-evaluation.d.ts +108 -0
  11. package/dist/formal-evaluation.d.ts.map +1 -0
  12. package/dist/formal-evaluation.js +78 -0
  13. package/dist/formal-evaluation.js.map +1 -0
  14. package/dist/formal-worker.d.ts +2 -0
  15. package/dist/formal-worker.d.ts.map +1 -0
  16. package/dist/formal-worker.js +32 -0
  17. package/dist/formal-worker.js.map +1 -0
  18. package/dist/formal.d.ts +148 -0
  19. package/dist/formal.d.ts.map +1 -0
  20. package/dist/formal.js +99 -0
  21. package/dist/formal.js.map +1 -0
  22. package/dist/impact.d.ts +20 -0
  23. package/dist/impact.d.ts.map +1 -0
  24. package/dist/impact.js +23 -0
  25. package/dist/impact.js.map +1 -0
  26. package/dist/index.d.ts +3 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +151 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/pipeline.d.ts +38 -0
  31. package/dist/pipeline.d.ts.map +1 -0
  32. package/dist/pipeline.js +46 -0
  33. package/dist/pipeline.js.map +1 -0
  34. package/dist/project.d.ts +97 -0
  35. package/dist/project.d.ts.map +1 -0
  36. package/dist/project.js +101 -0
  37. package/dist/project.js.map +1 -0
  38. package/dist/registration.d.ts +595 -0
  39. package/dist/registration.d.ts.map +1 -0
  40. package/dist/registration.js +112 -0
  41. package/dist/registration.js.map +1 -0
  42. package/dist/report.d.ts +23 -0
  43. package/dist/report.d.ts.map +1 -0
  44. package/dist/report.js +34 -0
  45. package/dist/report.js.map +1 -0
  46. package/dist/scopes.d.ts +48 -0
  47. package/dist/scopes.d.ts.map +1 -0
  48. package/dist/scopes.js +60 -0
  49. package/dist/scopes.js.map +1 -0
  50. package/dist/trust.d.ts +533 -0
  51. package/dist/trust.d.ts.map +1 -0
  52. package/dist/trust.js +130 -0
  53. package/dist/trust.js.map +1 -0
  54. package/package.json +51 -4
  55. package/presets/basic-v1.json +21 -0
  56. package/presets/critical-v1.json +39 -0
  57. package/presets/standard-v1.json +21 -0
  58. package/schemas/config.schema.json +492 -0
  59. package/schemas/evidence.schema.json +3612 -0
  60. package/schemas/manifest.schema.json +225 -0
  61. package/schemas/policy.schema.json +21 -0
  62. package/schemas/registration.schema.json +1065 -0
  63. package/schemas/registry.schema.json +307 -0
  64. package/schemas/trust-root.schema.json +1445 -0
  65. package/templates/audit.yml +28 -0
  66. package/templates/protected-github-producer.yml +58 -0
  67. package/templates/protected-github-publisher.yml +111 -0
@@ -0,0 +1,533 @@
1
+ import { z } from 'zod';
2
+ import { type EvidenceSubject, type ManifestValidation, type Evidence, type Contract } from '@behavproof/core';
3
+ export declare const ClaimScopesSchema: z.ZodArray<z.ZodObject<{
4
+ contractId: z.ZodString;
5
+ caseIds: z.ZodArray<z.ZodString>;
6
+ targetRef: z.ZodString;
7
+ method: z.ZodString;
8
+ }, z.core.$strict>>;
9
+ export declare const TrustRootSchema: z.ZodObject<{
10
+ schemaVersion: z.ZodLiteral<1>;
11
+ policy: z.ZodObject<{
12
+ schemaVersion: z.ZodLiteral<1>;
13
+ profileVersion: z.ZodLiteral<"1">;
14
+ rules: z.ZodPipe<z.ZodUnknown, z.ZodRecord<z.ZodString, z.ZodObject<{
15
+ severity: z.ZodEnum<{
16
+ error: "error";
17
+ off: "off";
18
+ warn: "warn";
19
+ }>;
20
+ min: z.ZodOptional<z.ZodNumber>;
21
+ minMutants: z.ZodOptional<z.ZodNumber>;
22
+ allowNotApplicable: z.ZodOptional<z.ZodArray<z.ZodString>>;
23
+ }, z.core.$strict>>>;
24
+ }, z.core.$strict>;
25
+ config: z.ZodPipe<z.ZodObject<{
26
+ schemaVersion: z.ZodLiteral<1>;
27
+ formal: z.ZodOptional<z.ZodObject<{
28
+ models: z.ZodArray<z.ZodObject<{
29
+ id: z.ZodString;
30
+ contractId: z.ZodString;
31
+ model: z.ZodString;
32
+ modelSources: z.ZodDefault<z.ZodArray<z.ZodString>>;
33
+ quint: z.ZodObject<{
34
+ entry: z.ZodString;
35
+ version: z.ZodString;
36
+ apalacheVersion: z.ZodOptional<z.ZodString>;
37
+ }, z.core.$strict>;
38
+ properties: z.ZodArray<z.ZodString>;
39
+ checks: z.ZodArray<z.ZodEnum<{
40
+ parse: "parse";
41
+ typecheck: "typecheck";
42
+ test: "test";
43
+ run: "run";
44
+ verify: "verify";
45
+ }>>;
46
+ maxSteps: z.ZodNumber;
47
+ maxSamples: z.ZodDefault<z.ZodNumber>;
48
+ seed: z.ZodString;
49
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
50
+ report: z.ZodString;
51
+ driver: z.ZodOptional<z.ZodString>;
52
+ driverSources: z.ZodOptional<z.ZodArray<z.ZodString>>;
53
+ implementation: z.ZodOptional<z.ZodString>;
54
+ implementationSources: z.ZodDefault<z.ZodArray<z.ZodString>>;
55
+ conformanceReport: z.ZodOptional<z.ZodString>;
56
+ traceReceipt: z.ZodOptional<z.ZodString>;
57
+ traceDirectory: z.ZodOptional<z.ZodString>;
58
+ requiredActions: z.ZodDefault<z.ZodArray<z.ZodString>>;
59
+ minTraces: z.ZodDefault<z.ZodNumber>;
60
+ minComparisons: z.ZodDefault<z.ZodNumber>;
61
+ requireCanary: z.ZodDefault<z.ZodBoolean>;
62
+ canary: z.ZodOptional<z.ZodObject<{
63
+ faultId: z.ZodString;
64
+ implementation: z.ZodString;
65
+ targetRef: z.ZodString;
66
+ }, z.core.$strict>>;
67
+ }, z.core.$strict>>;
68
+ }, z.core.$strict>>;
69
+ mode: z.ZodDefault<z.ZodEnum<{
70
+ audit: "audit";
71
+ gate: "gate";
72
+ }>>;
73
+ profile: z.ZodDefault<z.ZodEnum<{
74
+ basic: "basic";
75
+ standard: "standard";
76
+ critical: "critical";
77
+ }>>;
78
+ profileVersion: z.ZodDefault<z.ZodLiteral<"1">>;
79
+ riskOverrides: z.ZodDefault<z.ZodArray<z.ZodObject<{
80
+ selector: z.ZodDiscriminatedUnion<[z.ZodObject<{
81
+ kind: z.ZodLiteral<"path">;
82
+ value: z.ZodString;
83
+ }, z.core.$strict>, z.ZodObject<{
84
+ kind: z.ZodLiteral<"module">;
85
+ value: z.ZodString;
86
+ }, z.core.$strict>, z.ZodObject<{
87
+ kind: z.ZodLiteral<"contract-kind">;
88
+ value: z.ZodEnum<{
89
+ external: "external";
90
+ examples: "examples";
91
+ invariant: "invariant";
92
+ state_machine: "state_machine";
93
+ api_contract: "api_contract";
94
+ }>;
95
+ }, z.core.$strict>], "kind">;
96
+ profile: z.ZodEnum<{
97
+ basic: "basic";
98
+ standard: "standard";
99
+ critical: "critical";
100
+ }>;
101
+ }, z.core.$strict>>>;
102
+ git: z.ZodDefault<z.ZodObject<{
103
+ base: z.ZodDefault<z.ZodString>;
104
+ }, z.core.$strict>>;
105
+ reports: z.ZodDefault<z.ZodObject<{
106
+ vitest: z.ZodOptional<z.ZodString>;
107
+ coverage: z.ZodOptional<z.ZodString>;
108
+ mutation: z.ZodOptional<z.ZodString>;
109
+ }, z.core.$strict>>;
110
+ executionManifests: z.ZodDefault<z.ZodArray<z.ZodString>>;
111
+ rules: z.ZodDefault<z.ZodPipe<z.ZodUnknown, z.ZodRecord<z.ZodString, z.ZodObject<{
112
+ severity: z.ZodEnum<{
113
+ error: "error";
114
+ off: "off";
115
+ warn: "warn";
116
+ }>;
117
+ min: z.ZodOptional<z.ZodNumber>;
118
+ minMutants: z.ZodOptional<z.ZodNumber>;
119
+ allowNotApplicable: z.ZodOptional<z.ZodArray<z.ZodString>>;
120
+ }, z.core.$strict>>>>;
121
+ contracts: z.ZodDefault<z.ZodObject<{
122
+ enabled: z.ZodDefault<z.ZodBoolean>;
123
+ sources: z.ZodDefault<z.ZodArray<z.ZodObject<{
124
+ type: z.ZodEnum<{
125
+ external: "external";
126
+ "vitest-inline": "vitest-inline";
127
+ manifest: "manifest";
128
+ gherkin: "gherkin";
129
+ openapi: "openapi";
130
+ }>;
131
+ include: z.ZodArray<z.ZodString>;
132
+ }, z.core.$strict>>>;
133
+ requireExecutionEvidence: z.ZodDefault<z.ZodBoolean>;
134
+ approval: z.ZodDefault<z.ZodObject<{
135
+ provider: z.ZodLiteral<"github-protected-review">;
136
+ requiredForRisk: z.ZodDefault<z.ZodArray<z.ZodEnum<{
137
+ basic: "basic";
138
+ standard: "standard";
139
+ critical: "critical";
140
+ }>>>;
141
+ onUnverifiable: z.ZodDefault<z.ZodLiteral<"unknown">>;
142
+ }, z.core.$strict>>;
143
+ documents: z.ZodDefault<z.ZodObject<{
144
+ output: z.ZodDefault<z.ZodString>;
145
+ commit: z.ZodDefault<z.ZodBoolean>;
146
+ }, z.core.$strict>>;
147
+ }, z.core.$strict>>;
148
+ }, z.core.$strict>, z.ZodTransform<{
149
+ rules: Record<string, {
150
+ severity: "error" | "off" | "warn";
151
+ min?: number | undefined;
152
+ minMutants?: number | undefined;
153
+ allowNotApplicable?: string[] | undefined;
154
+ }>;
155
+ schemaVersion: 1;
156
+ mode: "audit" | "gate";
157
+ profile: "basic" | "standard" | "critical";
158
+ profileVersion: "1";
159
+ riskOverrides: {
160
+ selector: {
161
+ kind: "path";
162
+ value: string;
163
+ } | {
164
+ kind: "module";
165
+ value: string;
166
+ } | {
167
+ kind: "contract-kind";
168
+ value: "external" | "examples" | "invariant" | "state_machine" | "api_contract";
169
+ };
170
+ profile: "basic" | "standard" | "critical";
171
+ }[];
172
+ git: {
173
+ base: string;
174
+ };
175
+ reports: {
176
+ vitest?: string | undefined;
177
+ coverage?: string | undefined;
178
+ mutation?: string | undefined;
179
+ };
180
+ executionManifests: string[];
181
+ contracts: {
182
+ enabled: boolean;
183
+ sources: {
184
+ type: "external" | "vitest-inline" | "manifest" | "gherkin" | "openapi";
185
+ include: string[];
186
+ }[];
187
+ requireExecutionEvidence: boolean;
188
+ approval: {
189
+ provider: "github-protected-review";
190
+ requiredForRisk: ("basic" | "standard" | "critical")[];
191
+ onUnverifiable: "unknown";
192
+ };
193
+ documents: {
194
+ output: string;
195
+ commit: boolean;
196
+ };
197
+ };
198
+ formal?: {
199
+ models: {
200
+ id: string;
201
+ contractId: string;
202
+ model: string;
203
+ modelSources: string[];
204
+ quint: {
205
+ entry: string;
206
+ version: string;
207
+ apalacheVersion?: string | undefined;
208
+ };
209
+ properties: string[];
210
+ checks: ("parse" | "typecheck" | "test" | "run" | "verify")[];
211
+ maxSteps: number;
212
+ maxSamples: number;
213
+ seed: string;
214
+ timeoutMs: number;
215
+ report: string;
216
+ implementationSources: string[];
217
+ requiredActions: string[];
218
+ minTraces: number;
219
+ minComparisons: number;
220
+ requireCanary: boolean;
221
+ driver?: string | undefined;
222
+ driverSources?: string[] | undefined;
223
+ implementation?: string | undefined;
224
+ conformanceReport?: string | undefined;
225
+ traceReceipt?: string | undefined;
226
+ traceDirectory?: string | undefined;
227
+ canary?: {
228
+ faultId: string;
229
+ implementation: string;
230
+ targetRef: string;
231
+ } | undefined;
232
+ }[];
233
+ } | undefined;
234
+ }, {
235
+ schemaVersion: 1;
236
+ mode: "audit" | "gate";
237
+ profile: "basic" | "standard" | "critical";
238
+ profileVersion: "1";
239
+ riskOverrides: {
240
+ selector: {
241
+ kind: "path";
242
+ value: string;
243
+ } | {
244
+ kind: "module";
245
+ value: string;
246
+ } | {
247
+ kind: "contract-kind";
248
+ value: "external" | "examples" | "invariant" | "state_machine" | "api_contract";
249
+ };
250
+ profile: "basic" | "standard" | "critical";
251
+ }[];
252
+ git: {
253
+ base: string;
254
+ };
255
+ reports: {
256
+ vitest?: string | undefined;
257
+ coverage?: string | undefined;
258
+ mutation?: string | undefined;
259
+ };
260
+ executionManifests: string[];
261
+ rules: Record<string, {
262
+ severity: "error" | "off" | "warn";
263
+ min?: number | undefined;
264
+ minMutants?: number | undefined;
265
+ allowNotApplicable?: string[] | undefined;
266
+ }>;
267
+ contracts: {
268
+ enabled: boolean;
269
+ sources: {
270
+ type: "external" | "vitest-inline" | "manifest" | "gherkin" | "openapi";
271
+ include: string[];
272
+ }[];
273
+ requireExecutionEvidence: boolean;
274
+ approval: {
275
+ provider: "github-protected-review";
276
+ requiredForRisk: ("basic" | "standard" | "critical")[];
277
+ onUnverifiable: "unknown";
278
+ };
279
+ documents: {
280
+ output: string;
281
+ commit: boolean;
282
+ };
283
+ };
284
+ formal?: {
285
+ models: {
286
+ id: string;
287
+ contractId: string;
288
+ model: string;
289
+ modelSources: string[];
290
+ quint: {
291
+ entry: string;
292
+ version: string;
293
+ apalacheVersion?: string | undefined;
294
+ };
295
+ properties: string[];
296
+ checks: ("parse" | "typecheck" | "test" | "run" | "verify")[];
297
+ maxSteps: number;
298
+ maxSamples: number;
299
+ seed: string;
300
+ timeoutMs: number;
301
+ report: string;
302
+ implementationSources: string[];
303
+ requiredActions: string[];
304
+ minTraces: number;
305
+ minComparisons: number;
306
+ requireCanary: boolean;
307
+ driver?: string | undefined;
308
+ driverSources?: string[] | undefined;
309
+ implementation?: string | undefined;
310
+ conformanceReport?: string | undefined;
311
+ traceReceipt?: string | undefined;
312
+ traceDirectory?: string | undefined;
313
+ canary?: {
314
+ faultId: string;
315
+ implementation: string;
316
+ targetRef: string;
317
+ } | undefined;
318
+ }[];
319
+ } | undefined;
320
+ }>>;
321
+ baseline: z.ZodObject<{
322
+ schemaVersion: z.ZodLiteral<1>;
323
+ repositoryId: z.ZodOptional<z.ZodString>;
324
+ commitSha: z.ZodString;
325
+ contracts: z.ZodArray<z.ZodObject<{
326
+ id: z.ZodString;
327
+ formal: z.ZodOptional<z.ZodObject<{
328
+ modelId: z.ZodString;
329
+ modelHash: z.ZodString;
330
+ driverHash: z.ZodOptional<z.ZodString>;
331
+ propertyIds: z.ZodArray<z.ZodString>;
332
+ }, z.core.$strict>>;
333
+ kind: z.ZodEnum<{
334
+ external: "external";
335
+ examples: "examples";
336
+ invariant: "invariant";
337
+ state_machine: "state_machine";
338
+ api_contract: "api_contract";
339
+ }>;
340
+ intentIds: z.ZodArray<z.ZodString>;
341
+ revisionHash: z.ZodString;
342
+ sourceRef: z.ZodString;
343
+ caseIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
344
+ risk: z.ZodOptional<z.ZodEnum<{
345
+ basic: "basic";
346
+ standard: "standard";
347
+ critical: "critical";
348
+ }>>;
349
+ cases: z.ZodOptional<z.ZodArray<z.ZodObject<{
350
+ id: z.ZodString;
351
+ input: z.ZodJSONSchema;
352
+ expected: z.ZodJSONSchema;
353
+ negative: z.ZodOptional<z.ZodBoolean>;
354
+ }, z.core.$strict>>>;
355
+ }, z.core.$strict>>;
356
+ intents: z.ZodArray<z.ZodObject<{
357
+ id: z.ZodString;
358
+ statement: z.ZodString;
359
+ risk: z.ZodEnum<{
360
+ basic: "basic";
361
+ standard: "standard";
362
+ critical: "critical";
363
+ }>;
364
+ contentHash: z.ZodString;
365
+ origin: z.ZodObject<{
366
+ kind: z.ZodEnum<{
367
+ external: "external";
368
+ manifest: "manifest";
369
+ inline: "inline";
370
+ }>;
371
+ ref: z.ZodString;
372
+ }, z.core.$strict>;
373
+ }, z.core.$strict>>;
374
+ policyHash: z.ZodOptional<z.ZodString>;
375
+ extractorVersion: z.ZodOptional<z.ZodString>;
376
+ scope: z.ZodOptional<z.ZodArray<z.ZodString>>;
377
+ discoveryDiagnostics: z.ZodOptional<z.ZodArray<z.ZodObject<{
378
+ code: z.ZodString;
379
+ sourceRef: z.ZodString;
380
+ message: z.ZodString;
381
+ }, z.core.$strict>>>;
382
+ }, z.core.$strict>;
383
+ policySource: z.ZodOptional<z.ZodObject<{
384
+ repository: z.ZodString;
385
+ commitSha: z.ZodString;
386
+ ref: z.ZodString;
387
+ fileHash: z.ZodString;
388
+ policyHash: z.ZodString;
389
+ }, z.core.$strict>>;
390
+ runner: z.ZodOptional<z.ZodObject<{
391
+ kind: z.ZodLiteral<"vitest">;
392
+ version: z.ZodString;
393
+ manifestRef: z.ZodString;
394
+ }, z.core.$strict>>;
395
+ inputs: z.ZodArray<z.ZodString>;
396
+ qualitySources: z.ZodOptional<z.ZodArray<z.ZodString>>;
397
+ configPaths: z.ZodArray<z.ZodString>;
398
+ dependencyLockPath: z.ZodOptional<z.ZodString>;
399
+ manifests: z.ZodArray<z.ZodObject<{
400
+ ref: z.ZodString;
401
+ manifestHash: z.ZodOptional<z.ZodString>;
402
+ expected: z.ZodObject<{
403
+ executionId: z.ZodString;
404
+ subject: z.ZodObject<{
405
+ repositoryId: z.ZodOptional<z.ZodString>;
406
+ prHeadSha: z.ZodOptional<z.ZodString>;
407
+ testedCommitSha: z.ZodString;
408
+ testedCommitParents: z.ZodOptional<z.ZodArray<z.ZodString>>;
409
+ sourceTreeHash: z.ZodString;
410
+ dirty: z.ZodBoolean;
411
+ baseSha: z.ZodOptional<z.ZodString>;
412
+ diffBaseSha: z.ZodOptional<z.ZodString>;
413
+ }, z.core.$strict>;
414
+ commandHash: z.ZodString;
415
+ configHashes: z.ZodRecord<z.ZodString, z.ZodString>;
416
+ dependencyLockHash: z.ZodOptional<z.ZodString>;
417
+ artifacts: z.ZodArray<z.ZodObject<{
418
+ ref: z.ZodString;
419
+ kind: z.ZodString;
420
+ scope: z.ZodArray<z.ZodString>;
421
+ }, z.core.$strict>>;
422
+ }, z.core.$strict>;
423
+ authority: z.ZodDiscriminatedUnion<[z.ZodObject<{
424
+ kind: z.ZodLiteral<"ci">;
425
+ producer: z.ZodObject<{
426
+ tool: z.ZodString;
427
+ version: z.ZodString;
428
+ collectorVersion: z.ZodString;
429
+ }, z.core.$strict>;
430
+ ci: z.ZodObject<{
431
+ repositoryId: z.ZodString;
432
+ workflowRef: z.ZodString;
433
+ runId: z.ZodString;
434
+ runAttempt: z.ZodNumber;
435
+ jobId: z.ZodString;
436
+ eventName: z.ZodString;
437
+ }, z.core.$strict>;
438
+ }, z.core.$strict>, z.ZodObject<{
439
+ kind: z.ZodLiteral<"local">;
440
+ producer: z.ZodObject<{
441
+ tool: z.ZodString;
442
+ version: z.ZodString;
443
+ collectorVersion: z.ZodString;
444
+ }, z.core.$strict>;
445
+ executionId: z.ZodString;
446
+ commandHash: z.ZodString;
447
+ }, z.core.$strict>], "kind">;
448
+ github: z.ZodOptional<z.ZodObject<{
449
+ repository: z.ZodString;
450
+ workflowPath: z.ZodString;
451
+ workflowSha: z.ZodString;
452
+ jobName: z.ZodString;
453
+ artifactName: z.ZodString;
454
+ archivePath: z.ZodString;
455
+ archiveEntries: z.ZodRecord<z.ZodString, z.ZodString>;
456
+ }, z.core.$strict>>;
457
+ }, z.core.$strict>>;
458
+ github: z.ZodOptional<z.ZodObject<{
459
+ repository: z.ZodString;
460
+ pr: z.ZodNumber;
461
+ reviewers: z.ZodArray<z.ZodString>;
462
+ requiredChecks: z.ZodArray<z.ZodObject<{
463
+ context: z.ZodString;
464
+ appId: z.ZodNumber;
465
+ }, z.core.$strict>>;
466
+ }, z.core.$strict>>;
467
+ notApplicable: z.ZodDefault<z.ZodArray<z.ZodObject<{
468
+ ruleId: z.ZodString;
469
+ reason: z.ZodString;
470
+ evidenceRef: z.ZodString;
471
+ }, z.core.$strict>>>;
472
+ claimScopes: z.ZodDefault<z.ZodArray<z.ZodObject<{
473
+ contractId: z.ZodString;
474
+ caseIds: z.ZodArray<z.ZodString>;
475
+ targetRef: z.ZodString;
476
+ method: z.ZodString;
477
+ }, z.core.$strict>>>;
478
+ pipeline: z.ZodOptional<z.ZodObject<{
479
+ workflow: z.ZodString;
480
+ gateJob: z.ZodString;
481
+ requiredJobs: z.ZodArray<z.ZodString>;
482
+ artifacts: z.ZodArray<z.ZodString>;
483
+ protectedBranch: z.ZodString;
484
+ currentRun: z.ZodOptional<z.ZodObject<{
485
+ ci: z.ZodObject<{
486
+ repositoryId: z.ZodString;
487
+ workflowRef: z.ZodString;
488
+ runId: z.ZodString;
489
+ runAttempt: z.ZodNumber;
490
+ jobId: z.ZodString;
491
+ eventName: z.ZodString;
492
+ }, z.core.$strict>;
493
+ workflowPath: z.ZodString;
494
+ workflowSha: z.ZodString;
495
+ workflowHash: z.ZodString;
496
+ }, z.core.$strict>>;
497
+ }, z.core.$strict>>;
498
+ }, z.core.$strict>;
499
+ export type TrustRoot = z.infer<typeof TrustRootSchema>;
500
+ export declare function loadTrust(root: string, path: string): Promise<TrustRoot>;
501
+ export declare function authenticate(root: string, trust: TrustRoot | undefined, subject: EvidenceSubject): Promise<{
502
+ verified: Set<string>;
503
+ failures: string[];
504
+ unknowns: string[];
505
+ manifests: {
506
+ ref: string;
507
+ validation: ManifestValidation;
508
+ }[];
509
+ trustedCi: boolean;
510
+ artifactBytes: Map<string, Uint8Array<ArrayBufferLike>>;
511
+ configHashes: Record<string, string>;
512
+ dependencyLockHash: string | undefined;
513
+ observations: {
514
+ manifestRef: string;
515
+ observation: import("@behavproof/adapter-github").Observation;
516
+ }[];
517
+ }>;
518
+ export declare const approvalKey: (v: unknown) => string;
519
+ export declare function isCurrentClaim(evidence: Evidence, artifactRef: string, subject: EvidenceSubject, policyHash: string, contracts: readonly Pick<Contract, 'id' | 'revisionHash'>[]): boolean;
520
+ /** Runner selection belongs to the protected invocation and one authenticated
521
+ * test artifact. It never grants artifact/producer authority by itself. */
522
+ export declare function selectedRunner(trust: TrustRoot | undefined, auth: {
523
+ failures: readonly string[];
524
+ verified: ReadonlySet<string>;
525
+ manifests: readonly {
526
+ ref: string;
527
+ validation: ManifestValidation;
528
+ }[];
529
+ }, testRef: string | undefined, inputs: readonly string[]): {
530
+ runner: "vitest";
531
+ version: string;
532
+ } | undefined;
533
+ //# sourceMappingURL=trust.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust.d.ts","sourceRoot":"","sources":["../src/trust.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAA6O,KAAK,eAAe,EAAE,KAAK,kBAAkB,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG1V,eAAO,MAAM,iBAAiB;;;;;mBAA2e,CAAC;AAC1gB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eA6CqG,CAAC;sBAAwC,CAAC;8BAChI,CAAC;;;;;;;;;;;;;;;;;;;;;;;kBAO2G,CAAC;oBAAsC,CAAC;oBAAsC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAMS,CAAC;;;;;;;;;;;;;;sBAAkf,CAAC;6BAA+C,CAAC;8BAAkD,CAAC;iCAAmD,CAAC;4BAA8C,CAAC;8BAAgD,CAAC;sBAAwC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAyuB,CAAC;oBAAsC,CAAC;oBAAsC,CAAC;;;;;eAAkJ,CAAC;sBAAwC,CAAC;8BAAgD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAAizB,CAAC;;;;;;;;;;;;;;sBAAkf,CAAC;6BAA+C,CAAC;8BAAkD,CAAC;iCAAmD,CAAC;4BAA8C,CAAC;8BAAgD,CAAC;sBAAwC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAjD99G,CAAC;AAChJ,MAAM,MAAM,SAAS,GAAC,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AACtD,wBAAsB,SAAS,CAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,MAAM,GAAE,OAAO,CAAC,SAAS,CAAC,CAI1E;AACD,wBAAsB,YAAY,CAAC,IAAI,EAAC,MAAM,EAAC,KAAK,EAAC,SAAS,GAAC,SAAS,EAAC,OAAO,EAAC,eAAe;;;;;aAE4C,MAAM;oBAAY,kBAAkB;;;;;;;qBAD/I,MAAM;qBAAa,OAAO,4BAA4B,EAAE,WAAW;;GAwBnG;AACD,eAAO,MAAM,WAAW,GAAE,GAAE,OAAO,WAAU,CAAC;AAE9C,wBAAgB,cAAc,CAAC,QAAQ,EAAC,QAAQ,EAAC,WAAW,EAAC,MAAM,EAAC,OAAO,EAAC,eAAe,EAAC,UAAU,EAAC,MAAM,EAAC,SAAS,EAAC,SAAS,IAAI,CAAC,QAAQ,EAAC,IAAI,GAAC,cAAc,CAAC,EAAE,GAAE,OAAO,CAI7K;AAED;2EAC2E;AAC3E,wBAAgB,cAAc,CAAC,KAAK,EAAC,SAAS,GAAC,SAAS,EAAC,IAAI,EAAC;IAAC,QAAQ,EAAC,SAAS,MAAM,EAAE,CAAC;IAAA,QAAQ,EAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAAA,SAAS,EAAC,SAAS;QAAC,GAAG,EAAC,MAAM,CAAC;QAAA,UAAU,EAAC,kBAAkB,CAAA;KAAC,EAAE,CAAA;CAAC,EAAC,OAAO,EAAC,MAAM,GAAC,SAAS,EAAC,MAAM,EAAC,SAAS,MAAM,EAAE;;;cAKxO"}
package/dist/trust.js ADDED
@@ -0,0 +1,130 @@
1
+ import { z } from 'zod';
2
+ import { resolve, dirname, basename, relative, sep, isAbsolute } from 'node:path';
3
+ import { realpath } from 'node:fs/promises';
4
+ import { ConfigSchema, PolicySchema, RegistrySnapshotSchema, RelativePathSchema, HashSchema, CiIdentitySchema, ManifestExpectedSchema, ProducerAuthoritySchema, safeReadJson, safeRead, hashBytes, validateManifest, ExecutionManifestSchema, hash } from '@behavproof/core';
5
+ import { GitHubAuthority, verifyArtifactArchive } from '@behavproof/adapter-github';
6
+ import { git } from './project.js';
7
+ export const ClaimScopesSchema = z.array(z.strictObject({ contractId: z.string().min(1), caseIds: z.array(z.string().min(1)).min(1), targetRef: z.string().min(1), method: z.string().min(1) })).superRefine((scopes, ctx) => { if (new Set(scopes.map(scope => scope.contractId)).size !== scopes.length)
8
+ ctx.addIssue({ code: 'custom', message: 'Only one claim scope per contract is supported' }); for (const scope of scopes)
9
+ if (new Set(scope.caseIds).size !== scope.caseIds.length)
10
+ ctx.addIssue({ code: 'custom', message: 'Duplicate case IDs in claim scope' }); });
11
+ export const TrustRootSchema = z.strictObject({
12
+ schemaVersion: z.literal(1), policy: PolicySchema, config: ConfigSchema, baseline: RegistrySnapshotSchema,
13
+ policySource: z.strictObject({ repository: z.string().regex(/^[\w-]+\/[\w.-]+$/), commitSha: z.string().regex(/^[a-f0-9]{40}$/), ref: RelativePathSchema, fileHash: HashSchema, policyHash: HashSchema }).optional(),
14
+ runner: z.strictObject({ kind: z.literal('vitest'), version: z.string().regex(/^\d+\.\d+\.\d+(?:[-+][\w.-]+)?$/), manifestRef: RelativePathSchema }).optional(),
15
+ inputs: z.array(RelativePathSchema).min(1), qualitySources: z.array(RelativePathSchema).min(1).optional(), configPaths: z.array(RelativePathSchema), dependencyLockPath: RelativePathSchema.optional(),
16
+ manifests: z.array(z.strictObject({ ref: RelativePathSchema, manifestHash: HashSchema.optional(), expected: ManifestExpectedSchema, authority: ProducerAuthoritySchema, github: z.strictObject({ repository: z.string().min(1), workflowPath: z.string(), workflowSha: z.string(), jobName: z.string(), artifactName: z.string(), archivePath: RelativePathSchema, archiveEntries: z.record(RelativePathSchema, RelativePathSchema) }).optional() }).refine(row => row.authority.kind !== 'local' || row.manifestHash !== undefined, 'Local authority requires host-pinned manifestHash')),
17
+ github: z.strictObject({ repository: z.string().regex(/^[\w-]+\/[\w.-]+$/), pr: z.number().int().positive(), reviewers: z.array(z.string().min(1)).min(1), requiredChecks: z.array(z.strictObject({ context: z.string().min(1), appId: z.number().int().positive() })).min(1) }).optional(),
18
+ notApplicable: z.array(z.strictObject({ ruleId: z.string().min(1), reason: z.string().min(1), evidenceRef: RelativePathSchema })).default([]),
19
+ claimScopes: ClaimScopesSchema.default([]),
20
+ pipeline: z.strictObject({ workflow: RelativePathSchema, gateJob: z.string().min(1), requiredJobs: z.array(z.string().min(1)).min(1), artifacts: z.array(RelativePathSchema).min(1), protectedBranch: z.string().min(1), currentRun: z.strictObject({ ci: CiIdentitySchema, workflowPath: RelativePathSchema, workflowSha: z.string().regex(/^[a-f0-9]{40}$/), workflowHash: HashSchema }).optional() }).optional(),
21
+ }).refine(trust => !trust.policySource || trust.policySource.policyHash === hash(trust.policy), 'Registered policy source hash does not match policy');
22
+ export async function loadTrust(root, path) {
23
+ const actual = await realpath(resolve(root, path)), base = await realpath((await git(root, ['rev-parse', '--show-toplevel'])).trim()), rel = relative(base, actual);
24
+ if (rel === '' || (!isAbsolute(rel) && rel !== '..' && !rel.startsWith(`..${sep}`)))
25
+ throw Error('--trust-root must be outside the project');
26
+ return TrustRootSchema.parse(await safeReadJson(dirname(actual), basename(actual)));
27
+ }
28
+ export async function authenticate(root, trust, subject) {
29
+ const observations = [];
30
+ const artifactBytes = new Map();
31
+ const verified = new Set(), failures = [], unknowns = [], manifests = [];
32
+ const configHashes = {};
33
+ let dependencyLockHash;
34
+ let trustedCi = false;
35
+ if (!trust)
36
+ return { verified, failures, unknowns: ['External producer authority unavailable'], manifests, trustedCi, artifactBytes, configHashes, dependencyLockHash, observations };
37
+ for (const path of trust.configPaths)
38
+ configHashes[path] = hashBytes(await safeRead(root, path));
39
+ dependencyLockHash = trust.dependencyLockPath ? hashBytes(await safeRead(root, trust.dependencyLockPath)) : undefined;
40
+ for (const spec of trust.manifests) {
41
+ let manifestBytes;
42
+ try {
43
+ manifestBytes = await safeRead(root, spec.ref);
44
+ }
45
+ catch (e) {
46
+ if (e.code === 'ENOENT') {
47
+ unknowns.push(`Missing manifest: ${spec.ref}`);
48
+ continue;
49
+ }
50
+ throw e;
51
+ }
52
+ const manifest = ExecutionManifestSchema.parse(JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(manifestBytes))), bytes = {};
53
+ for (const a of manifest.artifacts) {
54
+ try {
55
+ bytes[a.ref] = await safeRead(root, a.ref);
56
+ }
57
+ catch (e) {
58
+ if (e.code !== 'ENOENT')
59
+ throw e;
60
+ }
61
+ }
62
+ let authority = spec.authority;
63
+ if ((authority.kind === 'local' || spec.manifestHash !== undefined) && hash(manifest) !== spec.manifestHash) {
64
+ failures.push('Host-pinned manifest digest mismatch');
65
+ continue;
66
+ }
67
+ if (authority.kind === 'ci') {
68
+ if (!spec.github) {
69
+ authority = undefined;
70
+ unknowns.push('CI authority requires live GitHub verification');
71
+ }
72
+ else {
73
+ const g = spec.github;
74
+ const archive = await safeRead(root, g.archivePath), digest = hashBytes(archive);
75
+ const archiveMatch = verifyArtifactArchive(archive, { [spec.ref]: manifestBytes, ...bytes }, g.archiveEntries);
76
+ if (archiveMatch.status !== 'pass') {
77
+ unknowns.push(...archiveMatch.reasons);
78
+ continue;
79
+ }
80
+ const result = await new GitHubAuthority({ repository: g.repository, ...(process.env.GITHUB_TOKEN ? { token: process.env.GITHUB_TOKEN } : {}) }).producer(manifest.ci, { ci: authority.ci, workflowPath: g.workflowPath, workflowSha: g.workflowSha, jobName: g.jobName, artifactName: g.artifactName, artifactDigest: digest });
81
+ observations.push({ manifestRef: spec.ref, observation: result });
82
+ if (result.status !== 'pass') {
83
+ authority = undefined;
84
+ unknowns.push(...result.reasons);
85
+ }
86
+ }
87
+ }
88
+ const result = validateManifest(manifest, spec.expected, bytes, authority);
89
+ if (hash(spec.expected.subject) !== hash(subject) || hash(spec.expected.configHashes) !== hash(configHashes) || spec.expected.dependencyLockHash !== dependencyLockHash) {
90
+ result.subjectMatch = 'fail';
91
+ result.reasons.push('Host-selected expectation does not match current input/config/lock snapshot');
92
+ }
93
+ manifests.push({ ref: spec.ref, validation: result });
94
+ const states = [result.artifactIntegrity, result.producerTrust, result.subjectMatch, result.executionStatus];
95
+ if (states.includes('fail'))
96
+ failures.push(...result.reasons);
97
+ else if (states.every(x => x === 'pass')) {
98
+ for (const a of manifest.artifacts) {
99
+ const captured = bytes[a.ref];
100
+ if (artifactBytes.has(a.ref) && hashBytes(artifactBytes.get(a.ref)) !== hashBytes(captured))
101
+ throw Error('Conflicting authenticated artifact snapshots');
102
+ artifactBytes.set(a.ref, captured);
103
+ verified.add(a.ref);
104
+ }
105
+ if (authority?.kind === 'ci')
106
+ trustedCi = true;
107
+ }
108
+ else
109
+ unknowns.push(...result.reasons);
110
+ }
111
+ return { verified, failures: failures.sort(), unknowns: unknowns.sort(), manifests, trustedCi, artifactBytes, configHashes, dependencyLockHash, observations };
112
+ }
113
+ export const approvalKey = (v) => hash(v);
114
+ export function isCurrentClaim(evidence, artifactRef, subject, policyHash, contracts) {
115
+ const payload = evidence.payload;
116
+ const active = contracts.find(c => c.id === payload.contractId);
117
+ return !!active && evidence.source.artifactRef === artifactRef && hash(evidence.context.subject ?? null) === hash(subject) && evidence.context.effectivePolicyHash === policyHash && evidence.context.contractHash === active.revisionHash;
118
+ }
119
+ /** Runner selection belongs to the protected invocation and one authenticated
120
+ * test artifact. It never grants artifact/producer authority by itself. */
121
+ export function selectedRunner(trust, auth, testRef, inputs) {
122
+ const runner = trust?.runner;
123
+ if (!runner || !testRef || !inputs.includes('package.json') || auth.failures.length || !auth.verified.has(testRef))
124
+ return undefined;
125
+ const spec = trust.manifests.find(row => row.ref === runner.manifestRef), validation = auth.manifests.find(row => row.ref === runner.manifestRef)?.validation;
126
+ if (!spec?.expected.artifacts.some(row => row.kind === 'test' && row.ref === testRef) || !validation || ![validation.artifactIntegrity, validation.producerTrust, validation.subjectMatch, validation.executionStatus].every(status => status === 'pass'))
127
+ return undefined;
128
+ return { runner: runner.kind, version: runner.version };
129
+ }
130
+ //# sourceMappingURL=trust.js.map