@peac/audit 0.10.9

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,556 @@
1
+ "use strict";
2
+ /**
3
+ * Verification Report (v0.9.30+)
4
+ *
5
+ * Deterministic verification of dispute bundles with JCS-canonicalized reports.
6
+ * The report_hash enables cross-language parity: TS and Go implementations
7
+ * must produce identical hashes for the same bundle verification.
8
+ *
9
+ * Key design principles:
10
+ * 1. Real Ed25519 signature verification using @peac/crypto
11
+ * 2. No timestamps in deterministic output
12
+ * 3. All arrays sorted by stable keys for reproducibility
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.verifyBundle = verifyBundle;
16
+ exports.serializeReport = serializeReport;
17
+ exports.formatReportText = formatReportText;
18
+ const node_crypto_1 = require("node:crypto");
19
+ const crypto_1 = require("@peac/crypto");
20
+ const dispute_bundle_js_1 = require("./dispute-bundle.js");
21
+ const dispute_bundle_js_2 = require("./dispute-bundle.js");
22
+ const dispute_bundle_types_js_1 = require("./dispute-bundle-types.js");
23
+ /**
24
+ * Compute SHA-256 hash of data with self-describing format.
25
+ * Returns `sha256:<64 lowercase hex chars>` format.
26
+ */
27
+ function sha256Hex(data) {
28
+ const hash = (0, node_crypto_1.createHash)('sha256');
29
+ hash.update(data);
30
+ return `sha256:${hash.digest('hex')}`;
31
+ }
32
+ /** Decode base64url to Buffer */
33
+ function base64urlDecode(str) {
34
+ const padded = str + '='.repeat((4 - (str.length % 4)) % 4);
35
+ const base64 = padded.replace(/-/g, '+').replace(/_/g, '/');
36
+ return Buffer.from(base64, 'base64');
37
+ }
38
+ /** Parse JWS to extract header and payload */
39
+ function parseJws(jws) {
40
+ const parts = jws.split('.');
41
+ if (parts.length !== 3) {
42
+ return null;
43
+ }
44
+ try {
45
+ const headerJson = base64urlDecode(parts[0]).toString('utf8');
46
+ const payloadJson = base64urlDecode(parts[1]).toString('utf8');
47
+ return {
48
+ header: JSON.parse(headerJson),
49
+ payload: JSON.parse(payloadJson),
50
+ signature: parts[2],
51
+ };
52
+ }
53
+ catch {
54
+ return null;
55
+ }
56
+ }
57
+ /** Create a bundle error */
58
+ function bundleError(code, message, details) {
59
+ return { code, message, details };
60
+ }
61
+ /**
62
+ * Strip undefined values from an object recursively.
63
+ * JCS canonicalization cannot handle undefined values.
64
+ */
65
+ function stripUndefined(obj) {
66
+ if (obj === null || obj === undefined) {
67
+ return obj;
68
+ }
69
+ if (Array.isArray(obj)) {
70
+ return obj.map(stripUndefined);
71
+ }
72
+ if (typeof obj === 'object') {
73
+ const result = {};
74
+ for (const [key, value] of Object.entries(obj)) {
75
+ if (value !== undefined) {
76
+ result[key] = stripUndefined(value);
77
+ }
78
+ }
79
+ return result;
80
+ }
81
+ return obj;
82
+ }
83
+ /**
84
+ * Verify receipt claims (basic validation without cryptographic signature check).
85
+ *
86
+ * This validates:
87
+ * - Required claims are present (jti, iss, iat)
88
+ * - Timestamps are valid (not expired, not in future)
89
+ *
90
+ * Note: Signature verification requires access to the signing key and is
91
+ * handled separately. This function focuses on claim validation.
92
+ */
93
+ function verifyReceiptClaims(payload, now) {
94
+ const errors = [];
95
+ const nowSec = Math.floor(now.getTime() / 1000);
96
+ // Required claims
97
+ if (!payload.jti) {
98
+ errors.push('E_RECEIPT_MISSING_JTI');
99
+ }
100
+ if (!payload.iss) {
101
+ errors.push('E_RECEIPT_MISSING_ISS');
102
+ }
103
+ if (payload.iat === undefined) {
104
+ errors.push('E_RECEIPT_MISSING_IAT');
105
+ }
106
+ else {
107
+ const iat = typeof payload.iat === 'number' ? payload.iat : NaN;
108
+ if (isNaN(iat)) {
109
+ errors.push('E_RECEIPT_INVALID_IAT');
110
+ }
111
+ else if (iat > nowSec + 300) {
112
+ // Allow 5 min clock skew
113
+ errors.push('E_RECEIPT_NOT_YET_VALID');
114
+ }
115
+ }
116
+ // Check expiry if present
117
+ if (payload.exp !== undefined) {
118
+ const exp = typeof payload.exp === 'number' ? payload.exp : NaN;
119
+ if (isNaN(exp)) {
120
+ errors.push('E_RECEIPT_INVALID_EXP');
121
+ }
122
+ else if (exp < nowSec) {
123
+ errors.push('E_RECEIPT_EXPIRED');
124
+ }
125
+ }
126
+ return {
127
+ valid: errors.length === 0,
128
+ errors,
129
+ };
130
+ }
131
+ /**
132
+ * Find the key ID used to sign a receipt.
133
+ */
134
+ function getReceiptKeyId(header) {
135
+ return typeof header.kid === 'string' ? header.kid : undefined;
136
+ }
137
+ /**
138
+ * Convert JWK to raw Ed25519 public key bytes (32 bytes).
139
+ * Returns null if the JWK is not a valid Ed25519 key.
140
+ */
141
+ function jwkToPublicKeyBytes(jwk) {
142
+ if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519' || !jwk.x) {
143
+ return null;
144
+ }
145
+ // Decode base64url to bytes
146
+ const padded = jwk.x + '='.repeat((4 - (jwk.x.length % 4)) % 4);
147
+ const base64 = padded.replace(/-/g, '+').replace(/_/g, '/');
148
+ const bytes = Buffer.from(base64, 'base64');
149
+ if (bytes.length !== 32) {
150
+ return null;
151
+ }
152
+ return new Uint8Array(bytes);
153
+ }
154
+ /**
155
+ * Find a key by kid in the bundle's JWKS.
156
+ */
157
+ function findKey(keys, kid) {
158
+ return keys.find((k) => k.kid === kid);
159
+ }
160
+ /**
161
+ * Verify a single receipt with real Ed25519 signature verification.
162
+ *
163
+ * In offline mode, we use only the keys bundled in the JWKS.
164
+ * All signature verification is cryptographic - not just key presence.
165
+ */
166
+ async function verifyReceipt(receiptId, jws, bundleContents, options) {
167
+ const parsed = parseJws(jws);
168
+ if (!parsed) {
169
+ return {
170
+ receipt_id: receiptId,
171
+ signature_valid: false,
172
+ claims_valid: false,
173
+ errors: ['E_RECEIPT_INVALID_FORMAT'],
174
+ };
175
+ }
176
+ const { header, payload } = parsed;
177
+ const keyId = getReceiptKeyId(header);
178
+ const errors = [];
179
+ // Check key ID presence
180
+ if (!keyId) {
181
+ return {
182
+ receipt_id: receiptId,
183
+ signature_valid: false,
184
+ claims_valid: false,
185
+ errors: ['E_RECEIPT_MISSING_KID'],
186
+ };
187
+ }
188
+ // Find the key in the bundle's JWKS
189
+ const jwk = findKey(bundleContents.keys.keys, keyId);
190
+ if (!jwk) {
191
+ // Key not found - in offline mode this is fatal
192
+ if (options.offline) {
193
+ return {
194
+ receipt_id: receiptId,
195
+ signature_valid: false,
196
+ claims_valid: false,
197
+ key_id: keyId,
198
+ errors: [dispute_bundle_js_2.BundleErrorCodes.KEY_MISSING],
199
+ };
200
+ }
201
+ // In online mode, we could try to fetch the key, but for now fail
202
+ return {
203
+ receipt_id: receiptId,
204
+ signature_valid: false,
205
+ claims_valid: false,
206
+ key_id: keyId,
207
+ errors: [dispute_bundle_js_2.BundleErrorCodes.KEY_MISSING],
208
+ };
209
+ }
210
+ // Convert JWK to raw public key bytes
211
+ const publicKeyBytes = jwkToPublicKeyBytes(jwk);
212
+ if (!publicKeyBytes) {
213
+ return {
214
+ receipt_id: receiptId,
215
+ signature_valid: false,
216
+ claims_valid: false,
217
+ key_id: keyId,
218
+ errors: ['E_RECEIPT_INVALID_KEY_FORMAT'],
219
+ };
220
+ }
221
+ // Perform real Ed25519 signature verification
222
+ let signatureValid = false;
223
+ try {
224
+ const result = await (0, crypto_1.verify)(jws, publicKeyBytes);
225
+ signatureValid = result.valid;
226
+ if (!signatureValid) {
227
+ errors.push('E_RECEIPT_SIGNATURE_INVALID');
228
+ }
229
+ }
230
+ catch (err) {
231
+ // Handle crypto errors
232
+ if (err instanceof crypto_1.CryptoError) {
233
+ errors.push(`E_RECEIPT_CRYPTO_ERROR:${err.code}`);
234
+ }
235
+ else {
236
+ errors.push('E_RECEIPT_SIGNATURE_INVALID');
237
+ }
238
+ signatureValid = false;
239
+ }
240
+ // Validate claims
241
+ const claimsResult = verifyReceiptClaims(payload, options.now ?? new Date());
242
+ errors.push(...claimsResult.errors);
243
+ return {
244
+ receipt_id: receiptId,
245
+ signature_valid: signatureValid,
246
+ claims_valid: claimsResult.valid,
247
+ key_id: keyId,
248
+ errors,
249
+ claims: signatureValid && claimsResult.valid && errors.length === 0 ? payload : undefined,
250
+ };
251
+ }
252
+ /**
253
+ * Build key usage tracking.
254
+ */
255
+ function buildKeyUsage(results) {
256
+ const usage = new Map();
257
+ for (const result of results) {
258
+ if (result.key_id) {
259
+ const existing = usage.get(result.key_id) ?? [];
260
+ existing.push(result.receipt_id);
261
+ usage.set(result.key_id, existing);
262
+ }
263
+ }
264
+ const entries = [];
265
+ for (const [kid, receiptIds] of usage) {
266
+ entries.push({
267
+ kid,
268
+ receipts_signed: receiptIds.length,
269
+ receipt_ids: receiptIds.sort(),
270
+ });
271
+ }
272
+ // Sort by kid for determinism
273
+ return entries.sort((a, b) => a.kid.localeCompare(b.kid));
274
+ }
275
+ /**
276
+ * Generate auditor-friendly summary.
277
+ */
278
+ function generateAuditorSummary(totalReceipts, validCount, invalidCount, results) {
279
+ const headline = `${validCount}/${totalReceipts} receipts valid`;
280
+ const issues = [];
281
+ for (const result of results) {
282
+ if (!result.signature_valid || !result.claims_valid) {
283
+ const errorSummary = result.errors.length > 0 ? result.errors.join(', ') : 'validation failed';
284
+ issues.push(`Receipt ${result.receipt_id}: ${errorSummary}`);
285
+ }
286
+ }
287
+ // Sort issues for determinism
288
+ issues.sort();
289
+ let recommendation;
290
+ if (invalidCount === 0) {
291
+ recommendation = 'valid';
292
+ }
293
+ else if (invalidCount === totalReceipts) {
294
+ recommendation = 'invalid';
295
+ }
296
+ else {
297
+ recommendation = 'needs_review';
298
+ }
299
+ return {
300
+ headline,
301
+ issues,
302
+ recommendation,
303
+ };
304
+ }
305
+ /**
306
+ * Verify the bundle.sig if present.
307
+ * The bundle.sig is a JWS over { content_hash: "..." } signed with a key from the JWKS.
308
+ */
309
+ async function verifyBundleSignature(bundleContents) {
310
+ const { bundle_sig, keys, manifest } = bundleContents;
311
+ // No bundle.sig present
312
+ if (!bundle_sig) {
313
+ return { present: false };
314
+ }
315
+ // Parse the JWS to get the key ID
316
+ const parsed = parseJws(bundle_sig);
317
+ if (!parsed) {
318
+ return {
319
+ present: true,
320
+ valid: false,
321
+ error: 'E_BUNDLE_SIGNATURE_INVALID_FORMAT',
322
+ };
323
+ }
324
+ const keyId = typeof parsed.header.kid === 'string' ? parsed.header.kid : undefined;
325
+ if (!keyId) {
326
+ return {
327
+ present: true,
328
+ valid: false,
329
+ error: 'E_BUNDLE_SIGNATURE_MISSING_KID',
330
+ };
331
+ }
332
+ // Find the key in JWKS
333
+ const jwk = keys.keys.find((k) => k.kid === keyId);
334
+ if (!jwk) {
335
+ return {
336
+ present: true,
337
+ valid: false,
338
+ key_id: keyId,
339
+ error: dispute_bundle_js_2.BundleErrorCodes.KEY_MISSING,
340
+ };
341
+ }
342
+ // Convert JWK to raw public key bytes
343
+ const publicKeyBytes = jwkToPublicKeyBytes(jwk);
344
+ if (!publicKeyBytes) {
345
+ return {
346
+ present: true,
347
+ valid: false,
348
+ key_id: keyId,
349
+ error: 'E_BUNDLE_SIGNATURE_INVALID_KEY_FORMAT',
350
+ };
351
+ }
352
+ // Verify the signature
353
+ try {
354
+ const result = await (0, crypto_1.verify)(bundle_sig, publicKeyBytes);
355
+ if (!result.valid) {
356
+ return {
357
+ present: true,
358
+ valid: false,
359
+ key_id: keyId,
360
+ error: dispute_bundle_js_2.BundleErrorCodes.SIGNATURE_INVALID,
361
+ };
362
+ }
363
+ // Verify the content_hash in the payload matches the manifest
364
+ if (result.payload.content_hash !== manifest.content_hash) {
365
+ return {
366
+ present: true,
367
+ valid: false,
368
+ key_id: keyId,
369
+ error: 'E_BUNDLE_SIGNATURE_CONTENT_MISMATCH',
370
+ };
371
+ }
372
+ return {
373
+ present: true,
374
+ valid: true,
375
+ key_id: keyId,
376
+ };
377
+ }
378
+ catch (err) {
379
+ const errorMsg = err instanceof crypto_1.CryptoError
380
+ ? `E_BUNDLE_SIGNATURE_CRYPTO_ERROR:${err.code}`
381
+ : dispute_bundle_js_2.BundleErrorCodes.SIGNATURE_INVALID;
382
+ return {
383
+ present: true,
384
+ valid: false,
385
+ key_id: keyId,
386
+ error: errorMsg,
387
+ };
388
+ }
389
+ }
390
+ /**
391
+ * Verify all receipts in a dispute bundle and generate a deterministic report.
392
+ *
393
+ * @param zipBuffer - Buffer containing the ZIP archive
394
+ * @param options - Verification options
395
+ * @returns Promise resolving to a deterministic verification report
396
+ *
397
+ * @example
398
+ * ```typescript
399
+ * const zipData = fs.readFileSync('dispute-bundle.zip');
400
+ * const result = await verifyBundle(zipData, { offline: true });
401
+ *
402
+ * if (result.ok) {
403
+ * console.log('Report hash:', result.value.report_hash);
404
+ * console.log('Summary:', result.value.auditor_summary.headline);
405
+ * }
406
+ * ```
407
+ */
408
+ async function verifyBundle(zipBuffer, options) {
409
+ // Read and parse the bundle
410
+ const readResult = await (0, dispute_bundle_js_1.readDisputeBundle)(zipBuffer);
411
+ if (!readResult.ok) {
412
+ return readResult;
413
+ }
414
+ const bundleContents = readResult.value;
415
+ const { manifest, receipts } = bundleContents;
416
+ // Verify bundle.sig if present (authenticity)
417
+ const bundleSignature = await verifyBundleSignature(bundleContents);
418
+ // Verify each receipt with real Ed25519 signature verification
419
+ const results = [];
420
+ for (const receiptEntry of manifest.receipts) {
421
+ const jws = receipts.get(receiptEntry.receipt_id);
422
+ if (!jws) {
423
+ results.push({
424
+ receipt_id: receiptEntry.receipt_id,
425
+ signature_valid: false,
426
+ claims_valid: false,
427
+ errors: ['E_BUNDLE_RECEIPT_NOT_FOUND'],
428
+ });
429
+ continue;
430
+ }
431
+ const result = await verifyReceipt(receiptEntry.receipt_id, jws, bundleContents, options);
432
+ results.push(result);
433
+ }
434
+ // Sort results by receipt_id for determinism
435
+ results.sort((a, b) => a.receipt_id.localeCompare(b.receipt_id));
436
+ // Count valid/invalid
437
+ const validCount = results.filter((r) => r.signature_valid && r.claims_valid && r.errors.length === 0).length;
438
+ const invalidCount = results.length - validCount;
439
+ // Build key usage
440
+ const keysUsed = buildKeyUsage(results);
441
+ // Generate auditor summary
442
+ const auditorSummary = generateAuditorSummary(results.length, validCount, invalidCount, results);
443
+ // Build report without report_hash
444
+ const reportWithoutHash = {
445
+ version: dispute_bundle_types_js_1.VERIFICATION_REPORT_VERSION,
446
+ bundle_content_hash: manifest.content_hash,
447
+ bundle_signature: bundleSignature,
448
+ summary: {
449
+ total_receipts: results.length,
450
+ valid: validCount,
451
+ invalid: invalidCount,
452
+ },
453
+ receipts: results,
454
+ keys_used: keysUsed,
455
+ auditor_summary: auditorSummary,
456
+ };
457
+ // Compute report_hash = SHA-256 of JCS(report without report_hash)
458
+ // Strip undefined values first since JCS cannot handle them
459
+ const cleanedReport = stripUndefined(reportWithoutHash);
460
+ const reportHash = sha256Hex((0, crypto_1.canonicalize)(cleanedReport));
461
+ const report = {
462
+ ...reportWithoutHash,
463
+ report_hash: reportHash,
464
+ };
465
+ return {
466
+ ok: true,
467
+ value: report,
468
+ };
469
+ }
470
+ /**
471
+ * Serialize a verification report to JSON.
472
+ *
473
+ * @param report - Verification report
474
+ * @param pretty - Pretty print (default: false)
475
+ * @returns JSON string
476
+ */
477
+ function serializeReport(report, pretty = false) {
478
+ if (pretty) {
479
+ return JSON.stringify(report, null, 2);
480
+ }
481
+ return JSON.stringify(report);
482
+ }
483
+ /**
484
+ * Format verification report as human-readable text.
485
+ *
486
+ * @param report - Verification report
487
+ * @returns Human-readable text summary
488
+ */
489
+ function formatReportText(report) {
490
+ const lines = [];
491
+ lines.push('PEAC Dispute Bundle Verification Report');
492
+ lines.push('========================================');
493
+ lines.push('');
494
+ lines.push(`Bundle content hash: ${report.bundle_content_hash}`);
495
+ lines.push(`Report hash: ${report.report_hash}`);
496
+ lines.push('');
497
+ // Bundle signature status
498
+ lines.push('Bundle Signature');
499
+ lines.push('----------------');
500
+ if (!report.bundle_signature.present) {
501
+ lines.push(' Status: NOT SIGNED');
502
+ }
503
+ else if (report.bundle_signature.valid) {
504
+ lines.push(' Status: VALID');
505
+ lines.push(` Key ID: ${report.bundle_signature.key_id}`);
506
+ }
507
+ else {
508
+ lines.push(' Status: INVALID');
509
+ if (report.bundle_signature.key_id) {
510
+ lines.push(` Key ID: ${report.bundle_signature.key_id}`);
511
+ }
512
+ if (report.bundle_signature.error) {
513
+ lines.push(` Error: ${report.bundle_signature.error}`);
514
+ }
515
+ }
516
+ lines.push('');
517
+ lines.push('Summary');
518
+ lines.push('-------');
519
+ lines.push(`Total receipts: ${report.summary.total_receipts}`);
520
+ lines.push(`Valid: ${report.summary.valid}`);
521
+ lines.push(`Invalid: ${report.summary.invalid}`);
522
+ lines.push('');
523
+ lines.push(`Recommendation: ${report.auditor_summary.recommendation.toUpperCase()}`);
524
+ lines.push(`Headline: ${report.auditor_summary.headline}`);
525
+ lines.push('');
526
+ if (report.auditor_summary.issues.length > 0) {
527
+ lines.push('Issues');
528
+ lines.push('------');
529
+ for (const issue of report.auditor_summary.issues) {
530
+ lines.push(` - ${issue}`);
531
+ }
532
+ lines.push('');
533
+ }
534
+ if (report.keys_used.length > 0) {
535
+ lines.push('Keys Used');
536
+ lines.push('---------');
537
+ for (const keyUsage of report.keys_used) {
538
+ lines.push(` ${keyUsage.kid}: ${keyUsage.receipts_signed} receipt(s)`);
539
+ }
540
+ lines.push('');
541
+ }
542
+ lines.push('Receipt Details');
543
+ lines.push('---------------');
544
+ for (const receipt of report.receipts) {
545
+ const status = receipt.signature_valid && receipt.claims_valid ? 'VALID' : 'INVALID';
546
+ lines.push(` ${receipt.receipt_id}: ${status}`);
547
+ if (receipt.key_id) {
548
+ lines.push(` Key: ${receipt.key_id}`);
549
+ }
550
+ if (receipt.errors.length > 0) {
551
+ lines.push(` Errors: ${receipt.errors.join(', ')}`);
552
+ }
553
+ }
554
+ return lines.join('\n');
555
+ }
556
+ //# sourceMappingURL=verification-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verification-report.js","sourceRoot":"","sources":["../src/verification-report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Workflow DAG Verification (v0.10.1+)
3
+ *
4
+ * Verifies the structural integrity of workflow DAGs by checking:
5
+ * - ID format validity (workflow_id, step_id)
6
+ * - Unique step IDs
7
+ * - Consistent workflow IDs
8
+ * - Parent existence (no dangling references)
9
+ * - No self-parenting
10
+ * - Acyclicity (no cycles in the DAG)
11
+ * - Limits enforcement (node count, parent count, depth, edges)
12
+ *
13
+ * Each violation maps to a specific E_WORKFLOW_* error code for structured
14
+ * error handling and audit trails.
15
+ */
16
+ import type { WorkflowContext } from '@peac/schema';
17
+ import { ERROR_CODES } from '@peac/kernel';
18
+ /**
19
+ * DAG verification limits (DoS protection for full DAG analysis)
20
+ */
21
+ export declare const DAG_LIMITS: {
22
+ /** Maximum steps in a workflow DAG */
23
+ readonly maxSteps: 10000;
24
+ /** Maximum depth (longest path from root) */
25
+ readonly maxDepth: 100;
26
+ /** Maximum total edges (sum of all parent references) */
27
+ readonly maxTotalEdges: 100000;
28
+ };
29
+ /**
30
+ * Workflow error category for structured violations
31
+ */
32
+ export type WorkflowErrorCode = typeof ERROR_CODES.E_WORKFLOW_ID_INVALID | typeof ERROR_CODES.E_WORKFLOW_STEP_ID_INVALID | typeof ERROR_CODES.E_WORKFLOW_DAG_INVALID | typeof ERROR_CODES.E_WORKFLOW_CYCLE_DETECTED | typeof ERROR_CODES.E_WORKFLOW_PARENT_NOT_FOUND | typeof ERROR_CODES.E_WORKFLOW_LIMIT_EXCEEDED;
33
+ /**
34
+ * DAG violation details
35
+ */
36
+ export interface DagViolation {
37
+ /** Error code from E_WORKFLOW_* family */
38
+ code: WorkflowErrorCode;
39
+ /** Human-readable message */
40
+ message: string;
41
+ /** Structured details for debugging/audit */
42
+ details: {
43
+ /** Specific reason for the violation */
44
+ reason: string;
45
+ /** Step ID involved (if applicable) */
46
+ step_id?: string;
47
+ /** Parent step ID involved (if applicable) */
48
+ parent_step_id?: string;
49
+ /** Workflow ID involved (if applicable) */
50
+ workflow_id?: string;
51
+ /** Limit that was exceeded (if applicable) */
52
+ limit?: string;
53
+ /** Current value (if applicable) */
54
+ value?: number;
55
+ /** Maximum allowed value (if applicable) */
56
+ max?: number;
57
+ /** Cycle path (if applicable) */
58
+ cycle_path?: string[];
59
+ };
60
+ }
61
+ /**
62
+ * Result of DAG verification
63
+ */
64
+ export interface DagVerificationResult {
65
+ /** Whether the DAG is valid */
66
+ valid: boolean;
67
+ /** List of violations (empty if valid) */
68
+ violations: DagViolation[];
69
+ /** DAG statistics (computed during verification) */
70
+ stats: {
71
+ /** Number of steps */
72
+ stepCount: number;
73
+ /** Number of root steps (no parents) */
74
+ rootCount: number;
75
+ /** Maximum depth reached */
76
+ maxDepth: number;
77
+ /** Total edge count */
78
+ totalEdges: number;
79
+ /** Number of unique workflow IDs (should be 1) */
80
+ uniqueWorkflowIds: number;
81
+ };
82
+ }
83
+ /**
84
+ * Verify a workflow DAG for structural integrity
85
+ *
86
+ * @param contexts - Array of WorkflowContext objects representing the DAG
87
+ * @returns DagVerificationResult with violations and statistics
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * import { verifyWorkflowDag } from '@peac/audit';
92
+ *
93
+ * const result = verifyWorkflowDag(contexts);
94
+ * if (!result.valid) {
95
+ * for (const v of result.violations) {
96
+ * console.error(`${v.code}: ${v.message}`);
97
+ * }
98
+ * }
99
+ * ```
100
+ */
101
+ export declare function verifyWorkflowDag(contexts: WorkflowContext[]): DagVerificationResult;
102
+ /**
103
+ * Extract a specific violation by reason
104
+ *
105
+ * Utility for tests and error handling
106
+ */
107
+ export declare function findViolationByReason(result: DagVerificationResult, reason: string): DagViolation | undefined;
108
+ /**
109
+ * Check if result has a specific violation code
110
+ */
111
+ export declare function hasViolationCode(result: DagVerificationResult, code: WorkflowErrorCode): boolean;
112
+ //# sourceMappingURL=workflow-dag.d.ts.map