@snappedly-tools/shipyard 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +24 -14
  2. package/dist/MountConfig-K5ILnfht.d.ts +26 -0
  3. package/dist/{MountConfig-BHnKnA4h.d.ts → SandboxProvider-oUAwYlWm.d.ts} +1 -26
  4. package/dist/{chunk-L6PX5QTU.js → chunk-57EEKW3R.js} +57 -55
  5. package/dist/chunk-57EEKW3R.js.map +1 -0
  6. package/dist/{chunk-JI3HDDMS.js → chunk-HXSZM52J.js} +3 -3
  7. package/dist/{chunk-JI3HDDMS.js.map → chunk-HXSZM52J.js.map} +1 -1
  8. package/dist/{chunk-44I2BL6E.js → chunk-JZUBT4WG.js} +20 -4
  9. package/dist/chunk-JZUBT4WG.js.map +1 -0
  10. package/dist/chunk-NQRFVKCU.js +1840 -0
  11. package/dist/chunk-NQRFVKCU.js.map +1 -0
  12. package/dist/chunk-Z5C4LHVP.js +137 -0
  13. package/dist/chunk-Z5C4LHVP.js.map +1 -0
  14. package/dist/createSandbox-DmbnWAZv.d.ts +739 -0
  15. package/dist/index.d.ts +7 -2534
  16. package/dist/index.js +216 -7269
  17. package/dist/index.js.map +1 -1
  18. package/dist/integrations/github.d.ts +52 -0
  19. package/dist/integrations/github.js +1049 -0
  20. package/dist/integrations/github.js.map +1 -0
  21. package/dist/integrations/releases.d.ts +136 -0
  22. package/dist/integrations/releases.js +500 -0
  23. package/dist/integrations/releases.js.map +1 -0
  24. package/dist/main.js +641 -383
  25. package/dist/main.js.map +1 -1
  26. package/dist/publication-BPoy_M9M.d.ts +1200 -0
  27. package/dist/sandboxes/docker.d.ts +2 -1
  28. package/dist/sandboxes/docker.js +2 -2
  29. package/dist/templates/parallel-planner/main.mts +11 -7
  30. package/dist/templates/parallel-planner/setup.sh +1 -0
  31. package/dist/templates/parallel-planner-with-review/main.mts +11 -7
  32. package/dist/templates/parallel-planner-with-review/setup.sh +1 -0
  33. package/dist/templates/sequential-reviewer/main.mts +7 -3
  34. package/dist/templates/sequential-reviewer/setup.sh +1 -0
  35. package/dist/templates/shared/setup.sh +1 -0
  36. package/dist/templates/simple-loop/main.mts +7 -3
  37. package/dist/templates/simple-loop/setup.sh +1 -0
  38. package/dist/workflow/coordinator/migrations/002_workflow_phase_records.sql +11 -0
  39. package/dist/workflow/coordinator/migrations/003_phase_record_schema_version.sql +6 -0
  40. package/dist/workflow.d.ts +472 -0
  41. package/dist/workflow.js +4345 -0
  42. package/dist/workflow.js.map +1 -0
  43. package/package.json +13 -1
  44. package/dist/chunk-44I2BL6E.js.map +0 -1
  45. package/dist/chunk-L6PX5QTU.js.map +0 -1
@@ -0,0 +1,1200 @@
1
+ declare const WORKFLOW_CONTRACT_VERSION: 1;
2
+ type WorkItemKind = "planning-spec" | "executable-issue" | "pr-repair";
3
+ type RiskLevel = "low" | "medium" | "high" | "critical";
4
+ type WorkRisk = RiskLevel | "unknown";
5
+ type WorkScope = "small" | "substantial" | "unknown";
6
+ type WorkflowPhase = "triage" | "implementation" | "checking" | "review" | "repair" | "handoff" | "merge" | "release-verification";
7
+ type LifecycleState = "queued" | "waiting-info" | "authorized" | "implementing" | "checking" | "reviewing" | "repairing" | "human-review" | "merged" | "release-verifying" | "completed" | "failed" | "blocked" | "cancelled";
8
+ type PhaseOutcome = "completed" | "needs-info" | "blocked" | "failed" | "cancelled";
9
+ type CheckStatus = "passed" | "failed" | "incomplete" | "blocked" | "unknown";
10
+ type FindingSeverity = "info" | "low" | "medium" | "high" | "critical";
11
+ type ReviewAxis = "standards" | "spec" | "interface";
12
+ type FindingDisposition = "open" | "fixed" | "rejected" | "accepted" | "deferred";
13
+ interface WorkIdentity {
14
+ readonly repository: string;
15
+ readonly itemId: string;
16
+ readonly kind: WorkItemKind;
17
+ }
18
+ interface SourceReference {
19
+ readonly provider: "github" | "slack" | "manual";
20
+ readonly repository: string;
21
+ readonly itemId: string;
22
+ readonly url?: string;
23
+ /** Original content is retained durably but must not be echoed to an unauthorized destination. */
24
+ readonly originalBody: string;
25
+ readonly author?: string;
26
+ }
27
+ interface RevisionReference {
28
+ readonly branch: string;
29
+ readonly sha: string;
30
+ }
31
+ interface Authorization {
32
+ readonly status: "pending" | "approved" | "withdrawn";
33
+ readonly actor?: string;
34
+ readonly actorRole?: "maintainer" | "owner" | "policy";
35
+ readonly approvedAt?: string;
36
+ }
37
+ interface VerificationPlan {
38
+ readonly checks: readonly string[];
39
+ readonly artifacts: readonly string[];
40
+ }
41
+ interface WorkBrief {
42
+ readonly contractVersion: typeof WORKFLOW_CONTRACT_VERSION;
43
+ readonly id: string;
44
+ readonly revision: number;
45
+ readonly hash: string;
46
+ readonly identity: WorkIdentity;
47
+ readonly source: SourceReference;
48
+ readonly problem: string;
49
+ readonly evidence: readonly string[];
50
+ readonly acceptanceCriteria: readonly string[];
51
+ readonly exclusions: readonly string[];
52
+ readonly risk: WorkRisk;
53
+ readonly scope?: WorkScope;
54
+ readonly verification: VerificationPlan;
55
+ readonly unresolvedQuestions: readonly string[];
56
+ readonly authorization: Authorization;
57
+ readonly base: RevisionReference;
58
+ readonly policyRevision: string;
59
+ readonly skillRevision: string;
60
+ readonly createdAt: string;
61
+ }
62
+ interface CheckCommand {
63
+ readonly name: string;
64
+ readonly command: string;
65
+ readonly required: boolean;
66
+ }
67
+ interface PhaseBudget {
68
+ readonly maxAttempts: number;
69
+ readonly timeoutSeconds: number;
70
+ }
71
+ type AgentRole = "routine" | "strong";
72
+ interface AgentModelRoles {
73
+ readonly routine: string;
74
+ readonly strong: string;
75
+ }
76
+ type WorkerPolicy = {
77
+ readonly provider: string;
78
+ readonly sandbox: string;
79
+ readonly skillRevision: string;
80
+ } & ({
81
+ readonly model: string;
82
+ readonly models?: never;
83
+ } | {
84
+ readonly model?: never;
85
+ readonly models: AgentModelRoles;
86
+ });
87
+ interface AgentSelection {
88
+ readonly provider: string;
89
+ readonly model: string;
90
+ readonly role: AgentRole;
91
+ }
92
+ interface RepositoryPolicy {
93
+ readonly contractVersion: typeof WORKFLOW_CONTRACT_VERSION;
94
+ readonly repository: string;
95
+ readonly revision: string;
96
+ readonly baseBranch: string;
97
+ readonly issueClosure: "merge-and-ci" | "staging-verification" | "production-verification";
98
+ readonly authorization: {
99
+ readonly required: boolean;
100
+ readonly allowedActors: readonly ("maintainer" | "owner" | "policy")[];
101
+ readonly autoStartRisk: readonly RiskLevel[];
102
+ };
103
+ readonly worker: WorkerPolicy;
104
+ readonly checks: readonly CheckCommand[];
105
+ readonly phaseBudgets: Readonly<Record<WorkflowPhase, PhaseBudget>>;
106
+ readonly repairBudget: {
107
+ readonly maxBatches: number;
108
+ readonly maxFollowUps: number;
109
+ };
110
+ }
111
+ /** Whether a brief carries an authorization accepted by this repository policy. */
112
+ declare const isAuthorizationAllowed: (brief: Pick<WorkBrief, "authorization">, policy: Pick<RepositoryPolicy, "authorization">) => boolean;
113
+ interface CheckEvidence {
114
+ readonly name: string;
115
+ readonly command: string;
116
+ readonly status: CheckStatus;
117
+ readonly summary: string;
118
+ /** Candidate identity for checks that are used as a lifecycle gate. */
119
+ readonly baseSha?: string;
120
+ readonly headSha?: string;
121
+ readonly briefHash?: string;
122
+ readonly startedAt?: string;
123
+ readonly completedAt?: string;
124
+ readonly exitCode?: number;
125
+ readonly artifactRefs?: readonly string[];
126
+ }
127
+ interface Finding {
128
+ readonly id: string;
129
+ readonly severity: FindingSeverity;
130
+ readonly axis: ReviewAxis;
131
+ readonly disposition: FindingDisposition;
132
+ readonly title: string;
133
+ readonly evidence: string;
134
+ readonly location?: string;
135
+ readonly requirement?: string;
136
+ readonly verification?: string;
137
+ }
138
+ interface ReviewEvidence {
139
+ readonly outcome: "passed" | "actionable-findings" | "incomplete" | "blocked" | "failed";
140
+ readonly axes: readonly ReviewAxis[];
141
+ readonly findings: readonly Finding[];
142
+ readonly headSha: string;
143
+ readonly baseSha?: string;
144
+ readonly briefHash: string;
145
+ }
146
+ interface PhaseResult {
147
+ readonly contractVersion: typeof WORKFLOW_CONTRACT_VERSION;
148
+ readonly assignmentId: string;
149
+ readonly phase: WorkflowPhase;
150
+ readonly outcome: PhaseOutcome;
151
+ readonly identity: WorkIdentity;
152
+ /** Brief revision executed by this phase. */
153
+ readonly briefHash: string;
154
+ readonly base?: RevisionReference;
155
+ readonly head?: RevisionReference;
156
+ readonly summary: string;
157
+ readonly evidence: readonly string[];
158
+ readonly checks: readonly CheckEvidence[];
159
+ readonly commits: readonly string[];
160
+ readonly artifacts: readonly string[];
161
+ readonly questions: readonly string[];
162
+ readonly findings: readonly Finding[];
163
+ /** Review axes explicitly completed, including axes with no findings. */
164
+ readonly reviewAxes?: readonly ReviewAxis[];
165
+ readonly completedAt: string;
166
+ }
167
+ interface Assignment {
168
+ readonly contractVersion: typeof WORKFLOW_CONTRACT_VERSION;
169
+ readonly id: string;
170
+ readonly phase: WorkflowPhase;
171
+ readonly attempt: number;
172
+ readonly identity: WorkIdentity;
173
+ readonly briefId: string;
174
+ readonly briefRevision: number;
175
+ readonly briefHash: string;
176
+ readonly policyRevision: string;
177
+ readonly skillRevision: string;
178
+ /** Missing only on assignments persisted before role model selection shipped. */
179
+ readonly agentSelection?: AgentSelection;
180
+ readonly base: RevisionReference;
181
+ readonly head?: RevisionReference;
182
+ readonly createdAt: string;
183
+ }
184
+ interface TransitionContext {
185
+ readonly kind: WorkItemKind;
186
+ readonly authorization: Authorization["status"];
187
+ readonly checks?: readonly CheckEvidence[];
188
+ /** Required check names from the repository policy. */
189
+ readonly requiredCheckNames?: readonly string[];
190
+ /** Exact candidate identity required for lifecycle-gating check evidence. */
191
+ readonly checkCandidate?: {
192
+ readonly baseSha: string;
193
+ readonly headSha: string;
194
+ readonly briefHash: string;
195
+ };
196
+ readonly review?: ReviewEvidence;
197
+ readonly currentHeadSha?: string;
198
+ readonly assignedHeadSha?: string;
199
+ }
200
+ declare class ContractValidationError extends Error {
201
+ readonly issues: readonly string[];
202
+ constructor(message: string, issues?: readonly string[]);
203
+ }
204
+ type CreateWorkBriefInput = Omit<WorkBrief, "contractVersion" | "id" | "revision" | "hash"> & {
205
+ readonly id?: string;
206
+ readonly revision?: number;
207
+ /** Accepted for callers carrying a previously materialized brief; always recomputed. */
208
+ readonly hash?: string;
209
+ readonly contractVersion?: typeof WORKFLOW_CONTRACT_VERSION;
210
+ };
211
+ declare const createWorkBrief: (input: CreateWorkBriefInput) => WorkBrief;
212
+ declare const parseWorkBrief: (value: unknown) => WorkBrief;
213
+ type CreateRepositoryPolicyInput = Omit<RepositoryPolicy, "contractVersion">;
214
+ declare const parseRepositoryPolicy: (value: unknown) => RepositoryPolicy;
215
+ declare const createRepositoryPolicy: (input: CreateRepositoryPolicyInput) => RepositoryPolicy;
216
+ declare const resolveAgentSelection: (policy: Pick<RepositoryPolicy, "worker">, phase: WorkflowPhase, risk?: WorkRisk, scope?: WorkScope) => AgentSelection;
217
+ declare const parseCheckEvidence: (value: unknown) => CheckEvidence;
218
+ declare const requireTransition: (from: LifecycleState, to: LifecycleState, context: TransitionContext) => void;
219
+ interface CreateAssignmentInput {
220
+ readonly id: string;
221
+ readonly phase: WorkflowPhase;
222
+ readonly brief: WorkBrief;
223
+ readonly policy: RepositoryPolicy;
224
+ readonly attempt: number;
225
+ readonly head?: RevisionReference;
226
+ readonly createdAt: string;
227
+ }
228
+ declare const createAssignment: (input: CreateAssignmentInput) => Assignment;
229
+ declare const parsePhaseResult: (value: unknown) => PhaseResult;
230
+
231
+ type JobControl = "active" | "paused" | "cancelled" | "superseded";
232
+ type EventStatus = "received" | "accepted" | "ignored";
233
+ type EventIgnoreReason = "out-of-order" | "closed-item" | "withdrawn-authorization" | "repository-stopped" | "invalid-policy";
234
+ type DispatchStatus = "pending" | "claimed" | "started" | "completed" | "failed" | "cancelled";
235
+ type EffectStatus = "pending" | "claimed" | "succeeded" | "uncertain" | "failed" | "cancelled";
236
+ interface WorkKey {
237
+ readonly repository: string;
238
+ readonly itemId: string;
239
+ readonly briefRevision: number;
240
+ readonly phase: WorkflowPhase;
241
+ readonly relevantRevision: string;
242
+ }
243
+ interface WorkflowEventInput {
244
+ readonly deliveryId: string;
245
+ readonly brief: WorkBrief;
246
+ readonly policy: RepositoryPolicy;
247
+ readonly phase: WorkflowPhase;
248
+ readonly relevantRevision: string;
249
+ readonly observedAt: string;
250
+ /** A closed source item invalidates queued and active work. */
251
+ readonly sourceState?: "open" | "closed";
252
+ readonly payload?: unknown;
253
+ }
254
+ interface StoredEvent extends WorkflowEventInput {
255
+ readonly id: string;
256
+ readonly key: WorkKey;
257
+ readonly status: EventStatus;
258
+ readonly ignoreReason?: EventIgnoreReason;
259
+ readonly jobId?: string;
260
+ readonly receivedAt: string;
261
+ }
262
+ interface RepairBudgetUsage {
263
+ readonly repairBatches: number;
264
+ readonly followUps: number;
265
+ }
266
+ interface WorkflowJob {
267
+ readonly id: string;
268
+ readonly key: WorkKey;
269
+ readonly brief: WorkBrief;
270
+ readonly policy: RepositoryPolicy;
271
+ readonly state: LifecycleState;
272
+ readonly control: JobControl;
273
+ readonly phaseAttempts: Readonly<Record<WorkflowPhase, number>>;
274
+ readonly repairBatches: number;
275
+ readonly followUps: number;
276
+ readonly infrastructureRetries: number;
277
+ readonly infrastructureRetryLimit: number;
278
+ readonly assignments: readonly Assignment[];
279
+ readonly phaseResults: readonly PhaseResult[];
280
+ readonly activeAssignmentId?: string;
281
+ readonly latestObservedAt: string;
282
+ readonly createdAt: string;
283
+ readonly updatedAt: string;
284
+ readonly version: number;
285
+ }
286
+ interface DispatchIntent {
287
+ readonly id: string;
288
+ readonly dedupeKey: string;
289
+ readonly key: WorkKey;
290
+ readonly jobId: string;
291
+ readonly status: DispatchStatus;
292
+ readonly assignment?: Assignment;
293
+ readonly workerId?: string;
294
+ readonly claimedAt?: number;
295
+ readonly claimExpiresAt?: number;
296
+ readonly error?: string;
297
+ readonly createdAt: string;
298
+ readonly updatedAt: string;
299
+ }
300
+ interface EffectIntent {
301
+ readonly id: string;
302
+ readonly jobId: string;
303
+ readonly kind: string;
304
+ readonly marker: string;
305
+ readonly payload?: unknown;
306
+ readonly status: EffectStatus;
307
+ readonly externalRef?: unknown;
308
+ readonly workerId?: string;
309
+ readonly fencingToken?: number;
310
+ readonly claimedAt?: number;
311
+ readonly claimExpiresAt?: number;
312
+ readonly error?: string;
313
+ readonly createdAt: string;
314
+ readonly updatedAt: string;
315
+ }
316
+ interface BranchLease {
317
+ readonly leaseId: string;
318
+ readonly resourceKey: string;
319
+ readonly repository: string;
320
+ readonly branch: string;
321
+ readonly jobId: string;
322
+ readonly workerId: string;
323
+ readonly fencingToken: number;
324
+ readonly acquiredAt: number;
325
+ readonly heartbeatAt: number;
326
+ readonly expiresAt: number;
327
+ }
328
+ interface RepositoryControl {
329
+ readonly repository: string;
330
+ readonly stopped: boolean;
331
+ readonly reason?: string;
332
+ readonly updatedAt: string;
333
+ }
334
+ interface CoordinatorStorageTransaction {
335
+ insertEventIfAbsent(event: StoredEvent): Promise<{
336
+ readonly event: StoredEvent;
337
+ readonly inserted: boolean;
338
+ }>;
339
+ saveEvent(event: StoredEvent): Promise<void>;
340
+ /** Serialize intake for an identity even before its first job row exists. */
341
+ lockWorkIdentity(identity: WorkIdentity): Promise<void>;
342
+ getJob(jobId: string): Promise<WorkflowJob | undefined>;
343
+ findJobByKey(key: WorkKey, briefHash: string): Promise<WorkflowJob | undefined>;
344
+ findCurrentJob(identity: WorkIdentity): Promise<WorkflowJob | undefined>;
345
+ insertJob(job: WorkflowJob): Promise<void>;
346
+ saveJob(job: WorkflowJob): Promise<void>;
347
+ findDispatchByDedupeKey(dedupeKey: string): Promise<DispatchIntent | undefined>;
348
+ findDispatchByAssignmentId(assignmentId: string): Promise<DispatchIntent | undefined>;
349
+ findPendingDispatch(repository: string, nowMilliseconds: number, selector?: {
350
+ readonly jobId?: string;
351
+ readonly dispatchId?: string;
352
+ }): Promise<DispatchIntent | undefined>;
353
+ insertDispatchIfAbsent(dispatch: DispatchIntent): Promise<{
354
+ readonly dispatch: DispatchIntent;
355
+ readonly inserted: boolean;
356
+ }>;
357
+ saveDispatch(dispatch: DispatchIntent): Promise<void>;
358
+ findEffect(jobId: string, kind: string, marker: string): Promise<EffectIntent | undefined>;
359
+ insertEffectIfAbsent(effect: EffectIntent): Promise<{
360
+ readonly effect: EffectIntent;
361
+ readonly inserted: boolean;
362
+ }>;
363
+ saveEffect(effect: EffectIntent): Promise<void>;
364
+ getLease(repository: string, branch: string): Promise<BranchLease | undefined>;
365
+ /** Serialize lease acquisition even when no lease row exists yet. */
366
+ lockLeaseResource(repository: string, branch: string): Promise<void>;
367
+ saveLease(lease: BranchLease): Promise<void>;
368
+ findLeasesForJob(jobId: string): Promise<readonly BranchLease[]>;
369
+ findLeasesForRepository(repository: string): Promise<readonly BranchLease[]>;
370
+ getRepositoryControl(repository: string): Promise<RepositoryControl | undefined>;
371
+ saveRepositoryControl(control: RepositoryControl): Promise<void>;
372
+ }
373
+ interface CoordinatorStorage {
374
+ transaction<T>(operation: (transaction: CoordinatorStorageTransaction) => Promise<T>): Promise<T>;
375
+ }
376
+ interface CoordinatorClock {
377
+ now(): string;
378
+ nowMilliseconds(): number;
379
+ }
380
+ interface WorkflowCoordinatorOptions {
381
+ readonly storage: CoordinatorStorage;
382
+ readonly clock?: CoordinatorClock;
383
+ readonly idFactory?: (prefix: string) => string;
384
+ readonly infrastructureRetryLimit?: number;
385
+ readonly dispatchClaimTtlMs?: number;
386
+ readonly effectClaimTtlMs?: number;
387
+ }
388
+ interface DispatchRequest {
389
+ readonly repository: string;
390
+ readonly workerId: string;
391
+ /** Restrict dispatch to a known job/intent when a workflow runner is resuming. */
392
+ readonly jobId?: string;
393
+ readonly dispatchId?: string;
394
+ }
395
+ type DispatchBlockReason = "repository-stopped" | "job-paused" | "job-cancelled" | "job-superseded" | "authorization-withdrawn" | "authorization-pending" | "invalid-policy" | "semantic-budget-exhausted" | "infrastructure-retries-exhausted" | "invalid-transition";
396
+ interface IngestResult {
397
+ readonly disposition: "accepted" | "duplicate" | "out-of-order" | "ignored";
398
+ readonly event: StoredEvent;
399
+ readonly job?: WorkflowJob;
400
+ readonly dispatch?: DispatchIntent;
401
+ readonly reason?: EventIgnoreReason;
402
+ }
403
+ interface DispatchResult {
404
+ readonly status: "dispatched" | "none" | "blocked";
405
+ readonly dispatch?: DispatchIntent;
406
+ readonly assignment?: Assignment;
407
+ readonly job?: WorkflowJob;
408
+ readonly reason?: DispatchBlockReason;
409
+ }
410
+ interface AcquireBranchLeaseInput {
411
+ readonly repository: string;
412
+ readonly branch: string;
413
+ readonly jobId: string;
414
+ readonly workerId: string;
415
+ readonly ttlMs: number;
416
+ }
417
+ interface SubmitPhaseResultInput {
418
+ readonly jobId: string;
419
+ readonly result: PhaseResult;
420
+ /** Every non-duplicate result must be fenced by the worker's active lease. */
421
+ readonly lease: BranchLease;
422
+ }
423
+ interface SchedulePhaseInput {
424
+ readonly jobId: string;
425
+ readonly phase: WorkflowPhase;
426
+ readonly relevantRevision: string;
427
+ readonly head?: {
428
+ readonly branch: string;
429
+ readonly sha: string;
430
+ };
431
+ }
432
+ interface SchedulePhaseResult {
433
+ readonly status: "scheduled" | "duplicate" | "blocked";
434
+ readonly job: WorkflowJob;
435
+ readonly dispatch?: DispatchIntent;
436
+ readonly reason?: string;
437
+ }
438
+ interface PhaseResultSubmission {
439
+ readonly job: WorkflowJob;
440
+ readonly duplicate: boolean;
441
+ readonly transitioned: boolean;
442
+ }
443
+ interface InfrastructureFailureInput {
444
+ readonly jobId: string;
445
+ readonly assignmentId: string;
446
+ readonly error: string;
447
+ }
448
+ interface InfrastructureRetryResult {
449
+ readonly status: "retry-scheduled" | "exhausted" | "not-retryable";
450
+ readonly job: WorkflowJob;
451
+ readonly dispatch?: DispatchIntent;
452
+ }
453
+ interface RepairRequestResult {
454
+ readonly status: "scheduled" | "blocked" | "not-allowed";
455
+ readonly job: WorkflowJob;
456
+ readonly dispatch?: DispatchIntent;
457
+ readonly dispatchClaimExpired?: boolean;
458
+ readonly reason?: string;
459
+ }
460
+ interface EffectOperationContext {
461
+ readonly effect: EffectIntent;
462
+ readonly fencingToken: number;
463
+ }
464
+ interface PublishEffectInput<T> {
465
+ readonly jobId: string;
466
+ readonly lease: BranchLease;
467
+ /** Optional resource binding for effects that operate on a branch. */
468
+ readonly branch?: string;
469
+ /** Optional resource binding for effects that target the workflow item. */
470
+ readonly itemId?: string;
471
+ /** Optional candidate binding for effects that publish a commit head. */
472
+ readonly headSha?: string;
473
+ readonly kind: string;
474
+ readonly marker: string;
475
+ readonly payload?: unknown;
476
+ readonly reconcile?: (context: EffectOperationContext) => Promise<T | undefined>;
477
+ readonly publish: (context: EffectOperationContext) => Promise<T>;
478
+ }
479
+ interface EffectExecution<T> {
480
+ readonly disposition: "published" | "reconciled" | "already-succeeded" | "in-flight";
481
+ readonly effect: EffectIntent;
482
+ readonly externalRef?: T;
483
+ }
484
+
485
+ /** Minimal query surface implemented by `pg`, Neon, and compatible clients. */
486
+ interface PostgresQueryResult<Row extends Record<string, unknown> = Record<string, unknown>> {
487
+ readonly rows: readonly Row[];
488
+ readonly rowCount?: number | null;
489
+ }
490
+ interface PostgresQueryClient {
491
+ query<Row extends Record<string, unknown> = Record<string, unknown>>(text: string, values?: readonly unknown[]): Promise<PostgresQueryResult<Row>>;
492
+ }
493
+ interface PostgresConnection extends PostgresQueryClient {
494
+ release?: () => void;
495
+ }
496
+ interface PostgresCoordinatorStorageOptions {
497
+ /** A connected client or a pool with a transaction-scoped `connect()` method. */
498
+ readonly client: PostgresQueryClient & {
499
+ readonly connect?: () => Promise<PostgresConnection>;
500
+ };
501
+ }
502
+ /** PostgreSQL-backed implementation; schema installation remains an operator concern. */
503
+ declare class PostgresCoordinatorStorage implements CoordinatorStorage {
504
+ private readonly client;
505
+ constructor(options: PostgresCoordinatorStorageOptions);
506
+ transaction<T>(operation: (transaction: CoordinatorStorageTransaction) => Promise<T>): Promise<T>;
507
+ }
508
+
509
+ declare class LeaseLostError extends Error {
510
+ constructor(message?: string);
511
+ }
512
+ declare class LeaseBusyError extends Error {
513
+ constructor(message: string);
514
+ }
515
+ declare class WorkflowCoordinator {
516
+ private readonly storage;
517
+ private readonly clock;
518
+ private readonly idFactory;
519
+ private readonly infrastructureRetryLimit;
520
+ private readonly dispatchClaimTtlMs;
521
+ private readonly effectClaimTtlMs;
522
+ constructor(options: WorkflowCoordinatorOptions);
523
+ getJob(jobId: string): Promise<WorkflowJob | undefined>;
524
+ getCurrentJob(identity: WorkIdentity): Promise<WorkflowJob | undefined>;
525
+ getRepositoryControl(repository: string): Promise<RepositoryControl | undefined>;
526
+ ingest(input: WorkflowEventInput): Promise<IngestResult>;
527
+ dispatchNext(request: DispatchRequest): Promise<DispatchResult>;
528
+ private latestHeadForRevision;
529
+ private dispatchBlockReason;
530
+ acquireBranchLease(input: AcquireBranchLeaseInput): Promise<BranchLease>;
531
+ heartbeatBranchLease(lease: BranchLease): Promise<BranchLease>;
532
+ private assertLease;
533
+ publishEffect<T>(input: PublishEffectInput<T>): Promise<EffectExecution<T>>;
534
+ private assertPublicationAllowed;
535
+ private finishEffect;
536
+ recordPhaseResult(input: SubmitPhaseResultInput): Promise<{
537
+ job: WorkflowJob;
538
+ duplicate: boolean;
539
+ transitioned: boolean;
540
+ }>;
541
+ recordInfrastructureFailure(input: InfrastructureFailureInput): Promise<InfrastructureRetryResult>;
542
+ setRepositoryStop(input: {
543
+ readonly repository: string;
544
+ readonly stopped: boolean;
545
+ readonly reason?: string;
546
+ }): Promise<RepositoryControl>;
547
+ pauseJob(jobId: string, reason?: string): Promise<WorkflowJob>;
548
+ cancelJob(jobId: string, reason?: string): Promise<WorkflowJob>;
549
+ supersedeJob(jobId: string, reason?: string): Promise<WorkflowJob>;
550
+ resumeJob(jobId: string): Promise<WorkflowJob>;
551
+ private updateJobControl;
552
+ schedulePhase(input: SchedulePhaseInput): Promise<SchedulePhaseResult>;
553
+ scheduleRepair(input: {
554
+ readonly jobId: string;
555
+ readonly brief: WorkBrief;
556
+ readonly policy: RepositoryPolicy;
557
+ readonly followUp?: boolean;
558
+ readonly relevantRevision?: string;
559
+ }): Promise<RepairRequestResult>;
560
+ private cancelStoredJob;
561
+ }
562
+
563
+ interface HandoffCandidate {
564
+ readonly base: RevisionReference;
565
+ readonly head: RevisionReference;
566
+ readonly briefHash: string;
567
+ }
568
+ interface BranchProtectionState {
569
+ readonly enforced: boolean;
570
+ readonly humanApprovalRequired: boolean;
571
+ /** Fresh provider evidence; caller-supplied booleans alone are not a merge gate. */
572
+ readonly provider: "github";
573
+ readonly verifiedAt: string;
574
+ }
575
+ interface HumanApproval {
576
+ readonly actor: string;
577
+ readonly actorRole: "owner" | "maintainer";
578
+ readonly approvedAt: string;
579
+ readonly baseSha: string;
580
+ readonly headSha: string;
581
+ readonly briefHash: string;
582
+ }
583
+ interface HandoffReadinessInput {
584
+ readonly job: WorkflowJob;
585
+ readonly candidate: HandoffCandidate;
586
+ readonly checks: readonly CheckEvidence[];
587
+ readonly review: ReviewEvidence;
588
+ readonly requiredAxes?: readonly ReviewAxis[];
589
+ readonly branchProtection?: BranchProtectionState;
590
+ readonly humanApproval?: HumanApproval;
591
+ readonly now?: () => string;
592
+ readonly freshnessWindowSeconds?: number;
593
+ }
594
+ interface HandoffPacket {
595
+ readonly sourceIssue: string;
596
+ readonly pullRequest?: string;
597
+ readonly candidate: HandoffCandidate;
598
+ readonly briefRevision: number;
599
+ readonly briefHash: string;
600
+ readonly change: string;
601
+ readonly risk: WorkBrief["risk"];
602
+ readonly acceptanceCriteria: readonly string[];
603
+ readonly acceptanceEvidence: readonly string[];
604
+ readonly checks: readonly CheckEvidence[];
605
+ readonly reviewAxes: readonly ReviewAxis[];
606
+ readonly findings: readonly Finding[];
607
+ readonly limitations: readonly string[];
608
+ }
609
+ type HandoffOutcome = "blocked" | "ready-for-review" | "review-requested"
610
+ /** Retained for source-item triage; PR handoff uses ready-for-review. */
611
+ | "ready-for-human" | "repair-needed" | "rejected" | "abandoned" | "merge-ready" | "merged" | "open";
612
+ interface HandoffReadinessResult {
613
+ readonly outcome: "blocked" | "ready-for-review" | "review-requested" | "merge-ready";
614
+ readonly readyForReview: boolean;
615
+ readonly reviewRequested: boolean;
616
+ readonly readyForHuman: boolean;
617
+ readonly mergeReady: boolean;
618
+ readonly reasons: readonly string[];
619
+ readonly packet: HandoffPacket;
620
+ }
621
+ interface HumanHandoffPublisher {
622
+ requestReview(input: {
623
+ readonly packet: HandoffPacket;
624
+ readonly pullRequestNumber: number;
625
+ }): Promise<void>;
626
+ }
627
+ interface PrepareHandoffOptions extends HandoffReadinessInput {
628
+ readonly sourceIssueNumber: number;
629
+ readonly pullRequestNumber: number;
630
+ readonly publisher?: HumanHandoffPublisher;
631
+ readonly readCurrent?: () => Promise<HandoffCandidate>;
632
+ }
633
+ interface HumanReviewDecisionInput {
634
+ readonly decision: "approved" | "changes-requested" | "rejected" | "abandoned";
635
+ readonly reason?: string;
636
+ }
637
+ interface HumanReviewDecision {
638
+ readonly outcome: Extract<HandoffOutcome, "merge-ready" | "repair-needed" | "rejected" | "abandoned">;
639
+ readonly reason?: string;
640
+ }
641
+ interface HumanReviewRoundTripOptions {
642
+ readonly candidate: HandoffCandidate;
643
+ readonly pullRequestNumber: number;
644
+ readonly decision: HumanReviewDecisionInput;
645
+ /** Re-reads the PR head and brief before applying the human decision. */
646
+ readonly readCurrent: () => Promise<HandoffCandidate>;
647
+ /** Keeps a requested-changes repair on the existing PR branch. */
648
+ readonly requestRepair: (input: {
649
+ readonly candidate: HandoffCandidate;
650
+ readonly pullRequestNumber: number;
651
+ readonly reason: string;
652
+ }) => Promise<void>;
653
+ }
654
+ interface HumanReviewRoundTripResult {
655
+ readonly outcome: "blocked" | Extract<HandoffOutcome, "merge-ready" | "repair-needed" | "rejected" | "abandoned">;
656
+ readonly reason?: string;
657
+ readonly candidate: HandoffCandidate;
658
+ readonly pullRequestNumber: number;
659
+ }
660
+ interface MergeTransport {
661
+ mergeProtected(input: {
662
+ readonly pullRequestNumber: number;
663
+ readonly headSha: string;
664
+ readonly baseBranch: string;
665
+ }): Promise<{
666
+ readonly mergedSha: string;
667
+ }>;
668
+ }
669
+ interface MergeCandidateOptions extends Omit<HandoffReadinessInput, "branchProtection"> {
670
+ readonly pullRequestNumber: number;
671
+ readonly humanApproval: HumanApproval;
672
+ /** Re-reads the PR, branch and brief identity immediately before merging. */
673
+ readonly readCurrent: () => Promise<HandoffCandidate>;
674
+ /** Fetches fresh provider evidence immediately before a protected merge. */
675
+ readonly readBranchProtection: () => Promise<BranchProtectionState>;
676
+ readonly transport: MergeTransport;
677
+ }
678
+ interface MergeResult {
679
+ readonly outcome: "blocked" | "merged";
680
+ readonly reason?: string;
681
+ readonly mergedSha?: string;
682
+ }
683
+ interface CompletionInput {
684
+ readonly policy: RepositoryPolicy;
685
+ readonly mergedSha: string;
686
+ readonly candidate: HandoffCandidate;
687
+ readonly checks: readonly CheckEvidence[];
688
+ }
689
+ interface CompletionResult {
690
+ readonly outcome: "completed" | "open";
691
+ readonly reason?: string;
692
+ readonly mergedSha: string;
693
+ readonly checks: readonly CheckEvidence[];
694
+ }
695
+ interface SourceIssueCloser {
696
+ closeIssue(input: {
697
+ readonly issueNumber: number;
698
+ readonly mergedSha: string;
699
+ readonly checks: readonly CheckEvidence[];
700
+ }): Promise<void>;
701
+ }
702
+ interface CloseSourceIssueOptions extends CompletionInput {
703
+ readonly sourceIssueNumber: number;
704
+ readonly closer: SourceIssueCloser;
705
+ }
706
+ interface SourceIssueClosureResult extends CompletionResult {
707
+ readonly closed: boolean;
708
+ }
709
+ declare const evaluateHandoffReadiness: (input: HandoffReadinessInput) => HandoffReadinessResult;
710
+ declare const prepareHumanHandoff: (input: PrepareHandoffOptions) => Promise<HandoffReadinessResult>;
711
+ declare const resolveHumanReviewDecision: (input: HumanReviewDecisionInput) => HumanReviewDecision;
712
+ declare const processHumanReviewDecision: (input: HumanReviewRoundTripOptions) => Promise<HumanReviewRoundTripResult>;
713
+ declare const mergeProtectedCandidate: (input: MergeCandidateOptions) => Promise<MergeResult>;
714
+ declare const completeSourceIssue: (input: CompletionInput) => CompletionResult;
715
+ declare const closeSourceIssue: (input: CloseSourceIssueOptions) => Promise<SourceIssueClosureResult>;
716
+
717
+ type TriageCategory = "bug" | "enhancement" | "support" | "duplicate" | "sensitive" | "non-actionable";
718
+ type TriageOutcome = "completed" | "needs-info" | "duplicate" | "sensitive" | "non-actionable" | "blocked" | "failed";
719
+ interface TriageSource {
720
+ readonly provider: "github" | "slack" | "manual";
721
+ readonly repository: string;
722
+ readonly itemId: string;
723
+ readonly title: string;
724
+ readonly body: string;
725
+ readonly author?: string;
726
+ readonly url?: string;
727
+ readonly updatedAt: string;
728
+ readonly kind?: WorkItemKind;
729
+ readonly labels?: readonly string[];
730
+ }
731
+ interface ClarificationReply {
732
+ readonly id: string;
733
+ readonly body: string;
734
+ readonly author?: string;
735
+ readonly updatedAt: string;
736
+ }
737
+ interface TriageSourceConflict {
738
+ readonly fingerprint: string;
739
+ readonly updatedAt: string;
740
+ }
741
+ interface TriageAssessment {
742
+ readonly category: TriageCategory;
743
+ readonly evidence: readonly string[];
744
+ readonly relevantFiles: readonly string[];
745
+ readonly acceptanceCriteria: readonly string[];
746
+ readonly exclusions: readonly string[];
747
+ readonly risk: RiskLevel;
748
+ readonly verification: readonly string[];
749
+ readonly unresolvedQuestions: readonly string[];
750
+ readonly requirementsConfirmed: boolean;
751
+ readonly duplicateOf?: string;
752
+ readonly sensitiveReason?: string;
753
+ }
754
+ interface TriageInvestigationRequest {
755
+ readonly source: TriageSource;
756
+ readonly policy: RepositoryPolicy;
757
+ readonly base: RevisionReference;
758
+ readonly previous?: TriageRecord;
759
+ readonly clarificationReply?: ClarificationReply;
760
+ }
761
+ type TriageInvestigator = ((request: TriageInvestigationRequest) => Promise<TriageAssessment>) | {
762
+ investigate(request: TriageInvestigationRequest): Promise<TriageAssessment>;
763
+ };
764
+ interface TriageRecord {
765
+ readonly id: string;
766
+ readonly sourceKey: string;
767
+ /** Retained for durable investigation and resumption; never used as public output. */
768
+ readonly source: TriageSource;
769
+ readonly sourceUpdatedAt: string;
770
+ readonly sourceFingerprint: string;
771
+ readonly revision: number;
772
+ readonly category: TriageCategory;
773
+ readonly outcome: TriageOutcome;
774
+ readonly assessment: TriageAssessment;
775
+ readonly brief?: WorkBrief;
776
+ readonly questions: readonly string[];
777
+ readonly clarificationIds: readonly string[];
778
+ readonly pendingClarificationReplies?: readonly ClarificationReply[];
779
+ readonly sourceConflict?: TriageSourceConflict;
780
+ readonly duplicateOf?: string;
781
+ readonly publicMessage: string;
782
+ readonly createdAt: string;
783
+ readonly updatedAt: string;
784
+ }
785
+ interface TriageStore {
786
+ get(sourceKey: string): TriageRecord | undefined | Promise<TriageRecord | undefined>;
787
+ /**
788
+ * Atomically save only when the stored revision still matches the read
789
+ * revision. Custom stores must implement this as one compare-and-save.
790
+ */
791
+ compareAndSave(record: TriageRecord, expectedRevision: number | undefined): boolean | Promise<boolean>;
792
+ }
793
+ declare class InMemoryTriageStore implements TriageStore {
794
+ private readonly records;
795
+ get(sourceKey: string): TriageRecord | undefined;
796
+ compareAndSave(record: TriageRecord, expectedRevision: number | undefined): boolean;
797
+ }
798
+ interface PostgresTriageStoreOptions {
799
+ readonly client: PostgresQueryClient;
800
+ }
801
+ /** Durable triage records backed by the coordinator's PostgreSQL database. */
802
+ declare class PostgresTriageStore implements TriageStore {
803
+ private readonly records;
804
+ constructor(options: PostgresTriageStoreOptions);
805
+ get(sourceKey: string): Promise<TriageRecord | undefined>;
806
+ compareAndSave(record: TriageRecord, expectedRevision: number | undefined): Promise<boolean>;
807
+ }
808
+ interface RunTriageOptions {
809
+ readonly source: TriageSource;
810
+ readonly policy: RepositoryPolicy;
811
+ readonly base: RevisionReference;
812
+ readonly store: TriageStore;
813
+ readonly investigator?: TriageInvestigator;
814
+ readonly clarificationReply?: ClarificationReply;
815
+ readonly now?: () => string;
816
+ }
817
+ interface TriageResult {
818
+ readonly outcome: TriageOutcome;
819
+ readonly category: TriageCategory;
820
+ readonly brief?: WorkBrief;
821
+ readonly questions: readonly string[];
822
+ readonly publicMessage: string;
823
+ readonly record: TriageRecord;
824
+ readonly implementationEligible: boolean;
825
+ }
826
+ declare const defaultInvestigator: TriageInvestigator;
827
+ declare const runTriage: ({ source: rawSource, policy, base, store, investigator, clarificationReply, now, }: RunTriageOptions) => Promise<TriageResult>;
828
+
829
+ type GitHubEventName = "issues" | "issue_comment" | "pull_request" | "pull_request_review" | "pull_request_review_comment" | "check_run" | "check_suite";
830
+ type GitHubActorType = "User" | "Bot" | "Organization" | string;
831
+ interface GitHubActor {
832
+ readonly login: string;
833
+ readonly type?: GitHubActorType;
834
+ }
835
+ interface GitHubIssueSnapshot {
836
+ readonly number: number;
837
+ readonly title: string;
838
+ readonly body: string;
839
+ readonly state: "open" | "closed";
840
+ readonly updatedAt: string;
841
+ readonly htmlUrl?: string;
842
+ readonly authorLogin?: string;
843
+ readonly labels: readonly string[];
844
+ readonly pullRequestNumber?: number;
845
+ }
846
+ interface GitHubCommentSnapshot {
847
+ readonly id: string;
848
+ readonly body: string;
849
+ readonly updatedAt: string;
850
+ readonly htmlUrl?: string;
851
+ readonly authorLogin?: string;
852
+ }
853
+ interface GitHubPullRequestSnapshot {
854
+ readonly number: number;
855
+ readonly title: string;
856
+ readonly body: string;
857
+ readonly state: "open" | "closed";
858
+ readonly draft: boolean;
859
+ readonly branch: string;
860
+ readonly baseBranch: string;
861
+ readonly headSha: string;
862
+ readonly updatedAt: string;
863
+ readonly htmlUrl?: string;
864
+ readonly authorLogin?: string;
865
+ }
866
+ type GitHubPullRequestReviewState = "approved" | "changes-requested" | "commented" | "dismissed" | "pending";
867
+ interface GitHubPullRequestReviewSnapshot {
868
+ readonly id: string;
869
+ readonly state: GitHubPullRequestReviewState;
870
+ readonly headSha: string;
871
+ readonly submittedAt: string;
872
+ readonly authorLogin?: string;
873
+ }
874
+ interface GitHubBranchSnapshot {
875
+ readonly name: string;
876
+ readonly headSha: string;
877
+ readonly htmlUrl?: string;
878
+ }
879
+ interface GitHubCheckSnapshot {
880
+ readonly id: string;
881
+ readonly name: string;
882
+ readonly headSha: string;
883
+ readonly status: "queued" | "in_progress" | "completed";
884
+ readonly conclusion?: "success" | "failure" | "neutral" | "cancelled" | "timed_out" | "action_required" | "stale" | "skipped";
885
+ readonly htmlUrl?: string;
886
+ }
887
+ interface GitHubWebhookRequest {
888
+ readonly body: string | Uint8Array;
889
+ readonly headers: Readonly<Record<string, string | undefined>>;
890
+ }
891
+ interface GitHubWebhookEnvelope {
892
+ readonly eventName: string;
893
+ readonly deliveryId: string;
894
+ readonly payload: unknown;
895
+ readonly receivedAt: string;
896
+ }
897
+ interface GitHubAuthorizationPolicy {
898
+ /** Exact repository names allowed to produce workflow input. */
899
+ readonly allowedRepositories: readonly string[];
900
+ /** Exact GitHub logins allowed to submit workflow input. */
901
+ readonly allowedSenders: readonly string[];
902
+ /** Exact GitHub logins allowed to approve or request changes on tracked pull requests. */
903
+ readonly allowedReviewers: readonly string[];
904
+ /** Additional service logins treated as bot-originated. */
905
+ readonly botLogins?: readonly string[];
906
+ }
907
+ interface GitHubBriefDefaults {
908
+ readonly risk?: RiskLevel;
909
+ readonly acceptanceCriteria?: readonly string[];
910
+ readonly exclusions?: readonly string[];
911
+ readonly unresolvedQuestions?: readonly string[];
912
+ readonly verificationArtifacts?: readonly string[];
913
+ }
914
+ type GitHubIssueEventKind = "issue-created" | "issue-edited" | "issue-replied";
915
+ type GitHubTrackedPullRequestEventKind = "tracked-pr-updated";
916
+ type GitHubNormalizedEventKind = GitHubIssueEventKind | GitHubTrackedPullRequestEventKind;
917
+ type GitHubEventIgnoreReason = "unsupported-event" | "unsupported-action" | "bot-originated" | "unrelated-pull-request" | "triage-source-conflict" | "triage-incomplete";
918
+ interface GitHubNormalizedEvent {
919
+ readonly kind: GitHubNormalizedEventKind;
920
+ readonly eventName: GitHubEventName;
921
+ readonly action: string;
922
+ readonly deliveryId: string;
923
+ readonly repository: string;
924
+ readonly sender: GitHubActor;
925
+ readonly issueNumber: number;
926
+ readonly pullRequestNumber?: number;
927
+ readonly title: string;
928
+ readonly body: string;
929
+ readonly labels: readonly string[];
930
+ readonly relevantRevision: string;
931
+ readonly observedAt: string;
932
+ readonly sourceState: "open" | "closed";
933
+ readonly reply?: GitHubCommentSnapshot;
934
+ readonly review?: GitHubPullRequestReviewSnapshot;
935
+ readonly trackedPullRequest?: GitHubTrackedPullRequest;
936
+ readonly workflowEvent: WorkflowEventInput;
937
+ }
938
+ interface GitHubIgnoredEvent {
939
+ readonly disposition: "ignored";
940
+ readonly reason: GitHubEventIgnoreReason;
941
+ readonly eventName: string;
942
+ readonly action?: string;
943
+ readonly deliveryId: string;
944
+ readonly repository: string;
945
+ readonly sender: GitHubActor;
946
+ }
947
+ type GitHubNormalizationResult = {
948
+ readonly disposition: "accepted";
949
+ readonly event: GitHubNormalizedEvent;
950
+ } | GitHubIgnoredEvent;
951
+ type GitHubDeliveryStatus = "received" | "accepted" | "ignored" | "rejected";
952
+ interface GitHubDeliveryRecord {
953
+ readonly deliveryId: string;
954
+ readonly eventName: string;
955
+ readonly repository: string;
956
+ readonly senderLogin: string;
957
+ readonly receivedAt: string;
958
+ readonly payloadHash: string;
959
+ readonly payload: unknown;
960
+ readonly status: GitHubDeliveryStatus;
961
+ readonly eventKind?: GitHubNormalizedEventKind;
962
+ readonly reason?: string;
963
+ readonly jobId?: string;
964
+ }
965
+ interface GitHubDeliveryStore {
966
+ recordDeliveryIfAbsent(delivery: GitHubDeliveryRecord): Promise<{
967
+ readonly delivery: GitHubDeliveryRecord;
968
+ readonly inserted: boolean;
969
+ }>;
970
+ getDelivery(deliveryId: string): Promise<GitHubDeliveryRecord | undefined>;
971
+ updateDelivery(delivery: GitHubDeliveryRecord): Promise<void>;
972
+ }
973
+ interface GitHubTrackedPullRequest {
974
+ readonly repository: string;
975
+ readonly pullRequestNumber: number;
976
+ readonly jobId: string;
977
+ readonly itemId: string;
978
+ readonly branch: string;
979
+ readonly headSha: string;
980
+ readonly marker: string;
981
+ readonly brief: WorkBrief;
982
+ readonly policy: RepositoryPolicy;
983
+ readonly createdAt: string;
984
+ }
985
+ interface GitHubPullRequestReviewHandler {
986
+ readCurrent(input: {
987
+ readonly candidate: HandoffCandidate;
988
+ readonly trackedPullRequest: GitHubTrackedPullRequest;
989
+ }): Promise<HandoffCandidate>;
990
+ requestRepair(input: {
991
+ readonly candidate: HandoffCandidate;
992
+ readonly pullRequestNumber: number;
993
+ readonly reason: string;
994
+ }): Promise<void>;
995
+ }
996
+ interface GitHubTrackingStore {
997
+ findTrackedPullRequest(repository: string, pullRequestNumber: number): Promise<GitHubTrackedPullRequest | undefined>;
998
+ saveTrackedPullRequest(pullRequest: GitHubTrackedPullRequest): Promise<void>;
999
+ }
1000
+ interface GitHubBriefFactoryInput {
1001
+ readonly event: Omit<GitHubNormalizedEvent, "workflowEvent">;
1002
+ readonly itemKind: "planning-spec" | "executable-issue" | "pr-repair";
1003
+ readonly policy: RepositoryPolicy;
1004
+ readonly base: RevisionReference;
1005
+ readonly authorization: Authorization;
1006
+ readonly revision: number;
1007
+ readonly defaults?: GitHubBriefDefaults;
1008
+ }
1009
+ type GitHubBriefFactory = (input: GitHubBriefFactoryInput) => WorkBrief;
1010
+ interface GitHubIntegrationOptions {
1011
+ readonly coordinator: WorkflowCoordinator;
1012
+ readonly policy: RepositoryPolicy;
1013
+ readonly base: RevisionReference;
1014
+ readonly authorization: GitHubAuthorizationPolicy;
1015
+ readonly deliveryStore: GitHubDeliveryStore;
1016
+ readonly webhookSecret: string | Uint8Array;
1017
+ readonly trackingStore?: GitHubTrackingStore;
1018
+ /** Review events fail closed unless the caller wires candidate-bound handoff handling. */
1019
+ readonly reviewHandler?: GitHubPullRequestReviewHandler;
1020
+ readonly briefDefaults?: GitHubBriefDefaults;
1021
+ readonly briefFactory?: GitHubBriefFactory;
1022
+ /** Optional automatic investigation adapter; absent means intake remains raw triage. */
1023
+ readonly triage?: {
1024
+ readonly store: TriageStore;
1025
+ readonly investigator?: TriageInvestigator;
1026
+ };
1027
+ readonly now?: () => string;
1028
+ }
1029
+ interface GitHubWebhookReceipt {
1030
+ readonly status: "accepted" | "duplicate" | "ignored" | "rejected";
1031
+ readonly deliveryId: string;
1032
+ readonly reason?: string;
1033
+ readonly event?: GitHubNormalizedEvent;
1034
+ readonly ingest?: IngestResult;
1035
+ readonly review?: HumanReviewRoundTripResult;
1036
+ }
1037
+ interface GitHubReconciliationInput {
1038
+ readonly repository: string;
1039
+ readonly issueNumber?: number;
1040
+ readonly pullRequestNumber?: number;
1041
+ readonly transport: GitHubReadTransport;
1042
+ }
1043
+ interface GitHubReconciliationResult {
1044
+ readonly status: "accepted" | "duplicate" | "ignored" | "not-found";
1045
+ readonly deliveryId: string;
1046
+ readonly reason?: string;
1047
+ readonly event?: GitHubNormalizedEvent;
1048
+ readonly ingest?: IngestResult;
1049
+ }
1050
+ interface GitHubReadTransport {
1051
+ fetchIssue(input: {
1052
+ readonly repository: string;
1053
+ readonly issueNumber: number;
1054
+ }): Promise<GitHubIssueSnapshot | undefined>;
1055
+ fetchPullRequest(input: {
1056
+ readonly repository: string;
1057
+ readonly pullRequestNumber: number;
1058
+ }): Promise<GitHubPullRequestSnapshot | undefined>;
1059
+ findCommentByMarker(input: {
1060
+ readonly repository: string;
1061
+ readonly issueNumber: number;
1062
+ readonly marker: string;
1063
+ }): Promise<GitHubCommentSnapshot | undefined>;
1064
+ findBranchByName(input: {
1065
+ readonly repository: string;
1066
+ readonly branch: string;
1067
+ }): Promise<GitHubBranchSnapshot | undefined>;
1068
+ findPullRequestByMarker(input: {
1069
+ readonly repository: string;
1070
+ readonly marker: string;
1071
+ }): Promise<GitHubPullRequestSnapshot | undefined>;
1072
+ findCheckByMarker(input: {
1073
+ readonly repository: string;
1074
+ readonly marker: string;
1075
+ readonly headSha: string;
1076
+ }): Promise<GitHubCheckSnapshot | undefined>;
1077
+ findIssueByMarker(input: {
1078
+ readonly repository: string;
1079
+ readonly marker: string;
1080
+ }): Promise<GitHubIssueSnapshot | undefined>;
1081
+ }
1082
+ interface GitHubWriteTransport {
1083
+ createComment(input: {
1084
+ readonly repository: string;
1085
+ readonly issueNumber: number;
1086
+ readonly body: string;
1087
+ }): Promise<GitHubCommentSnapshot>;
1088
+ createBranch(input: {
1089
+ readonly repository: string;
1090
+ readonly branch: string;
1091
+ readonly headSha: string;
1092
+ readonly marker: string;
1093
+ }): Promise<GitHubBranchSnapshot>;
1094
+ createPullRequest(input: {
1095
+ readonly repository: string;
1096
+ readonly title: string;
1097
+ readonly body: string;
1098
+ readonly branch: string;
1099
+ readonly baseBranch: string;
1100
+ readonly draft: boolean;
1101
+ readonly marker: string;
1102
+ }): Promise<GitHubPullRequestSnapshot>;
1103
+ createCheck(input: {
1104
+ readonly repository: string;
1105
+ readonly name: string;
1106
+ readonly headSha: string;
1107
+ readonly marker: string;
1108
+ readonly status: GitHubCheckSnapshot["status"];
1109
+ readonly conclusion?: GitHubCheckSnapshot["conclusion"];
1110
+ readonly summary: string;
1111
+ }): Promise<GitHubCheckSnapshot>;
1112
+ createRepairIssue(input: {
1113
+ readonly repository: string;
1114
+ readonly title: string;
1115
+ readonly body: string;
1116
+ readonly marker: string;
1117
+ readonly labels: readonly string[];
1118
+ }): Promise<GitHubIssueSnapshot>;
1119
+ }
1120
+ interface GitHubPublicationOptions {
1121
+ readonly coordinator: WorkflowCoordinator;
1122
+ readonly transport: GitHubReadTransport & GitHubWriteTransport;
1123
+ readonly trackingStore: GitHubTrackingStore;
1124
+ readonly now?: () => string;
1125
+ }
1126
+ interface GitHubPublicationResult<T> {
1127
+ readonly marker: string;
1128
+ readonly remote: T | undefined;
1129
+ readonly disposition: EffectExecution<T>["disposition"];
1130
+ readonly effect: EffectIntent;
1131
+ }
1132
+ interface GitHubCommentPublicationInput {
1133
+ readonly jobId: string;
1134
+ readonly lease: BranchLease;
1135
+ readonly issueNumber: number;
1136
+ readonly body: string;
1137
+ readonly key?: string;
1138
+ }
1139
+ interface GitHubBriefPublicationInput {
1140
+ readonly jobId: string;
1141
+ readonly lease: BranchLease;
1142
+ readonly issueNumber: number;
1143
+ readonly brief: WorkBrief;
1144
+ }
1145
+ interface GitHubBranchPublicationInput {
1146
+ readonly jobId: string;
1147
+ readonly lease: BranchLease;
1148
+ readonly branch: string;
1149
+ readonly headSha: string;
1150
+ }
1151
+ interface GitHubPullRequestPublicationInput {
1152
+ readonly jobId: string;
1153
+ readonly lease: BranchLease;
1154
+ readonly title: string;
1155
+ readonly body: string;
1156
+ readonly branch: string;
1157
+ readonly baseBranch: string;
1158
+ readonly headSha: string;
1159
+ readonly draft?: boolean;
1160
+ }
1161
+ interface GitHubCheckPublicationInput {
1162
+ readonly jobId: string;
1163
+ readonly lease: BranchLease;
1164
+ /** Candidate branch used to bind the check to the active lease. */
1165
+ readonly branch?: string;
1166
+ readonly name: string;
1167
+ readonly headSha: string;
1168
+ readonly status: GitHubCheckSnapshot["status"];
1169
+ readonly conclusion?: GitHubCheckSnapshot["conclusion"];
1170
+ readonly summary: string;
1171
+ readonly key?: string;
1172
+ }
1173
+ interface GitHubRepairIssuePublicationInput {
1174
+ readonly jobId: string;
1175
+ readonly lease: BranchLease;
1176
+ readonly title: string;
1177
+ readonly body: string;
1178
+ readonly labels?: readonly string[];
1179
+ }
1180
+ interface GitHubRepairLinkPublicationInput {
1181
+ readonly jobId: string;
1182
+ readonly lease: BranchLease;
1183
+ readonly issueNumber: number;
1184
+ readonly repairIssueUrl: string;
1185
+ }
1186
+
1187
+ /** Coordinator-owned GitHub effects with stable markers and remote reconciliation. */
1188
+ declare class GitHubPublication {
1189
+ private readonly options;
1190
+ constructor(options: GitHubPublicationOptions);
1191
+ publishComment(input: GitHubCommentPublicationInput): Promise<GitHubPublicationResult<GitHubCommentSnapshot>>;
1192
+ publishBrief(input: GitHubBriefPublicationInput): Promise<GitHubPublicationResult<GitHubCommentSnapshot>>;
1193
+ publishBranch(input: GitHubBranchPublicationInput): Promise<GitHubPublicationResult<GitHubBranchSnapshot>>;
1194
+ publishPullRequest(input: GitHubPullRequestPublicationInput): Promise<GitHubPublicationResult<GitHubPullRequestSnapshot>>;
1195
+ publishCheck(input: GitHubCheckPublicationInput): Promise<GitHubPublicationResult<GitHubCheckSnapshot>>;
1196
+ publishRepairIssue(input: GitHubRepairIssuePublicationInput): Promise<GitHubPublicationResult<GitHubIssueSnapshot>>;
1197
+ publishRepairLink(input: GitHubRepairLinkPublicationInput): Promise<GitHubPublicationResult<GitHubCommentSnapshot>>;
1198
+ }
1199
+
1200
+ export { type CheckEvidence as $, type GitHubEventName as A, type GitHubIgnoredEvent as B, type GitHubIssueEventKind as C, type GitHubIssueSnapshot as D, type GitHubNormalizedEvent as E, type GitHubNormalizedEventKind as F, type GitHubDeliveryStore as G, type HumanReviewDecisionInput as H, GitHubPublication as I, type GitHubPublicationOptions as J, type GitHubPublicationResult as K, type GitHubPullRequestPublicationInput as L, type GitHubPullRequestReviewHandler as M, type GitHubPullRequestReviewState as N, type GitHubPullRequestSnapshot as O, type GitHubReadTransport as P, type GitHubRepairIssuePublicationInput as Q, type GitHubRepairLinkPublicationInput as R, type GitHubTrackedPullRequestEventKind as S, type GitHubWriteTransport as T, type CoordinatorStorage as U, type CoordinatorStorageTransaction as V, type WorkBrief as W, type Assignment as X, type RepositoryPolicy as Y, type AgentSelection as Z, type RevisionReference as _, type GitHubTrackingStore as a, type PostgresConnection as a$, type Finding as a0, type ReviewAxis as a1, type PhaseResult as a2, type FindingSeverity as a3, type ReviewEvidence as a4, WorkflowCoordinator as a5, type WorkflowJob as a6, type DispatchResult as a7, type BranchLease as a8, type DispatchIntent as a9, type EventIgnoreReason as aA, type EventStatus as aB, type FindingDisposition as aC, type HandoffCandidate as aD, type HandoffOutcome as aE, type HandoffPacket as aF, type HandoffReadinessInput as aG, type HandoffReadinessResult as aH, type HumanApproval as aI, type HumanHandoffPublisher as aJ, type HumanReviewDecision as aK, type HumanReviewRoundTripOptions as aL, type HumanReviewRoundTripResult as aM, InMemoryTriageStore as aN, type InfrastructureFailureInput as aO, type InfrastructureRetryResult as aP, type IngestResult as aQ, type JobControl as aR, LeaseBusyError as aS, LeaseLostError as aT, type LifecycleState as aU, type MergeCandidateOptions as aV, type MergeResult as aW, type MergeTransport as aX, type PhaseBudget as aY, type PhaseOutcome as aZ, type PhaseResultSubmission as a_, type WorkflowPhase as aa, type RepositoryControl as ab, type PostgresQueryClient as ac, type AcquireBranchLeaseInput as ad, type AgentModelRoles as ae, type AgentRole as af, type Authorization as ag, type BranchProtectionState as ah, type CheckCommand as ai, type CheckStatus as aj, type ClarificationReply as ak, type CloseSourceIssueOptions as al, type CompletionInput as am, type CompletionResult as an, ContractValidationError as ao, type CoordinatorClock as ap, type CreateAssignmentInput as aq, type CreateRepositoryPolicyInput as ar, type CreateWorkBriefInput as as, type DispatchBlockReason as at, type DispatchRequest as au, type DispatchStatus as av, type EffectExecution as aw, type EffectIntent as ax, type EffectOperationContext as ay, type EffectStatus as az, type GitHubDeliveryRecord as b, PostgresCoordinatorStorage as b0, type PostgresCoordinatorStorageOptions as b1, type PostgresQueryResult as b2, PostgresTriageStore as b3, type PostgresTriageStoreOptions as b4, type PrepareHandoffOptions as b5, type PublishEffectInput as b6, type RepairBudgetUsage as b7, type RepairRequestResult as b8, type RiskLevel as b9, type WorkerPolicy as bA, type WorkflowCoordinatorOptions as bB, type WorkflowEventInput as bC, closeSourceIssue as bD, completeSourceIssue as bE, createAssignment as bF, createRepositoryPolicy as bG, createWorkBrief as bH, defaultInvestigator as bI, evaluateHandoffReadiness as bJ, isAuthorizationAllowed as bK, mergeProtectedCandidate as bL, parseCheckEvidence as bM, parsePhaseResult as bN, parseRepositoryPolicy as bO, parseWorkBrief as bP, prepareHumanHandoff as bQ, processHumanReviewDecision as bR, requireTransition as bS, resolveAgentSelection as bT, resolveHumanReviewDecision as bU, runTriage as bV, type RunTriageOptions as ba, type SchedulePhaseInput as bb, type SchedulePhaseResult as bc, type SourceIssueCloser as bd, type SourceIssueClosureResult as be, type SourceReference as bf, type StoredEvent as bg, type SubmitPhaseResultInput as bh, type TransitionContext as bi, type TriageAssessment as bj, type TriageCategory as bk, type TriageInvestigationRequest as bl, type TriageInvestigator as bm, type TriageOutcome as bn, type TriageRecord as bo, type TriageResult as bp, type TriageSource as bq, type TriageSourceConflict as br, type TriageStore as bs, type VerificationPlan as bt, WORKFLOW_CONTRACT_VERSION as bu, type WorkIdentity as bv, type WorkItemKind as bw, type WorkKey as bx, type WorkRisk as by, type WorkScope as bz, type GitHubTrackedPullRequest as c, type GitHubIntegrationOptions as d, type GitHubWebhookRequest as e, type GitHubWebhookReceipt as f, type GitHubWebhookEnvelope as g, type GitHubNormalizationResult as h, type GitHubReconciliationInput as i, type GitHubReconciliationResult as j, type GitHubBriefFactoryInput as k, type GitHubPullRequestReviewSnapshot as l, type GitHubActor as m, type GitHubActorType as n, type GitHubAuthorizationPolicy as o, type GitHubBranchPublicationInput as p, type GitHubBranchSnapshot as q, type GitHubBriefDefaults as r, type GitHubBriefFactory as s, type GitHubBriefPublicationInput as t, type GitHubCheckPublicationInput as u, type GitHubCheckSnapshot as v, type GitHubCommentPublicationInput as w, type GitHubCommentSnapshot as x, type GitHubDeliveryStatus as y, type GitHubEventIgnoreReason as z };