ai-foreman 1.7.19 → 1.7.21

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 (205) hide show
  1. package/README.md +29 -5
  2. package/dist/activity.d.ts +3 -0
  3. package/dist/activity.js +18 -6
  4. package/dist/adapters/claude.d.ts +16 -0
  5. package/dist/adapters/claude.js +28 -3
  6. package/dist/adapters/codex.d.ts +20 -0
  7. package/dist/adapters/codex.js +99 -5
  8. package/dist/adapters/recovering.d.ts +9 -0
  9. package/dist/adapters/recovering.js +10 -0
  10. package/dist/adapters/types.d.ts +15 -0
  11. package/dist/agentRun.d.ts +7 -0
  12. package/dist/agentRun.js +24 -13
  13. package/dist/branch/currentGuard.d.ts +1 -0
  14. package/dist/branch/currentGuard.js +1 -0
  15. package/dist/branch/finalization.js +6 -1
  16. package/dist/branch/git.d.ts +1 -0
  17. package/dist/branch/git.js +15 -1
  18. package/dist/branch/runner.d.ts +2 -0
  19. package/dist/branch/runner.js +92 -5
  20. package/dist/buildAdmission.d.ts +61 -0
  21. package/dist/buildAdmission.js +286 -0
  22. package/dist/buildApproval.d.ts +2 -0
  23. package/dist/buildApproval.js +17 -0
  24. package/dist/buildAssignment.d.ts +33 -0
  25. package/dist/buildAssignment.js +215 -0
  26. package/dist/buildInterventions.d.ts +90 -0
  27. package/dist/buildInterventions.js +334 -0
  28. package/dist/buildLaunchGate.d.ts +1 -0
  29. package/dist/buildLaunchGate.js +36 -0
  30. package/dist/buildOwnershipReconciliation.d.ts +19 -0
  31. package/dist/buildOwnershipReconciliation.js +41 -0
  32. package/dist/buildOwnershipRepair.d.ts +33 -0
  33. package/dist/buildOwnershipRepair.js +111 -0
  34. package/dist/buildRuns.d.ts +24 -1
  35. package/dist/buildRuns.js +216 -70
  36. package/dist/buildSyntheticWork.d.ts +2 -0
  37. package/dist/buildSyntheticWork.js +30 -0
  38. package/dist/buildWorkAdmission.d.ts +17 -0
  39. package/dist/buildWorkAdmission.js +57 -0
  40. package/dist/buildWorkAuthorization.d.ts +2 -0
  41. package/dist/buildWorkAuthorization.js +23 -0
  42. package/dist/buildWorkContext.d.ts +3 -0
  43. package/dist/buildWorkContext.js +6 -0
  44. package/dist/buildWorkMigration.d.ts +9 -0
  45. package/dist/buildWorkMigration.js +206 -0
  46. package/dist/buildWorkReconciliation.d.ts +12 -0
  47. package/dist/buildWorkReconciliation.js +70 -0
  48. package/dist/builderGuidanceFollowup.d.ts +15 -0
  49. package/dist/builderGuidanceFollowup.js +34 -0
  50. package/dist/cli/doctor.js +3 -2
  51. package/dist/cli/graph.d.ts +2 -0
  52. package/dist/cli/graph.js +75 -0
  53. package/dist/cli/manager.d.ts +8 -0
  54. package/dist/cli/manager.js +234 -12
  55. package/dist/cli/recovery.js +3 -2
  56. package/dist/cli/runtimeAuthPrompt.d.ts +5 -0
  57. package/dist/cli/runtimeAuthPrompt.js +41 -7
  58. package/dist/cli/start.d.ts +8 -0
  59. package/dist/cli/start.js +2091 -1849
  60. package/dist/cli/status.js +20 -5
  61. package/dist/cli/tickets.js +9 -7
  62. package/dist/continuity.d.ts +16 -1
  63. package/dist/continuity.js +68 -12
  64. package/dist/foreman.d.ts +12 -4
  65. package/dist/foreman.js +397 -60
  66. package/dist/graph/boundary.d.ts +15 -0
  67. package/dist/graph/boundary.js +50 -0
  68. package/dist/graph/bridge.d.ts +9 -0
  69. package/dist/graph/bridge.js +146 -0
  70. package/dist/graph/bridge.py +205 -0
  71. package/dist/graph/config.d.ts +11 -0
  72. package/dist/graph/config.js +40 -0
  73. package/dist/graph/corpus.d.ts +16 -0
  74. package/dist/graph/corpus.js +188 -0
  75. package/dist/graph/derived.d.ts +17 -0
  76. package/dist/graph/derived.js +73 -0
  77. package/dist/graph/host.d.ts +4 -0
  78. package/dist/graph/host.js +160 -0
  79. package/dist/graph/install.d.ts +3 -0
  80. package/dist/graph/install.js +50 -0
  81. package/dist/graph/lifecycle.d.ts +11 -0
  82. package/dist/graph/lifecycle.js +124 -0
  83. package/dist/graph/maintenance.d.ts +43 -0
  84. package/dist/graph/maintenance.js +301 -0
  85. package/dist/graph/manager.d.ts +9 -0
  86. package/dist/graph/manager.js +92 -0
  87. package/dist/graph/preparation.d.ts +41 -0
  88. package/dist/graph/preparation.js +43 -0
  89. package/dist/graph/read.d.ts +27 -0
  90. package/dist/graph/read.js +152 -0
  91. package/dist/graph/semantic.d.ts +17 -0
  92. package/dist/graph/semantic.js +27 -0
  93. package/dist/graph/session.d.ts +8 -0
  94. package/dist/graph/session.js +92 -0
  95. package/dist/graph/sources.d.ts +4 -0
  96. package/dist/graph/sources.js +11 -0
  97. package/dist/graph/storage.d.ts +38 -0
  98. package/dist/graph/storage.js +159 -0
  99. package/dist/graph/turn.d.ts +17 -0
  100. package/dist/graph/turn.js +360 -0
  101. package/dist/graph/util.d.ts +5 -0
  102. package/dist/graph/util.js +51 -0
  103. package/dist/handoffs.d.ts +1 -0
  104. package/dist/handoffs.js +5 -1
  105. package/dist/humanDecision.d.ts +21 -2
  106. package/dist/humanDecision.js +169 -10
  107. package/dist/index.js +4 -1
  108. package/dist/installOwnership.d.ts +46 -0
  109. package/dist/installOwnership.js +440 -0
  110. package/dist/linuxProbeInventory.d.ts +12 -0
  111. package/dist/linuxProbeInventory.js +48 -0
  112. package/dist/log.d.ts +1 -1
  113. package/dist/log.js +7 -1
  114. package/dist/managerEvidence.d.ts +25 -0
  115. package/dist/managerEvidence.js +326 -0
  116. package/dist/managerEvidenceArtifacts.d.ts +38 -0
  117. package/dist/managerEvidenceArtifacts.js +118 -0
  118. package/dist/managerPacket.d.ts +2 -0
  119. package/dist/managerPacket.js +23 -0
  120. package/dist/markers.d.ts +1 -1
  121. package/dist/markers.js +2 -2
  122. package/dist/observability.js +1 -1
  123. package/dist/processIdentity.d.ts +21 -1
  124. package/dist/processIdentity.js +87 -5
  125. package/dist/providerPhase.d.ts +13 -0
  126. package/dist/providerPhase.js +26 -0
  127. package/dist/qaAuthorizedDisposition.d.ts +24 -0
  128. package/dist/qaAuthorizedDisposition.js +26 -0
  129. package/dist/qaBuildGate.d.ts +4 -0
  130. package/dist/qaBuildGate.js +216 -0
  131. package/dist/qaBuilderCoverage.d.ts +5 -0
  132. package/dist/qaBuilderCoverage.js +78 -0
  133. package/dist/qaContractCoverage.d.ts +10 -0
  134. package/dist/qaContractCoverage.js +55 -0
  135. package/dist/qaContractDelivery.d.ts +23 -0
  136. package/dist/qaContractDelivery.js +145 -0
  137. package/dist/qaContractFreshness.d.ts +15 -0
  138. package/dist/qaContractFreshness.js +36 -0
  139. package/dist/qaDeliveryJournal.d.ts +10 -0
  140. package/dist/qaDeliveryJournal.js +16 -1
  141. package/dist/qaEffectiveConfig.d.ts +20 -0
  142. package/dist/qaEffectiveConfig.js +40 -0
  143. package/dist/qaEvidenceReader.d.ts +14 -0
  144. package/dist/qaEvidenceReader.js +176 -0
  145. package/dist/qaFailureDelivery.d.ts +2 -0
  146. package/dist/qaFailureDelivery.js +107 -10
  147. package/dist/qaHandbackMigration.d.ts +1 -1
  148. package/dist/qaHandbackMigration.js +3 -3
  149. package/dist/qaPreparation.d.ts +26 -0
  150. package/dist/qaPreparation.js +150 -0
  151. package/dist/qaPreparationInputs.d.ts +8 -0
  152. package/dist/qaPreparationInputs.js +47 -0
  153. package/dist/qaPreparationMetrics.d.ts +145 -0
  154. package/dist/qaPreparationMetrics.js +120 -0
  155. package/dist/qaPreparationPolicy.d.ts +5 -0
  156. package/dist/qaPreparationPolicy.js +51 -0
  157. package/dist/qaPreparationStore.d.ts +157 -0
  158. package/dist/qaPreparationStore.js +412 -0
  159. package/dist/qaProtocolV2.d.ts +28 -0
  160. package/dist/qaProtocolV2.js +12 -0
  161. package/dist/qaReview.d.ts +6 -0
  162. package/dist/qaReview.js +293 -41
  163. package/dist/qaTimeline.d.ts +18 -0
  164. package/dist/qaTimeline.js +123 -0
  165. package/dist/qaVerificationContract.d.ts +17 -0
  166. package/dist/qaVerificationContract.js +236 -0
  167. package/dist/readinessCleanup.d.ts +19 -0
  168. package/dist/readinessCleanup.js +122 -0
  169. package/dist/readinessGate.d.ts +1 -0
  170. package/dist/readinessGate.js +82 -0
  171. package/dist/recoveryGuidance.d.ts +17 -0
  172. package/dist/recoveryGuidance.js +38 -0
  173. package/dist/runtimeAuth.d.ts +1 -0
  174. package/dist/runtimeAuth.js +5 -1
  175. package/dist/runtimeReadiness.d.ts +13 -0
  176. package/dist/runtimeReadiness.js +206 -10
  177. package/dist/sessionIdentity.d.ts +2 -0
  178. package/dist/sessionIdentity.js +14 -0
  179. package/dist/sessionLifecycle.js +3 -3
  180. package/dist/sources/sourceRegistry.js +7 -0
  181. package/dist/stateTransfer.js +85 -8
  182. package/dist/statusReporter.d.ts +1 -0
  183. package/dist/statusReporter.js +1 -0
  184. package/dist/supervisedStart.d.ts +6 -0
  185. package/dist/supervisedStart.js +178 -62
  186. package/dist/supervisor.d.ts +2 -0
  187. package/dist/supervisor.js +26 -2
  188. package/dist/terminalStyle.d.ts +21 -0
  189. package/dist/terminalStyle.js +50 -0
  190. package/dist/ticketPopulation.d.ts +1 -0
  191. package/dist/ticketPopulation.js +5 -1
  192. package/dist/tickets/commands.js +2 -2
  193. package/dist/tickets/queue.js +1 -1
  194. package/dist/tickets/ticketSchema.d.ts +198 -0
  195. package/dist/tickets/ticketSchema.js +2 -0
  196. package/dist/windowsProbeJob.d.ts +12 -0
  197. package/dist/windowsProbeJob.js +144 -0
  198. package/dist/workflowDb.d.ts +121 -6
  199. package/dist/workflowDb.js +874 -30
  200. package/dist/workflowReader.d.ts +116 -2
  201. package/dist/workflowReader.js +131 -4
  202. package/package.json +89 -8
  203. package/scripts/copy-graph-assets.mjs +3 -0
  204. package/scripts/graph-benchmark.mjs +20 -0
  205. package/scripts/graph-evaluation.mjs +85 -0
@@ -0,0 +1,111 @@
1
+ import { WorkflowDb } from "./workflowDb.js";
2
+ import { WorkflowReader } from "./workflowReader.js";
3
+ import { readQaEvidenceSnapshot, evidenceRecord } from "./qaEvidenceReader.js";
4
+ import { assessBuildOwnership, ownershipRevision } from "./buildOwnershipReconciliation.js";
5
+ import { captureBuildSource } from "./buildAssignment.js";
6
+ import { buildScopeRevision } from "./buildApproval.js";
7
+ import { loadTicketsConfig, resolveTicketPaths } from "./tickets/config.js";
8
+ import { loadTickets } from "./tickets/ticketLoader.js";
9
+ import { bindBuildAuthority, checkpointBuildRun } from "./buildRuns.js";
10
+ import { classifyProcess } from "./processIdentity.js";
11
+ import { validateOwnershipRepair } from "./buildWorkReconciliation.js";
12
+ export function prepareOwnershipRepair(projectDir, runId, workId) {
13
+ const snapshot = readQaEvidenceSnapshot(projectDir, runId);
14
+ if (snapshot.availability === "corrupt" || snapshot.availability === "unreadable" || snapshot.availability === "missing")
15
+ throw new Error("Ownership evidence must be readable and intact before repair");
16
+ const assignment = (snapshot.rows.operation_journal ?? []).filter(row => row.kind === "build-assignment" && evidenceRecord(row, "intent_json")?.ticketId === workId).sort((a, b) => String(a.created_at).localeCompare(String(b.created_at)) || String(a.idempotency_key).localeCompare(String(b.idempotency_key))).at(-1);
17
+ const intent = assignment ? evidenceRecord(assignment, "intent_json") : undefined;
18
+ const worktree = typeof intent?.worktree === "string" ? intent.worktree : projectDir;
19
+ const source = captureBuildSource(worktree);
20
+ const before = intent?.before;
21
+ const requiredPaths = [...new Set([...source.pathInventory.map(path => path.path), ...(before?.pathInventory ?? []).map(path => path.path)])].sort();
22
+ return { runId, workId, expectedRevision: ownershipRevision(snapshot), inspectedSourceDigest: source.digest, scopeRevision: buildScopeRevision(projectDir), requiredPaths, worktree, sourceInventory: source.pathInventory, ownership: assessBuildOwnership(projectDir, runId, snapshot), sourceMutationAuthorized: false, choices: ["link_provenance", "authorize_mapped_work", "quarantine"] };
23
+ }
24
+ export function repairOwnership(projectDir, value, userTurn, faults) {
25
+ validateOwnershipRepair(value);
26
+ const request = value;
27
+ if (!userTurn.trim().startsWith("/qa-repair ") || JSON.stringify(JSON.parse(userTurn.trim().slice("/qa-repair ".length))) !== JSON.stringify(request))
28
+ throw new Error("Repair requires the original explicit host request");
29
+ const reader = new WorkflowReader(projectDir);
30
+ try {
31
+ const lease = reader.currentLease();
32
+ const admission = reader.buildAdmission();
33
+ if (lease && classifyProcess(lease.pid, lease.processStart, lease.host).state !== "dead" || admission && classifyProcess(admission.pid, admission.processStart, admission.host).state !== "dead")
34
+ throw new Error("Stop and verify the build owner before repairing ownership");
35
+ }
36
+ finally {
37
+ reader.close();
38
+ }
39
+ const db = new WorkflowDb(projectDir);
40
+ let authority;
41
+ let lease;
42
+ try {
43
+ authority = db.acquireBuildRecoveryAdmission(request.runId);
44
+ lease = db.acquireLease(request.runId);
45
+ const prior = db.reconciliation(request.requestId);
46
+ const plan = prepareOwnershipRepair(projectDir, request.runId, request.workId);
47
+ if (request.scopeRevision !== plan.scopeRevision)
48
+ throw new Error("Requirements changed after the repair was prepared; inspect and approve current scope");
49
+ if (prior && prior.sourceDigest !== plan.inspectedSourceDigest)
50
+ throw new Error("Inspected source changed after the committed repair; prepare a new reconciliation before publication");
51
+ const definition = loadTickets(resolveTicketPaths(loadTicketsConfig(projectDir), projectDir).tickets).find(ticket => ticket.id === request.workId);
52
+ if (!definition && request.choice !== "quarantine")
53
+ throw new Error("Approved target ticket definition is unavailable; preserve quarantine until scope is resolved");
54
+ const receipt = db.atomic(() => {
55
+ faults?.afterDecision?.();
56
+ const receipt = db.reconcileWork(request, { revision: plan.expectedRevision, sourceDigest: plan.inspectedSourceDigest, definition, requiredPaths: plan.requiredPaths, userTurn });
57
+ faults?.afterMembership?.();
58
+ if (prior && !prior.executionDisposition && request.choice !== "quarantine" && !["completed", "waived"].includes(db.qaTicketHead(request.runId, request.workId).state)) {
59
+ // Compatibility for old receipts: retire only certificates predating
60
+ // this repair, never a fresh review issued after its committed outcome.
61
+ db.invalidateUnconsumedQaPassCertificates(request.runId, request.workId, "ownership-repair", new Date(), String(prior.createdAt));
62
+ }
63
+ if (!prior && request.choice !== "quarantine") {
64
+ const head = db.qaTicketHead(request.runId, request.workId);
65
+ if (!["completed", "waived"].includes(head.state))
66
+ db.invalidateUnconsumedQaPassCertificates(request.runId, request.workId, "ownership-repair");
67
+ if (!["idle", "operator-menu", "completed", "waived"].includes(head.state)) {
68
+ if (head.state === "passed")
69
+ db.transitionQa(request.runId, request.workId, head.revision, { type: "pass-invalidated", reason: "Ownership repair requires fresh QA on inspected source" });
70
+ else if (!["finalizing", "remediation-intended"].includes(head.state))
71
+ db.transitionQa(request.runId, request.workId, head.revision, { type: "operator-menu" });
72
+ else
73
+ throw new Error("Reconcile pending finalization/remediation before ownership repair");
74
+ }
75
+ const packet = db.qaRecoveryHead(request.runId, request.workId);
76
+ if (packet && packet.pendingAction !== "resolved")
77
+ db.putQaRecoveryHead({ ...packet, pendingAction: "resolved" });
78
+ if (!prior)
79
+ db.transition(request.runId, { checkpoint: "ownership-reconciled", event: "build_ownership_reconciled", payload: { ...receipt, retainedHistoricalPacket: packet } });
80
+ }
81
+ return receipt;
82
+ });
83
+ faults?.afterLocalCommit?.();
84
+ if (request.choice !== "quarantine") {
85
+ // Publication remains journaled separately; an interrupted publication can be repeated.
86
+ const state = db.getRun(request.runId)?.state;
87
+ if (state?.version !== undefined)
88
+ checkpointBuildRun(projectDir, bindBuildAuthority(state, lease), "ownership-reconciled");
89
+ }
90
+ faults?.afterPublication?.();
91
+ // Older immutable receipts used requiresFreshQa for every non-quarantine
92
+ // repair. Clarify execution eligibility without rewriting that history.
93
+ const head = db.qaTicketHead(request.runId, request.workId);
94
+ return receipt.executionDisposition ? receipt : { ...receipt, executionDisposition: request.choice === "quarantine" ? "quarantined" : head.state === "completed" ? "terminal_metadata_repaired" : head.state === "waived" ? "existing_waiver_policy" : "fresh_qa_required", requiresFreshQa: request.choice !== "quarantine" && !["completed", "waived"].includes(head.state), executionReopened: false };
95
+ }
96
+ finally {
97
+ try {
98
+ if (lease)
99
+ db.releaseLease(lease);
100
+ }
101
+ finally {
102
+ try {
103
+ if (authority)
104
+ db.releaseBuildAdmission(authority);
105
+ }
106
+ finally {
107
+ db.close();
108
+ }
109
+ }
110
+ }
111
+ }
@@ -1,12 +1,17 @@
1
+ export { withBuildInvocation as withBuildRecoveryInvocation, launchDigest as launchArgumentDigest } from "./buildAdmission.js";
1
2
  import type { AutonomyProfile, BuildRunRecordV2, ProviderSessionRefV1, ResolvedAgentSettings, ResolvedAutonomyPolicy, SessionAvailabilityV1 } from "rafi-spec";
3
+ import { type ProjectLease } from "./workflowDb.js";
2
4
  import { type ResolveSessionAvailabilityOptions } from "./sessionAvailability.js";
3
5
  export declare const BUILD_RUN_VERSION = 3;
4
6
  export declare const BUILD_RUN_DIRECTORY = ".foreman/runs";
5
7
  export declare const BUILD_HEARTBEAT_MS = 10000;
6
8
  export declare const BUILD_LEASE_STALE_MS = 45000;
9
+ export declare function bindBuildAuthority(run: BuildRunRecordV2, lease: ProjectLease): BuildRunRecordV2;
7
10
  export interface CreateBuildRunInput {
8
11
  runId?: string;
9
12
  tickets: string[];
13
+ authorizedBatch?: BuildRunRecordV2["authorizedBatch"];
14
+ builderCapabilities?: BuildRunRecordV2["builderCapabilities"];
10
15
  deliveryUnit?: string;
11
16
  branchMode?: BuildRunRecordV2["branchMode"];
12
17
  repositoryRoot: string;
@@ -44,10 +49,19 @@ export declare function recordBuildReceipt(projectDir: string, run: BuildRunReco
44
49
  export declare function heartbeatBuildRun(projectDir: string, run: BuildRunRecordV2, now?: Date): BuildRunRecordV2;
45
50
  export declare function releaseBuildLease(projectDir: string, run: BuildRunRecordV2, status?: BuildRunRecordV2["status"]): BuildRunRecordV2;
46
51
  export declare function completeBuildRun(projectDir: string, run: BuildRunRecordV2, now?: Date): BuildRunRecordV2;
52
+ /** A recovered ticket boundary is complete only when the saved run scope is done. */
53
+ export declare function finishRecoveredTicketScope(projectDir: string, run: BuildRunRecordV2, checkpoint: string): BuildRunRecordV2;
47
54
  export declare function readBuildRuns(projectDir: string): BuildRunRecordV2[];
48
55
  export declare function recoverableBuildRuns(projectDir: string, now?: Date): Array<BuildRunRecordV2 & {
49
56
  active: boolean;
57
+ ownership: "live" | "dead" | "unknown";
58
+ ownershipReason: string;
59
+ cleanupOnly?: boolean;
50
60
  }>;
61
+ /**
62
+ * Timestamp correlations are diagnostic hints, never executable membership.
63
+ */
64
+ export declare function legacyTrackerWorkHints(projectDir: string, run: BuildRunRecordV2): string[];
51
65
  export declare function isLeaseActive(run: BuildRunRecordV2, now?: Date): boolean;
52
66
  export declare function buildRecoveryPreview(run: BuildRunRecordV2): string[];
53
67
  export interface BuildRecoveryProjection {
@@ -74,7 +88,16 @@ export interface BuildRecoveryProjection {
74
88
  sessionCandidateRef?: ProviderSessionRefV1;
75
89
  sessionAvailability?: SessionAvailabilityV1;
76
90
  }
91
+ /** Saved context may be broader than the work authorized for this invocation. */
92
+ export declare function recoveryExecutionTickets(run: BuildRunRecordV2, requested: readonly string[], frozen: boolean): string[];
93
+ /** Read-only reconciliation also handles crashes before the last progress checkpoint. */
94
+ export declare function currentBranchTicketProgress(projectDir: string, run: BuildRunRecordV2): {
95
+ completed: string[];
96
+ remaining: string[];
97
+ pendingQa: string[];
98
+ } | undefined;
99
+ /** Match the frozen preview at both the resume wrapper and direct start boundary. */
100
+ export declare function currentBranchRecoveryTicket(projectDir: string, run: BuildRunRecordV2): string | undefined;
77
101
  export declare function projectBuildRecovery(projectDir: string, run: BuildRunRecordV2, now?: Date, ticketOverride?: string, sessionAvailability?: SessionAvailabilityV1): BuildRecoveryProjection;
78
102
  export declare function resolveBuildRecoveryProjection(projectDir: string, run: BuildRunRecordV2, now?: Date, ticketOverride?: string, probe?: ResolveSessionAvailabilityOptions): Promise<BuildRecoveryProjection>;
79
103
  export declare function formatBuildRecoveryProjection(projection: BuildRecoveryProjection): string[];
80
- export {};