@gitgov/core 1.13.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.
- package/README.md +151 -270
- package/dist/src/agent_runner-COAjsdtr.d.ts +2585 -0
- package/dist/src/fs.d.ts +1375 -0
- package/dist/src/fs.js +8483 -0
- package/dist/src/fs.js.map +1 -0
- package/dist/src/index-DMkBFK4C.d.ts +807 -0
- package/dist/src/index.d.ts +1709 -5212
- package/dist/src/index.js +4779 -8956
- package/dist/src/index.js.map +1 -1
- package/dist/src/memory.d.ts +267 -0
- package/dist/src/memory.js +790 -0
- package/dist/src/memory.js.map +1 -0
- package/dist/src/memory_file_lister-D0llxocS.d.ts +221 -0
- package/package.json +19 -8
- package/prompts/gitgov_agent_prompt.md +0 -480
|
@@ -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 };
|