@gitgov/core 1.12.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2585 @@
1
+ import { m as IConfigManager, C as ConfigStore, G as GitGovConfig, n as SyncConfig, o as SyncDefaults, k as AuditState, l as AuditStateUpdate, h as ISessionManager, S as SessionStore, a as GitGovSession, A as ActorState, i as SyncPreferencesUpdate, K as KeyProvider, s as FileLister, F as FsFileListerOptions, r as FileListOptions, t as FileStats, R as RecordStore, I as IGitModule } from './index-DMkBFK4C.js';
2
+
3
+ /**
4
+ * ConfigManager - Project Configuration Manager
5
+ *
6
+ * Provides typed access to GitGovernance project configuration (config.json).
7
+ * Configuration is versioned in Git and shared between collaborators.
8
+ *
9
+ * Uses ConfigStore abstraction for backend-agnostic persistence.
10
+ *
11
+ * NOTE: Session state (.session.json) is handled by SessionManager, not ConfigManager.
12
+ *
13
+ * @see packages/blueprints/03_products/core/specs/modules/config_session_module.md
14
+ * @see packages/blueprints/03_products/protocol/10_appendices/config_file.md
15
+ */
16
+
17
+ /**
18
+ * Configuration Manager Class
19
+ *
20
+ * Provides typed access to GitGovernance project configuration.
21
+ * Uses ConfigStore abstraction for backend-agnostic persistence.
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * // Production usage
26
+ * import { FsConfigStore } from '@gitgov/core/fs';
27
+ * const configStore = new FsConfigStore('/path/to/project');
28
+ * const configManager = new ConfigManager(configStore);
29
+ *
30
+ * // Test usage
31
+ * import { MemoryConfigStore } from '@gitgov/core/memory';
32
+ * const configStore = new MemoryConfigStore();
33
+ * configStore.setConfig({ ... });
34
+ * const configManager = new ConfigManager(configStore);
35
+ * ```
36
+ */
37
+ declare class ConfigManager implements IConfigManager {
38
+ private readonly configStore;
39
+ constructor(configStore: ConfigStore);
40
+ /**
41
+ * Load GitGovernance configuration
42
+ */
43
+ loadConfig(): Promise<GitGovConfig | null>;
44
+ /**
45
+ * Get root cycle from configuration
46
+ */
47
+ getRootCycle(): Promise<string | null>;
48
+ /**
49
+ * Get project information from configuration
50
+ */
51
+ getProjectInfo(): Promise<{
52
+ id: string;
53
+ name: string;
54
+ } | null>;
55
+ /**
56
+ * Get sync configuration from config.json
57
+ * Returns sync strategy and related settings with defaults
58
+ */
59
+ getSyncConfig(): Promise<SyncConfig | null>;
60
+ /**
61
+ * Get sync defaults from config.json
62
+ * Returns recommended defaults for pullScheduler and fileWatcher
63
+ */
64
+ getSyncDefaults(): Promise<SyncDefaults>;
65
+ /**
66
+ * Get audit state from config.json
67
+ * Returns last full audit commit and timestamp for incremental mode
68
+ */
69
+ getAuditState(): Promise<AuditState>;
70
+ /**
71
+ * Update audit state in config.json after a full audit
72
+ * This is used to enable incremental audits
73
+ */
74
+ updateAuditState(auditState: AuditStateUpdate): Promise<void>;
75
+ /**
76
+ * Get state branch name from configuration
77
+ */
78
+ getStateBranch(): Promise<string>;
79
+ }
80
+
81
+ /**
82
+ * SessionManager - Local Session State Manager
83
+ *
84
+ * Provides typed access to GitGovernance session state (.session.json).
85
+ * Session state is ephemeral, machine-local, and NOT versioned in Git.
86
+ *
87
+ * Uses SessionStore abstraction for backend-agnostic persistence.
88
+ *
89
+ * @see packages/blueprints/03_products/protocol/10_appendices/session_state.md
90
+ */
91
+
92
+ /**
93
+ * Session Manager Class
94
+ *
95
+ * Provides typed access to GitGovernance session state.
96
+ * Uses SessionStore abstraction for backend-agnostic persistence.
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * // Production usage
101
+ * import { FsSessionStore } from '@gitgov/core/fs';
102
+ * const sessionStore = new FsSessionStore('/path/to/project');
103
+ * const sessionManager = new SessionManager(sessionStore);
104
+ *
105
+ * // Test usage
106
+ * import { MemorySessionStore } from '@gitgov/core/memory';
107
+ * const sessionStore = new MemorySessionStore();
108
+ * sessionStore.setSession({ ... });
109
+ * const sessionManager = new SessionManager(sessionStore);
110
+ * ```
111
+ */
112
+ declare class SessionManager implements ISessionManager {
113
+ private readonly sessionStore;
114
+ constructor(sessionStore: SessionStore);
115
+ /**
116
+ * Load GitGovernance session state
117
+ * [EARS-E1] Auto-detects actor from .key files if no session or no actorId exists
118
+ */
119
+ loadSession(): Promise<GitGovSession | null>;
120
+ /**
121
+ * [EARS-E1] Detect actor from .key files in .gitgov/actors/
122
+ */
123
+ detectActorFromKeyFiles(): Promise<string | null>;
124
+ /**
125
+ * Get actor state for a specific actor
126
+ */
127
+ getActorState(actorId: string): Promise<ActorState | null>;
128
+ /**
129
+ * Update actor state for a specific actor
130
+ */
131
+ updateActorState(actorId: string, state: Partial<ActorState>): Promise<void>;
132
+ /**
133
+ * Get cloud session token
134
+ */
135
+ getCloudSessionToken(): Promise<string | null>;
136
+ /**
137
+ * Get sync preferences from session
138
+ */
139
+ getSyncPreferences(): Promise<GitGovSession['syncPreferences'] | null>;
140
+ /**
141
+ * Update sync preferences in .session.json
142
+ * These are local machine preferences that override project defaults
143
+ */
144
+ updateSyncPreferences(preferences: SyncPreferencesUpdate): Promise<void>;
145
+ /**
146
+ * Get last session info (last human who interacted)
147
+ */
148
+ getLastSession(): Promise<{
149
+ actorId: string;
150
+ timestamp: string;
151
+ } | null>;
152
+ }
153
+
154
+ /**
155
+ * FsKeyProvider - Filesystem-based KeyProvider implementation
156
+ *
157
+ * Stores private keys alongside actor records in .gitgov/actors/{actorId}.key
158
+ * Used in development and CLI environments.
159
+ *
160
+ * @module key_provider/fs/fs_key_provider
161
+ */
162
+
163
+ /**
164
+ * Options for FsKeyProvider.
165
+ */
166
+ interface FsKeyProviderOptions {
167
+ /** Directory where key files are stored (same as actors: .gitgov/actors) */
168
+ actorsDir: string;
169
+ /** File extension for key files (default: '.key') */
170
+ extension?: string;
171
+ /** File permissions for key files (default: 0o600 - owner read/write only) */
172
+ fileMode?: number;
173
+ }
174
+ /**
175
+ * Filesystem-based KeyProvider implementation.
176
+ * Keys are stored alongside actor records with .key extension.
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * const provider = new FsKeyProvider({ actorsDir: '.gitgov/actors' });
181
+ * await provider.setPrivateKey('actor:human:alice', 'base64PrivateKey...');
182
+ * const key = await provider.getPrivateKey('actor:human:alice');
183
+ * ```
184
+ */
185
+ declare class FsKeyProvider implements KeyProvider {
186
+ private readonly actorsDir;
187
+ private readonly extension;
188
+ private readonly fileMode;
189
+ constructor(options: FsKeyProviderOptions);
190
+ /**
191
+ * [EARS-KP01] Retrieves the private key for an actor.
192
+ * [EARS-FKP07] Trims whitespace from content.
193
+ * [EARS-FKP08] Returns null for empty key file.
194
+ */
195
+ getPrivateKey(actorId: string): Promise<string | null>;
196
+ /**
197
+ * [EARS-KP03] Stores a private key for an actor.
198
+ * [EARS-FKP01] Creates actorsDir if not exists.
199
+ * [EARS-FKP02] Writes key to {actorsDir}/{actorId}.key.
200
+ * [EARS-FKP03] Sets secure file permissions (0600).
201
+ */
202
+ setPrivateKey(actorId: string, privateKey: string): Promise<void>;
203
+ /**
204
+ * [EARS-FKP06] Checks if a private key exists for an actor.
205
+ */
206
+ hasPrivateKey(actorId: string): Promise<boolean>;
207
+ /**
208
+ * [EARS-KP04] Deletes the private key for an actor.
209
+ */
210
+ deletePrivateKey(actorId: string): Promise<boolean>;
211
+ /**
212
+ * [EARS-FKP04] Builds the key file path, sanitizing actorId to prevent path traversal.
213
+ * [EARS-FKP05] Replaces slashes with underscores.
214
+ */
215
+ private getKeyPath;
216
+ /**
217
+ * [EARS-FKP04] Sanitizes actorId to prevent directory traversal.
218
+ * [EARS-FKP05] Replaces path separators with underscores.
219
+ * [EARS-FKP09] Throws INVALID_ACTOR_ID for empty actorId.
220
+ */
221
+ private sanitizeActorId;
222
+ /**
223
+ * Sanitizes actorId for logging (removes potential secrets).
224
+ */
225
+ private sanitizeForLog;
226
+ }
227
+
228
+ /**
229
+ * FsFileLister - Filesystem-based FileLister implementation
230
+ *
231
+ * Uses fast-glob for pattern matching and fs/promises for file operations.
232
+ * Used in CLI and development environments.
233
+ *
234
+ * @module file_lister/fs/fs_file_lister
235
+ */
236
+
237
+ /**
238
+ * Filesystem-based FileLister implementation.
239
+ * Uses fast-glob for pattern matching and fs/promises for file operations.
240
+ *
241
+ * @example
242
+ * ```typescript
243
+ * const lister = new FsFileLister({ cwd: '/path/to/project' });
244
+ * const files = await lister.list(['**\/*.ts'], { ignore: ['node_modules/**'] });
245
+ * const content = await lister.read('src/index.ts');
246
+ * ```
247
+ */
248
+ declare class FsFileLister implements FileLister {
249
+ private readonly cwd;
250
+ constructor(options: FsFileListerOptions);
251
+ /**
252
+ * [EARS-FL01] Lists files matching glob patterns.
253
+ * [EARS-FFL01] Excludes files matching ignore patterns.
254
+ */
255
+ list(patterns: string[], options?: FileListOptions): Promise<string[]>;
256
+ /**
257
+ * [EARS-FL02] Checks if a file exists.
258
+ */
259
+ exists(filePath: string): Promise<boolean>;
260
+ /**
261
+ * [EARS-FL03] Reads file content as string.
262
+ * [EARS-FFL03] Throws FILE_NOT_FOUND for missing files.
263
+ */
264
+ read(filePath: string): Promise<string>;
265
+ /**
266
+ * [EARS-FL04] Gets file statistics.
267
+ * [EARS-FFL03] Throws FILE_NOT_FOUND for missing files.
268
+ */
269
+ stat(filePath: string): Promise<FileStats>;
270
+ /**
271
+ * [EARS-FFL04] Validates that the path doesn't contain traversal characters.
272
+ * [EARS-FFL05] Validates that the path is not absolute.
273
+ */
274
+ private validatePath;
275
+ }
276
+
277
+ /**
278
+ * This file was automatically generated from actor_record_schema.json.
279
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source schema,
280
+ * and run 'pnpm compile:types' to regenerate this file.
281
+ */
282
+ /**
283
+ * Canonical schema for actor records as defined in actor_protocol.md
284
+ */
285
+ interface ActorRecord {
286
+ /**
287
+ * Unique, human-readable identifier for the actor.
288
+ */
289
+ id: string;
290
+ /**
291
+ * The type of actor.
292
+ */
293
+ type: 'human' | 'agent';
294
+ /**
295
+ * The name of the actor to be used in user interfaces.
296
+ */
297
+ displayName: string;
298
+ /**
299
+ * The Ed25519 public key (base64 encoded, 44 characters) for verifying the actor's signatures.
300
+ */
301
+ publicKey: string;
302
+ /**
303
+ * List of capacity roles defining the actor's skills and permissions. Uses hierarchical format with colons.
304
+ *
305
+ * @minItems 1
306
+ */
307
+ roles: [string, ...string[]];
308
+ /**
309
+ * Optional. The lifecycle status of the actor. Defaults to 'active' if not specified.
310
+ */
311
+ status?: 'active' | 'revoked';
312
+ /**
313
+ * Optional. The ID of the actor that replaces this one.
314
+ */
315
+ supersededBy?: string;
316
+ /**
317
+ * An optional field for additional, non-canonical metadata.
318
+ */
319
+ metadata?: {};
320
+ }
321
+
322
+ /**
323
+ * This file was automatically generated from agent_record_schema.json.
324
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source schema,
325
+ * and run 'pnpm compile:types' to regenerate this file.
326
+ */
327
+ /**
328
+ * Canonical schema for agent operational manifests.
329
+ */
330
+ interface AgentRecord<TMetadata = object> {
331
+ /**
332
+ * Unique identifier for the agent, linking to an ActorRecord.
333
+ */
334
+ id: string;
335
+ status?: 'active' | 'archived';
336
+ /**
337
+ * Optional list of triggers that activate the agent.
338
+ * Additional fields are allowed and depend on trigger type:
339
+ * - webhook triggers: 'event' (event identifier), 'filter' (condition)
340
+ * - scheduled triggers: 'cron' (cron expression)
341
+ * - manual triggers: 'command' (example CLI command)
342
+ *
343
+ */
344
+ triggers?: {
345
+ /**
346
+ * Type of trigger that activates the agent
347
+ */
348
+ type: 'manual' | 'webhook' | 'scheduled';
349
+ [k: string]: unknown | undefined;
350
+ }[];
351
+ knowledge_dependencies?: string[];
352
+ prompt_engine_requirements?: {
353
+ roles?: string[];
354
+ skills?: string[];
355
+ };
356
+ /**
357
+ * Optional framework-specific or deployment-specific metadata for agent extensions.
358
+ * Common use cases: framework identification (langchain, google-adk), deployment info (provider, image, region),
359
+ * cost tracking (cost_per_invocation, currency), tool capabilities, maintainer info.
360
+ * This field does NOT affect agent execution - it is purely informational.
361
+ *
362
+ */
363
+ metadata?: TMetadata;
364
+ engine: {
365
+ type: 'local';
366
+ /**
367
+ * Runtime environment (typescript, python, etc.)
368
+ */
369
+ runtime?: string;
370
+ /**
371
+ * Path to the agent entry file
372
+ */
373
+ entrypoint?: string;
374
+ /**
375
+ * Function name to invoke
376
+ */
377
+ function?: string;
378
+ } | {
379
+ type: 'api';
380
+ /**
381
+ * HTTP endpoint for the agent
382
+ */
383
+ url: string;
384
+ method?: 'POST' | 'GET' | 'PUT';
385
+ /**
386
+ * Authentication configuration for API requests
387
+ */
388
+ auth?: {
389
+ /**
390
+ * Authentication type. 'actor-signature' uses the agent's ActorRecord keypair to sign requests.
391
+ */
392
+ type?: 'bearer' | 'oauth' | 'api-key' | 'actor-signature';
393
+ /**
394
+ * Reference to secret in Secret Manager (for bearer/api-key/oauth auth types)
395
+ */
396
+ secret_key?: string;
397
+ /**
398
+ * Direct token value (not recommended for production, use secret_key instead)
399
+ */
400
+ token?: string;
401
+ [k: string]: unknown | undefined;
402
+ };
403
+ } | {
404
+ type: 'mcp';
405
+ /**
406
+ * MCP server endpoint
407
+ */
408
+ url: string;
409
+ /**
410
+ * Name of the MCP tool to invoke. If not specified, defaults to agentId without 'agent:' prefix.
411
+ */
412
+ tool?: string;
413
+ /**
414
+ * Authentication configuration for MCP server
415
+ */
416
+ auth?: {
417
+ /**
418
+ * Authentication type. 'actor-signature' uses the agent's ActorRecord keypair to sign requests.
419
+ */
420
+ type?: 'bearer' | 'oauth' | 'api-key' | 'actor-signature';
421
+ /**
422
+ * Reference to secret in Secret Manager (for bearer/api-key/oauth auth types)
423
+ */
424
+ secret_key?: string;
425
+ /**
426
+ * Direct token value (not recommended for production, use secret_key instead)
427
+ */
428
+ token?: string;
429
+ [k: string]: unknown | undefined;
430
+ };
431
+ } | {
432
+ type: 'custom';
433
+ /**
434
+ * Custom protocol identifier (e.g., 'a2a', 'grpc')
435
+ */
436
+ protocol?: string;
437
+ /**
438
+ * Protocol-specific configuration
439
+ */
440
+ config?: {};
441
+ };
442
+ }
443
+
444
+ /**
445
+ * This file was automatically generated from changelog_record_schema.json.
446
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source schema,
447
+ * and run 'pnpm compile:types' to regenerate this file.
448
+ */
449
+ /**
450
+ * Canonical schema for changelog records - aggregates N tasks into 1 release note
451
+ */
452
+ interface ChangelogRecord {
453
+ /**
454
+ * Unique identifier for the changelog entry
455
+ */
456
+ id: string;
457
+ /**
458
+ * Executive title of the deliverable
459
+ */
460
+ title: string;
461
+ /**
462
+ * Detailed description of the value delivered, including key decisions and impact
463
+ */
464
+ description: string;
465
+ /**
466
+ * IDs of tasks that compose this deliverable (minimum 1 required)
467
+ *
468
+ * @minItems 1
469
+ */
470
+ relatedTasks: [string, ...string[]];
471
+ /**
472
+ * Unix timestamp in seconds when the deliverable was completed
473
+ */
474
+ completedAt: number;
475
+ /**
476
+ * Optional IDs of cycles related to this deliverable
477
+ */
478
+ relatedCycles?: string[];
479
+ /**
480
+ * Optional IDs of key execution records related to this work
481
+ */
482
+ relatedExecutions?: string[];
483
+ /**
484
+ * Optional version or release identifier (e.g., 'v1.0.0', 'sprint-24')
485
+ */
486
+ version?: string;
487
+ /**
488
+ * Optional tags for categorization (e.g., 'feature:auth', 'bugfix', 'security')
489
+ */
490
+ tags?: string[];
491
+ /**
492
+ * Optional list of git commit hashes related to this deliverable
493
+ */
494
+ commits?: string[];
495
+ /**
496
+ * Optional list of main files that were created or modified
497
+ */
498
+ files?: string[];
499
+ /**
500
+ * Optional additional context, decisions, or learnings
501
+ */
502
+ notes?: string;
503
+ }
504
+
505
+ /**
506
+ * This file was automatically generated from cycle_record_schema.json.
507
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source schema,
508
+ * and run 'pnpm compile:types' to regenerate this file.
509
+ */
510
+ /**
511
+ * Canonical schema for cycle records - strategic grouping of work
512
+ */
513
+ interface CycleRecord {
514
+ /**
515
+ * Unique identifier for the cycle (10 timestamp + 1 dash + 5 'cycle' + 1 dash + max 50 slug = 67 max)
516
+ */
517
+ id: string;
518
+ /**
519
+ * Human-readable title for the cycle (e.g., 'Sprint 24', 'Auth v2.0', 'Q4 2025')
520
+ */
521
+ title: string;
522
+ /**
523
+ * The lifecycle status of the cycle
524
+ */
525
+ status: 'planning' | 'active' | 'completed' | 'archived';
526
+ /**
527
+ * Optional array of Task IDs that belong to this cycle. Can be empty for cycles that only contain child cycles. (10 timestamp + 1 dash + 4 'task' + 1 dash + max 50 slug = 66 max)
528
+ */
529
+ taskIds?: string[];
530
+ /**
531
+ * Optional array of Cycle IDs that are children of this cycle, allowing for hierarchies (e.g., Q1 containing Sprint 1, Sprint 2, Sprint 3). (10 timestamp + 1 dash + 5 'cycle' + 1 dash + max 50 slug = 67 max)
532
+ */
533
+ childCycleIds?: string[];
534
+ /**
535
+ * Optional list of key:value tags for categorization (e.g., 'roadmap:q4', 'team:alpha', 'okr:growth').
536
+ */
537
+ tags?: string[];
538
+ /**
539
+ * Optional description of the cycle's goals, objectives, and context
540
+ */
541
+ notes?: string;
542
+ }
543
+
544
+ /**
545
+ * This file was automatically generated from execution_record_schema.json.
546
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source schema,
547
+ * and run 'pnpm compile:types' to regenerate this file.
548
+ */
549
+ /**
550
+ * Canonical schema for execution log records - the universal event stream
551
+ */
552
+ interface ExecutionRecord<TMetadata = object> {
553
+ /**
554
+ * Unique identifier for the execution log entry (10 timestamp + 1 dash + 4 'exec' + 1 dash + max 50 slug = 66 max)
555
+ */
556
+ id: string;
557
+ /**
558
+ * ID of the parent task this execution belongs to (10 timestamp + 1 dash + 4 'task' + 1 dash + max 50 slug = 66 max)
559
+ */
560
+ taskId: string;
561
+ /**
562
+ * Semantic classification of the execution event
563
+ */
564
+ type: 'analysis' | 'progress' | 'blocker' | 'completion' | 'info' | 'correction';
565
+ /**
566
+ * Human-readable title for the execution (used to generate ID)
567
+ */
568
+ title: string;
569
+ /**
570
+ * The tangible, verifiable output or result of the execution.
571
+ * This is the "WHAT" - evidence of work or event summary.
572
+ *
573
+ */
574
+ result: string;
575
+ /**
576
+ * Optional narrative, context and decisions behind the execution.
577
+ * This is the "HOW" and "WHY" - the story behind the result.
578
+ *
579
+ */
580
+ notes?: string;
581
+ /**
582
+ * Optional list of typed references to relevant commits, files, PRs, or external documents.
583
+ * Should use typed prefixes for clarity and trazabilidad (see execution_protocol_appendix.md):
584
+ * - commit: Git commit SHA
585
+ * - pr: Pull Request number
586
+ * - file: File path (relative to repo root)
587
+ * - url: External URL
588
+ * - issue: GitHub Issue number
589
+ * - task: TaskRecord ID
590
+ * - exec: ExecutionRecord ID (for corrections or dependencies)
591
+ * - changelog: ChangelogRecord ID
592
+ *
593
+ */
594
+ references?: string[];
595
+ /**
596
+ * Optional structured data for machine consumption.
597
+ * Use this field for data that needs to be programmatically processed (e.g., audit findings,
598
+ * performance metrics, scan results). This complements result (human-readable WHAT) and
599
+ * notes (narrative HOW/WHY) by providing structured, queryable data.
600
+ * Common use cases: audit findings arrays, performance metrics, tool outputs, scan summaries.
601
+ *
602
+ */
603
+ metadata?: TMetadata;
604
+ }
605
+
606
+ /**
607
+ * This file was automatically generated from feedback_record_schema.json.
608
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source schema,
609
+ * and run 'pnpm compile:types' to regenerate this file.
610
+ */
611
+ /**
612
+ * Canonical schema for feedback records - structured conversation about work
613
+ */
614
+ interface FeedbackRecord<TMetadata = object> {
615
+ /**
616
+ * Unique identifier for the feedback entry
617
+ */
618
+ id: string;
619
+ /**
620
+ * The type of entity this feedback refers to
621
+ */
622
+ entityType: 'task' | 'execution' | 'changelog' | 'feedback' | 'cycle';
623
+ /**
624
+ * The ID of the entity this feedback refers to.
625
+ * Must match the pattern for its entityType:
626
+ * - task: ^\d{10}-task-[a-z0-9-]{1,50}$
627
+ * - execution: ^\d{10}-exec-[a-z0-9-]{1,50}$
628
+ * - changelog: ^\d{10}-changelog-[a-z0-9-]{1,50}$
629
+ * - feedback: ^\d{10}-feedback-[a-z0-9-]{1,50}$
630
+ * - cycle: ^\d{10}-cycle-[a-z0-9-]{1,50}$
631
+ *
632
+ */
633
+ entityId: string;
634
+ /**
635
+ * The semantic intent of the feedback
636
+ */
637
+ type: 'blocking' | 'suggestion' | 'question' | 'approval' | 'clarification' | 'assignment';
638
+ /**
639
+ * The lifecycle status of the feedback.
640
+ * Note: FeedbackRecords are immutable. To change status, create a new feedback
641
+ * that references this one using entityType: "feedback" and resolvesFeedbackId.
642
+ *
643
+ */
644
+ status: 'open' | 'acknowledged' | 'resolved' | 'wontfix';
645
+ /**
646
+ * The content of the feedback. Reduced from 10000 to 5000 chars for practical use.
647
+ */
648
+ content: string;
649
+ /**
650
+ * Optional. The Actor ID responsible for addressing the feedback (e.g., 'human:maria', 'agent:camilo:cursor')
651
+ */
652
+ assignee?: string;
653
+ /**
654
+ * Optional. The ID of another feedback record that this one resolves or responds to
655
+ */
656
+ resolvesFeedbackId?: string;
657
+ /**
658
+ * Optional structured data for machine consumption.
659
+ * Use this field for domain-specific data that needs to be programmatically processed.
660
+ * Common use cases: waiver details (fingerprint, ruleId, file, line), approval context, assignment metadata.
661
+ *
662
+ */
663
+ metadata?: TMetadata;
664
+ }
665
+
666
+ /**
667
+ * This file was automatically generated from task_record_schema.json.
668
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source schema,
669
+ * and run 'pnpm compile:types' to regenerate this file.
670
+ */
671
+ /**
672
+ * Canonical schema for task records as defined in task_protocol.md
673
+ */
674
+ interface TaskRecord {
675
+ /**
676
+ * Unique identifier for the task (10 timestamp + 1 dash + 4 'task' + 1 dash + max 50 slug = 66 max)
677
+ */
678
+ id: string;
679
+ /**
680
+ * A brief, human-readable title for the task. Used to generate the ID slug.
681
+ */
682
+ title: string;
683
+ /**
684
+ * Optional. The IDs of the strategic cycles this task belongs to. (10 timestamp + 1 dash + 5 'cycle' + 1 dash + max 50 slug = 67 max)
685
+ */
686
+ cycleIds?: string[];
687
+ /**
688
+ * Current state of the task in the institutional flow
689
+ */
690
+ status: 'draft' | 'review' | 'ready' | 'active' | 'done' | 'archived' | 'paused' | 'discarded';
691
+ /**
692
+ * Strategic or tactical priority level
693
+ */
694
+ priority: 'low' | 'medium' | 'high' | 'critical';
695
+ /**
696
+ * Functional, technical or strategic summary of the objective
697
+ */
698
+ description: string;
699
+ /**
700
+ * Optional. List of key:value tags for categorization and role suggestion (e.g., 'skill:react', 'role:agent:developer').
701
+ */
702
+ tags?: string[];
703
+ /**
704
+ * Valid links or files, when mentioned
705
+ */
706
+ references?: string[];
707
+ /**
708
+ * Additional comments, decisions made or added context
709
+ */
710
+ notes?: string;
711
+ }
712
+
713
+ /**
714
+ * This file was automatically generated from embedded_metadata_schema.json.
715
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source schema,
716
+ * and run 'pnpm compile:types' to regenerate this file.
717
+ */
718
+ /**
719
+ * Canonical schema for the wrapper structure of all GitGovernance records.
720
+ */
721
+ type EmbeddedMetadataRecord$1 = {
722
+ header: {
723
+ /**
724
+ * Version of the embedded metadata format.
725
+ */
726
+ version: '1.0';
727
+ /**
728
+ * The type of the record contained in the payload.
729
+ */
730
+ type: 'actor' | 'agent' | 'task' | 'execution' | 'changelog' | 'feedback' | 'cycle' | 'custom';
731
+ /**
732
+ * Optional URL to a custom schema for the payload.
733
+ */
734
+ schemaUrl?: string;
735
+ /**
736
+ * Optional SHA-256 checksum of the custom schema.
737
+ */
738
+ schemaChecksum?: string;
739
+ /**
740
+ * SHA-256 checksum of the canonically serialized payload.
741
+ */
742
+ payloadChecksum: string;
743
+ /**
744
+ * An array of one or more signature objects.
745
+ *
746
+ * @minItems 1
747
+ */
748
+ signatures: [
749
+ {
750
+ /**
751
+ * The Actor ID of the signer (must match ActorRecord.id pattern).
752
+ */
753
+ keyId: string;
754
+ /**
755
+ * The context role of the signature (e.g., 'author', 'reviewer', 'auditor', or 'custom:*').
756
+ */
757
+ role: string;
758
+ /**
759
+ * Human-readable note from the signer. Part of the signature digest.
760
+ */
761
+ notes: string;
762
+ /**
763
+ * The Ed25519 signature (base64 encoded, 88 chars with padding) of the signature digest.
764
+ */
765
+ signature: string;
766
+ /**
767
+ * Unix timestamp of the signature.
768
+ */
769
+ timestamp: number;
770
+ },
771
+ ...{
772
+ /**
773
+ * The Actor ID of the signer (must match ActorRecord.id pattern).
774
+ */
775
+ keyId: string;
776
+ /**
777
+ * The context role of the signature (e.g., 'author', 'reviewer', 'auditor', or 'custom:*').
778
+ */
779
+ role: string;
780
+ /**
781
+ * Human-readable note from the signer. Part of the signature digest.
782
+ */
783
+ notes: string;
784
+ /**
785
+ * The Ed25519 signature (base64 encoded, 88 chars with padding) of the signature digest.
786
+ */
787
+ signature: string;
788
+ /**
789
+ * Unix timestamp of the signature.
790
+ */
791
+ timestamp: number;
792
+ }[]
793
+ ];
794
+ };
795
+ /**
796
+ * The specific record data, validated against the schema defined by header.type.
797
+ */
798
+ payload: {};
799
+ } & {
800
+ [k: string]: unknown | undefined;
801
+ };
802
+
803
+ /**
804
+ * Extract Signature type from the auto-generated base type.
805
+ * This is hardcoded solution but avoids duplication and uses the generated type as source of truth.
806
+ */
807
+ type Signature = EmbeddedMetadataRecord$1['header']['signatures'][0];
808
+ /**
809
+ * Extract Header type from the auto-generated base type.
810
+ * This is the complete header structure for EmbeddedMetadata.
811
+ */
812
+ type EmbeddedMetadataHeader = EmbeddedMetadataRecord$1['header'];
813
+ /**
814
+ * Generic version of EmbeddedMetadataRecord that accepts any payload type T.
815
+ * This extends the auto-generated base type but makes the payload generic.
816
+ * We need to explicitly preserve the header structure due to the index signature in the base type.
817
+ */
818
+ type EmbeddedMetadataRecord<T extends GitGovRecordPayload> = {
819
+ header: EmbeddedMetadataHeader;
820
+ payload: T;
821
+ };
822
+
823
+ /**
824
+ * A custom record type for testing purposes.
825
+ */
826
+ type CustomRecord = {
827
+ type: 'custom';
828
+ data: unknown;
829
+ };
830
+ /**
831
+ * Defines the possible 'type' values for any record in the system.
832
+ */
833
+ type GitGovRecordType = "actor" | "agent" | "cycle" | "task" | "execution" | "changelog" | "feedback" | "custom";
834
+ /**
835
+ * The canonical payload for any GitGovernance record.
836
+ */
837
+ type GitGovRecordPayload = ActorRecord | AgentRecord | CycleRecord | TaskRecord | ExecutionRecord | ChangelogRecord | FeedbackRecord | CustomRecord;
838
+ /**
839
+ * The canonical type for any record in GitGovernance, wrapping a payload with metadata.
840
+ */
841
+ type GitGovRecord = EmbeddedMetadataRecord<GitGovRecordPayload>;
842
+ /**
843
+ * Specific GitGov record types with full metadata (header + payload).
844
+ * These types provide clean, type-safe access to records with their signatures and checksums.
845
+ *
846
+ * @example
847
+ * const taskRecord: GitGovTaskRecord = await taskStore.read(taskId);
848
+ * const authorId = taskRecord.header.signatures[0].keyId;
849
+ */
850
+ type GitGovTaskRecord = EmbeddedMetadataRecord<TaskRecord>;
851
+ type GitGovCycleRecord = EmbeddedMetadataRecord<CycleRecord>;
852
+ type GitGovFeedbackRecord = EmbeddedMetadataRecord<FeedbackRecord>;
853
+ type GitGovExecutionRecord = EmbeddedMetadataRecord<ExecutionRecord>;
854
+ type GitGovChangelogRecord = EmbeddedMetadataRecord<ChangelogRecord>;
855
+ type GitGovActorRecord = EmbeddedMetadataRecord<ActorRecord>;
856
+ type GitGovAgentRecord = EmbeddedMetadataRecord<AgentRecord>;
857
+ type ActorPayload = Partial<ActorRecord>;
858
+ type AgentPayload = Partial<AgentRecord>;
859
+ type CyclePayload = Partial<CycleRecord>;
860
+ type TaskPayload = Partial<TaskRecord>;
861
+ type ExecutionPayload = Partial<ExecutionRecord>;
862
+ type ChangelogPayload = Partial<ChangelogRecord>;
863
+ type FeedbackPayload = Partial<FeedbackRecord>;
864
+ /**
865
+ * Base class for all GitGovernance-specific errors.
866
+ * Centralized here as it's used across multiple modules (schemas, validation, etc.)
867
+ */
868
+ declare class GitGovError extends Error {
869
+ readonly code: string;
870
+ constructor(message: string, code: string);
871
+ }
872
+
873
+ /**
874
+ * RecordStores - Typed container for all stores
875
+ *
876
+ * Allows injecting multiple stores to modules that need them.
877
+ * Keys correspond to directory names in .gitgov/
878
+ *
879
+ * All stores are OPTIONAL.
880
+ * Reason: LintModule.lint(stores) can receive only relevant stores.
881
+ * Example: To validate only tasks, pass { tasks: taskStore }.
882
+ * The module iterates over Object.entries(stores) and skips undefined.
883
+ */
884
+ type RecordStores$1 = {
885
+ actors?: RecordStore<GitGovActorRecord>;
886
+ agents?: RecordStore<GitGovAgentRecord>;
887
+ tasks?: RecordStore<GitGovTaskRecord>;
888
+ cycles?: RecordStore<GitGovCycleRecord>;
889
+ executions?: RecordStore<GitGovExecutionRecord>;
890
+ feedbacks?: RecordStore<GitGovFeedbackRecord>;
891
+ changelogs?: RecordStore<GitGovChangelogRecord>;
892
+ };
893
+
894
+ /**
895
+ * MetricsAdapter Dependencies - Facade + Dependency Injection Pattern
896
+ */
897
+ type MetricsAdapterDependencies = {
898
+ stores: Required<Pick<RecordStores$1, 'tasks' | 'cycles' | 'feedbacks' | 'executions' | 'actors'>>;
899
+ platformApi?: IPlatformApi;
900
+ };
901
+ interface IPlatformApi {
902
+ getTokenConsumption(timeframe: string): Promise<TokenConsumption[]>;
903
+ }
904
+ type TokenConsumption = {
905
+ agentId: string;
906
+ tokens: number;
907
+ cost: number;
908
+ timestamp: number;
909
+ };
910
+ type SystemStatus = {
911
+ tasks: {
912
+ total: number;
913
+ byStatus: Record<string, number>;
914
+ byPriority: Record<string, number>;
915
+ };
916
+ cycles: {
917
+ total: number;
918
+ active: number;
919
+ completed: number;
920
+ };
921
+ health: {
922
+ overallScore: number;
923
+ blockedTasks: number;
924
+ staleTasks: number;
925
+ };
926
+ };
927
+ type TaskHealthReport = {
928
+ taskId: string;
929
+ healthScore: number;
930
+ timeInCurrentStage: number;
931
+ stalenessIndex: number;
932
+ blockingFeedbacks: number;
933
+ lastActivity: number;
934
+ recommendations: string[];
935
+ };
936
+ type ProductivityMetrics = {
937
+ throughput: number;
938
+ leadTime: number;
939
+ cycleTime: number;
940
+ tasksCompleted7d: number;
941
+ averageCompletionTime: number;
942
+ };
943
+ type CollaborationMetrics = {
944
+ activeAgents: number;
945
+ totalAgents: number;
946
+ agentUtilization: number;
947
+ humanAgentRatio: number;
948
+ collaborationIndex: number;
949
+ };
950
+ /**
951
+ * MetricsAdapter Interface - The System Analyst
952
+ */
953
+ interface IMetricsAdapter {
954
+ getSystemStatus(): Promise<SystemStatus>;
955
+ getTaskHealth(taskId: string): Promise<TaskHealthReport>;
956
+ getProductivityMetrics(): Promise<ProductivityMetrics>;
957
+ getCollaborationMetrics(): Promise<CollaborationMetrics>;
958
+ calculateTimeInCurrentStage(task: TaskRecord): number;
959
+ calculateStalenessIndex(tasks: TaskRecord[]): number;
960
+ calculateBlockingFeedbackAge(feedback: FeedbackRecord[]): number;
961
+ calculateHealth(tasks: TaskRecord[]): number;
962
+ calculateBacklogDistribution(tasks: TaskRecord[]): Record<string, number>;
963
+ calculateTasksCreatedToday(tasks: TaskRecord[]): number;
964
+ calculateThroughput(tasks: TaskRecord[]): number;
965
+ calculateLeadTime(tasks: TaskRecord[]): number;
966
+ calculateCycleTime(tasks: TaskRecord[]): number;
967
+ calculateActiveAgents(actors: ActorRecord[], executions: ExecutionRecord[]): number;
968
+ }
969
+
970
+ /**
971
+ * MetricsAdapter - The System Analyst
972
+ *
973
+ * Implements Facade + Dependency Injection Pattern for testeable and configurable orchestration.
974
+ * Acts as Mediator between analytics system and multi-store data sources.
975
+ */
976
+ declare class MetricsAdapter implements IMetricsAdapter {
977
+ private stores;
978
+ private platformApi;
979
+ constructor(dependencies: MetricsAdapterDependencies);
980
+ /**
981
+ * [EARS-A1] Gets aggregated system status using Tier 1 metrics.
982
+ */
983
+ getSystemStatus(): Promise<SystemStatus>;
984
+ /**
985
+ * [EARS-A2] Gets task health analysis using Tier 1 metrics.
986
+ */
987
+ getTaskHealth(taskId: string): Promise<TaskHealthReport>;
988
+ /**
989
+ * [EARS-E1] Gets productivity metrics using Tier 2 calculations.
990
+ */
991
+ getProductivityMetrics(): Promise<ProductivityMetrics>;
992
+ /**
993
+ * [EARS-E2] Gets collaboration metrics with agent activity analysis.
994
+ */
995
+ getCollaborationMetrics(): Promise<CollaborationMetrics>;
996
+ /**
997
+ * [EARS-B1] Calculates exact days since last state change.
998
+ */
999
+ calculateTimeInCurrentStage(task: TaskRecord): number;
1000
+ /**
1001
+ * [EARS-B2] Calculates days since last ExecutionRecord.
1002
+ */
1003
+ calculateStalenessIndex(tasks: TaskRecord[]): number;
1004
+ /**
1005
+ * [EARS-B3] Calculates days of oldest active blocking feedback.
1006
+ */
1007
+ calculateBlockingFeedbackAge(feedback: FeedbackRecord[]): number;
1008
+ /**
1009
+ * [EARS-B4] Calculates health percentage using improved protocol formula.
1010
+ */
1011
+ calculateHealth(tasks: TaskRecord[]): number;
1012
+ /**
1013
+ * [EARS-B5] Returns status distribution with percentages.
1014
+ */
1015
+ calculateBacklogDistribution(tasks: TaskRecord[]): Record<string, number>;
1016
+ /**
1017
+ * [EARS-B6] Counts tasks created in last 24 hours.
1018
+ */
1019
+ calculateTasksCreatedToday(tasks: TaskRecord[]): number;
1020
+ /**
1021
+ * [EARS-D1] Counts tasks moved to 'done' in last 7 days.
1022
+ */
1023
+ calculateThroughput(tasks: TaskRecord[]): number;
1024
+ /**
1025
+ * [EARS-D2] Calculates average done-draft time for lead time.
1026
+ */
1027
+ calculateLeadTime(tasks: TaskRecord[]): number;
1028
+ /**
1029
+ * [EARS-D3] Calculates average done-active time for cycle time.
1030
+ */
1031
+ calculateCycleTime(tasks: TaskRecord[]): number;
1032
+ /**
1033
+ * [EARS-D4] Counts unique agents with executions in 24h.
1034
+ */
1035
+ calculateActiveAgents(actors: ActorRecord[], executions: ExecutionRecord[]): number;
1036
+ /**
1037
+ * Extracts timestamp from ID (format: {timestamp}-{type}-{slug})
1038
+ */
1039
+ private getTimestampFromId;
1040
+ /**
1041
+ * Counts tasks by status
1042
+ */
1043
+ private countTasksByStatus;
1044
+ /**
1045
+ * Counts tasks by priority
1046
+ */
1047
+ private countTasksByPriority;
1048
+ /**
1049
+ * [EARS-C3] Throws NotImplementedError for Tier 3 functions.
1050
+ */
1051
+ calculateQuality(_tasks: TaskRecord[]): number;
1052
+ calculateReworkRate(_tasks: TaskRecord[]): number;
1053
+ calculateCompletionRate(_tasks: TaskRecord[]): number;
1054
+ calculateAuditScoreDistribution(_tasks: TaskRecord[]): Record<string, number>;
1055
+ calculateEpicPromotionRate(_tasks: TaskRecord[]): number;
1056
+ calculateTaskRefinementRate(_tasks: TaskRecord[]): number;
1057
+ calculatePlanningAccuracy(_tasks: TaskRecord[]): number;
1058
+ calculateDependencyDiscoveryRate(_tasks: TaskRecord[]): number;
1059
+ /**
1060
+ * [EARS-C4] Returns null for Premium metrics without Platform API.
1061
+ */
1062
+ calculateCostBurnRate(_consumption: TokenConsumption[]): number;
1063
+ calculateTokenConsumption(_consumption: TokenConsumption[]): number;
1064
+ calculateTokenConsumptionByAgent(_consumption: TokenConsumption[]): Record<string, number>;
1065
+ calculateAiAccuracyRate(_tasks: TaskRecord[], _feedback: FeedbackRecord[]): number;
1066
+ calculateAgentExecutionTime(_executions: ExecutionRecord[]): number;
1067
+ }
1068
+
1069
+ /**
1070
+ * Event Bus types for GitGovernance event-driven architecture
1071
+ */
1072
+ /**
1073
+ * Event metadata for ordering and debugging
1074
+ */
1075
+ type EventMetadata = {
1076
+ /** Unique event identifier */
1077
+ eventId: string;
1078
+ /** Event creation timestamp */
1079
+ timestamp: number;
1080
+ /** Event processing timestamp (set by handlers) */
1081
+ processedAt?: number;
1082
+ /** Source adapter that emitted the event */
1083
+ sourceAdapter: string;
1084
+ /** Sequence number for ordering (optional) */
1085
+ sequenceNumber?: number;
1086
+ };
1087
+ /**
1088
+ * Base event structure
1089
+ */
1090
+ type BaseEvent = {
1091
+ /** Event type identifier */
1092
+ type: string;
1093
+ /** Event timestamp */
1094
+ timestamp: number;
1095
+ /** Event payload */
1096
+ payload: unknown;
1097
+ /** Source that emitted the event */
1098
+ source: string;
1099
+ /** Event metadata for ordering and debugging */
1100
+ metadata?: EventMetadata;
1101
+ };
1102
+
1103
+ type TaskCreatedEvent = BaseEvent & {
1104
+ type: 'task.created';
1105
+ payload: {
1106
+ taskId: string;
1107
+ triggeredBy: string;
1108
+ };
1109
+ };
1110
+ type TaskStatusChangedEvent = BaseEvent & {
1111
+ type: 'task.status.changed';
1112
+ payload: {
1113
+ taskId: string;
1114
+ oldStatus: TaskRecord['status'];
1115
+ newStatus: TaskRecord['status'];
1116
+ triggeredBy: string;
1117
+ reason?: string;
1118
+ };
1119
+ };
1120
+
1121
+ type CycleCreatedEvent = BaseEvent & {
1122
+ type: 'cycle.created';
1123
+ payload: {
1124
+ cycleId: string;
1125
+ triggeredBy: string;
1126
+ };
1127
+ };
1128
+ type CycleStatusChangedEvent = BaseEvent & {
1129
+ type: 'cycle.status.changed';
1130
+ payload: {
1131
+ cycleId: string;
1132
+ oldStatus: CycleRecord['status'];
1133
+ newStatus: CycleRecord['status'];
1134
+ triggeredBy: string;
1135
+ };
1136
+ };
1137
+
1138
+ type ExecutionCreatedEvent = BaseEvent & {
1139
+ type: 'execution.created';
1140
+ payload: Pick<ExecutionRecord, 'taskId' | 'type' | 'title'> & {
1141
+ executionId: string;
1142
+ triggeredBy: string;
1143
+ isFirstExecution: boolean;
1144
+ };
1145
+ };
1146
+
1147
+ type FeedbackCreatedEvent = BaseEvent & {
1148
+ type: 'feedback.created';
1149
+ payload: Pick<FeedbackRecord, 'entityType' | 'entityId' | 'type' | 'status' | 'content' | 'assignee' | 'resolvesFeedbackId'> & {
1150
+ feedbackId: string;
1151
+ triggeredBy: string;
1152
+ };
1153
+ };
1154
+
1155
+ type ChangelogCreatedEvent = BaseEvent & {
1156
+ type: 'changelog.created';
1157
+ payload: Pick<ChangelogRecord, 'relatedTasks' | 'title' | 'version'> & {
1158
+ changelogId: string;
1159
+ };
1160
+ };
1161
+
1162
+ type ActorCreatedEvent = BaseEvent & {
1163
+ type: 'identity.actor.created';
1164
+ payload: Pick<ActorRecord, 'type' | 'publicKey' | 'roles'> & {
1165
+ actorId: string;
1166
+ isBootstrap: boolean;
1167
+ };
1168
+ };
1169
+ type ActorRevokedEvent = BaseEvent & {
1170
+ type: 'identity.actor.revoked';
1171
+ payload: Pick<ActorRecord, 'supersededBy'> & {
1172
+ actorId: string;
1173
+ revokedBy: string;
1174
+ revocationReason: 'compromised' | 'rotation' | 'manual';
1175
+ };
1176
+ };
1177
+ type AgentRegisteredEvent = BaseEvent & {
1178
+ type: 'identity.agent.registered';
1179
+ payload: Pick<AgentRecord, 'engine'> & {
1180
+ agentId: string;
1181
+ correspondingActorId: string;
1182
+ };
1183
+ };
1184
+ /**
1185
+ * System events
1186
+ */
1187
+ type SystemDailyTickEvent = BaseEvent & {
1188
+ type: 'system.daily_tick';
1189
+ payload: {
1190
+ date: string;
1191
+ };
1192
+ };
1193
+ /**
1194
+ * Union type of all possible events
1195
+ */
1196
+ type GitGovEvent = TaskCreatedEvent | TaskStatusChangedEvent | CycleCreatedEvent | CycleStatusChangedEvent | ExecutionCreatedEvent | FeedbackCreatedEvent | ChangelogCreatedEvent | ActorCreatedEvent | ActorRevokedEvent | AgentRegisteredEvent | SystemDailyTickEvent;
1197
+ /**
1198
+ * Event handler function type
1199
+ */
1200
+ type EventHandler<T extends BaseEvent = BaseEvent> = (event: T) => void | Promise<void>;
1201
+ /**
1202
+ * Event subscription
1203
+ */
1204
+ type EventSubscription = {
1205
+ /** Unique subscription ID */
1206
+ id: string;
1207
+ /** Event type being subscribed to */
1208
+ eventType: string;
1209
+ /** Handler function */
1210
+ handler: EventHandler;
1211
+ /** Subscription metadata */
1212
+ metadata?: {
1213
+ subscriberName?: string;
1214
+ createdAt: number;
1215
+ };
1216
+ };
1217
+ /**
1218
+ * Activity Event for IndexerAdapter activity tracking
1219
+ * Uses discriminated unions for type-safe metadata per event type
1220
+ */
1221
+ type ActivityEvent = {
1222
+ timestamp: number;
1223
+ type: "task_created";
1224
+ entityId: string;
1225
+ entityTitle: string;
1226
+ actorId?: string;
1227
+ metadata?: {
1228
+ priority?: string;
1229
+ status?: string;
1230
+ };
1231
+ } | {
1232
+ timestamp: number;
1233
+ type: "cycle_created";
1234
+ entityId: string;
1235
+ entityTitle: string;
1236
+ actorId?: string;
1237
+ metadata?: {
1238
+ status?: string;
1239
+ };
1240
+ } | {
1241
+ timestamp: number;
1242
+ type: "feedback_created";
1243
+ entityId: string;
1244
+ entityTitle: string;
1245
+ actorId?: string;
1246
+ metadata?: {
1247
+ type?: string;
1248
+ assignee?: string;
1249
+ resolution?: string;
1250
+ };
1251
+ } | {
1252
+ timestamp: number;
1253
+ type: "changelog_created";
1254
+ entityId: string;
1255
+ entityTitle: string;
1256
+ actorId?: string;
1257
+ metadata?: {
1258
+ version?: string;
1259
+ };
1260
+ } | {
1261
+ timestamp: number;
1262
+ type: "execution_created";
1263
+ entityId: string;
1264
+ entityTitle: string;
1265
+ actorId?: string;
1266
+ metadata?: {
1267
+ executionType?: string;
1268
+ taskId?: string;
1269
+ };
1270
+ } | {
1271
+ timestamp: number;
1272
+ type: "actor_created";
1273
+ entityId: string;
1274
+ entityTitle: string;
1275
+ actorId?: string;
1276
+ metadata?: {
1277
+ type?: string;
1278
+ };
1279
+ } | {
1280
+ timestamp: number;
1281
+ type: "agent_registered";
1282
+ entityId: string;
1283
+ entityTitle: string;
1284
+ actorId?: string;
1285
+ metadata?: Record<string, never>;
1286
+ };
1287
+
1288
+ /**
1289
+ * Event Stream interface - Contract for both Local and Global bus implementations
1290
+ */
1291
+ interface IEventStream {
1292
+ /**
1293
+ * Publish an event to the bus
1294
+ */
1295
+ publish(event: BaseEvent): void;
1296
+ /**
1297
+ * Subscribe to events of a specific type
1298
+ */
1299
+ subscribe<T extends BaseEvent = BaseEvent>(eventType: string, handler: EventHandler<T>): EventSubscription;
1300
+ /**
1301
+ * Unsubscribe from events
1302
+ */
1303
+ unsubscribe(subscriptionId: string): boolean;
1304
+ /**
1305
+ * Get all active subscriptions
1306
+ */
1307
+ getSubscriptions(): EventSubscription[];
1308
+ /**
1309
+ * Clear all subscriptions (for testing/cleanup)
1310
+ */
1311
+ clearSubscriptions(): void;
1312
+ /**
1313
+ * Wait for all pending event handlers to complete (for testing)
1314
+ */
1315
+ waitForIdle(options?: {
1316
+ timeout?: number;
1317
+ }): Promise<void>;
1318
+ }
1319
+ /**
1320
+ * Local EventBus implementation using Node.js EventEmitter
1321
+ *
1322
+ * This is the "Free Tier" implementation that operates in-memory
1323
+ * and provides synchronous event delivery for local-first usage.
1324
+ *
1325
+ * Design Principles:
1326
+ * - Decoupled Producers: Adapters emit events without knowing consumers
1327
+ * - Pluggable Consumers: Event handlers can be added/removed dynamically
1328
+ * - Type Safety: Full TypeScript support for all event types
1329
+ * - Performance: In-memory delivery with minimal overhead
1330
+ */
1331
+ declare class EventBus implements IEventStream {
1332
+ private emitter;
1333
+ private subscriptions;
1334
+ private pendingHandlers;
1335
+ constructor();
1336
+ /**
1337
+ * Publish an event to all subscribers
1338
+ *
1339
+ * @param event - The event to publish
1340
+ */
1341
+ publish(event: BaseEvent): void;
1342
+ /**
1343
+ * Subscribe to events of a specific type
1344
+ *
1345
+ * @param eventType - The event type to subscribe to
1346
+ * @param handler - The handler function to call when event is received
1347
+ * @returns EventSubscription object with subscription details
1348
+ */
1349
+ subscribe<T extends BaseEvent = BaseEvent>(eventType: string, handler: EventHandler<T>): EventSubscription;
1350
+ /**
1351
+ * Unsubscribe from events
1352
+ *
1353
+ * @param subscriptionId - The subscription ID to remove
1354
+ * @returns true if subscription was found and removed, false otherwise
1355
+ */
1356
+ unsubscribe(subscriptionId: string): boolean;
1357
+ /**
1358
+ * Get all active subscriptions
1359
+ *
1360
+ * @returns Array of all active subscriptions
1361
+ */
1362
+ getSubscriptions(): EventSubscription[];
1363
+ /**
1364
+ * Clear all subscriptions (for testing/cleanup)
1365
+ */
1366
+ clearSubscriptions(): void;
1367
+ /**
1368
+ * Get subscription count for a specific event type
1369
+ *
1370
+ * @param eventType - The event type to count subscribers for
1371
+ * @returns Number of active subscriptions for the event type
1372
+ */
1373
+ getSubscriptionCount(eventType: string): number;
1374
+ /**
1375
+ * Get all event types that have active subscriptions
1376
+ *
1377
+ * @returns Array of event types with active subscriptions
1378
+ */
1379
+ getActiveEventTypes(): string[];
1380
+ /**
1381
+ * Subscribe to all events (wildcard subscription)
1382
+ * Useful for debugging, monitoring, or logging
1383
+ *
1384
+ * @param handler - Handler that will receive all events
1385
+ * @returns EventSubscription object
1386
+ */
1387
+ subscribeToAll(handler: EventHandler<BaseEvent>): EventSubscription;
1388
+ /**
1389
+ * Wait for all pending event handlers to complete.
1390
+ * This is primarily useful for testing to ensure event handlers finish before assertions.
1391
+ *
1392
+ * In production, events are fire-and-forget for performance.
1393
+ * In tests, use this to synchronize and avoid race conditions.
1394
+ *
1395
+ * @param options - Optional configuration
1396
+ * @param options.timeout - Maximum time to wait in ms (default: 5000)
1397
+ * @returns Promise that resolves when all handlers complete or timeout occurs
1398
+ *
1399
+ * @example
1400
+ * ```typescript
1401
+ * await feedbackAdapter.create(...); // publishes event
1402
+ * await eventBus.waitForIdle(); // wait for BacklogAdapter.handleFeedbackCreated()
1403
+ * const task = await backlogAdapter.getTask(taskId);
1404
+ * expect(task.status).toBe('paused'); // now safe to assert
1405
+ * ```
1406
+ */
1407
+ waitForIdle(options?: {
1408
+ timeout?: number;
1409
+ }): Promise<void>;
1410
+ }
1411
+ /**
1412
+ * Singleton instance for application-wide event bus usage
1413
+ */
1414
+ declare const eventBus: EventBus;
1415
+ /**
1416
+ * Type-safe event publisher helper
1417
+ * Ensures events conform to GitGovEvent union type
1418
+ */
1419
+ declare function publishEvent(event: GitGovEvent): void;
1420
+ /**
1421
+ * Type-safe event subscriber helper
1422
+ * Provides better TypeScript inference for specific event types
1423
+ */
1424
+ declare function subscribeToEvent<T extends GitGovEvent>(eventType: T['type'], handler: EventHandler<T>): EventSubscription;
1425
+
1426
+ /**
1427
+ * Collection of all records with full GitGov metadata (headers + payloads).
1428
+ * This allows access to signatures, checksums, and other metadata for enrichment.
1429
+ *
1430
+ * @see GitGovTaskRecord - Full record type with header.signatures for author/lastModifier extraction
1431
+ */
1432
+ type AllRecords = {
1433
+ tasks: GitGovTaskRecord[];
1434
+ cycles: GitGovCycleRecord[];
1435
+ feedback: GitGovFeedbackRecord[];
1436
+ executions: GitGovExecutionRecord[];
1437
+ changelogs: GitGovChangelogRecord[];
1438
+ actors: GitGovActorRecord[];
1439
+ };
1440
+ /**
1441
+ * System-wide derived states for dashboard analytics and filtering.
1442
+ * Calculated by calculateDerivedStates() during index generation.
1443
+ *
1444
+ * @see derived_data_protocol.md for calculation algorithms
1445
+ */
1446
+ type DerivedStates = {
1447
+ stalledTasks: string[];
1448
+ atRiskTasks: string[];
1449
+ needsClarificationTasks: string[];
1450
+ blockedByDependencyTasks: string[];
1451
+ };
1452
+ /**
1453
+ * Optimized version of DerivedStates using Sets for O(1) lookup performance.
1454
+ * Used internally by enrichTaskRecord() to efficiently check task membership.
1455
+ *
1456
+ * Conversion from DerivedStates (arrays) to DerivedStateSets (Sets) happens once
1457
+ * in generateIndex() before processing multiple tasks, avoiding repeated O(n) lookups.
1458
+ */
1459
+ type DerivedStateSets = {
1460
+ stalledTasks: Set<string>;
1461
+ atRiskTasks: Set<string>;
1462
+ needsClarificationTasks: Set<string>;
1463
+ blockedByDependencyTasks: Set<string>;
1464
+ };
1465
+ /**
1466
+ * Enhanced Task Record with complete intelligence layer.
1467
+ * Calculated by enrichTaskRecord() with relationships, metrics, and derived states.
1468
+ *
1469
+ * @see indexer_adapter.md Section 3.6 - EnrichedTaskRecord Specification (EARS 25-48)
1470
+ */
1471
+ type EnrichedTaskRecord = TaskRecord & {
1472
+ derivedState: {
1473
+ isStalled: boolean;
1474
+ isAtRisk: boolean;
1475
+ needsClarification: boolean;
1476
+ isBlockedByDependency: boolean;
1477
+ healthScore: number;
1478
+ timeInCurrentStage: number;
1479
+ };
1480
+ relationships: {
1481
+ author?: {
1482
+ actorId: string;
1483
+ timestamp: number;
1484
+ };
1485
+ lastModifier?: {
1486
+ actorId: string;
1487
+ timestamp: number;
1488
+ };
1489
+ assignedTo: Array<{
1490
+ actorId: string;
1491
+ assignedAt?: number;
1492
+ }>;
1493
+ dependsOn: string[];
1494
+ blockedBy: string[];
1495
+ cycles: Array<{
1496
+ id: string;
1497
+ title: string;
1498
+ }>;
1499
+ };
1500
+ metrics: {
1501
+ executionCount: number;
1502
+ blockingFeedbackCount: number;
1503
+ openQuestionCount: number;
1504
+ timeToResolution?: number;
1505
+ };
1506
+ release: {
1507
+ isReleased: boolean;
1508
+ lastReleaseVersion?: string;
1509
+ };
1510
+ lastUpdated: number;
1511
+ lastActivityType: 'task_modified' | 'feedback_received' | 'execution_added' | 'changelog_created' | 'task_created';
1512
+ recentActivity?: string;
1513
+ };
1514
+ /**
1515
+ * IndexData - Complete cached index structure.
1516
+ * Generated by generateIndex() and consumed by CLI/Dashboard.
1517
+ */
1518
+ type IndexData = {
1519
+ metadata: {
1520
+ generatedAt: string;
1521
+ lastCommitHash: string;
1522
+ integrityStatus: 'valid' | 'warnings' | 'errors';
1523
+ recordCounts: Record<string, number>;
1524
+ generationTime: number;
1525
+ };
1526
+ metrics: SystemStatus & ProductivityMetrics & CollaborationMetrics;
1527
+ derivedStates: DerivedStates;
1528
+ activityHistory: ActivityEvent[];
1529
+ tasks: GitGovTaskRecord[];
1530
+ enrichedTasks: EnrichedTaskRecord[];
1531
+ cycles: GitGovCycleRecord[];
1532
+ actors: GitGovActorRecord[];
1533
+ feedback: GitGovFeedbackRecord[];
1534
+ };
1535
+ /**
1536
+ * Integrity validation error types.
1537
+ */
1538
+ type IntegrityError = {
1539
+ type: 'schema_violation' | 'checksum_failure' | 'signature_invalid';
1540
+ recordId: string;
1541
+ message: string;
1542
+ };
1543
+ /**
1544
+ * Integrity validation warning types.
1545
+ */
1546
+ type IntegrityWarning = {
1547
+ type: 'missing_reference' | 'deprecated_field' | 'performance_issue';
1548
+ recordId: string;
1549
+ message: string;
1550
+ };
1551
+ /**
1552
+ * Result of validateIntegrity() operation.
1553
+ */
1554
+ type IntegrityReport = {
1555
+ status: 'valid' | 'warnings' | 'errors';
1556
+ recordsScanned: number;
1557
+ errorsFound: IntegrityError[];
1558
+ warningsFound: IntegrityWarning[];
1559
+ validationTime: number;
1560
+ checksumFailures: number;
1561
+ signatureFailures: number;
1562
+ };
1563
+ /**
1564
+ * Result of generateIndex() operation.
1565
+ */
1566
+ type IndexGenerationReport = {
1567
+ success: boolean;
1568
+ recordsProcessed: number;
1569
+ metricsCalculated: number;
1570
+ derivedStatesApplied: number;
1571
+ generationTime: number;
1572
+ errors: string[];
1573
+ performance: {
1574
+ readTime: number;
1575
+ calculationTime: number;
1576
+ writeTime: number;
1577
+ };
1578
+ };
1579
+ /**
1580
+ * IndexerAdapter Dependencies - Facade + Dependency Injection Pattern.
1581
+ *
1582
+ * @see indexer_adapter.md Section 2 - Architecture
1583
+ */
1584
+ type IndexerAdapterDependencies = {
1585
+ metricsAdapter: MetricsAdapter;
1586
+ stores: Required<Pick<RecordStores$1, 'tasks' | 'cycles' | 'feedbacks' | 'executions' | 'changelogs' | 'actors'>>;
1587
+ cacheStore: RecordStore<IndexData>;
1588
+ };
1589
+ /**
1590
+ * IndexerAdapter Interface - The Cache Engine.
1591
+ */
1592
+ interface IIndexerAdapter {
1593
+ generateIndex(): Promise<IndexGenerationReport>;
1594
+ getIndexData(): Promise<IndexData | null>;
1595
+ validateIntegrity(): Promise<IntegrityReport>;
1596
+ calculateDerivedStates(allRecords: AllRecords): Promise<DerivedStates>;
1597
+ calculateActivityHistory(allRecords: AllRecords): Promise<ActivityEvent[]>;
1598
+ calculateLastUpdated(task: GitGovTaskRecord, relatedRecords: AllRecords): Promise<{
1599
+ lastUpdated: number;
1600
+ lastActivityType: EnrichedTaskRecord['lastActivityType'];
1601
+ recentActivity: string;
1602
+ }>;
1603
+ enrichTaskRecord(task: GitGovTaskRecord, relatedRecords: AllRecords, derivedStateSets: DerivedStateSets): Promise<EnrichedTaskRecord>;
1604
+ isIndexUpToDate(): Promise<boolean>;
1605
+ invalidateCache(): Promise<void>;
1606
+ }
1607
+
1608
+ /**
1609
+ * Public interface for pure LintModule operations (no I/O).
1610
+ *
1611
+ * This interface defines the core validation logic that works with
1612
+ * GitGovRecord objects in memory, without any filesystem operations.
1613
+ *
1614
+ * For filesystem operations (directory scanning, file reading, backups),
1615
+ * use IFsLintModule.
1616
+ *
1617
+ * @example
1618
+ * ```typescript
1619
+ * const lintModule: ILintModule = new LintModule({ stores });
1620
+ *
1621
+ * // Validate a single record (pure)
1622
+ * const results = lintModule.lintRecord(record, { recordId, entityType });
1623
+ *
1624
+ * // Validate all records from stores
1625
+ * const report = await lintModule.lint(options);
1626
+ *
1627
+ * // Fix a record (returns fixed record, no I/O)
1628
+ * const fixedRecord = lintModule.fixRecord(record, results, { keyId, privateKey });
1629
+ * ```
1630
+ */
1631
+ interface ILintModule {
1632
+ /**
1633
+ * Validates a single record object (pure validation).
1634
+ * Does NOT read files - receives pre-loaded record.
1635
+ *
1636
+ * @param record - The GitGovRecord object to validate
1637
+ * @param context - Context with recordId and entityType
1638
+ * @returns Array of lint results
1639
+ */
1640
+ lintRecord(record: GitGovRecord, context: LintRecordContext): LintResult[];
1641
+ /**
1642
+ * Validates all records from stores.
1643
+ * Each implementation resolves its own data source.
1644
+ *
1645
+ * @param options - Configuration options
1646
+ * @returns Consolidated lint report
1647
+ */
1648
+ lint(options?: Partial<LintOptions>): Promise<LintReport>;
1649
+ /**
1650
+ * Applies fixes to a record and returns the fixed version.
1651
+ * Does NOT write to disk - returns modified object.
1652
+ *
1653
+ * @param record - The record to fix
1654
+ * @param results - Lint results identifying problems
1655
+ * @param options - Fix options including privateKey for signing
1656
+ * @returns The fixed record
1657
+ */
1658
+ fixRecord(record: GitGovRecord, results: LintResult[], options: FixRecordOptions): GitGovRecord;
1659
+ }
1660
+ /**
1661
+ * Entry for batch validation.
1662
+ * Used by LintModule.lint() to process multiple records.
1663
+ */
1664
+ interface RecordEntry {
1665
+ /** The GitGovRecord object */
1666
+ record: GitGovRecord;
1667
+ /** Record ID */
1668
+ id: string;
1669
+ /** Entity type */
1670
+ type: Exclude<GitGovRecordType, 'custom'>;
1671
+ /** Optional file path for error reporting (FsLintModule provides this) */
1672
+ filePath?: string;
1673
+ }
1674
+ /**
1675
+ * Context for single record validation.
1676
+ */
1677
+ interface LintRecordContext {
1678
+ /** Record ID */
1679
+ recordId: string;
1680
+ /** Entity type */
1681
+ entityType: Exclude<GitGovRecordType, 'custom'>;
1682
+ /** Optional file path for error reporting */
1683
+ filePath?: string;
1684
+ }
1685
+ /**
1686
+ * Stores for reference lookups (pure interface).
1687
+ * Uses generic RecordStore<T> interface, not filesystem-specific RecordStore.
1688
+ */
1689
+ interface RecordStores {
1690
+ actors?: RecordStore<GitGovRecord>;
1691
+ agents?: RecordStore<GitGovRecord>;
1692
+ tasks?: RecordStore<GitGovRecord>;
1693
+ cycles?: RecordStore<GitGovRecord>;
1694
+ executions?: RecordStore<GitGovRecord>;
1695
+ feedbacks?: RecordStore<GitGovRecord>;
1696
+ changelogs?: RecordStore<GitGovRecord>;
1697
+ }
1698
+ /**
1699
+ * Dependencies for pure LintModule.
1700
+ * All dependencies are optional for maximum flexibility.
1701
+ */
1702
+ interface LintModuleDependencies {
1703
+ /** Stores for reference lookups (OPTIONAL) */
1704
+ stores?: RecordStores;
1705
+ /**
1706
+ * Indexing adapter for advanced reference resolution (OPTIONAL)
1707
+ * If not present, reference validations will be limited.
1708
+ */
1709
+ indexerAdapter?: IIndexerAdapter;
1710
+ }
1711
+ /**
1712
+ * Options for pure record fix operation.
1713
+ * Does NOT include filesystem-specific options like createBackups.
1714
+ */
1715
+ interface FixRecordOptions {
1716
+ /** Types of problems to repair (default: all fixable) */
1717
+ fixTypes?: ValidatorType[];
1718
+ /** KeyId (actorId) for signing (default: 'system:migrator') */
1719
+ keyId?: string;
1720
+ /** Private key for signing (REQUIRED for signature fixes) */
1721
+ privateKey?: string;
1722
+ }
1723
+ /**
1724
+ * Options for pure LintModule operations.
1725
+ * Does NOT include filesystem-specific options like path.
1726
+ */
1727
+ interface LintOptions {
1728
+ /**
1729
+ * Validar referencias tipadas inteligentemente (default: false)
1730
+ * Requiere stores presente para lookups.
1731
+ */
1732
+ validateReferences?: boolean;
1733
+ /**
1734
+ * Validar resolución de actorIds (default: false)
1735
+ * Verifica que los actorIds existen via stores.
1736
+ */
1737
+ validateActors?: boolean;
1738
+ /**
1739
+ * Validar checksums de embedded metadata (default: true)
1740
+ * Usa SHA256 sobre JSON canónico.
1741
+ */
1742
+ validateChecksums?: boolean;
1743
+ /**
1744
+ * Validar estructura de firmas (default: true)
1745
+ * Verifica formato Ed25519 y campos requeridos.
1746
+ */
1747
+ validateSignatures?: boolean;
1748
+ /**
1749
+ * Validar consistencia temporal de timestamps (default: true)
1750
+ * Valida que createdAt <= updatedAt <= completedAt.
1751
+ */
1752
+ validateTimestamps?: boolean;
1753
+ /**
1754
+ * Modo fail-fast o acumular todos los errores (default: false)
1755
+ * Si true, detiene al primer error fatal.
1756
+ */
1757
+ failFast?: boolean;
1758
+ /**
1759
+ * Modo concurrente para batch processing (default: true)
1760
+ * Procesa múltiples records en paralelo.
1761
+ */
1762
+ concurrent?: boolean;
1763
+ /**
1764
+ * Límite de concurrencia (default: 10)
1765
+ * Número máximo de records procesados simultáneamente.
1766
+ */
1767
+ concurrencyLimit?: number;
1768
+ }
1769
+ /**
1770
+ * Reporte consolidado de la ejecución de lint.
1771
+ */
1772
+ interface LintReport {
1773
+ /** Resumen cuantitativo de los resultados */
1774
+ summary: LintSummary;
1775
+ /** Lista detallada de cada problema encontrado */
1776
+ results: LintResult[];
1777
+ /** Metadata de la ejecución */
1778
+ metadata: {
1779
+ /** Timestamp ISO 8601 de ejecución */
1780
+ timestamp: string;
1781
+ /** Opciones utilizadas en esta ejecución */
1782
+ options: LintOptions;
1783
+ /** Versión del módulo lint */
1784
+ version: string;
1785
+ };
1786
+ }
1787
+ /**
1788
+ * Resumen cuantitativo de resultados de lint.
1789
+ */
1790
+ interface LintSummary {
1791
+ /** Número total de archivos/records verificados */
1792
+ filesChecked: number;
1793
+ /** Número total de errores fatales que requieren corrección */
1794
+ errors: number;
1795
+ /** Número total de advertencias que sugieren mejoras */
1796
+ warnings: number;
1797
+ /** Número de problemas auto-reparables con fix() */
1798
+ fixable: number;
1799
+ /** Tiempo de ejecución en milisegundos */
1800
+ executionTime: number;
1801
+ }
1802
+ /**
1803
+ * Resultado individual de validación para una entidad específica.
1804
+ */
1805
+ interface LintResult {
1806
+ /** Nivel de severidad del problema detectado */
1807
+ level: "error" | "warning" | "info";
1808
+ /** Ruta relativa del archivo donde se detectó el problema */
1809
+ filePath: string;
1810
+ /** Tipo de validador que generó este resultado */
1811
+ validator: ValidatorType;
1812
+ /** Mensaje descriptivo del problema encontrado */
1813
+ message: string;
1814
+ /** Información de la entidad GitGovernance afectada */
1815
+ entity: {
1816
+ type: "actor" | "agent" | "task" | "cycle" | "execution" | "changelog" | "feedback";
1817
+ id: string;
1818
+ };
1819
+ /** Indica si el error es auto-reparable con fixRecord() */
1820
+ fixable: boolean;
1821
+ /** Indica si el error fue reparado automáticamente (post-fix) */
1822
+ fixed?: boolean;
1823
+ /** Contexto adicional para debugging */
1824
+ context?: {
1825
+ field?: string;
1826
+ actual?: unknown;
1827
+ expected?: unknown;
1828
+ };
1829
+ }
1830
+ /**
1831
+ * Tipos de validadores disponibles en el pipeline.
1832
+ */
1833
+ type ValidatorType = "SCHEMA_VALIDATION" | "REFERENTIAL_INTEGRITY" | "TYPED_REFERENCE" | "BIDIRECTIONAL_CONSISTENCY" | "EMBEDDED_METADATA_STRUCTURE" | "CHECKSUM_VERIFICATION" | "SIGNATURE_STRUCTURE" | "FILE_NAMING_CONVENTION" | "TEMPORAL_CONSISTENCY" | "ACTOR_RESOLUTION" | "SOFT_DELETE_DETECTION" | "SCHEMA_VERSION_MISMATCH";
1834
+ /**
1835
+ * Contexto de ejecución para validación de un record individual.
1836
+ */
1837
+ interface ValidationContext {
1838
+ /** Path del archivo siendo validado */
1839
+ filePath: string;
1840
+ /** Configuración de validadores habilitados */
1841
+ enabledValidators: ValidatorType[];
1842
+ /** Caché de records ya cargados (para referencias) */
1843
+ recordCache?: Map<string, GitGovRecord>;
1844
+ /** Modo fail-fast habilitado */
1845
+ failFast: boolean;
1846
+ }
1847
+ /**
1848
+ * Reporte de operación de auto-fix.
1849
+ */
1850
+ interface FixReport {
1851
+ /** Resumen de reparaciones aplicadas */
1852
+ summary: {
1853
+ /** Número de problemas reparados exitosamente */
1854
+ fixed: number;
1855
+ /** Número de problemas que fallaron al reparar */
1856
+ failed: number;
1857
+ /** Número de backups creados */
1858
+ backupsCreated: number;
1859
+ };
1860
+ /** Detalles de cada reparación */
1861
+ fixes: FixResult[];
1862
+ }
1863
+ /**
1864
+ * Resultado individual de reparación.
1865
+ */
1866
+ interface FixResult {
1867
+ /** Path del archivo reparado */
1868
+ filePath: string;
1869
+ /** Tipo de problema reparado */
1870
+ validator: ValidatorType;
1871
+ /** Descripción de la reparación aplicada */
1872
+ action: string;
1873
+ /** Éxito de la reparación */
1874
+ success: boolean;
1875
+ /** Error si falló la reparación */
1876
+ error?: string;
1877
+ /** Path del backup creado (si aplica) */
1878
+ backupPath?: string;
1879
+ }
1880
+
1881
+ /**
1882
+ * Environment validation result.
1883
+ * Used by filesystem implementations to check prerequisites.
1884
+ */
1885
+ type EnvironmentValidation = {
1886
+ /** Whether environment is valid for initialization */
1887
+ isValid: boolean;
1888
+ /** Whether directory contains Git repository (fs-only) */
1889
+ isGitRepo: boolean;
1890
+ /** Whether process has write permissions */
1891
+ hasWritePermissions: boolean;
1892
+ /** Whether GitGovernance is already initialized */
1893
+ isAlreadyInitialized: boolean;
1894
+ /** Path to .gitgov directory (if already initialized) */
1895
+ gitgovPath?: string;
1896
+ /** List of validation warnings */
1897
+ warnings: string[];
1898
+ /** Actionable suggestions for user */
1899
+ suggestions: string[];
1900
+ /** Whether a remote 'origin' is configured */
1901
+ hasRemote?: boolean;
1902
+ /** Whether the current branch has commits */
1903
+ hasCommits?: boolean;
1904
+ /** Name of the current branch */
1905
+ currentBranch?: string;
1906
+ };
1907
+
1908
+ /**
1909
+ * Public interface for project initialization operations (pure - no I/O assumptions).
1910
+ *
1911
+ * This interface defines the contract for initializing GitGovernance projects
1912
+ * across different backends (filesystem, database, API).
1913
+ *
1914
+ * The project context (path, tenant ID, etc.) is injected at construction time,
1915
+ * so methods operate on the pre-configured project without needing explicit paths.
1916
+ *
1917
+ * Implementations:
1918
+ * - FsProjectInitializer: Local filesystem (.gitgov/ directory)
1919
+ * - DbProjectInitializer: Database (SaaS multi-tenant)
1920
+ * - ApiProjectInitializer: Remote API (agents, serverless)
1921
+ *
1922
+ * @example
1923
+ * ```typescript
1924
+ * // CLI uses FsProjectInitializer with projectRoot injected
1925
+ * const initializer: IProjectInitializer = new FsProjectInitializer('/path/to/project');
1926
+ * await initializer.createProjectStructure();
1927
+ *
1928
+ * // SaaS uses DbProjectInitializer with tenant injected
1929
+ * const initializer: IProjectInitializer = new DbProjectInitializer(pool, 'tenant-123');
1930
+ * await initializer.createProjectStructure();
1931
+ * ```
1932
+ */
1933
+ interface IProjectInitializer {
1934
+ /**
1935
+ * Creates the project structure (directories for fs, tables for db, etc).
1936
+ */
1937
+ createProjectStructure(): Promise<void>;
1938
+ /**
1939
+ * Checks if a project is already initialized.
1940
+ *
1941
+ * @returns true if already initialized
1942
+ */
1943
+ isInitialized(): Promise<boolean>;
1944
+ /**
1945
+ * Writes the project configuration.
1946
+ *
1947
+ * @param config - GitGovConfig to persist
1948
+ */
1949
+ writeConfig(config: GitGovConfig): Promise<void>;
1950
+ /**
1951
+ * Initializes a session for the bootstrap actor.
1952
+ *
1953
+ * @param actorId - ID of the bootstrap actor
1954
+ */
1955
+ initializeSession(actorId: string): Promise<void>;
1956
+ /**
1957
+ * Cleans up partial setup if initialization fails.
1958
+ */
1959
+ rollback(): Promise<void>;
1960
+ /**
1961
+ * Validates environment for project initialization.
1962
+ *
1963
+ * @returns Validation result with warnings and suggestions
1964
+ */
1965
+ validateEnvironment(): Promise<EnvironmentValidation>;
1966
+ /**
1967
+ * Reads a file from the project context.
1968
+ *
1969
+ * @param filePath - Path to the file (relative or absolute depending on backend)
1970
+ * @returns File contents as string
1971
+ */
1972
+ readFile(filePath: string): Promise<string>;
1973
+ /**
1974
+ * Copies the agent prompt to the project root for IDE access.
1975
+ */
1976
+ copyAgentPrompt(): Promise<void>;
1977
+ /**
1978
+ * Sets up version control integration (e.g., .gitignore for fs).
1979
+ */
1980
+ setupGitIntegration(): Promise<void>;
1981
+ /**
1982
+ * Gets the path/identifier for an actor record.
1983
+ *
1984
+ * @param actorId - Actor ID
1985
+ * @returns Path or identifier for the actor
1986
+ */
1987
+ getActorPath(actorId: string): string;
1988
+ }
1989
+
1990
+ /**
1991
+ * IdentityAdapter Interface - The Identity Management Contract
1992
+ *
1993
+ * NOTE: AgentRecord operations have been moved to AgentAdapter.
1994
+ * Use AgentAdapter for createAgentRecord, getAgentRecord, listAgentRecords.
1995
+ */
1996
+ interface IIdentityAdapter {
1997
+ createActor(payload: ActorPayload, signerId: string): Promise<ActorRecord>;
1998
+ getActor(actorId: string): Promise<ActorRecord | null>;
1999
+ listActors(): Promise<ActorRecord[]>;
2000
+ revokeActor(actorId: string, revokedBy?: string, reason?: "compromised" | "rotation" | "manual", supersededBy?: string): Promise<ActorRecord>;
2001
+ resolveCurrentActorId(originalActorId: string): Promise<string>;
2002
+ getCurrentActor(): Promise<ActorRecord>;
2003
+ getEffectiveActorForAgent(agentId: string): Promise<ActorRecord | null>;
2004
+ signRecord<T extends GitGovRecord>(record: T, actorId: string, role: string, notes: string): Promise<T>;
2005
+ rotateActorKey(actorId: string): Promise<{
2006
+ oldActor: ActorRecord;
2007
+ newActor: ActorRecord;
2008
+ }>;
2009
+ authenticate(sessionToken: string): Promise<void>;
2010
+ getActorPublicKey(keyId: string): Promise<string | null>;
2011
+ }
2012
+ /**
2013
+ * IdentityAdapter Dependencies - Facade + Dependency Injection Pattern
2014
+ */
2015
+ interface IdentityAdapterDependencies {
2016
+ stores: Required<Pick<RecordStores$1, 'actors'>>;
2017
+ keyProvider: KeyProvider;
2018
+ sessionManager: ISessionManager;
2019
+ eventBus?: IEventStream;
2020
+ }
2021
+
2022
+ declare class IdentityAdapter implements IIdentityAdapter {
2023
+ private stores;
2024
+ private keyProvider;
2025
+ private sessionManager;
2026
+ private eventBus;
2027
+ constructor(dependencies: IdentityAdapterDependencies);
2028
+ /**
2029
+ * Get actor public key for validation - used by other adapters
2030
+ */
2031
+ getActorPublicKey(keyId: string): Promise<string | null>;
2032
+ createActor(payload: ActorPayload, _signerId: string): Promise<ActorRecord>;
2033
+ getActor(actorId: string): Promise<ActorRecord | null>;
2034
+ listActors(): Promise<ActorRecord[]>;
2035
+ signRecord<T extends GitGovRecord>(record: T, actorId: string, role: string, notes: string): Promise<T>;
2036
+ /**
2037
+ * Resolves the current active ActorRecord ID by following the succession chain.
2038
+ * This is critical for AgentRecord operations after key rotation.
2039
+ *
2040
+ * @param originalActorId - The original actor ID (may be revoked)
2041
+ * @returns Promise<string> - The current active actor ID
2042
+ */
2043
+ resolveCurrentActorId(originalActorId: string): Promise<string>;
2044
+ /**
2045
+ * Gets the current ActorRecord of the system based on active session or fallback.
2046
+ * This is critical for CLI commands that need to know "who is the current user".
2047
+ *
2048
+ * @returns Promise<ActorRecord> - The current active ActorRecord
2049
+ */
2050
+ getCurrentActor(): Promise<ActorRecord>;
2051
+ /**
2052
+ * Gets the effective (current active) ActorRecord for an AgentRecord.
2053
+ * This resolves the succession chain to get the current cryptographic identity.
2054
+ *
2055
+ * @param agentId - The AgentRecord ID (may reference revoked ActorRecord)
2056
+ * @returns Promise<ActorRecord | null> - The current active ActorRecord or null
2057
+ */
2058
+ getEffectiveActorForAgent(agentId: string): Promise<ActorRecord | null>;
2059
+ rotateActorKey(actorId: string): Promise<{
2060
+ oldActor: ActorRecord;
2061
+ newActor: ActorRecord;
2062
+ }>;
2063
+ revokeActor(actorId: string, revokedBy?: string, reason?: "compromised" | "rotation" | "manual", supersededBy?: string): Promise<ActorRecord>;
2064
+ authenticate(_sessionToken: string): Promise<void>;
2065
+ }
2066
+
2067
+ /**
2068
+ * SyncStateModule Dependencies
2069
+ */
2070
+ type SyncStateModuleDependencies = {
2071
+ /** Low-level Git module (required) */
2072
+ git: IGitModule;
2073
+ /** Configuration manager (required) */
2074
+ config: ConfigManager;
2075
+ /** Identity adapter for signature verification and signing (required) */
2076
+ identity: IIdentityAdapter;
2077
+ /** Lint module for record validation (required) */
2078
+ lint: ILintModule;
2079
+ /** Indexer adapter for automatic re-indexing after pull/resolve (required) */
2080
+ indexer: IIndexerAdapter;
2081
+ };
2082
+ /**
2083
+ * Options for pushState operation
2084
+ */
2085
+ type SyncStatePushOptions = {
2086
+ /** Branch to push from (default: current branch) */
2087
+ sourceBranch?: string;
2088
+ /** Actor ID publishing the state (required) */
2089
+ actorId: string;
2090
+ /** Simulate operation without making real changes */
2091
+ dryRun?: boolean;
2092
+ /** Force push even if there are unsynced remote changes */
2093
+ force?: boolean;
2094
+ };
2095
+ /**
2096
+ * Result of pushState operation
2097
+ */
2098
+ type SyncStatePushResult = {
2099
+ /** Indicates if the operation was successful */
2100
+ success: boolean;
2101
+ /** Number of files synced */
2102
+ filesSynced: number;
2103
+ /** Name of the branch pushed from */
2104
+ sourceBranch: string;
2105
+ /** Created commit hash (null if no changes or dry-run) */
2106
+ commitHash: string | null;
2107
+ /** Created commit message */
2108
+ commitMessage: string | null;
2109
+ /** Indicates if a conflict was detected during reconciliation */
2110
+ conflictDetected: boolean;
2111
+ /** Conflict information if detected */
2112
+ conflictInfo?: ConflictInfo;
2113
+ /** Error message if operation failed */
2114
+ error?: string;
2115
+ /** [EARS-B16] Implicit pull results when push does reconciliation with remote */
2116
+ implicitPull?: {
2117
+ /** Whether changes were pulled from remote */
2118
+ hasChanges: boolean;
2119
+ /** Number of files updated from remote */
2120
+ filesUpdated: number;
2121
+ /** Whether index was regenerated */
2122
+ reindexed: boolean;
2123
+ };
2124
+ };
2125
+ /**
2126
+ * Options for pullState operation
2127
+ */
2128
+ type SyncStatePullOptions = {
2129
+ /** Force re-indexing even if there are no new changes */
2130
+ forceReindex?: boolean;
2131
+ /** [EARS-C11] Force pull even if local changes would be overwritten */
2132
+ force?: boolean;
2133
+ };
2134
+ /**
2135
+ * Result of pullState operation
2136
+ */
2137
+ type SyncStatePullResult = {
2138
+ /** Indicates if the operation was successful */
2139
+ success: boolean;
2140
+ /** Indicates if there were new remote changes */
2141
+ hasChanges: boolean;
2142
+ /** Number of files updated */
2143
+ filesUpdated: number;
2144
+ /** Indicates if re-indexing was executed */
2145
+ reindexed: boolean;
2146
+ /** Indicates if a conflict was detected during pull */
2147
+ conflictDetected: boolean;
2148
+ /** Conflict information if detected */
2149
+ conflictInfo?: ConflictInfo;
2150
+ /** Error message if operation failed */
2151
+ error?: string;
2152
+ /** [EARS-C11] Files that were forcefully overwritten (when force: true) */
2153
+ forcedOverwrites?: string[];
2154
+ };
2155
+ /**
2156
+ * Options for resolveConflict operation
2157
+ */
2158
+ type SyncStateResolveOptions = {
2159
+ /** Justification for the conflict resolution (required) */
2160
+ reason: string;
2161
+ /** Actor ID resolving the conflict (required) */
2162
+ actorId: string;
2163
+ };
2164
+ /**
2165
+ * Result of resolveConflict operation
2166
+ */
2167
+ type SyncStateResolveResult = {
2168
+ /** Indicates if the operation was successful */
2169
+ success: boolean;
2170
+ /** Commit hash of the created rebase commit */
2171
+ rebaseCommitHash: string;
2172
+ /** Commit hash of the signed resolution commit */
2173
+ resolutionCommitHash: string;
2174
+ /** Number of conflicts resolved */
2175
+ conflictsResolved: number;
2176
+ /** Actor ID who resolved the conflict */
2177
+ resolvedBy: string;
2178
+ /** Reason for resolution */
2179
+ reason: string;
2180
+ /** Error message if operation failed */
2181
+ error?: string;
2182
+ };
2183
+ /**
2184
+ * Detailed information about a detected conflict
2185
+ */
2186
+ type ConflictInfo = {
2187
+ /** Type of conflict detected */
2188
+ type: ConflictType;
2189
+ /** Files affected by the conflict */
2190
+ affectedFiles: string[];
2191
+ /** Descriptive message of the conflict */
2192
+ message: string;
2193
+ /** Instructions to resolve the conflict */
2194
+ resolutionSteps: string[];
2195
+ };
2196
+ /**
2197
+ * Auxiliary type to identify the conflict type
2198
+ *
2199
+ * Git-Native conflict model (post-refactor):
2200
+ * - rebase_conflict: Used for all Git-level conflicts during push/pull
2201
+ * - local_changes_conflict: Used when pull would overwrite local changes (EARS-C10)
2202
+ * - integrity_violation: Used when resolution commits are missing
2203
+ */
2204
+ type ConflictType = "rebase_conflict" | "integrity_violation" | "local_changes_conflict";
2205
+ /**
2206
+ * Information about a detected integrity violation
2207
+ */
2208
+ type IntegrityViolation = {
2209
+ /** Commit hash of the rebase commit without resolution */
2210
+ rebaseCommitHash: string;
2211
+ /** Message of the rebase commit */
2212
+ commitMessage: string;
2213
+ /** Timestamp of the commit */
2214
+ timestamp: string;
2215
+ /** Author of the commit */
2216
+ author: string;
2217
+ };
2218
+ /**
2219
+ * Verification scope for state audit
2220
+ */
2221
+ type AuditScope = "current" | "state-branch" | "all";
2222
+ /**
2223
+ * Scope for expected files verification
2224
+ */
2225
+ type ExpectedFilesScope = "head" | "all-commits";
2226
+ /**
2227
+ * Options for state audit
2228
+ */
2229
+ type AuditStateOptions = {
2230
+ /** Verification scope: which Records to verify (default: "all") */
2231
+ scope?: AuditScope;
2232
+ /** Verify signatures in Records (default: true) */
2233
+ verifySignatures?: boolean;
2234
+ /** Verify checksums of Records (default: true) */
2235
+ verifyChecksums?: boolean;
2236
+ /** Verify that expected files exist (default: true) */
2237
+ verifyExpectedFiles?: boolean;
2238
+ /** Scope for expected files verification (default: "head") */
2239
+ expectedFilesScope?: ExpectedFilesScope;
2240
+ /** Path of specific files to audit (default: all in .gitgov/) */
2241
+ filePaths?: string[];
2242
+ };
2243
+ /**
2244
+ * Conflict diff information for a file
2245
+ */
2246
+ type ConflictFileDiff = {
2247
+ /** Path of the conflicted file */
2248
+ filePath: string;
2249
+ /** Content of the local version (ours) */
2250
+ localContent: string;
2251
+ /** Content of the remote version (theirs) */
2252
+ remoteContent: string;
2253
+ /** Base content (common ancestor) */
2254
+ baseContent: string | null;
2255
+ /** Lines with conflict markers (if they still exist) */
2256
+ conflictMarkers?: Array<{
2257
+ line: number;
2258
+ marker: string;
2259
+ }>;
2260
+ };
2261
+ /**
2262
+ * Structured conflict diff
2263
+ */
2264
+ type ConflictDiff = {
2265
+ /** Conflicted files with their diff */
2266
+ files: ConflictFileDiff[];
2267
+ /** Descriptive message of the conflict */
2268
+ message: string;
2269
+ /** Instructions to resolve */
2270
+ resolutionSteps: string[];
2271
+ };
2272
+ /**
2273
+ * Complete state audit report
2274
+ *
2275
+ * This report combines SyncStateModule-specific audits (rebase integrity, commits)
2276
+ * with structural validation from LintModule (signatures, checksums, schemas).
2277
+ */
2278
+ type AuditStateReport = {
2279
+ /** Indicates if the audit passed without violations */
2280
+ passed: boolean;
2281
+ /** Scope used for the audit */
2282
+ scope: AuditScope;
2283
+ /** Total commits analyzed */
2284
+ totalCommits: number;
2285
+ /** Rebase commits found */
2286
+ rebaseCommits: number;
2287
+ /** Resolution commits found */
2288
+ resolutionCommits: number;
2289
+ /** Integrity violations of resolutions (SyncStateModule-specific) */
2290
+ integrityViolations: IntegrityViolation[];
2291
+ /** Summary message of the audit */
2292
+ summary: string;
2293
+ /** Complete LintModule report for structural validation (signatures, checksums, schemas, etc.) */
2294
+ lintReport?: LintReport;
2295
+ };
2296
+ /**
2297
+ * Information of a changed file in the delta
2298
+ */
2299
+ type StateDeltaFile = {
2300
+ /** File status: Added, Modified, Deleted */
2301
+ status: "A" | "M" | "D";
2302
+ /** File path */
2303
+ file: string;
2304
+ };
2305
+
2306
+ /**
2307
+ * ISyncStateModule - State Synchronization Interface
2308
+ *
2309
+ * Defines the contract for state synchronization between local working tree
2310
+ * and a shared state branch. Implementations handle the I/O specifics:
2311
+ * - FsSyncStateModule: Uses local filesystem + git CLI (packages/core/src/sync_state/fs_sync/)
2312
+ * - Future: GithubSyncStateModule via GitHub API
2313
+ *
2314
+ * @module sync_state
2315
+ */
2316
+
2317
+ /**
2318
+ * State synchronization module interface.
2319
+ *
2320
+ * Provides push/pull/resolve operations for syncing .gitgov/ records
2321
+ * with a shared state branch (e.g., gitgov-state).
2322
+ */
2323
+ interface ISyncStateModule {
2324
+ /** Returns the configured state branch name (default: "gitgov-state") */
2325
+ getStateBranchName(): Promise<string>;
2326
+ /** Ensures the state branch exists (creates if missing) */
2327
+ ensureStateBranch(): Promise<void>;
2328
+ /** Calculates the file delta between source branch and state branch */
2329
+ calculateStateDelta(sourceBranch: string): Promise<StateDeltaFile[]>;
2330
+ /** Checks if a rebase operation is currently in progress */
2331
+ isRebaseInProgress(): Promise<boolean>;
2332
+ /** Returns list of files that still contain conflict markers */
2333
+ checkConflictMarkers(filePaths: string[]): Promise<string[]>;
2334
+ /** Returns structured diff information for conflicted files */
2335
+ getConflictDiff(filePaths?: string[]): Promise<ConflictDiff>;
2336
+ /** Verifies that all rebase commits have corresponding resolution commits */
2337
+ verifyResolutionIntegrity(): Promise<IntegrityViolation[]>;
2338
+ /** Audits the state branch for integrity violations and structural issues */
2339
+ auditState(options?: AuditStateOptions): Promise<AuditStateReport>;
2340
+ /** Pushes local .gitgov/ state to the shared state branch */
2341
+ pushState(options: SyncStatePushOptions): Promise<SyncStatePushResult>;
2342
+ /** Pulls remote state changes into local .gitgov/ */
2343
+ pullState(options?: SyncStatePullOptions): Promise<SyncStatePullResult>;
2344
+ /** Resolves a rebase conflict with signed resolution commit */
2345
+ resolveConflict(options: SyncStateResolveOptions): Promise<SyncStateResolveResult>;
2346
+ }
2347
+
2348
+ /**
2349
+ * ExecutionAdapter Dependencies - Facade + Dependency Injection Pattern
2350
+ */
2351
+ type ExecutionAdapterDependencies = {
2352
+ stores: Required<Pick<RecordStores$1, 'tasks' | 'executions'>>;
2353
+ identity: IdentityAdapter;
2354
+ eventBus: IEventStream;
2355
+ };
2356
+ /**
2357
+ * ExecutionAdapter Interface - The Chronicler of the System
2358
+ */
2359
+ interface IExecutionAdapter {
2360
+ /**
2361
+ * Records a new execution event.
2362
+ */
2363
+ create(payload: Partial<ExecutionRecord>, actorId: string): Promise<ExecutionRecord>;
2364
+ /**
2365
+ * Gets a specific ExecutionRecord by its ID.
2366
+ */
2367
+ getExecution(executionId: string): Promise<ExecutionRecord | null>;
2368
+ /**
2369
+ * Gets all ExecutionRecords for a specific Task.
2370
+ */
2371
+ getExecutionsByTask(taskId: string): Promise<ExecutionRecord[]>;
2372
+ /**
2373
+ * Gets all ExecutionRecords in the system.
2374
+ */
2375
+ getAllExecutions(): Promise<ExecutionRecord[]>;
2376
+ }
2377
+
2378
+ /**
2379
+ * Union type of all supported engines.
2380
+ */
2381
+ type Engine = AgentRecord["engine"];
2382
+ /**
2383
+ * Supported engine types by the runner.
2384
+ */
2385
+ type EngineType = Engine["type"];
2386
+ /**
2387
+ * Local engine configuration.
2388
+ * Agent executes in the same process.
2389
+ */
2390
+ type LocalEngine = Extract<Engine, {
2391
+ type: "local";
2392
+ }>;
2393
+ /**
2394
+ * API engine configuration.
2395
+ * Agent executes on a remote server via HTTP.
2396
+ */
2397
+ type ApiEngine = Extract<Engine, {
2398
+ type: "api";
2399
+ }>;
2400
+ /**
2401
+ * MCP engine configuration.
2402
+ * Agent executes as MCP server (Model Context Protocol).
2403
+ */
2404
+ type McpEngine = Extract<Engine, {
2405
+ type: "mcp";
2406
+ }>;
2407
+ /**
2408
+ * Custom engine configuration.
2409
+ * Allows extensibility via registered protocol handlers.
2410
+ */
2411
+ type CustomEngine = Extract<Engine, {
2412
+ type: "custom";
2413
+ }>;
2414
+ /**
2415
+ * Authentication configuration for remote backends (API/MCP).
2416
+ * Extracted from the API engine's auth field.
2417
+ */
2418
+ type AuthConfig = NonNullable<ApiEngine["auth"]>;
2419
+ /**
2420
+ * Authentication types for remote backends.
2421
+ */
2422
+ type AuthType = NonNullable<AuthConfig["type"]>;
2423
+ /**
2424
+ * Execution context passed to each agent.
2425
+ * Includes all information needed for traceability.
2426
+ */
2427
+ type AgentExecutionContext = {
2428
+ /** Agent ID being executed (e.g., "agent:source-audit") */
2429
+ agentId: string;
2430
+ /** ActorRecord executing (type "agent") */
2431
+ actorId: string;
2432
+ /** TaskRecord that triggered this execution (required) */
2433
+ taskId: string;
2434
+ /** Unique UUID for this execution */
2435
+ runId: string;
2436
+ /** Optional input passed to the agent (from RunOptions.input) */
2437
+ input?: unknown;
2438
+ };
2439
+ /**
2440
+ * Options for executing an agent.
2441
+ */
2442
+ type RunOptions = {
2443
+ /** Agent ID to execute (e.g., "agent:source-audit") */
2444
+ agentId: string;
2445
+ /** TaskRecord that triggers this execution (required) */
2446
+ taskId: string;
2447
+ /** Actor executing. If not provided, uses agentId */
2448
+ actorId?: string;
2449
+ /** Specific tool to invoke (MCP engines only) */
2450
+ tool?: string;
2451
+ /** Input to pass to the agent */
2452
+ input?: unknown;
2453
+ };
2454
+ /**
2455
+ * Structured output from the agent.
2456
+ * Captured by the runner from each backend.
2457
+ */
2458
+ type AgentOutput = {
2459
+ /** Response data from agent (free structure) */
2460
+ data?: unknown;
2461
+ /** Text message (summary or description) */
2462
+ message?: string;
2463
+ /** Generated artifacts (file paths, record IDs, etc.) */
2464
+ artifacts?: string[];
2465
+ /** Additional agent metadata */
2466
+ metadata?: Record<string, unknown>;
2467
+ };
2468
+ /**
2469
+ * Complete response from an agent execution.
2470
+ * Returned by runner.runOnce().
2471
+ */
2472
+ type AgentResponse = {
2473
+ /** Unique UUID for this execution */
2474
+ runId: string;
2475
+ /** Executed agent ID */
2476
+ agentId: string;
2477
+ /** Execution status */
2478
+ status: "success" | "error";
2479
+ /** Agent output (only if status: "success") */
2480
+ output?: AgentOutput;
2481
+ /** Error message (only if status: "error") */
2482
+ error?: string;
2483
+ /** Created ExecutionRecord ID */
2484
+ executionRecordId: string;
2485
+ /** Start timestamp */
2486
+ startedAt: string;
2487
+ /** Completion timestamp */
2488
+ completedAt: string;
2489
+ /** Duration in milliseconds */
2490
+ durationMs: number;
2491
+ };
2492
+ /**
2493
+ * AgentRunner module dependencies (filesystem implementation).
2494
+ */
2495
+ type AgentRunnerDependencies = {
2496
+ /** Path to project root (REQUIRED, injected from CLI/bootstrap) */
2497
+ projectRoot: string;
2498
+ /** Path to .gitgov directory (optional, defaults to projectRoot/.gitgov) */
2499
+ gitgovPath?: string;
2500
+ /** IdentityAdapter for actor-signature auth (required if that auth type is used) */
2501
+ identityAdapter?: IIdentityAdapter;
2502
+ /** ExecutionAdapter for persisting executions (REQUIRED) */
2503
+ executionAdapter: IExecutionAdapter;
2504
+ /** EventBus for emitting events (optional, no events if not provided) */
2505
+ eventBus?: IEventStream;
2506
+ /** Protocol handler registry (for engine.type: "custom") */
2507
+ protocolHandlers?: ProtocolHandlerRegistry;
2508
+ /** Runtime handler registry (for engine.runtime in local engines) */
2509
+ runtimeHandlers?: RuntimeHandlerRegistry;
2510
+ };
2511
+ /**
2512
+ * Events emitted by the runner via EventBus.
2513
+ */
2514
+ type AgentRunnerEvent = {
2515
+ type: "agent:started";
2516
+ payload: {
2517
+ runId: string;
2518
+ agentId: string;
2519
+ taskId: string;
2520
+ startedAt: string;
2521
+ };
2522
+ } | {
2523
+ type: "agent:completed";
2524
+ payload: {
2525
+ runId: string;
2526
+ agentId: string;
2527
+ taskId: string;
2528
+ status: "success";
2529
+ durationMs: number;
2530
+ executionRecordId: string;
2531
+ };
2532
+ } | {
2533
+ type: "agent:error";
2534
+ payload: {
2535
+ runId: string;
2536
+ agentId: string;
2537
+ taskId: string;
2538
+ status: "error";
2539
+ error: string;
2540
+ durationMs: number;
2541
+ executionRecordId: string;
2542
+ };
2543
+ };
2544
+
2545
+ /**
2546
+ * Interface for agent loader (allows mocking in tests).
2547
+ */
2548
+ interface IAgentLoader {
2549
+ loadAgent(agentId: string): Promise<AgentRecord>;
2550
+ }
2551
+ /**
2552
+ * Interface for AgentRunner implementations.
2553
+ * Allows different backends (filesystem, memory, serverless).
2554
+ */
2555
+ interface IAgentRunner {
2556
+ /**
2557
+ * Executes an agent once and returns the response.
2558
+ * TaskRecord must exist before calling this method.
2559
+ */
2560
+ runOnce(opts: RunOptions): Promise<AgentResponse>;
2561
+ }
2562
+ /**
2563
+ * Registry for protocol handlers (engine.type: "custom").
2564
+ */
2565
+ interface ProtocolHandlerRegistry {
2566
+ register(protocol: string, handler: ProtocolHandler): void;
2567
+ get(protocol: string): ProtocolHandler | undefined;
2568
+ }
2569
+ /**
2570
+ * Handler for engine.type: "custom".
2571
+ */
2572
+ type ProtocolHandler = (engine: CustomEngine, ctx: AgentExecutionContext) => Promise<AgentOutput>;
2573
+ /**
2574
+ * Registry for runtime handlers (engine.runtime in local engines).
2575
+ */
2576
+ interface RuntimeHandlerRegistry {
2577
+ register(runtime: string, handler: RuntimeHandler): void;
2578
+ get(runtime: string): RuntimeHandler | undefined;
2579
+ }
2580
+ /**
2581
+ * Handler for engine.runtime in local engines.
2582
+ */
2583
+ type RuntimeHandler = (engine: LocalEngine, ctx: AgentExecutionContext) => Promise<AgentOutput>;
2584
+
2585
+ export { type GitGovChangelogRecord as $, type AuditStateOptions as A, type ActorPayload as B, ConfigManager as C, type ActorRecord as D, type EnvironmentValidation as E, type FixRecordOptions as F, type GitGovRecord as G, type AgentPayload as H, type ILintModule as I, type AgentRecord as J, type ChangelogPayload as K, type LintOptions as L, type ChangelogRecord as M, type CustomRecord as N, type CyclePayload as O, type ProtocolHandlerRegistry as P, type CycleRecord as Q, type RecordStores as R, SessionManager as S, type EmbeddedMetadataHeader as T, type EmbeddedMetadataRecord as U, type ExecutionPayload as V, type ExecutionRecord as W, type FeedbackPayload as X, type FeedbackRecord as Y, type GitGovActorRecord as Z, type GitGovAgentRecord as _, type LintReport as a, type ConflictFileDiff as a$, type GitGovCycleRecord as a0, GitGovError as a1, type GitGovExecutionRecord as a2, type GitGovFeedbackRecord as a3, type GitGovRecordPayload as a4, type GitGovRecordType as a5, type GitGovTaskRecord as a6, type Signature as a7, type TaskPayload as a8, type TaskRecord as a9, type TaskCreatedEvent as aA, type TaskStatusChangedEvent as aB, eventBus as aC, publishEvent as aD, subscribeToEvent as aE, type IndexerAdapterDependencies as aF, type IndexGenerationReport as aG, type IndexData as aH, type IntegrityReport as aI, type AllRecords as aJ, type DerivedStates as aK, type EnrichedTaskRecord as aL, type DerivedStateSets as aM, type IntegrityError as aN, type IntegrityWarning as aO, type IIdentityAdapter as aP, IdentityAdapter as aQ, type IdentityAdapterDependencies as aR, type LintModuleDependencies as aS, type FixResult as aT, type LintSummary as aU, type RecordEntry as aV, type ValidationContext as aW, type ValidatorType as aX, type IExecutionAdapter as aY, type ExecutionAdapterDependencies as aZ, type AuditScope as a_, type RecordStores$1 as aa, type CollaborationMetrics as ab, type IMetricsAdapter as ac, type IPlatformApi as ad, MetricsAdapter as ae, type MetricsAdapterDependencies as af, type ProductivityMetrics as ag, type SystemStatus as ah, type TaskHealthReport as ai, type TokenConsumption as aj, type ActivityEvent as ak, type ActorCreatedEvent as al, type ActorRevokedEvent as am, type AgentRegisteredEvent as an, type BaseEvent as ao, type ChangelogCreatedEvent as ap, type CycleCreatedEvent as aq, type CycleStatusChangedEvent as ar, EventBus as as, type EventHandler as at, type EventMetadata as au, type EventSubscription as av, type ExecutionCreatedEvent as aw, type FeedbackCreatedEvent as ax, type GitGovEvent as ay, type SystemDailyTickEvent as az, type FixReport as b, type ConflictInfo as b0, type ConflictType as b1, type ExpectedFilesScope as b2, type AgentExecutionContext as b3, type AgentOutput as b4, type AgentRunnerEvent as b5, type ApiEngine as b6, type AuthConfig as b7, type AuthType as b8, type CustomEngine as b9, type Engine as ba, type EngineType as bb, type IAgentLoader as bc, type LocalEngine as bd, type McpEngine as be, type ProtocolHandler as bf, type RuntimeHandler as bg, type RuntimeHandlerRegistry as bh, type IIndexerAdapter as c, type LintRecordContext as d, type LintResult as e, type IProjectInitializer as f, type ISyncStateModule as g, type SyncStateModuleDependencies as h, type StateDeltaFile as i, type ConflictDiff as j, type IntegrityViolation as k, type AuditStateReport as l, type SyncStatePushOptions as m, type SyncStatePushResult as n, type SyncStatePullOptions as o, type SyncStatePullResult as p, type SyncStateResolveOptions as q, type SyncStateResolveResult as r, type IEventStream as s, type IAgentRunner as t, type AgentRunnerDependencies as u, type RunOptions as v, type AgentResponse as w, FsKeyProvider as x, type FsKeyProviderOptions as y, FsFileLister as z };