ai-foreman 1.7.13 → 1.7.14
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 +33 -3
- package/dist/adapters/claude.d.ts +5 -0
- package/dist/adapters/claude.js +122 -16
- package/dist/adapters/codex.d.ts +2 -0
- package/dist/adapters/codex.js +30 -8
- package/dist/adapters/recovering.d.ts +2 -0
- package/dist/adapters/recovering.js +6 -0
- package/dist/adapters/types.d.ts +22 -0
- package/dist/agentRun.js +21 -3
- package/dist/branch/currentGuard.d.ts +2 -0
- package/dist/branch/currentGuard.js +9 -0
- package/dist/branch/finalization.d.ts +22 -0
- package/dist/branch/finalization.js +120 -0
- package/dist/branch/git.js +7 -2
- package/dist/branch/runner.d.ts +3 -2
- package/dist/branch/runner.js +277 -75
- package/dist/buildRuns.d.ts +1 -0
- package/dist/buildRuns.js +33 -3
- package/dist/cli/start.js +314 -86
- package/dist/cli/state.d.ts +4 -0
- package/dist/cli/state.js +69 -0
- package/dist/continuity.d.ts +4 -0
- package/dist/continuity.js +26 -3
- package/dist/foreman.d.ts +22 -4
- package/dist/foreman.js +105 -19
- package/dist/handoffs.d.ts +5 -2
- package/dist/handoffs.js +93 -12
- package/dist/index.js +2 -0
- package/dist/qaFailureDelivery.d.ts +100 -0
- package/dist/qaFailureDelivery.js +570 -0
- package/dist/qaProtocolV2.d.ts +233 -0
- package/dist/qaProtocolV2.js +114 -0
- package/dist/qaRecovery.d.ts +15 -3
- package/dist/qaRecovery.js +477 -83
- package/dist/qaReview.d.ts +42 -17
- package/dist/qaReview.js +1216 -457
- package/dist/qaRuntime.d.ts +14 -0
- package/dist/qaRuntime.js +44 -0
- package/dist/qaSnapshot.d.ts +34 -0
- package/dist/qaSnapshot.js +302 -34
- package/dist/stateTransfer.d.ts +57 -0
- package/dist/stateTransfer.js +644 -0
- package/dist/statusReporter.d.ts +2 -0
- package/dist/statusReporter.js +6 -0
- package/dist/workflowDb.d.ts +245 -2
- package/dist/workflowDb.js +647 -6
- package/package.json +15 -3
package/dist/workflowDb.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { BuildRecoveryDecisionReceipt, ContextSample, ContinuityCheckpoint, ContinuityDelta, ContinuityEvent, ContinuityHead, ContinuityHeadState, HandoffLineage, HandoffManifestV1, LiveSettingsAcknowledgment, OperationLifecycle, PendingHumanDecision, ProviderSessionRefV1, RecoveryAttemptOutcome, RecoveryAttemptReceipt, ResolvedAutonomyPolicy, ResolvedAgentSettings, SessionUsageSample, StructuredInterruption, SupervisorState, WorkflowIssue } from "rafi-spec";
|
|
1
|
+
import type { BuildRecoveryDecisionReceipt, ContextSample, ContinuityCheckpoint, ContinuityDelta, ContinuityEvent, ContinuityHead, ContinuityHeadState, HandoffLineage, HandoffAcceptanceReceiptV1, HandoffManifestV1, LiveSettingsAcknowledgment, OperationLifecycle, PendingHumanDecision, ProviderSessionRefV1, RecoveryAttemptOutcome, RecoveryAttemptReceipt, ResolvedAutonomyPolicy, ResolvedAgentSettings, SessionUsageSample, StructuredInterruption, SupervisorState, WorkflowIssue } from "rafi-spec";
|
|
2
2
|
import type { BranchResumeSession } from "./branch/resume.js";
|
|
3
|
+
import { type BuilderRemediationReceiptV2, type FrozenQaSourceStateV2, type HandoffAcceptanceReceiptV2, type QaPassCertificateV2, type QaReducerEventV2, type QaReducerStateV2, type QaReportDisposition, type QaReviewBasisV2, type QaTurnIntentV2, type QaTurnReceiptV2 } from "./qaProtocolV2.js";
|
|
3
4
|
export declare const WORKFLOW_DB_FILE = ".rafi/recovery.sqlite3";
|
|
4
5
|
export type WorkflowKind = "plan" | "ticket-plan" | "ticket-populate" | "uninstall" | "build" | "qa-remediation" | "recovery" | "legacy";
|
|
5
6
|
export type WorkflowRunStatus = "running" | "paused" | "blocked" | "completed" | "failed" | "cancelled" | "superseded";
|
|
@@ -74,6 +75,121 @@ export interface RoleMutationLease {
|
|
|
74
75
|
sessionKey?: string;
|
|
75
76
|
movedAt: string;
|
|
76
77
|
}
|
|
78
|
+
export interface QaRecoveryHeadRecord {
|
|
79
|
+
runId: string;
|
|
80
|
+
ticketId: string;
|
|
81
|
+
packetId: string;
|
|
82
|
+
packetPath: string;
|
|
83
|
+
packetDigest: string;
|
|
84
|
+
reviewedStateDigest: string;
|
|
85
|
+
revision: number;
|
|
86
|
+
correctionTurns: number;
|
|
87
|
+
pendingAction: string;
|
|
88
|
+
updatedAt: string;
|
|
89
|
+
}
|
|
90
|
+
export interface QaPacketProjectionRecord {
|
|
91
|
+
runId: string;
|
|
92
|
+
ticketId: string;
|
|
93
|
+
packetRevision: number;
|
|
94
|
+
packetDigest: string;
|
|
95
|
+
path: string;
|
|
96
|
+
/** Exact canonical manifest bytes needed to finish an interrupted filesystem publication. */
|
|
97
|
+
manifestJson?: string;
|
|
98
|
+
status: "intended" | "published";
|
|
99
|
+
createdAt: string;
|
|
100
|
+
}
|
|
101
|
+
export interface QaFinalizationStepRecord {
|
|
102
|
+
operationId: string;
|
|
103
|
+
runId: string;
|
|
104
|
+
ticketId: string;
|
|
105
|
+
certificateId: string;
|
|
106
|
+
kind: string;
|
|
107
|
+
status: "intended" | "completed" | "invalidated";
|
|
108
|
+
intent: {
|
|
109
|
+
expectedSourceStateDigest: string;
|
|
110
|
+
expectedGitTree: string;
|
|
111
|
+
allowedProjectionPaths: string[];
|
|
112
|
+
reducerRevision: number;
|
|
113
|
+
};
|
|
114
|
+
receipt?: unknown;
|
|
115
|
+
}
|
|
116
|
+
export interface QaReviewAttemptRecord {
|
|
117
|
+
attemptId: string;
|
|
118
|
+
runId: string;
|
|
119
|
+
ticketId: string;
|
|
120
|
+
reviewNumber: number;
|
|
121
|
+
cycle: number;
|
|
122
|
+
remediationGeneration: number;
|
|
123
|
+
sourceDigest: string;
|
|
124
|
+
status: "started" | "passed" | "failed" | "interrupted";
|
|
125
|
+
reportDigest?: string;
|
|
126
|
+
findingIds?: string[];
|
|
127
|
+
namespacedFindingIds?: string[];
|
|
128
|
+
detail?: string;
|
|
129
|
+
createdAt: string;
|
|
130
|
+
updatedAt: string;
|
|
131
|
+
}
|
|
132
|
+
export interface QaRemediationAttemptRecord {
|
|
133
|
+
attemptId: string;
|
|
134
|
+
runId: string;
|
|
135
|
+
ticketId: string;
|
|
136
|
+
reviewAttemptId: string;
|
|
137
|
+
generation: number;
|
|
138
|
+
mode: "validated-report" | "planner-remediation";
|
|
139
|
+
status: "intended" | "started" | "succeeded" | "failed" | "uncertain";
|
|
140
|
+
requestDigest: string;
|
|
141
|
+
responseDigest?: string;
|
|
142
|
+
summaryDigest?: string;
|
|
143
|
+
detail?: string;
|
|
144
|
+
createdAt: string;
|
|
145
|
+
updatedAt: string;
|
|
146
|
+
}
|
|
147
|
+
export type QaFailureHandoffState = "prepared" | "delivery-intended" | "delivery-uncertain" | "response-invalid" | "builder-blocked" | "remediation-reported" | "recheck-required" | "source-drift";
|
|
148
|
+
export interface QaFailureHandoffRecord {
|
|
149
|
+
handoffId: string;
|
|
150
|
+
operationId: string;
|
|
151
|
+
runId: string;
|
|
152
|
+
ticketId: string;
|
|
153
|
+
reviewAttemptId: string;
|
|
154
|
+
reportDigest: string;
|
|
155
|
+
generation: number;
|
|
156
|
+
reviewedContentDigest: string;
|
|
157
|
+
reviewBasisDigest: string;
|
|
158
|
+
state: QaFailureHandoffState;
|
|
159
|
+
handoffDigest: string;
|
|
160
|
+
hostInstructionDigest: string;
|
|
161
|
+
builderSession?: ProviderSessionRefV1;
|
|
162
|
+
providerTurnId?: string;
|
|
163
|
+
receiptDigest?: string;
|
|
164
|
+
responseDigest?: string;
|
|
165
|
+
parsedResponseDigest?: string;
|
|
166
|
+
postSourceDigest?: string;
|
|
167
|
+
detail?: string;
|
|
168
|
+
createdAt: string;
|
|
169
|
+
updatedAt: string;
|
|
170
|
+
}
|
|
171
|
+
export interface QaTransitionRecordV2 {
|
|
172
|
+
sequence: number;
|
|
173
|
+
runId: string;
|
|
174
|
+
ticketId: string;
|
|
175
|
+
fromRevision: number;
|
|
176
|
+
toRevision: number;
|
|
177
|
+
event: QaReducerEventV2;
|
|
178
|
+
state: QaReducerStateV2;
|
|
179
|
+
createdAt: string;
|
|
180
|
+
}
|
|
181
|
+
export interface QaReportRecordV2 {
|
|
182
|
+
reportDigest: string;
|
|
183
|
+
runId: string;
|
|
184
|
+
ticketId: string;
|
|
185
|
+
reviewNumber: number;
|
|
186
|
+
sourceStateDigest: string;
|
|
187
|
+
reviewBasisDigest: string;
|
|
188
|
+
disposition: QaReportDisposition;
|
|
189
|
+
report: unknown;
|
|
190
|
+
createdAt: string;
|
|
191
|
+
updatedAt: string;
|
|
192
|
+
}
|
|
77
193
|
/** Authoritative persistence for every resumable workflow in a project. */
|
|
78
194
|
export declare class WorkflowDb {
|
|
79
195
|
readonly projectDir: string;
|
|
@@ -185,8 +301,135 @@ export declare class WorkflowDb {
|
|
|
185
301
|
operations(runId: string): OperationRecord[];
|
|
186
302
|
putEvidence(kind: "handoff" | "diff" | "test" | "qa", value: string | Buffer, now?: Date): string;
|
|
187
303
|
getEvidence(digest: string): Buffer | undefined;
|
|
304
|
+
putQaRecoveryHead(input: Omit<QaRecoveryHeadRecord, "updatedAt">, now?: Date): QaRecoveryHeadRecord;
|
|
305
|
+
qaRecoveryHead(runId: string, ticketId?: string): QaRecoveryHeadRecord | undefined;
|
|
306
|
+
pendingQaRecoveryHeads(runId: string): QaRecoveryHeadRecord[];
|
|
307
|
+
beginQaReviewAttempt(input: Omit<QaReviewAttemptRecord, "status" | "createdAt" | "updatedAt">, now?: Date): QaReviewAttemptRecord;
|
|
308
|
+
finishQaReviewAttempt(attemptId: string, patch: Pick<QaReviewAttemptRecord, "status"> & Partial<Pick<QaReviewAttemptRecord, "reportDigest" | "findingIds" | "namespacedFindingIds" | "detail">>, now?: Date): QaReviewAttemptRecord;
|
|
309
|
+
qaReviewAttempts(runId: string, ticketId: string): QaReviewAttemptRecord[];
|
|
310
|
+
qaReviewAttempt(attemptId: string): QaReviewAttemptRecord | undefined;
|
|
311
|
+
beginQaRemediationAttempt(input: Omit<QaRemediationAttemptRecord, "status" | "createdAt" | "updatedAt">, now?: Date): QaRemediationAttemptRecord;
|
|
312
|
+
commitQaRemediationIntent(expectedRevision: number, recovery: RecoveryAttemptReceipt, remediation: Omit<QaRemediationAttemptRecord, "status" | "createdAt" | "updatedAt">, now?: Date): QaReducerStateV2;
|
|
313
|
+
updateQaRemediationAttempt(attemptId: string, status: QaRemediationAttemptRecord["status"], patch?: Partial<Pick<QaRemediationAttemptRecord, "responseDigest" | "summaryDigest" | "detail">>, now?: Date): QaRemediationAttemptRecord;
|
|
314
|
+
qaRemediationAttempts(runId: string, ticketId: string): QaRemediationAttemptRecord[];
|
|
315
|
+
qaRemediationAttempt(attemptId: string): QaRemediationAttemptRecord | undefined;
|
|
316
|
+
recordQaFailureHandoffPrepared(input: {
|
|
317
|
+
handoffId: string;
|
|
318
|
+
operationId: string;
|
|
319
|
+
runId: string;
|
|
320
|
+
ticketId: string;
|
|
321
|
+
reviewAttemptId: string;
|
|
322
|
+
reportDigest: string;
|
|
323
|
+
generation: number;
|
|
324
|
+
reviewedContentDigest: string;
|
|
325
|
+
reviewBasisDigest: string;
|
|
326
|
+
handoffDigest: string;
|
|
327
|
+
hostInstructionDigest: string;
|
|
328
|
+
}, now?: Date): QaFailureHandoffRecord;
|
|
329
|
+
markQaFailureHandoffDeliveryIntended(handoffId: string, builderSession: ProviderSessionRefV1, now?: Date): QaFailureHandoffRecord;
|
|
330
|
+
transitionQaFailureHandoff(handoffId: string, state: QaFailureHandoffState, patch?: Partial<Pick<QaFailureHandoffRecord, "builderSession" | "providerTurnId" | "receiptDigest" | "responseDigest" | "parsedResponseDigest" | "postSourceDigest" | "detail">>, now?: Date): QaFailureHandoffRecord;
|
|
331
|
+
qaFailureHandoff(handoffId: string): QaFailureHandoffRecord | undefined;
|
|
332
|
+
qaFailureHandoffs(runId: string, ticketId: string): QaFailureHandoffRecord[];
|
|
333
|
+
qaTicketHead(runId: string, ticketId: string): QaReducerStateV2;
|
|
334
|
+
pendingQaTicketHeads(runId: string): QaReducerStateV2[];
|
|
335
|
+
/** Compare-and-swap the authoritative QA reducer head and append its event atomically. */
|
|
336
|
+
transitionQa(runId: string, ticketId: string, expectedRevision: number, event: QaReducerEventV2, now?: Date): QaReducerStateV2;
|
|
337
|
+
qaTransitions(runId: string, ticketId: string): QaTransitionRecordV2[];
|
|
338
|
+
assertQaRunFinalizable(runId: string): void;
|
|
339
|
+
putQaSourceState(state: FrozenQaSourceStateV2): void;
|
|
340
|
+
putQaReviewBasis(runId: string, ticketId: string, basis: QaReviewBasisV2, now?: Date): void;
|
|
341
|
+
commitQaReviewReady(source: FrozenQaSourceStateV2, basis: QaReviewBasisV2, session: ProviderSessionRefV1, confinement: {
|
|
342
|
+
digest: string;
|
|
343
|
+
}, attempt: {
|
|
344
|
+
attemptId: string;
|
|
345
|
+
cycle: number;
|
|
346
|
+
remediationGeneration: number;
|
|
347
|
+
}, expectedRevision: number, now?: Date): QaReducerStateV2;
|
|
348
|
+
recordQaHandoffReceipt(receipt: HandoffAcceptanceReceiptV2): void;
|
|
349
|
+
qaHandoffReceipt(operationId: string): HandoffAcceptanceReceiptV2 | undefined;
|
|
350
|
+
beginQaTurn(intent: QaTurnIntentV2): void;
|
|
351
|
+
commitQaTurnIntent(intent: QaTurnIntentV2, expectedRevision: number): QaReducerStateV2;
|
|
352
|
+
finishQaTurn(receipt: QaTurnReceiptV2): void;
|
|
353
|
+
recordQaReport(input: Omit<QaReportRecordV2, "disposition" | "createdAt" | "updatedAt">, findingIds: string[], now?: Date): QaReportRecordV2;
|
|
354
|
+
commitQaFailure(input: Omit<QaReportRecordV2, "disposition" | "createdAt" | "updatedAt">, findingIds: string[], expectedRevision: number, now?: Date): QaReducerStateV2;
|
|
355
|
+
/** Accept a failed verdict, its exact attempt outcome, report, findings, and reducer edge atomically. */
|
|
356
|
+
commitQaFailureAttempt(attemptId: string, input: Omit<QaReportRecordV2, "disposition" | "createdAt" | "updatedAt">, rawFindingIds: string[], namespacedFindingIds: string[], detail: string, expectedRevision: number, now?: Date): QaReducerStateV2;
|
|
357
|
+
qaReportChains(reportDigest: string): Array<{
|
|
358
|
+
predecessorReportDigest: string;
|
|
359
|
+
successorReportDigest: string;
|
|
360
|
+
relation: string;
|
|
361
|
+
createdAt: string;
|
|
362
|
+
}>;
|
|
363
|
+
qaReport(reportDigest: string): QaReportRecordV2 | undefined;
|
|
364
|
+
unresolvedQaReports(runId: string, ticketId: string): QaReportRecordV2[];
|
|
365
|
+
setQaReportDisposition(reportDigest: string, disposition: QaReportDisposition, reason: string, now?: Date): void;
|
|
366
|
+
markQaReportsRecheckRequired(runId: string, ticketId: string, reason: string, now?: Date): void;
|
|
367
|
+
resolveQaReportsAfterPass(runId: string, ticketId: string, now?: Date): void;
|
|
368
|
+
commitQaWaiver(runId: string, ticketId: string, expectedRevision: number, reason: string, now?: Date): QaReducerStateV2;
|
|
369
|
+
recordBuilderRemediationReceipt(receipt: BuilderRemediationReceiptV2): void;
|
|
370
|
+
commitBuilderRemediationSuccess(receipt: BuilderRemediationReceiptV2, expectedRevision: number, now?: Date): QaReducerStateV2;
|
|
371
|
+
commitQaRemediationOutcome(input: {
|
|
372
|
+
recoveryAttemptId: string;
|
|
373
|
+
remediationAttemptId: string;
|
|
374
|
+
outcome: "succeeded" | "failed" | "uncertain";
|
|
375
|
+
detail?: string;
|
|
376
|
+
responseDigest?: string;
|
|
377
|
+
summaryDigest?: string;
|
|
378
|
+
receipt?: BuilderRemediationReceiptV2;
|
|
379
|
+
expectedRevision: number;
|
|
380
|
+
}, now?: Date): QaReducerStateV2;
|
|
381
|
+
issueQaPassCertificate(input: Omit<QaPassCertificateV2, "version" | "certificateId" | "unresolvedReportCount" | "issuedAt">, now?: Date): QaPassCertificateV2;
|
|
382
|
+
commitQaPass(input: Omit<QaPassCertificateV2, "version" | "certificateId" | "unresolvedReportCount" | "issuedAt">, expectedRevision: number, now?: Date): QaPassCertificateV2;
|
|
383
|
+
/** Accept a passing verdict, its review-attempt outcome, report resolution, certificate, and reducer edge atomically. */
|
|
384
|
+
commitQaPassAttempt(attemptId: string, input: Omit<QaPassCertificateV2, "version" | "certificateId" | "unresolvedReportCount" | "issuedAt">, detail: string, expectedRevision: number, now?: Date): QaPassCertificateV2;
|
|
385
|
+
consumeQaPassCertificate(runId: string, ticketId: string, certificateId: string, consumer: string, now?: Date): QaPassCertificateV2;
|
|
386
|
+
invalidateUnconsumedQaPassCertificates(runId: string, ticketId: string, reason: string, now?: Date): void;
|
|
387
|
+
invalidateQaPassBeforeFinalization(input: {
|
|
388
|
+
runId: string;
|
|
389
|
+
ticketId: string;
|
|
390
|
+
certificateId: string;
|
|
391
|
+
expectedSourceStateDigest: string;
|
|
392
|
+
expectedRevision: number;
|
|
393
|
+
reason: string;
|
|
394
|
+
}, now?: Date): QaReducerStateV2;
|
|
395
|
+
beginQaFinalization(input: {
|
|
396
|
+
runId: string;
|
|
397
|
+
ticketId: string;
|
|
398
|
+
certificateId: string;
|
|
399
|
+
consumer: string;
|
|
400
|
+
expectedSourceStateDigest: string;
|
|
401
|
+
expectedGitTree: string;
|
|
402
|
+
allowedProjectionPaths: string[];
|
|
403
|
+
expectedRevision: number;
|
|
404
|
+
operationId: string;
|
|
405
|
+
}, now?: Date): QaReducerStateV2;
|
|
406
|
+
planQaFinalizationStep(input: {
|
|
407
|
+
operationId: string;
|
|
408
|
+
runId: string;
|
|
409
|
+
ticketId: string;
|
|
410
|
+
certificateId: string;
|
|
411
|
+
kind: string;
|
|
412
|
+
intent: unknown;
|
|
413
|
+
}, now?: Date): void;
|
|
414
|
+
finishQaFinalizationStep(operationId: string, receipt: unknown, now?: Date): void;
|
|
415
|
+
finishPendingQaFinalizationSteps(runId: string, ticketId: string, receipt: unknown, now?: Date): void;
|
|
416
|
+
qaFinalizationSteps(runId: string, ticketId: string): QaFinalizationStepRecord[];
|
|
417
|
+
invalidateQaFinalization(runId: string, ticketId: string, expectedRevision: number, reason: string, branch?: string, now?: Date): QaReducerStateV2;
|
|
418
|
+
completeQaFinalization(runId: string, ticketId: string, expectedRevision: number, receipt: unknown, now?: Date): QaReducerStateV2;
|
|
419
|
+
planQaPacketProjection(input: {
|
|
420
|
+
runId: string;
|
|
421
|
+
ticketId: string;
|
|
422
|
+
qaRevision: number;
|
|
423
|
+
packetDigest: string;
|
|
424
|
+
path: string;
|
|
425
|
+
manifestJson: string;
|
|
426
|
+
}, now?: Date): void;
|
|
427
|
+
finishQaPacketProjection(runId: string, ticketId: string, packetDigest: string): void;
|
|
428
|
+
qaPacketProjection(packetDigest: string): QaPacketProjectionRecord | undefined;
|
|
429
|
+
qaPacketProjectionsAtPath(path: string): QaPacketProjectionRecord[];
|
|
430
|
+
pendingQaPacketProjections(runId: string): QaPacketProjectionRecord[];
|
|
188
431
|
stageHandoff(manifest: HandoffManifestV1, markdown: string): HandoffLineage;
|
|
189
|
-
acceptHandoff(runId: string, generation: number, successor: string | ProviderSessionRefV1, now?: Date): HandoffLineage;
|
|
432
|
+
acceptHandoff(runId: string, generation: number, successor: string | ProviderSessionRefV1, now?: Date, receipt?: HandoffAcceptanceReceiptV1): HandoffLineage;
|
|
190
433
|
/** Fence the initial role owner without overwriting a lease already moved by a handoff. */
|
|
191
434
|
claimInitialRoleLease(runId: string, role: "builder" | "qa", providerSession: string | ProviderSessionRefV1, now?: Date): RoleMutationLease;
|
|
192
435
|
roleMutationLease(runId: string, role: "builder" | "qa"): RoleMutationLease | undefined;
|