artifact-graph 0.8.2 → 0.8.3

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,1459 @@
1
+ export { dirname, extname } from 'node:path';
2
+
3
+ /**
4
+ * packet-constants.ts
5
+ *
6
+ * Shared constants for packet assembly, validation, and auditing.
7
+ * Extracted here to avoid circular imports between index.ts and packet-validator.ts.
8
+ */
9
+ /** Always-present baseline items included in every implementation packet */
10
+ declare const ALWAYS_PRESENT_ITEMS: {
11
+ path: string;
12
+ reason: string;
13
+ }[];
14
+ /** Baseline items count derived from ALWAYS_PRESENT_ITEMS */
15
+ declare const BASELINE_ITEMS_COUNT: number;
16
+ /** Baseline constraints — well-known constraints derived from baseline artifacts */
17
+ declare const BASELINE_CONSTRAINTS: {
18
+ id: string;
19
+ description: string;
20
+ source: string;
21
+ }[];
22
+ /** Baseline constraints count derived from BASELINE_CONSTRAINTS */
23
+ declare const BASELINE_CONSTRAINTS_COUNT: number;
24
+
25
+ /**
26
+ * target-selector.ts
27
+ *
28
+ * Unified target selector for the artifact-graph CLI.
29
+ * Parses `--target <type>:<id>` and resolves from legacy flags,
30
+ * enforcing mutual exclusivity between the two forms.
31
+ */
32
+
33
+ /**
34
+ * Parse a `<type>:<id>` selector string, splitting only on the first colon.
35
+ * Colons within the ID portion are preserved (e.g. `e2e_test:batch:TC-001` → `{ type: 'e2e_test', id: 'batch:TC-001' }`).
36
+ */
37
+ declare function parseTargetSelector(value: string): ArtifactTarget;
38
+ /**
39
+ * Resolve the effective target from CLI flags.
40
+ *
41
+ * Accepts either `--target <type>:<id>` OR one of the legacy flags (`--feature`, `--scenario`, etc.).
42
+ * Mixing both forms is a hard error.
43
+ *
44
+ * @param flags Parsed CLI flags (Record<string, string | boolean>)
45
+ * @param schema Loaded artifact schema — used to verify target capability
46
+ * @returns Resolved ArtifactTarget
47
+ * @throws Error on invalid/mutually-exclusive/unsupported flags
48
+ */
49
+ declare function resolveCliTarget(flags: Record<string, string | boolean>, schema: ArtifactSchema): ArtifactTarget;
50
+
51
+ /**
52
+ * packet-assembler.ts
53
+ *
54
+ * Deterministic implementation packet assembly from context manifest.
55
+ * No LLM involvement — pure data transformation.
56
+ */
57
+
58
+ /** Target information for the packet */
59
+ interface PacketTarget {
60
+ type: string;
61
+ id: string;
62
+ uid: string;
63
+ title?: string;
64
+ sourcePath?: string;
65
+ status?: string;
66
+ }
67
+ /** Single item in a packet category */
68
+ interface PacketItem {
69
+ path: string;
70
+ reason: string;
71
+ required: boolean;
72
+ tier?: string;
73
+ reasons?: string[];
74
+ }
75
+ /** Category section in the packet */
76
+ interface PacketCategory {
77
+ category: string;
78
+ total: number;
79
+ items: PacketItem[];
80
+ }
81
+ /** Omitted item in the packet */
82
+ interface PacketOmittedItem {
83
+ path: string;
84
+ reason: string;
85
+ tier?: string;
86
+ }
87
+ /** Single step in recommended review order */
88
+ interface ReviewOrderStep {
89
+ step: number;
90
+ category: string;
91
+ reason: string;
92
+ }
93
+ /** Single item in risk checklist */
94
+ interface RiskChecklistItem {
95
+ id: string;
96
+ description: string;
97
+ checked: boolean;
98
+ }
99
+ /** Blueprint draft: manifest-derived skeleton for implementation */
100
+ interface ImplementationBlueprintDraft {
101
+ objective: {
102
+ featureId: string | null;
103
+ scenarioId: string | null;
104
+ decisionId: string | null;
105
+ designId: string | null;
106
+ e2eTestId: string | null;
107
+ description: string;
108
+ scope: string;
109
+ nonGoals: string[];
110
+ };
111
+ contextChecklist: {
112
+ categories: {
113
+ name: string;
114
+ count: number;
115
+ paths: string[];
116
+ }[];
117
+ };
118
+ fileChanges: {
119
+ path: string;
120
+ action: string;
121
+ description: string;
122
+ source: string;
123
+ }[];
124
+ constraints: {
125
+ id: string;
126
+ description: string;
127
+ source: string;
128
+ }[];
129
+ validationCommands: string[];
130
+ recommendedReviewOrder: ReviewOrderStep[];
131
+ riskChecklist: RiskChecklistItem[];
132
+ }
133
+ /** AssemblePacket options */
134
+ interface PacketOptions {
135
+ /** Override default validation commands */
136
+ validationCommands?: string[];
137
+ /** Context mode used during resolution */
138
+ mode?: ContextMode;
139
+ /** Max per category used during resolution */
140
+ maxPerCategory?: number;
141
+ /** Fixed ISO 8601 timestamp for reproducible output. If omitted, uses current time. */
142
+ generatedAt?: string;
143
+ }
144
+ /** Top-level implementation packet */
145
+ interface ImplementationPacket {
146
+ schemaVersion: '1.0';
147
+ generatedAt: string;
148
+ target: PacketTarget;
149
+ contextManifestSummary: {
150
+ totalCategories: number;
151
+ totalItems: number;
152
+ totalOmitted: number;
153
+ totalMissing: number;
154
+ mode: string;
155
+ maxPerCategory: number;
156
+ };
157
+ requiredBaseline: PacketCategory;
158
+ contextByTier: {
159
+ direct: PacketCategory[];
160
+ matrix: PacketCategory[];
161
+ transitive: PacketCategory[];
162
+ };
163
+ omittedItems: PacketOmittedItem[];
164
+ missing: string[];
165
+ missingDetails?: MissingDetail[];
166
+ implementationBlueprintDraft: ImplementationBlueprintDraft;
167
+ validationCommands: string[];
168
+ /** Explicit universal baseline policy: true=enabled, false=disabled. Absent=legacy (pre-0.5) packet. */
169
+ baselinePolicy?: boolean;
170
+ }
171
+ /**
172
+ * Assemble an implementation packet from a context manifest.
173
+ *
174
+ * This is a pure data transformation. Packet content is derived from the
175
+ * manifest; generatedAt is variable unless a fixed value is supplied.
176
+ * No LLM is involved.
177
+ */
178
+ declare function assemblePacket(manifest: ContextManifest, options?: PacketOptions): ImplementationPacket;
179
+ /**
180
+ * Render an implementation packet as Markdown.
181
+ *
182
+ * Output is designed to be directly usable as a pre-implementation brief
183
+ * for Claude Code or other AI coding agents.
184
+ */
185
+ declare function renderPacketMarkdown(packet: ImplementationPacket): string;
186
+
187
+ /**
188
+ * packet-validator.ts
189
+ *
190
+ * Schema validation for implementation packets.
191
+ * Validates both structured JSON packets and rendered Markdown packets.
192
+ *
193
+ * v1.12: accepts optional schema to derive valid target types dynamically.
194
+ * Without schema, falls back to the static VALID_PACKET_TARGET_TYPES list.
195
+ *
196
+ * v0.5: PKT-004 no longer infers opt-out from missingDetails or total=0.
197
+ * baselinePolicy=true|absent → must match ALWAYS_PRESENT_ITEMS exactly.
198
+ * baselinePolicy=false → must be total=0, items=[].
199
+ */
200
+
201
+ /** Valid target types for packets (legacy static fallback) */
202
+ declare const VALID_PACKET_TARGET_TYPES: readonly ["feature", "scenario", "decision", "design", "e2e_test"];
203
+ type PacketTargetType = typeof VALID_PACKET_TARGET_TYPES[number];
204
+ declare function isPacketTargetType(type: string): type is PacketTargetType;
205
+ /**
206
+ * Check whether a type is a valid packet target, optionally using a loaded schema.
207
+ * When a schema is provided, uses dynamic target-capable types.
208
+ * Without schema, uses the static VALID_PACKET_TARGET_TYPES.
209
+ */
210
+ type PacketTargetSchema = {
211
+ types: Record<string, {
212
+ target?: boolean;
213
+ role?: string;
214
+ }>;
215
+ idPatterns?: Record<string, string>;
216
+ };
217
+ declare function isPacketTargetTypeDynamic(type: string, schema?: PacketTargetSchema): boolean;
218
+ interface PacketValidationIssue {
219
+ severity: 'error' | 'warning';
220
+ code: string;
221
+ message: string;
222
+ path?: string;
223
+ }
224
+ interface PacketValidationResult {
225
+ ok: boolean;
226
+ issues: PacketValidationIssue[];
227
+ }
228
+ /**
229
+ * Validate a structured ImplementationPacket against schema rules.
230
+ *
231
+ * Rules:
232
+ * - PKT-001: schemaVersion must be '1.0'
233
+ * - PKT-002: target.type must be a valid packet target type
234
+ * - PKT-003: target.id must be non-empty
235
+ * - PKT-004: requiredBaseline.total must equal baseline items count
236
+ * - PKT-005: constraints must have exactly baseline count and include C-RULE-01
237
+ * - PKT-006: validationCommands must have at least 4 entries
238
+ * - PKT-007: missing.length > 0 is a warning
239
+ */
240
+ declare function validatePacket(packet: ImplementationPacket, schema?: PacketTargetSchema): PacketValidationResult;
241
+ /**
242
+ * Validate a rendered Markdown packet for required section structure.
243
+ *
244
+ * Checks that all required section headings are present.
245
+ */
246
+ declare function validatePacketMarkdown(markdown: string): PacketValidationResult;
247
+
248
+ /**
249
+ * packet-audit.ts
250
+ *
251
+ * Batch audit of implementation packets from a targets file.
252
+ * Each target is processed independently — a single failure does not abort the batch.
253
+ */
254
+
255
+ interface PacketAuditEntry {
256
+ type: string;
257
+ id: string;
258
+ status: 'passed' | 'failed' | 'missing';
259
+ outputPath?: string;
260
+ missingCount: number;
261
+ omittedCount: number;
262
+ itemsCount: number;
263
+ baselineCount: number;
264
+ constraintsCount: number;
265
+ errors: string[];
266
+ validationIssues?: PacketValidationIssue[];
267
+ missingDetailsSummary?: {
268
+ ref: string;
269
+ kind: string;
270
+ suggestedAction: string;
271
+ }[];
272
+ }
273
+ interface PacketAuditSummary {
274
+ schemaVersion: '1.3';
275
+ total: number;
276
+ passed: number;
277
+ failed: number;
278
+ missing: number;
279
+ totalOmitted: number;
280
+ targets: PacketAuditEntry[];
281
+ generatedAt: string;
282
+ /** Absolute path to the targets file (--targets-file mode only) */
283
+ sourceTargetsPath?: string;
284
+ /** Context mode used for this audit run */
285
+ mode?: ContextMode;
286
+ /** Output format used for this audit run */
287
+ format?: 'json' | 'markdown';
288
+ /** maxPerCategory value used (undefined = default) */
289
+ maxPerCategory?: number;
290
+ /** How packet files were written: 'full' (all), 'summary-only' (none), 'sample' (selected) */
291
+ packetOutputMode?: 'full' | 'summary-only' | 'sample';
292
+ /** Targets for which packet files were written (--sample-targets mode) */
293
+ sampleTargets?: string[];
294
+ /** Paths to sample packet files written */
295
+ sampleOutputPaths?: string[];
296
+ /** Detail level: 'full' includes all targets, 'compact' omits passed targets */
297
+ summaryDetail?: 'full' | 'compact';
298
+ /** Per-type counts (compact mode) */
299
+ countsByType?: Record<string, number>;
300
+ }
301
+ interface TargetRef {
302
+ type: string;
303
+ id: string;
304
+ }
305
+ interface AuditOptions {
306
+ root: string;
307
+ outDir?: string;
308
+ format?: 'json' | 'markdown';
309
+ mode?: ContextMode;
310
+ maxPerCategory?: number;
311
+ /** When true (default), check universal baseline files. When false, skip. */
312
+ universalBaseline?: boolean;
313
+ /** Absolute path to the targets file (--targets-file mode only) */
314
+ sourceTargetsPath?: string;
315
+ /** If true, do not write individual packet files — only summary */
316
+ summaryOnly?: boolean;
317
+ /** List of target keys (type:id) for which to write packet files */
318
+ sampleTargets?: string[];
319
+ /** Detail level: 'full' includes all targets, 'compact' omits passed targets */
320
+ summaryDetail?: 'full' | 'compact';
321
+ /** Artifact schema for dynamic target type validation in validatePacket */
322
+ schema?: ArtifactSchema;
323
+ }
324
+ interface ParseError {
325
+ line: number;
326
+ raw: string;
327
+ message: string;
328
+ }
329
+ interface ParseResult {
330
+ targets: TargetRef[];
331
+ errors: ParseError[];
332
+ }
333
+ /**
334
+ * Parse a targets file where each line is `type:id`.
335
+ * Blank lines and lines starting with `#` are skipped.
336
+ * Returns structured result with valid targets and parse errors.
337
+ *
338
+ * When a schema is provided, target types are validated against the schema's
339
+ * target-capable types (dynamic). Without a schema, falls back to the static
340
+ * VALID_PACKET_TARGET_TYPES list for backward compatibility.
341
+ */
342
+ declare function parseTargetsFile(content: string, schema?: ArtifactSchema): ParseResult;
343
+ /**
344
+ * Audit a list of targets by generating packets for each.
345
+ * Each target is processed independently — a single failure does not abort the batch.
346
+ */
347
+ declare function auditPackets(root: string, targets: TargetRef[], options: AuditOptions, graph?: ArtifactGraph): Promise<PacketAuditSummary>;
348
+ interface DiscoverAuditOptions {
349
+ root: string;
350
+ outDir?: string;
351
+ format?: 'json' | 'markdown';
352
+ mode?: ContextMode;
353
+ maxPerCategory?: number;
354
+ limit?: number;
355
+ summaryOnly?: boolean;
356
+ sampleTargets?: string[];
357
+ summaryDetail?: 'full' | 'compact';
358
+ /** Artifact schema for dynamic target type validation */
359
+ schema?: ArtifactSchema;
360
+ /** When true (default), check universal baseline files. When false, skip. */
361
+ universalBaseline?: boolean;
362
+ }
363
+ /**
364
+ * Scan artifacts, discover targets, then audit packets for each.
365
+ * Single scan is reused for both discovery and audit.
366
+ *
367
+ * When options.universalBaseline is undefined, falls back to config.context?.universal_baseline.
368
+ */
369
+ declare function discoverAndAuditPackets(root: string, options: DiscoverAuditOptions): Promise<PacketAuditSummary>;
370
+
371
+ /**
372
+ * packet-prompt.ts
373
+ *
374
+ * Generate a compressed Claude Code task prompt from an implementation packet.
375
+ * Output is designed to be directly pasted into Claude Code as a task instruction.
376
+ * Default max 4000 characters; references packet/evidence paths when content exceeds limit.
377
+ * No LLM involvement — pure template rendering.
378
+ */
379
+
380
+ /** Options for packet-prompt generation */
381
+ interface PacketPromptOptions {
382
+ /** Max character count for the output prompt. Default: 4000 */
383
+ maxChars?: number;
384
+ /** Fixed ISO 8601 timestamp for reproducible output */
385
+ generatedAt?: string;
386
+ /** Root path for resolving file references */
387
+ root?: string;
388
+ }
389
+ /** Default max character count */
390
+ declare const DEFAULT_MAX_CHARS = 4000;
391
+ /** Minimum prompt size that can still satisfy validatePacketPrompt() for supported target IDs. */
392
+ declare const MIN_PROMPT_CHARS = 320;
393
+ /** Structured error returned when prompt cannot be compressed to the requested maxChars */
394
+ interface PacketPromptError {
395
+ ok: false;
396
+ reason: string;
397
+ actualLength: number;
398
+ minRequired: number;
399
+ }
400
+ /**
401
+ * Generate a compressed Claude Code task prompt from a packet.
402
+ *
403
+ * Output is ≤ maxChars characters by default.
404
+ * When content would exceed the limit, context details are replaced with
405
+ * references to the packet command.
406
+ * Returns a PacketPromptError object when the prompt cannot be compressed to maxChars.
407
+ */
408
+ declare function renderPacketPrompt(packet: ImplementationPacket, options?: PacketPromptOptions): string | PacketPromptError;
409
+
410
+ /**
411
+ * packet-prompt-validator.ts
412
+ *
413
+ * Lightweight validator for packet-prompt output.
414
+ * Validates that a generated handoff prompt contains all required sections.
415
+ * Used by both CLI validation and evidence generation.
416
+ */
417
+ interface PromptValidationIssue {
418
+ code: string;
419
+ message: string;
420
+ severity: 'error' | 'warning';
421
+ }
422
+ interface PromptValidationResult {
423
+ ok: boolean;
424
+ issues: PromptValidationIssue[];
425
+ }
426
+ /**
427
+ * Validate a packet-prompt output string.
428
+ *
429
+ * Checks that the prompt contains all required sections:
430
+ * - 目标信息
431
+ * - packet 命令或来源
432
+ * - 验证命令
433
+ * - 提交要求
434
+ * - 禁止事项
435
+ * - 不得回退规则
436
+ * - SEC severity 规则
437
+ * - 中文主导(warning)
438
+ */
439
+ declare function validatePacketPrompt(prompt: string): PromptValidationResult;
440
+
441
+ declare const VERSION_LOCK_PATH = "artifacts/traceability-version-lock.json";
442
+ declare const VERSION_INDEX_SCHEMA_VERSION = "1.0";
443
+ declare const VERSION_LOCK_SCHEMA_VERSION = "1.0";
444
+ type VersionSourceKind = 'artifact' | 'code' | 'test';
445
+ type VersionEdgeKind = 'references' | 'covers' | 'depends_on' | 'implements' | 'verifies';
446
+ type VersionLockStatus = 'fresh' | 'target_not_found' | 'artifact_changed' | 'source_changed' | 'verified_by_changed' | 'missing_lock' | 'orphan_lock';
447
+ interface VersionedNode {
448
+ uid: string;
449
+ type: string;
450
+ id: string;
451
+ path: string;
452
+ title: string;
453
+ line: number;
454
+ sourceKind: VersionSourceKind;
455
+ contentHash: string;
456
+ }
457
+ interface VersionedEdge {
458
+ from: string;
459
+ to: string;
460
+ kind: VersionEdgeKind | string;
461
+ source: string;
462
+ sourcePath: string;
463
+ sourceLine: number;
464
+ fromHash?: string;
465
+ toHash?: string;
466
+ }
467
+ interface VersionIndex {
468
+ schemaVersion: typeof VERSION_INDEX_SCHEMA_VERSION;
469
+ root: string;
470
+ graph: {
471
+ nodes: number;
472
+ edges: number;
473
+ };
474
+ nodes: VersionedNode[];
475
+ edges: VersionedEdge[];
476
+ }
477
+ interface VersionLockRef {
478
+ type: string;
479
+ id: string;
480
+ path: string;
481
+ contentHash: string;
482
+ }
483
+ interface VersionLockSourceRef {
484
+ type: 'code' | 'test';
485
+ path: string;
486
+ contentHash: string;
487
+ }
488
+ interface VersionLockEntry {
489
+ edgeId: string;
490
+ kind: 'implements' | 'verifies';
491
+ artifact: VersionLockRef;
492
+ source: VersionLockSourceRef;
493
+ verifiedBy?: VersionLockSourceRef[];
494
+ }
495
+ interface ArtifactRelationEndpoint {
496
+ type: string;
497
+ id: string;
498
+ path: string;
499
+ contentHash: string;
500
+ }
501
+ interface ArtifactRelationLock {
502
+ edgeId: string;
503
+ kind: string;
504
+ source: ArtifactRelationEndpoint;
505
+ target: ArtifactRelationEndpoint;
506
+ }
507
+ interface VersionLockFile {
508
+ schemaVersion: typeof VERSION_LOCK_SCHEMA_VERSION;
509
+ locks: VersionLockEntry[];
510
+ artifactRelations?: ArtifactRelationLock[];
511
+ }
512
+ interface VersionLockIssue {
513
+ status: VersionLockStatus;
514
+ edgeId: string;
515
+ message: string;
516
+ artifact?: VersionLockRef;
517
+ source?: VersionLockSourceRef | VersionLockRef;
518
+ currentArtifactHash?: string;
519
+ currentSourceHash?: string;
520
+ currentVerifiedByHash?: string;
521
+ verifiedByPath?: string;
522
+ }
523
+ interface VersionLockAuditResult {
524
+ schemaVersion: '1.0';
525
+ root: string;
526
+ lockPath: string;
527
+ totalLocks: number;
528
+ fresh: number;
529
+ totalArtifactRelationLocks: number;
530
+ artifactRelationFresh: number;
531
+ issues: VersionLockIssue[];
532
+ }
533
+ interface TraceVersionResult {
534
+ schemaVersion: '1.0';
535
+ root: string;
536
+ lockPath: string;
537
+ target: {
538
+ uid: string;
539
+ node?: VersionedNode;
540
+ };
541
+ currentEdges: VersionedEdge[];
542
+ locks: VersionLockEntry[];
543
+ artifactRelations: ArtifactRelationLock[];
544
+ issues: VersionLockIssue[];
545
+ }
546
+ interface VersionLockUpdateOptions {
547
+ target: string;
548
+ source: string;
549
+ verifiedBy?: string[];
550
+ lockPath?: string;
551
+ }
552
+ interface VersionLockBootstrapOptions {
553
+ lockPath?: string;
554
+ force?: boolean;
555
+ }
556
+ interface VersionLockRefreshOptions {
557
+ lockPath?: string;
558
+ changedOnly?: boolean;
559
+ changedPaths?: string[];
560
+ all?: boolean;
561
+ removeOrphans?: boolean;
562
+ }
563
+ interface VersionLockRefreshResult {
564
+ schemaVersion: '1.0';
565
+ root: string;
566
+ lockPath: string;
567
+ mode: 'all' | 'changed-only';
568
+ changedPaths: string[];
569
+ affectedEdges: string[];
570
+ addedLocks: string[];
571
+ updatedLocks: string[];
572
+ retainedOrphans: string[];
573
+ removedOrphans: string[];
574
+ addedArtifactRelationLocks: string[];
575
+ updatedArtifactRelationLocks: string[];
576
+ retainedArtifactRelationOrphans: string[];
577
+ removedArtifactRelationLocks: string[];
578
+ postAudit: VersionLockAuditResult;
579
+ warnings: string[];
580
+ }
581
+ declare function buildVersionIndex(root: string, graph?: ArtifactGraph): Promise<VersionIndex>;
582
+ declare function auditVersionLock(root: string, lockPath?: string, graph?: ArtifactGraph, config?: ArtifactSchema): Promise<VersionLockAuditResult>;
583
+ declare function updateVersionLock(root: string, options: VersionLockUpdateOptions): Promise<VersionLockFile>;
584
+ declare function bootstrapVersionLock(root: string, options?: VersionLockBootstrapOptions): Promise<VersionLockFile>;
585
+ declare function refreshVersionLock(root: string, options?: VersionLockRefreshOptions): Promise<VersionLockRefreshResult>;
586
+ declare function traceVersion(root: string, target: string, lockPath?: string): Promise<TraceVersionResult>;
587
+ declare function renderVersionLockAuditMarkdown(result: VersionLockAuditResult): string;
588
+ declare function renderVersionLockRefreshMarkdown(result: VersionLockRefreshResult): string;
589
+ declare function renderTraceVersionMarkdown(result: TraceVersionResult): string;
590
+
591
+ type ArtifactGraphCliSource = 'node_modules' | 'path' | 'legacy' | 'plugin-bundled';
592
+ interface ArtifactGraphCliCandidate {
593
+ source: ArtifactGraphCliSource;
594
+ path: string;
595
+ exists: boolean;
596
+ }
597
+ interface ArtifactGraphCliResolution {
598
+ path?: string;
599
+ source?: ArtifactGraphCliSource;
600
+ candidates: ArtifactGraphCliCandidate[];
601
+ warnings: string[];
602
+ }
603
+ interface ResolveArtifactGraphCliOptions {
604
+ projectCliPath?: string;
605
+ fallbackPath?: string;
606
+ }
607
+ interface ArtifactChainDoctorReport {
608
+ schemaVersion: '1.0';
609
+ root: string;
610
+ cli: ArtifactGraphCliResolution;
611
+ node: {
612
+ version: string;
613
+ compatible: boolean;
614
+ required: '>=22.0.0';
615
+ };
616
+ config: {
617
+ path: string;
618
+ exists: boolean;
619
+ };
620
+ lock: {
621
+ path: string;
622
+ exists: boolean;
623
+ };
624
+ supportedCommands: string[];
625
+ warnings: string[];
626
+ }
627
+ declare function resolveArtifactGraphCli(root: string, options?: ResolveArtifactGraphCliOptions): Promise<ArtifactGraphCliResolution>;
628
+ declare function doctorArtifactChain(root: string, options?: ResolveArtifactGraphCliOptions): Promise<ArtifactChainDoctorReport>;
629
+ declare function renderDoctorMarkdown(report: ArtifactChainDoctorReport): string;
630
+
631
+ type GitChangeMode = 'staged' | 'worktree' | 'base';
632
+ interface CollectChangedPathsOptions {
633
+ mode: GitChangeMode;
634
+ base?: string;
635
+ }
636
+ interface GitChangeResult {
637
+ root: string;
638
+ mode: GitChangeMode;
639
+ base?: string;
640
+ changedPaths: string[];
641
+ unstagedPaths: string[];
642
+ stagedUnstagedConflictPaths: string[];
643
+ }
644
+ declare function collectChangedPaths(root: string, options: CollectChangedPathsOptions): Promise<GitChangeResult>;
645
+
646
+ type GitHookName = 'pre-commit' | 'pre-push';
647
+ declare function resolveGitHookPath(root: string, hookName: GitHookName): Promise<string>;
648
+
649
+ interface ManagedHookBlockOptions {
650
+ hookPath: string;
651
+ block: string;
652
+ markerId?: string;
653
+ uninstall?: boolean;
654
+ }
655
+ interface HookInstallResult {
656
+ hookPath: string;
657
+ action: 'installed' | 'replaced' | 'uninstalled' | 'unchanged';
658
+ markerId: string;
659
+ }
660
+ type HookEntryKind = 'missing' | 'file' | 'symlink' | 'other';
661
+ interface HookSnapshot {
662
+ kind: HookEntryKind;
663
+ bytes: Buffer;
664
+ dev?: bigint;
665
+ ino?: bigint;
666
+ size?: bigint;
667
+ mtimeNs?: bigint;
668
+ mode?: bigint;
669
+ linkTarget?: string;
670
+ }
671
+ interface DesiredHookState {
672
+ exists: boolean;
673
+ bytes: Buffer;
674
+ mode?: number;
675
+ }
676
+ interface PreparedManagedHookBlock {
677
+ readonly hookPath: string;
678
+ readonly result: HookInstallResult;
679
+ readonly snapshot: HookSnapshot;
680
+ readonly desired: DesiredHookState;
681
+ readonly writeRequired: boolean;
682
+ }
683
+ declare function prepareManagedHookBlock(options: ManagedHookBlockOptions): Promise<PreparedManagedHookBlock>;
684
+ declare function applyPreparedManagedHookBlocks(prepared: readonly PreparedManagedHookBlock[]): Promise<HookInstallResult[]>;
685
+ declare function installManagedHookBlock(options: ManagedHookBlockOptions): Promise<HookInstallResult>;
686
+
687
+ /**
688
+ * Review Result Protocol validator.
689
+ *
690
+ * Validates a JSON object against the review-result.schema.json constraints.
691
+ * Does NOT use ajv or any JSON-schema library — pure deterministic checks
692
+ * for zero-dependency CLI use.
693
+ */
694
+ interface ValidationError {
695
+ path: string;
696
+ message: string;
697
+ }
698
+ /**
699
+ * Validate a review result object against the v1.0 protocol.
700
+ *
701
+ * @param input - Parsed JSON to validate (not a string).
702
+ * @returns Array of validation errors. Empty = valid.
703
+ */
704
+ declare function validateReviewResult(input: unknown): ValidationError[];
705
+
706
+ /**
707
+ * Review Result Protocol v1.0 — TypeScript types.
708
+ *
709
+ * Canonical schema: schemas/review-result.schema.json
710
+ * These types are the programmatic equivalent; keep both in sync.
711
+ */
712
+ type ReviewStatus = 'SUCCEEDED' | 'FAILED' | 'BLOCKED' | 'NEEDS_INPUT' | 'SKIPPED';
713
+ type ReviewDecision = 'PASS' | 'FAIL' | 'PASS_WITH_RESIDUAL_MINOR' | 'BLOCKED' | 'NEEDS_INPUT' | 'NOT_APPLICABLE';
714
+ type FindingSeverity = 'block' | 'warn' | 'info';
715
+ type FindingStatus = 'open' | 'resolved' | 'accepted' | 'superseded';
716
+ type ExecutorType = 'script' | 'worker' | 'agent' | 'manual' | 'cli';
717
+ interface FindingLocation {
718
+ file?: string;
719
+ line?: number;
720
+ column?: number;
721
+ }
722
+ interface Finding {
723
+ id: string;
724
+ severity: FindingSeverity;
725
+ category?: string;
726
+ message: string;
727
+ location?: FindingLocation;
728
+ artifact_id?: string;
729
+ evidence?: string;
730
+ suggested_fix?: string;
731
+ status?: FindingStatus;
732
+ resolved_by?: string;
733
+ }
734
+ interface EvidenceObject {
735
+ type: string;
736
+ path: string;
737
+ status?: string;
738
+ decision?: string;
739
+ summary?: string;
740
+ command?: string;
741
+ result?: string;
742
+ }
743
+ type Evidence = string | EvidenceObject;
744
+ interface Producer {
745
+ executor: ExecutorType;
746
+ name: string;
747
+ skill?: string;
748
+ }
749
+ interface AcceptanceSourceResult {
750
+ run_id: string;
751
+ stage_id?: string;
752
+ producer: Producer;
753
+ }
754
+ interface AcceptanceData {
755
+ reviewer: Producer;
756
+ source_result: AcceptanceSourceResult;
757
+ }
758
+ interface BatchDefinition {
759
+ id: string;
760
+ files: string[];
761
+ chars?: number;
762
+ }
763
+ interface ReviewMetrics {
764
+ files_reviewed?: number;
765
+ files_scanned?: number;
766
+ findings_count?: number;
767
+ deterministic_findings_count?: number;
768
+ semantic_findings_count?: number;
769
+ block_count?: number;
770
+ warn_count?: number;
771
+ info_count?: number;
772
+ resolved_count?: number;
773
+ batch_count?: number;
774
+ scenario_count?: number;
775
+ }
776
+ interface ReviewData {
777
+ source_files?: string[];
778
+ files?: string[];
779
+ batches?: BatchDefinition[];
780
+ metrics?: ReviewMetrics;
781
+ findings?: Finding[];
782
+ resolved_findings?: Finding[];
783
+ repair_worker_needed?: boolean;
784
+ }
785
+ interface RepairValidation {
786
+ command?: string;
787
+ exit_code?: number;
788
+ findings_remaining?: number;
789
+ }
790
+ interface RepairData {
791
+ source_review_run_id?: string;
792
+ source_review_stage_id?: string;
793
+ findings_addressed?: Finding[];
794
+ files_modified?: string[];
795
+ validation_after_repair?: RepairValidation;
796
+ }
797
+ interface ReviewResult {
798
+ schema_version: '1.0';
799
+ run_id: string;
800
+ stage_id?: string;
801
+ attempt?: number;
802
+ status: ReviewStatus;
803
+ decision: ReviewDecision;
804
+ summary: string;
805
+ outputs?: string[];
806
+ warnings?: string[];
807
+ blocking_reason?: string | null;
808
+ degradation?: string | null;
809
+ producer?: Producer;
810
+ acceptance?: AcceptanceData;
811
+ evidence?: Evidence[];
812
+ review?: ReviewData;
813
+ repair?: RepairData;
814
+ }
815
+
816
+ interface ContractIdentity {
817
+ /** Major identity (e.g., "artifact.e2e-test@1") */
818
+ major: string;
819
+ /** Authority namespace (e.g., "artifact", "project", "io.github.org") */
820
+ authority: string;
821
+ /** Namespace for ID resolution */
822
+ namespace: string;
823
+ /** Immutable revision digest (sha256:...) */
824
+ revisionDigest: string;
825
+ /** Machine-readable relation rules for this contract */
826
+ relationRules?: Record<string, RelationRule>;
827
+ /** Machine-readable semantic markers for this contract */
828
+ semanticMarkers?: Record<string, SemanticMarker>;
829
+ }
830
+ interface RelationRule {
831
+ /** Allowed target types for this relation kind */
832
+ allowedTargetTypes: string[];
833
+ /** Minimum cardinality (0 = optional) */
834
+ min: number;
835
+ /** Maximum cardinality */
836
+ max: number;
837
+ /** Anchor policy: "required", "optional", or "forbidden" */
838
+ anchorPolicy: 'required' | 'optional' | 'forbidden';
839
+ }
840
+ interface SemanticMarker {
841
+ /** Canonical JSON pointer to the semantic slot */
842
+ jsonPointer: string;
843
+ /** Markdown marker identifier (e.g., "scope", "system-boundary") */
844
+ markdownMarker: string;
845
+ /** Whether this marker is required */
846
+ required: boolean;
847
+ }
848
+ interface ContractDefinition {
849
+ identity: ContractIdentity;
850
+ schema: ContractSchema;
851
+ /** Raw schema content for digest computation */
852
+ rawContent: string;
853
+ }
854
+ interface ContractSchema {
855
+ $id: string;
856
+ title: string;
857
+ version: string;
858
+ contractIdentity: ContractIdentity;
859
+ type: string;
860
+ required: string[];
861
+ properties: Record<string, unknown>;
862
+ definitions?: Record<string, unknown>;
863
+ additionalProperties?: boolean;
864
+ }
865
+ declare const CONTRACT_ERROR_CODES: {
866
+ /** Contract identity not found */
867
+ readonly CONTRACT_NOT_FOUND: "CONTRACT_NOT_FOUND";
868
+ /** Invalid contract identity format */
869
+ readonly INVALID_IDENTITY: "INVALID_IDENTITY";
870
+ /** Revision digest mismatch */
871
+ readonly DIGEST_MISMATCH: "DIGEST_MISMATCH";
872
+ /** Duplicate contract identity */
873
+ readonly DUPLICATE_IDENTITY: "DUPLICATE_IDENTITY";
874
+ /** Multiple active write contracts for same type */
875
+ readonly MULTIPLE_ACTIVE_WRITE: "MULTIPLE_ACTIVE_WRITE";
876
+ /** Unknown authority namespace */
877
+ readonly UNKNOWN_AUTHORITY: "UNKNOWN_AUTHORITY";
878
+ /** Namespace authority violation */
879
+ readonly AUTHORITY_VIOLATION: "AUTHORITY_VIOLATION";
880
+ /** Schema validation failed */
881
+ readonly SCHEMA_VALIDATION_FAILED: "SCHEMA_VALIDATION_FAILED";
882
+ /** Canonical IR normalization failed */
883
+ readonly NORMALIZATION_FAILED: "NORMALIZATION_FAILED";
884
+ /** Policy compatibility check failed */
885
+ readonly POLICY_INCOMPATIBLE: "POLICY_INCOMPATIBLE";
886
+ /** Legacy revision cannot be normalized */
887
+ readonly LEGACY_NORMALIZATION_FAILED: "LEGACY_NORMALIZATION_FAILED";
888
+ /** Canonical and legacy conflict */
889
+ readonly CANONICAL_LEGACY_CONFLICT: "CANONICAL_LEGACY_CONFLICT";
890
+ /** Relation rule violation */
891
+ readonly RELATION_RULE_VIOLATION: "RELATION_RULE_VIOLATION";
892
+ /** Relation rules missing in contract (fail closed) */
893
+ readonly RELATION_RULES_MISSING: "RELATION_RULES_MISSING";
894
+ /** Ambiguous revision — multiple revisions found, no unique active write */
895
+ readonly AMBIGUOUS_REVISION: "AMBIGUOUS_REVISION";
896
+ /** Invalid relation kind */
897
+ readonly RELATION_INVALID_KIND: "RELATION_INVALID_KIND";
898
+ /** Invalid relation target type */
899
+ readonly RELATION_INVALID_TARGET_TYPE: "RELATION_INVALID_TARGET_TYPE";
900
+ /** Relation below minimum cardinality */
901
+ readonly RELATION_BELOW_MIN: "RELATION_BELOW_MIN";
902
+ /** Relation above maximum cardinality */
903
+ readonly RELATION_ABOVE_MAX: "RELATION_ABOVE_MAX";
904
+ /** Missing required anchor */
905
+ readonly RELATION_MISSING_ANCHOR: "RELATION_MISSING_ANCHOR";
906
+ /** Forbidden anchor present */
907
+ readonly RELATION_FORBIDDEN_ANCHOR: "RELATION_FORBIDDEN_ANCHOR";
908
+ /** Missing required semantic marker */
909
+ readonly MARKER_MISSING: "MARKER_MISSING";
910
+ /** Duplicate semantic marker */
911
+ readonly MARKER_DUPLICATE: "MARKER_DUPLICATE";
912
+ /** Unknown semantic marker */
913
+ readonly MARKER_UNKNOWN: "MARKER_UNKNOWN";
914
+ };
915
+ type ContractErrorCode = typeof CONTRACT_ERROR_CODES[keyof typeof CONTRACT_ERROR_CODES];
916
+ declare class ContractError extends Error {
917
+ readonly code: ContractErrorCode;
918
+ readonly details?: Record<string, unknown> | undefined;
919
+ constructor(code: ContractErrorCode, message: string, details?: Record<string, unknown> | undefined);
920
+ }
921
+ /**
922
+ * Check if a namespace is official (artifact or artifact.*)
923
+ */
924
+ declare function isOfficialNamespace(namespace: string): boolean;
925
+ /**
926
+ * Validate namespace authority
927
+ * - Official namespace (artifact.*) can only be used by official contracts
928
+ * - Third-party must use their own authority (e.g., io.github.org.*)
929
+ * - Project contracts use project.<project-id>.*
930
+ */
931
+ declare function validateNamespaceAuthority(identity: ContractIdentity, expectedAuthority?: string): void;
932
+ /**
933
+ * Compute immutable revision digest for contract content.
934
+ * Uses SHA-256 on canonicalized content (revisionDigest field excluded).
935
+ */
936
+ declare function computeRevisionDigest(content: string): string;
937
+ /**
938
+ * Verify that content matches expected digest
939
+ */
940
+ declare function verifyDigest(content: string, expectedDigest: string): boolean;
941
+ interface ContractRegistryEntry {
942
+ contract: ContractDefinition;
943
+ isActive: boolean;
944
+ isWriteTarget: boolean;
945
+ loadedAt: string;
946
+ }
947
+ declare class ContractRegistry {
948
+ private contracts;
949
+ private typeToActiveWrite;
950
+ private majorToContracts;
951
+ /**
952
+ * Register a contract
953
+ * @throws ContractError if duplicate identity or multiple active write contracts
954
+ */
955
+ register(contract: ContractDefinition, options?: {
956
+ isActive?: boolean;
957
+ isWriteTarget?: boolean;
958
+ }): void;
959
+ /**
960
+ * Resolve by major identity. Multiple revisions require a unique active write
961
+ * revision; insertion order is never a resolution policy.
962
+ */
963
+ get(major: string): ContractDefinition | undefined;
964
+ /**
965
+ * Get contract by major identity and digest
966
+ */
967
+ getByMajorAndDigest(major: string, digest: string): ContractDefinition | undefined;
968
+ /**
969
+ * Get all contracts for a major identity
970
+ */
971
+ getByMajor(major: string): ContractDefinition[];
972
+ /**
973
+ * Get active write contract for a type
974
+ */
975
+ getActiveWriteContract(typePrefix: string): ContractDefinition | undefined;
976
+ /**
977
+ * List all registered contracts
978
+ */
979
+ list(): ContractRegistryEntry[];
980
+ /**
981
+ * Check if a contract is registered by major identity
982
+ */
983
+ has(major: string): boolean;
984
+ /**
985
+ * Check if a contract is registered by major identity and digest
986
+ */
987
+ hasByMajorAndDigest(major: string, digest: string): boolean;
988
+ }
989
+ interface CanonicalIR {
990
+ /** Artifact type */
991
+ type: string;
992
+ /** Artifact ID */
993
+ id: string;
994
+ /** Contract major identity used */
995
+ contractMajor: string;
996
+ /** Contract revision digest */
997
+ contractDigest: string;
998
+ /** Normalized canonical data */
999
+ canonical: Record<string, unknown>;
1000
+ /** Source revision (legacy or canonical) */
1001
+ sourceRevision: 'canonical' | 'legacy';
1002
+ /** Normalization warnings */
1003
+ warnings: string[];
1004
+ }
1005
+ interface NormalizationError {
1006
+ code: string;
1007
+ path: string;
1008
+ message: string;
1009
+ }
1010
+ interface NormalizationResult {
1011
+ success: boolean;
1012
+ ir?: CanonicalIR;
1013
+ errors: NormalizationError[];
1014
+ warnings: string[];
1015
+ }
1016
+ interface LegacyFieldMapping {
1017
+ /** Legacy field name */
1018
+ legacy: string;
1019
+ /** Canonical field name */
1020
+ canonical: string;
1021
+ /** Transform function (optional) */
1022
+ transform?: (value: unknown) => unknown;
1023
+ /** Whether field is required in canonical */
1024
+ required?: boolean;
1025
+ }
1026
+ interface NormalizerConfig {
1027
+ /** Contract identity this normalizer targets */
1028
+ contractMajor: string;
1029
+ /** Field mappings from legacy to canonical */
1030
+ fieldMappings: LegacyFieldMapping[];
1031
+ /** Validation function for canonical form */
1032
+ validate?: (canonical: Record<string, unknown>) => string[];
1033
+ }
1034
+ /**
1035
+ * Normalize data to canonical IR.
1036
+ * Handles:
1037
+ * - Pure canonical input: returns sourceRevision: 'canonical'
1038
+ * - Pure legacy input: maps to canonical, returns sourceRevision: 'legacy'
1039
+ * - Mixed input: detects canonical/legacy conflicts
1040
+ */
1041
+ declare function normalizeToCanonical(legacyData: Record<string, unknown>, config: NormalizerConfig, contract: ContractDefinition): NormalizationResult;
1042
+ interface ProjectPolicy {
1043
+ /** Policy identity */
1044
+ id: string;
1045
+ /** Base contract this policy tightens */
1046
+ baseContractMajor: string;
1047
+ /** Additional required fields */
1048
+ additionalRequired?: string[];
1049
+ /** Restricted enum values (subset of base) */
1050
+ restrictedEnums?: Record<string, unknown[]>;
1051
+ /** Minimum cardinality overrides */
1052
+ minCardinality?: Record<string, number>;
1053
+ /** Maximum cardinality overrides */
1054
+ maxCardinality?: Record<string, number>;
1055
+ /** Additional constraints */
1056
+ constraints?: Record<string, unknown>;
1057
+ }
1058
+ interface PolicyCompatibilityResult {
1059
+ compatible: boolean;
1060
+ errors: string[];
1061
+ warnings: string[];
1062
+ }
1063
+ /**
1064
+ * Validate that project policy only tightens (never loosens) base contract.
1065
+ * - Arrays use minItems/maxItems; numbers use minimum/maximum.
1066
+ * - Enum restrictions must be subsets of base enum.
1067
+ * - Unimplemented constraints are rejected (fail-closed).
1068
+ */
1069
+ declare function validatePolicyCompatibility(policy: ProjectPolicy, baseContract: ContractDefinition): PolicyCompatibilityResult;
1070
+ interface LoadContractOptions {
1071
+ /** Expected authority (optional, for validation) */
1072
+ expectedAuthority?: string;
1073
+ }
1074
+ /**
1075
+ * Load contract from JSON file.
1076
+ * Digest verification is always on (fail-closed) — no bypass option.
1077
+ */
1078
+ declare function loadContract(contractPath: string, options?: LoadContractOptions): Promise<ContractDefinition>;
1079
+ /**
1080
+ * Load all contracts from a directory.
1081
+ * Fails closed: if ANY contract is invalid, the entire load fails.
1082
+ */
1083
+ declare function loadContractsFromDirectory(contractsDir: string, options?: LoadContractOptions): Promise<ContractDefinition[]>;
1084
+ interface SchemaValidationResult {
1085
+ valid: boolean;
1086
+ errors: string[];
1087
+ }
1088
+ /**
1089
+ * Validate data against a contract schema using AJV.
1090
+ * AJV is a runtime dependency — if unavailable, validation fails closed.
1091
+ */
1092
+ declare function validateContractAgainstSchema(data: unknown, contract: ContractDefinition): SchemaValidationResult;
1093
+ declare const E2E_NORMALIZER_CONFIG: NormalizerConfig;
1094
+ /**
1095
+ * Normalize a legacy E2E artifact to canonical IR.
1096
+ * The legacy format has flat fields (id, title, status, scope as string, etc.)
1097
+ * while the canonical format uses nested objects (metadata.id, scope.business_goal, etc.)
1098
+ * Requires explicit contract — no default identity fallback.
1099
+ */
1100
+ declare function normalizeE2eLegacyArtifact(legacyData: Record<string, unknown>, contract: ContractDefinition): NormalizationResult;
1101
+ interface ContractCatalogEntry {
1102
+ identity: ContractIdentity;
1103
+ contract: ContractDefinition;
1104
+ }
1105
+ /**
1106
+ * Machine-readable contract catalog.
1107
+ * Lists, resolves and explains registered contracts.
1108
+ * Uses (major, digest) as revision key for multi-revision support.
1109
+ */
1110
+ declare class ContractCatalog {
1111
+ private contracts;
1112
+ private majorToContracts;
1113
+ private majorToActiveWrite;
1114
+ /**
1115
+ * Add a contract to the catalog
1116
+ * @throws ContractError if duplicate identity
1117
+ */
1118
+ add(contract: ContractDefinition, options?: {
1119
+ isActive?: boolean;
1120
+ isWriteTarget?: boolean;
1121
+ }): void;
1122
+ /**
1123
+ * Resolve a contract by major identity.
1124
+ * - 0 entries: returns undefined
1125
+ * - 1 entry: returns it
1126
+ * - multiple: if there's a unique active write, returns it; otherwise throws AMBIGUOUS_REVISION
1127
+ */
1128
+ resolve(major: string): ContractDefinition | undefined;
1129
+ /**
1130
+ * Resolve a contract by major identity and exact digest
1131
+ */
1132
+ resolveByDigest(major: string, digest: string): ContractDefinition | undefined;
1133
+ /**
1134
+ * List all catalog entries (all revisions)
1135
+ */
1136
+ list(): ContractCatalogEntry[];
1137
+ /**
1138
+ * Get catalog as JSON-serializable object (all revisions)
1139
+ */
1140
+ toJSON(): Record<string, unknown>;
1141
+ }
1142
+ /**
1143
+ * Load contract catalog from a contracts directory
1144
+ */
1145
+ declare function loadContractCatalog(contractsDir: string, options?: LoadContractOptions): Promise<ContractCatalog>;
1146
+
1147
+ interface ArtifactNode {
1148
+ uid: string;
1149
+ type: string;
1150
+ code: string;
1151
+ title: string;
1152
+ path: string;
1153
+ line: number;
1154
+ status?: string;
1155
+ attrs?: Record<string, unknown>;
1156
+ aliases?: string[];
1157
+ }
1158
+ interface ArtifactEdge {
1159
+ from: string;
1160
+ to: string;
1161
+ kind: string;
1162
+ source: string;
1163
+ sourcePath: string;
1164
+ sourceLine: number;
1165
+ }
1166
+ interface ValidationIssue {
1167
+ code: string;
1168
+ severity: 'error' | 'warning' | 'info';
1169
+ message: string;
1170
+ node?: string;
1171
+ edge?: ArtifactEdge;
1172
+ path: string;
1173
+ line: number;
1174
+ }
1175
+ interface ArtifactExtraFieldSchema {
1176
+ name: string;
1177
+ type: 'string' | 'number' | 'boolean' | 'enum';
1178
+ enum?: Array<string | number | boolean>;
1179
+ }
1180
+ interface ArtifactTypeSchema {
1181
+ paths: string[];
1182
+ idPattern?: string;
1183
+ displayName?: string;
1184
+ role?: ArtifactTypeRole;
1185
+ layer?: string;
1186
+ aliases?: string[];
1187
+ target?: boolean;
1188
+ extraFields?: ArtifactExtraFieldSchema[];
1189
+ }
1190
+ interface ArtifactTarget {
1191
+ type: string;
1192
+ id: string;
1193
+ }
1194
+ interface ArtifactEdgeRule {
1195
+ from: string;
1196
+ to: string;
1197
+ kind: string;
1198
+ }
1199
+ /** E2E test runner configuration */
1200
+ interface E2eRunnerConfig {
1201
+ /** Runner name (e.g., 'playwright', 'vitest', 'jest') */
1202
+ name: string;
1203
+ /** Test kind accepted by this runner: 'unit', 'integration', or 'e2e' */
1204
+ kind?: 'unit' | 'integration' | 'e2e';
1205
+ /** Root directory for test discovery (relative to project root) */
1206
+ root: string;
1207
+ /** Include glob patterns for test files */
1208
+ include: string[];
1209
+ /** Exclude glob patterns for test files */
1210
+ exclude?: string[];
1211
+ /** Test ignore patterns (files that should not be considered as tests) */
1212
+ testIgnore?: string[];
1213
+ }
1214
+ /** Waiver entry with mandatory reason */
1215
+ interface E2eWaiver {
1216
+ id: string;
1217
+ reason: string;
1218
+ }
1219
+ interface ArtifactSchema {
1220
+ types: Record<string, ArtifactTypeSchema>;
1221
+ idPatterns: Record<string, string>;
1222
+ relationFields: Record<string, string[]>;
1223
+ allowedEdges: ArtifactEdgeRule[];
1224
+ forbiddenEdges: ArtifactEdgeRule[];
1225
+ statuses: string[];
1226
+ idRanges: Record<string, Record<string, {
1227
+ prefix: string;
1228
+ start: number;
1229
+ end: number;
1230
+ }>>;
1231
+ /** Context resolution overrides */
1232
+ context?: {
1233
+ /** When false, skip universal baseline injection. Default: true. */
1234
+ universal_baseline?: boolean;
1235
+ };
1236
+ /** E2E coverage proof configuration */
1237
+ e2e?: {
1238
+ /** Minimum executable_ref coverage rate (0-1) for warning */
1239
+ executable_ref_warning?: number;
1240
+ /** Minimum executable_ref coverage rate (0-1) for error */
1241
+ executable_ref_error?: number;
1242
+ /** Whether to report uncovered scenarios. Default true. */
1243
+ report_uncovered_scenarios?: boolean;
1244
+ /** Whether to report uncovered features. Default true. */
1245
+ report_uncovered_features?: boolean;
1246
+ /** Scenario waivers (id + reason) from coverage requirements */
1247
+ scenario_waivers?: E2eWaiver[];
1248
+ /** Feature waivers (id + reason) from coverage requirements */
1249
+ feature_waivers?: E2eWaiver[];
1250
+ /** E2E test runner configurations */
1251
+ runners?: E2eRunnerConfig[];
1252
+ };
1253
+ }
1254
+ declare const TARGET_ARTIFACT_TYPES: readonly ["feature", "scenario", "decision", "design", "e2e_test"];
1255
+ type TargetArtifactType = typeof TARGET_ARTIFACT_TYPES[number];
1256
+ type ArtifactTypeRole = TargetArtifactType | 'context' | 'candidate' | 'not-recommended';
1257
+ interface ArtifactTypeMetadata {
1258
+ type: string;
1259
+ displayName: string;
1260
+ role: ArtifactTypeRole;
1261
+ layer: string;
1262
+ aliases: string[];
1263
+ targetCapable: boolean;
1264
+ }
1265
+ declare function isTargetArtifactType(type: string): type is TargetArtifactType;
1266
+ declare function getArtifactTypeMetadata(schema: ArtifactSchema, type: string): ArtifactTypeMetadata;
1267
+ declare function getTargetArtifactTypes(schema?: ArtifactSchema): string[];
1268
+ /**
1269
+ * Resolve a token (which may be an exact type name or an explicit alias) to
1270
+ * the canonical artifact type name. Returns `undefined` if no match.
1271
+ *
1272
+ * Strict matching only — no automatic hyphen/underscore conversion.
1273
+ */
1274
+ declare function resolveArtifactTypeName(schema: ArtifactSchema, token: string): string | undefined;
1275
+ interface ArtifactGraph {
1276
+ nodes: ArtifactNode[];
1277
+ edges: ArtifactEdge[];
1278
+ generatedAt: string;
1279
+ /** Normalized absolute project root passed to scanArtifacts. Optional for backward compatibility. */
1280
+ root?: string;
1281
+ /** Scan-time diagnostics. Optional for backward compatibility with consumers that build graph literals without this field. */
1282
+ diagnostics?: ValidationIssue[];
1283
+ }
1284
+ interface QueryOptions {
1285
+ from?: string;
1286
+ to?: string;
1287
+ depth?: number;
1288
+ }
1289
+ type ContextTier = 'baseline' | 'target' | 'direct' | 'matrix' | 'transitive';
1290
+ interface ContextItem {
1291
+ path: string;
1292
+ reason: string;
1293
+ required?: boolean;
1294
+ tier?: ContextTier;
1295
+ reasons?: string[];
1296
+ }
1297
+ interface MissingDetail {
1298
+ ref: string;
1299
+ from: string;
1300
+ kind: 'unresolved-outgoing' | 'unresolved-incoming' | 'target-not-found' | 'multiple-targets' | 'missing-baseline';
1301
+ message: string;
1302
+ suggestedAction: string;
1303
+ }
1304
+ interface ContextManifest {
1305
+ schemaVersion?: string;
1306
+ target: {
1307
+ type: string;
1308
+ id: string;
1309
+ uid: string;
1310
+ title?: string;
1311
+ sourcePath?: string;
1312
+ status?: string;
1313
+ };
1314
+ context: Record<string, ContextItem[]>;
1315
+ missing: string[];
1316
+ missingDetails?: MissingDetail[];
1317
+ omitted?: ContextItem[];
1318
+ /** Explicit universal baseline policy: true=enabled, false=disabled. Used by validatePacket to prevent inferring opt-out from total=0. */
1319
+ baselinePolicy?: boolean;
1320
+ }
1321
+ type ContextMode = 'full' | 'implementation';
1322
+ interface ContextOptions {
1323
+ feature?: string;
1324
+ scenario?: string;
1325
+ decision?: string;
1326
+ design?: string;
1327
+ e2e_test?: string;
1328
+ /** Unified target (type + id) resolved from `--target <type>:<id>`. Additive — old fields preserved. */
1329
+ target?: ArtifactTarget;
1330
+ mode?: ContextMode;
1331
+ maxPerCategory?: number;
1332
+ /**
1333
+ * When true (default), inject all ALWAYS_PRESENT_ITEMS as required baseline
1334
+ * and report missing ones in manifest.missing. When false, skip baseline
1335
+ * injection entirely for lightweight projects.
1336
+ */
1337
+ universalBaseline?: boolean;
1338
+ /** Project root for baseline file existence checks. Required when universalBaseline is true. */
1339
+ root?: string;
1340
+ }
1341
+ declare const DEFAULT_SCHEMA: ArtifactSchema;
1342
+ declare function loadConfig(root: string): Promise<ArtifactSchema>;
1343
+ declare function buildGraph(nodes: Omit<ArtifactNode, 'uid'>[], edges: ArtifactEdge[], diagnostics?: ValidationIssue[], root?: string): ArtifactGraph;
1344
+ declare function scanArtifacts(root: string, schema?: ArtifactSchema): Promise<ArtifactGraph>;
1345
+ /**
1346
+ * Resolve traceability-matrix-v2 edges:
1347
+ * 1. Edges pointing to matrix-row targets (traceability-matrix-v2:*) are kept as-is.
1348
+ * 2. Unresolved refs (`resolve:BARE_ID`) are resolved to real artifact nodes when possible,
1349
+ * otherwise left as `resolve:BARE_ID` (which becomes a DANGLING_REFERENCE in validateGraph).
1350
+ */
1351
+ declare function resolveMatrixEdges(graph: ArtifactGraph): ArtifactGraph;
1352
+ declare function validateGraph(graph: ArtifactGraph, schema?: ArtifactSchema): ValidationIssue[];
1353
+ declare function validateScenarioPrdLinks(graph: ArtifactGraph, schema?: ArtifactSchema): ValidationIssue[];
1354
+ declare function validateScenarioPrdLinkIndex(root: string, graph: ArtifactGraph): Promise<ValidationIssue[]>;
1355
+ declare function queryGraph(graph: ArtifactGraph, options: QueryOptions): ArtifactGraph;
1356
+ declare function renderMermaid(graph: ArtifactGraph): string;
1357
+ declare function nextId(graph: ArtifactGraph, schema: ArtifactSchema, type: string, rangeName: string): string;
1358
+ declare function writeGraphCache(root: string, graph: ArtifactGraph): Promise<void>;
1359
+ declare function validateExecutableTraceability(root: string, config?: ArtifactSchema): Promise<ValidationIssue[]>;
1360
+ /** O2: E2E coverage statistics and blackhole diagnostics */
1361
+ interface E2eCoverageStats {
1362
+ totalTestCases: number;
1363
+ withExecutableRef: number;
1364
+ executableRefRate: string;
1365
+ /** TCs by status */
1366
+ statusBreakdown: Record<string, number>;
1367
+ /** TCs by chain_type */
1368
+ chainTypeBreakdown: Record<string, number>;
1369
+ /** Scenarios with zero E2E coverage */
1370
+ uncoveredScenarios: string[];
1371
+ /** Features with zero E2E coverage */
1372
+ uncoveredFeatures: string[];
1373
+ /** Configurable thresholds */
1374
+ thresholdWarnings: string[];
1375
+ thresholdErrors: string[];
1376
+ /** Derived ac_coverage_rate per feature */
1377
+ acCoverageRateByFeature: Record<string, {
1378
+ numerator: number;
1379
+ denominator: number;
1380
+ rate: number;
1381
+ }>;
1382
+ /** Multi-dimensional scenario coverage */
1383
+ scenarioCoverage: Record<string, {
1384
+ linked: boolean;
1385
+ acCovered: boolean;
1386
+ waived: boolean;
1387
+ verified: boolean;
1388
+ }>;
1389
+ /** Multi-dimensional feature coverage */
1390
+ featureCoverage: Record<string, {
1391
+ linked: boolean;
1392
+ acCovered: boolean;
1393
+ waived: boolean;
1394
+ verified: boolean;
1395
+ }>;
1396
+ }
1397
+ interface E2eCoverageThresholds {
1398
+ /** Minimum executable_ref coverage rate (0-1). Below this triggers warning. */
1399
+ executableRefWarning?: number;
1400
+ /** Minimum executable_ref coverage rate (0-1). Below this triggers error. */
1401
+ executableRefError?: number;
1402
+ /** Whether to report uncovered scenarios as warnings. Default true. */
1403
+ reportUncoveredScenarios?: boolean;
1404
+ /** Whether to report uncovered features as warnings. Default true. */
1405
+ reportUncoveredFeatures?: boolean;
1406
+ /** Explicit waivers: scenario IDs that are waived from coverage requirements */
1407
+ scenarioWaivers?: E2eWaiver[];
1408
+ /** Explicit waivers: feature IDs that are waived from coverage requirements */
1409
+ featureWaivers?: E2eWaiver[];
1410
+ }
1411
+ declare function computeE2eCoverageStats(graph: ArtifactGraph, root: string, thresholds?: E2eCoverageThresholds): Promise<E2eCoverageStats>;
1412
+ /** O4: Deterministic, idempotent E2E registry generation from Markdown sources */
1413
+ interface E2eRegistryBatch {
1414
+ batch_id: string;
1415
+ file: string;
1416
+ scope: string;
1417
+ ac_coverage: Record<string, string[]>;
1418
+ related_scenarios: string[];
1419
+ test_case_count: number;
1420
+ status_summary?: Record<string, number>;
1421
+ /** Batch-level status: 'blocked' when frontmatter fixes_block indicates blocking */
1422
+ status?: string;
1423
+ /** Blocking reasons from frontmatter fixes_block */
1424
+ blocking_reasons?: Record<string, string>;
1425
+ }
1426
+ interface E2eRegistry {
1427
+ registry_version: string;
1428
+ generated_at: string;
1429
+ total_batches: number;
1430
+ total_test_cases: number;
1431
+ batches: E2eRegistryBatch[];
1432
+ }
1433
+ /**
1434
+ * Generate E2E registry from Markdown test files.
1435
+ * Deterministic: same input always produces same output (except generated_at).
1436
+ * Use `--deterministic` to set generated_at to epoch for idempotent diff checks.
1437
+ */
1438
+ declare function generateE2eRegistry(root: string, opts?: {
1439
+ deterministic?: boolean;
1440
+ }): Promise<E2eRegistry>;
1441
+ interface DiscoverOptions {
1442
+ limit?: number;
1443
+ schema?: ArtifactSchema;
1444
+ }
1445
+ /**
1446
+ * Discover audit targets from an artifact graph.
1447
+ * Collects configured target-capable artifact nodes, sorted by id within each type.
1448
+ * When the total exceeds `limit`, uses round-robin across configured target types
1449
+ * to keep the sample balanced.
1450
+ */
1451
+ declare function discoverTargets(graph: ArtifactGraph, options?: DiscoverOptions): Array<{
1452
+ type: string;
1453
+ id: string;
1454
+ }>;
1455
+
1456
+ declare function resolveArtifactContext(graph: ArtifactGraph, opts: ContextOptions): ContextManifest;
1457
+ declare function formatContextMarkdown(manifest: ContextManifest): string;
1458
+
1459
+ export { ALWAYS_PRESENT_ITEMS as ALWAYS_PRESENT, type ArtifactChainDoctorReport, type ArtifactEdge, type ArtifactEdgeRule, type ArtifactExtraFieldSchema, type ArtifactGraph, type ArtifactGraphCliCandidate, type ArtifactGraphCliResolution, type ArtifactGraphCliSource, type ArtifactNode, type ArtifactSchema, type ArtifactTarget, type ArtifactTypeMetadata, type ArtifactTypeRole, type ArtifactTypeSchema, BASELINE_CONSTRAINTS, BASELINE_CONSTRAINTS_COUNT, BASELINE_ITEMS_COUNT, type BatchDefinition, CONTRACT_ERROR_CODES, type CanonicalIR, type CollectChangedPathsOptions, type ContextItem, type ContextManifest, type ContextMode, type ContextOptions, type ContextTier, ContractCatalog, type ContractCatalogEntry, type ContractDefinition, ContractError, type ContractErrorCode, type ContractIdentity, ContractRegistry, type ContractRegistryEntry, type ContractSchema, DEFAULT_MAX_CHARS, DEFAULT_SCHEMA, type DiscoverOptions, E2E_NORMALIZER_CONFIG, type E2eCoverageStats, type E2eCoverageThresholds, type E2eRegistry, type E2eRegistryBatch, type E2eRunnerConfig, type E2eWaiver, type Evidence, type EvidenceObject, type ExecutorType, type Finding, type FindingLocation, type FindingSeverity, type FindingStatus, type GitChangeMode, type GitChangeResult, type GitHookName, type HookInstallResult, type ImplementationBlueprintDraft, type ImplementationPacket, type LegacyFieldMapping, type LoadContractOptions, MIN_PROMPT_CHARS, type ManagedHookBlockOptions, type MissingDetail, type NormalizationResult, type NormalizerConfig, type PacketAuditEntry, type PacketAuditSummary, type PacketCategory, type PacketItem, type PacketOmittedItem, type PacketOptions, type PacketPromptError, type PacketPromptOptions, type PacketTarget, type PacketTargetType, type PacketValidationIssue, type PacketValidationResult, type PolicyCompatibilityResult, type PreparedManagedHookBlock, type Producer, type ProjectPolicy, type PromptValidationIssue, type PromptValidationResult, type QueryOptions, type RepairData, type RepairValidation, type ResolveArtifactGraphCliOptions, type ReviewData, type ReviewDecision, type ReviewMetrics, type ReviewOrderStep, type ReviewResult, type ReviewStatus, type RiskChecklistItem, type SchemaValidationResult, TARGET_ARTIFACT_TYPES, type TargetArtifactType, type TraceVersionResult, VALID_PACKET_TARGET_TYPES, VERSION_INDEX_SCHEMA_VERSION, VERSION_LOCK_PATH, VERSION_LOCK_SCHEMA_VERSION, type ValidationError, type ValidationIssue, type VersionEdgeKind, type VersionIndex, type VersionLockAuditResult, type VersionLockBootstrapOptions, type VersionLockEntry, type VersionLockFile, type VersionLockIssue, type VersionLockRef, type VersionLockRefreshOptions, type VersionLockRefreshResult, type VersionLockSourceRef, type VersionLockStatus, type VersionLockUpdateOptions, type VersionSourceKind, type VersionedEdge, type VersionedNode, applyPreparedManagedHookBlocks, assemblePacket, auditPackets, auditVersionLock, bootstrapVersionLock, buildGraph, buildVersionIndex, collectChangedPaths, computeE2eCoverageStats, computeRevisionDigest, discoverAndAuditPackets, discoverTargets, doctorArtifactChain, formatContextMarkdown, generateE2eRegistry, getArtifactTypeMetadata, getTargetArtifactTypes, installManagedHookBlock, isOfficialNamespace, isPacketTargetType, isPacketTargetTypeDynamic, isTargetArtifactType, loadConfig, loadContract, loadContractCatalog, loadContractsFromDirectory, nextId, normalizeE2eLegacyArtifact, normalizeToCanonical, parseTargetSelector, parseTargetsFile, prepareManagedHookBlock, queryGraph, refreshVersionLock, renderDoctorMarkdown, renderMermaid, renderPacketMarkdown, renderPacketPrompt, renderTraceVersionMarkdown, renderVersionLockAuditMarkdown, renderVersionLockRefreshMarkdown, resolveArtifactContext, resolveArtifactGraphCli, resolveArtifactTypeName, resolveCliTarget, resolveGitHookPath, resolveMatrixEdges, scanArtifacts, traceVersion, updateVersionLock, validateContractAgainstSchema, validateExecutableTraceability, validateGraph, validateNamespaceAuthority, validatePacket, validatePacketMarkdown, validatePacketPrompt, validatePolicyCompatibility, validateReviewResult, validateScenarioPrdLinkIndex, validateScenarioPrdLinks, verifyDigest, writeGraphCache };