@farmslot/protocol 0.5.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 (227) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +213 -0
  3. package/dist/agent-roles.d.ts +15 -0
  4. package/dist/agent-roles.d.ts.map +1 -0
  5. package/dist/agent-roles.js +101 -0
  6. package/dist/agent-roles.js.map +1 -0
  7. package/dist/events.d.ts +265 -0
  8. package/dist/events.d.ts.map +1 -0
  9. package/dist/events.js +72 -0
  10. package/dist/events.js.map +1 -0
  11. package/dist/frames.d.ts +29 -0
  12. package/dist/frames.d.ts.map +1 -0
  13. package/dist/frames.js +15 -0
  14. package/dist/frames.js.map +1 -0
  15. package/dist/github-ref.d.ts +15 -0
  16. package/dist/github-ref.d.ts.map +1 -0
  17. package/dist/github-ref.js +30 -0
  18. package/dist/github-ref.js.map +1 -0
  19. package/dist/index.d.ts +14 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +14 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/methods/auth.d.ts +46 -0
  24. package/dist/methods/auth.d.ts.map +1 -0
  25. package/dist/methods/auth.js +5 -0
  26. package/dist/methods/auth.js.map +1 -0
  27. package/dist/methods/backlog.d.ts +63 -0
  28. package/dist/methods/backlog.d.ts.map +1 -0
  29. package/dist/methods/backlog.js +12 -0
  30. package/dist/methods/backlog.js.map +1 -0
  31. package/dist/methods/chat.d.ts +290 -0
  32. package/dist/methods/chat.d.ts.map +1 -0
  33. package/dist/methods/chat.js +22 -0
  34. package/dist/methods/chat.js.map +1 -0
  35. package/dist/methods/config.d.ts +81 -0
  36. package/dist/methods/config.d.ts.map +1 -0
  37. package/dist/methods/config.js +16 -0
  38. package/dist/methods/config.js.map +1 -0
  39. package/dist/methods/copilot.d.ts +23 -0
  40. package/dist/methods/copilot.d.ts.map +1 -0
  41. package/dist/methods/copilot.js +5 -0
  42. package/dist/methods/copilot.js.map +1 -0
  43. package/dist/methods/decisions.d.ts +9 -0
  44. package/dist/methods/decisions.d.ts.map +1 -0
  45. package/dist/methods/decisions.js +2 -0
  46. package/dist/methods/decisions.js.map +1 -0
  47. package/dist/methods/diagnostics.d.ts +8 -0
  48. package/dist/methods/diagnostics.d.ts.map +1 -0
  49. package/dist/methods/diagnostics.js +2 -0
  50. package/dist/methods/diagnostics.js.map +1 -0
  51. package/dist/methods/dispatch.d.ts +198 -0
  52. package/dist/methods/dispatch.d.ts.map +1 -0
  53. package/dist/methods/dispatch.js +12 -0
  54. package/dist/methods/dispatch.js.map +1 -0
  55. package/dist/methods/eval.d.ts +119 -0
  56. package/dist/methods/eval.d.ts.map +1 -0
  57. package/dist/methods/eval.js +9 -0
  58. package/dist/methods/eval.js.map +1 -0
  59. package/dist/methods/fleet.d.ts +86 -0
  60. package/dist/methods/fleet.d.ts.map +1 -0
  61. package/dist/methods/fleet.js +9 -0
  62. package/dist/methods/fleet.js.map +1 -0
  63. package/dist/methods/fs.d.ts +42 -0
  64. package/dist/methods/fs.d.ts.map +1 -0
  65. package/dist/methods/fs.js +2 -0
  66. package/dist/methods/fs.js.map +1 -0
  67. package/dist/methods/git.d.ts +103 -0
  68. package/dist/methods/git.d.ts.map +1 -0
  69. package/dist/methods/git.js +2 -0
  70. package/dist/methods/git.js.map +1 -0
  71. package/dist/methods/index.d.ts +25 -0
  72. package/dist/methods/index.d.ts.map +1 -0
  73. package/dist/methods/index.js +26 -0
  74. package/dist/methods/index.js.map +1 -0
  75. package/dist/methods/intelligence.d.ts +218 -0
  76. package/dist/methods/intelligence.d.ts.map +1 -0
  77. package/dist/methods/intelligence.js +20 -0
  78. package/dist/methods/intelligence.js.map +1 -0
  79. package/dist/methods/nodes.d.ts +22 -0
  80. package/dist/methods/nodes.d.ts.map +1 -0
  81. package/dist/methods/nodes.js +2 -0
  82. package/dist/methods/nodes.js.map +1 -0
  83. package/dist/methods/pr.d.ts +75 -0
  84. package/dist/methods/pr.d.ts.map +1 -0
  85. package/dist/methods/pr.js +2 -0
  86. package/dist/methods/pr.js.map +1 -0
  87. package/dist/methods/registry.d.ts +196 -0
  88. package/dist/methods/registry.d.ts.map +1 -0
  89. package/dist/methods/registry.js +229 -0
  90. package/dist/methods/registry.js.map +1 -0
  91. package/dist/methods/resources.d.ts +89 -0
  92. package/dist/methods/resources.d.ts.map +1 -0
  93. package/dist/methods/resources.js +13 -0
  94. package/dist/methods/resources.js.map +1 -0
  95. package/dist/methods/run.d.ts +398 -0
  96. package/dist/methods/run.d.ts.map +1 -0
  97. package/dist/methods/run.js +34 -0
  98. package/dist/methods/run.js.map +1 -0
  99. package/dist/methods/search.d.ts +19 -0
  100. package/dist/methods/search.d.ts.map +1 -0
  101. package/dist/methods/search.js +2 -0
  102. package/dist/methods/search.js.map +1 -0
  103. package/dist/methods/slot.d.ts +192 -0
  104. package/dist/methods/slot.d.ts.map +1 -0
  105. package/dist/methods/slot.js +21 -0
  106. package/dist/methods/slot.js.map +1 -0
  107. package/dist/methods/task.d.ts +18 -0
  108. package/dist/methods/task.d.ts.map +1 -0
  109. package/dist/methods/task.js +2 -0
  110. package/dist/methods/task.js.map +1 -0
  111. package/dist/methods/terminal.d.ts +66 -0
  112. package/dist/methods/terminal.d.ts.map +1 -0
  113. package/dist/methods/terminal.js +2 -0
  114. package/dist/methods/terminal.js.map +1 -0
  115. package/dist/methods/tmux.d.ts +108 -0
  116. package/dist/methods/tmux.d.ts.map +1 -0
  117. package/dist/methods/tmux.js +3 -0
  118. package/dist/methods/tmux.js.map +1 -0
  119. package/dist/methods/workspace.d.ts +11 -0
  120. package/dist/methods/workspace.d.ts.map +1 -0
  121. package/dist/methods/workspace.js +2 -0
  122. package/dist/methods/workspace.js.map +1 -0
  123. package/dist/methods.d.ts +2 -0
  124. package/dist/methods.d.ts.map +1 -0
  125. package/dist/methods.js +3 -0
  126. package/dist/methods.js.map +1 -0
  127. package/dist/recipe-compat.d.ts +89 -0
  128. package/dist/recipe-compat.d.ts.map +1 -0
  129. package/dist/recipe-compat.js +977 -0
  130. package/dist/recipe-compat.js.map +1 -0
  131. package/dist/run-family-readiness.d.ts +31 -0
  132. package/dist/run-family-readiness.d.ts.map +1 -0
  133. package/dist/run-family-readiness.js +223 -0
  134. package/dist/run-family-readiness.js.map +1 -0
  135. package/dist/signal.d.ts +14 -0
  136. package/dist/signal.d.ts.map +1 -0
  137. package/dist/signal.js +4 -0
  138. package/dist/signal.js.map +1 -0
  139. package/dist/step-io.d.ts +277 -0
  140. package/dist/step-io.d.ts.map +1 -0
  141. package/dist/step-io.js +26 -0
  142. package/dist/step-io.js.map +1 -0
  143. package/dist/surfaces.d.ts +36 -0
  144. package/dist/surfaces.d.ts.map +1 -0
  145. package/dist/surfaces.js +392 -0
  146. package/dist/surfaces.js.map +1 -0
  147. package/dist/tmux-worker-watchlist.d.ts +36 -0
  148. package/dist/tmux-worker-watchlist.d.ts.map +1 -0
  149. package/dist/tmux-worker-watchlist.js +82 -0
  150. package/dist/tmux-worker-watchlist.js.map +1 -0
  151. package/dist/types/agents.d.ts +59 -0
  152. package/dist/types/agents.d.ts.map +1 -0
  153. package/dist/types/agents.js +10 -0
  154. package/dist/types/agents.js.map +1 -0
  155. package/dist/types/backlog.d.ts +66 -0
  156. package/dist/types/backlog.d.ts.map +1 -0
  157. package/dist/types/backlog.js +13 -0
  158. package/dist/types/backlog.js.map +1 -0
  159. package/dist/types/chat.d.ts +203 -0
  160. package/dist/types/chat.d.ts.map +1 -0
  161. package/dist/types/chat.js +19 -0
  162. package/dist/types/chat.js.map +1 -0
  163. package/dist/types/common.d.ts +13 -0
  164. package/dist/types/common.d.ts.map +1 -0
  165. package/dist/types/common.js +3 -0
  166. package/dist/types/common.js.map +1 -0
  167. package/dist/types/config.d.ts +154 -0
  168. package/dist/types/config.d.ts.map +1 -0
  169. package/dist/types/config.js +2 -0
  170. package/dist/types/config.js.map +1 -0
  171. package/dist/types/dispatch.d.ts +77 -0
  172. package/dist/types/dispatch.d.ts.map +1 -0
  173. package/dist/types/dispatch.js +2 -0
  174. package/dist/types/dispatch.js.map +1 -0
  175. package/dist/types/evals.d.ts +341 -0
  176. package/dist/types/evals.d.ts.map +1 -0
  177. package/dist/types/evals.js +459 -0
  178. package/dist/types/evals.js.map +1 -0
  179. package/dist/types/family.d.ts +163 -0
  180. package/dist/types/family.d.ts.map +1 -0
  181. package/dist/types/family.js +2 -0
  182. package/dist/types/family.js.map +1 -0
  183. package/dist/types/index.d.ts +17 -0
  184. package/dist/types/index.d.ts.map +1 -0
  185. package/dist/types/index.js +17 -0
  186. package/dist/types/index.js.map +1 -0
  187. package/dist/types/recipes.d.ts +94 -0
  188. package/dist/types/recipes.d.ts.map +1 -0
  189. package/dist/types/recipes.js +7 -0
  190. package/dist/types/recipes.js.map +1 -0
  191. package/dist/types/resources.d.ts +110 -0
  192. package/dist/types/resources.d.ts.map +1 -0
  193. package/dist/types/resources.js +2 -0
  194. package/dist/types/resources.js.map +1 -0
  195. package/dist/types/reviews.d.ts +85 -0
  196. package/dist/types/reviews.d.ts.map +1 -0
  197. package/dist/types/reviews.js +2 -0
  198. package/dist/types/reviews.js.map +1 -0
  199. package/dist/types/runs.d.ts +1105 -0
  200. package/dist/types/runs.d.ts.map +1 -0
  201. package/dist/types/runs.js +297 -0
  202. package/dist/types/runs.js.map +1 -0
  203. package/dist/types/slots.d.ts +108 -0
  204. package/dist/types/slots.d.ts.map +1 -0
  205. package/dist/types/slots.js +2 -0
  206. package/dist/types/slots.js.map +1 -0
  207. package/dist/types/task.d.ts +37 -0
  208. package/dist/types/task.d.ts.map +1 -0
  209. package/dist/types/task.js +2 -0
  210. package/dist/types/task.js.map +1 -0
  211. package/dist/types/terminal.d.ts +12 -0
  212. package/dist/types/terminal.d.ts.map +1 -0
  213. package/dist/types/terminal.js +2 -0
  214. package/dist/types/terminal.js.map +1 -0
  215. package/dist/types/workspace.d.ts +44 -0
  216. package/dist/types/workspace.d.ts.map +1 -0
  217. package/dist/types/workspace.js +2 -0
  218. package/dist/types/workspace.js.map +1 -0
  219. package/dist/types.d.ts +2 -0
  220. package/dist/types.d.ts.map +1 -0
  221. package/dist/types.js +3 -0
  222. package/dist/types.js.map +1 -0
  223. package/dist/version.d.ts +2 -0
  224. package/dist/version.d.ts.map +1 -0
  225. package/dist/version.js +7 -0
  226. package/dist/version.js.map +1 -0
  227. package/package.json +109 -0
@@ -0,0 +1,1105 @@
1
+ import type { ArtifactRef, SelfReviewIssue } from '../step-io.js';
2
+ import type { AgentContext, SafetyTier } from './agents.js';
3
+ import type { FailureCategory, RunRecoveryProposalConfidence } from './chat.js';
4
+ import type { TaskTemplateSelection, TemplateProvenance } from './evals.js';
5
+ import type { EvidenceQualityReport, RecipeQualityArtifact } from './recipes.js';
6
+ import type { SlotHealth } from './slots.js';
7
+ export type RunStatus = 'created' | 'grading' | 'writing-task' | 'slot-finding' | 'preparing' | 'dispatching' | 'monitoring' | 'self-reviewing' | 'completing' | 'human-gating' | 'ci-watching' | 'paused' | 'done' | 'blocked' | 'failed' | 'cancelled';
8
+ export declare const TERMINAL_RUN_STATUSES: readonly RunStatus[];
9
+ export declare function isTerminalRunStatus(status: RunStatus): boolean;
10
+ export type RunStepStatus = 'pending' | 'running' | 'done' | 'failed' | 'skipped';
11
+ export interface RunStep {
12
+ name: string;
13
+ status: RunStepStatus;
14
+ detail?: string;
15
+ startedAt?: string;
16
+ completedAt?: string;
17
+ durationMs?: number;
18
+ inputs?: Record<string, unknown>;
19
+ outputs?: Record<string, unknown>;
20
+ }
21
+ export type LiveRecipeSource = 'decision' | 'recipe-run-live' | 'recipe-run-artifacts' | 'final-artifacts';
22
+ export type LiveRecipeSelectionReason = 'latest-run' | 'user-selected' | 'decision-derived' | 'fallback-none';
23
+ export interface LiveRecipeContext {
24
+ source: LiveRecipeSource;
25
+ recipeRunId: string | null;
26
+ artifactRoot: string | null;
27
+ artifactManifest: ArtifactRef[] | null;
28
+ usedTypedArtifactManifest?: boolean;
29
+ recipeJson: string | null;
30
+ recipeQualityArtifact: RecipeQualityArtifact | null;
31
+ qualityReport: EvidenceQualityReport | null;
32
+ workerLearnings: string | null;
33
+ isStale: boolean;
34
+ selectionReason: LiveRecipeSelectionReason;
35
+ }
36
+ export declare const LIVE_RECIPE_EVIDENCE_PURPOSES: Set<string>;
37
+ export declare const LIVE_RECIPE_EVIDENCE_FILES: Set<string>;
38
+ export declare function hasLiveRecipeEvidence(context: Pick<LiveRecipeContext, 'recipeJson' | 'recipeQualityArtifact' | 'qualityReport' | 'workerLearnings' | 'artifactManifest'>): boolean;
39
+ export type RecipeRunArtifactGroupKind = 'current-artifacts' | 'latest-valid' | 'live-run';
40
+ export type RecipeRunArtifactGroupStatus = 'pass' | 'fail' | 'unknown';
41
+ export interface RecipeRunArtifactGroup extends LiveRecipeContext {
42
+ id: string;
43
+ label: string;
44
+ groupKind: RecipeRunArtifactGroupKind;
45
+ promoted: boolean;
46
+ status: RecipeRunArtifactGroupStatus;
47
+ }
48
+ export interface ReviewLineComment {
49
+ path: string;
50
+ line: number;
51
+ body: string;
52
+ severity: string;
53
+ }
54
+ export interface EvidenceManifestStandalone {
55
+ label: string;
56
+ covers?: string[];
57
+ file: string;
58
+ note?: string;
59
+ }
60
+ export interface ReviewGatePayload {
61
+ kind: 'review';
62
+ prNumber: number | null;
63
+ repo: string | null;
64
+ recommendation: string;
65
+ reviewMd: string;
66
+ lineComments: ReviewLineComment[];
67
+ artifactManifest?: EvidenceManifestEntry[];
68
+ artifactUrls?: Record<string, string>;
69
+ reviewSnapshot?: ReviewDiffSnapshot;
70
+ reviewInputArtifactPaths?: string[];
71
+ stale?: boolean;
72
+ evidenceMarkdown?: string;
73
+ recipeJson?: string;
74
+ recipeQualityArtifact?: RecipeQualityArtifact | null;
75
+ qualityReport?: EvidenceQualityReport | null;
76
+ workerLearnings?: string;
77
+ }
78
+ export type PublicationTarget = 'draft' | 'ready';
79
+ export type PublicationStatus = 'not_published' | 'pending_publish' | 'published_draft' | 'published_ready' | 'publish_failed';
80
+ export interface ReviewDepthPolicy {
81
+ minimumIndependentReviews: number;
82
+ requireCrossRunner: boolean;
83
+ extraLoopsRequested: number;
84
+ requestedBy: 'dispatch' | 'human-gate' | 'agent-gate';
85
+ }
86
+ export type ReviewValidationDepth = 'static-code' | 'full-live';
87
+ export declare const REVIEW_VALIDATION_DEPTHS: readonly ReviewValidationDepth[];
88
+ export declare function isReviewValidationDepth(value: unknown): value is ReviewValidationDepth;
89
+ export declare function reviewValidationDepthForLoop(index: number, total: number): ReviewValidationDepth;
90
+ export interface ReviewLoopRequest {
91
+ order: number;
92
+ runner: 'same' | ReviewRunnerId;
93
+ model?: string | null;
94
+ validationDepth?: ReviewValidationDepth;
95
+ }
96
+ export type ReviewRunnerId = 'claude' | 'codex' | 'cursor' | 'opencode';
97
+ export interface DiffStat {
98
+ files: number;
99
+ additions: number;
100
+ deletions: number;
101
+ }
102
+ export interface EvidenceManifestEntry {
103
+ path: string;
104
+ purpose: string;
105
+ sizeBytes?: number;
106
+ sha256?: string;
107
+ }
108
+ export interface ReviewDiffSnapshot {
109
+ baseRef?: string | null;
110
+ baseSha?: string | null;
111
+ headRef?: string | null;
112
+ headSha?: string | null;
113
+ diffPath?: string | null;
114
+ diffHash?: string | null;
115
+ diffStat?: DiffStat;
116
+ capturedAt: string;
117
+ source: 'local-git' | 'github-pr' | 'unavailable';
118
+ missingReason?: string;
119
+ error?: string;
120
+ }
121
+ export interface ReviewFixDeltaSnapshot extends ReviewDiffSnapshot {
122
+ fixBaseSha?: string | null;
123
+ fixHeadSha?: string | null;
124
+ }
125
+ export interface RunnerSessionUsage {
126
+ runnerSessionId?: string | null;
127
+ runnerSessionPath?: string | null;
128
+ runner?: string | null;
129
+ actualModel?: string | null;
130
+ turns?: number | null;
131
+ inputTokens?: number | null;
132
+ outputTokens?: number | null;
133
+ cacheCreation?: number | null;
134
+ cacheRead?: number | null;
135
+ reasoningOutputTokens?: number | null;
136
+ totalTokens?: number | null;
137
+ costUsd?: number | null;
138
+ measuredAt: string;
139
+ source: 'runner-transcript' | 'unavailable';
140
+ /** What this measurement covers. `session-total` is the runner transcript total at measurement time. */
141
+ scope?: 'session-total';
142
+ error?: string;
143
+ }
144
+ export type ReviewLoopTimelineSegmentKind = 'review' | 'worker-fix' | 're-review';
145
+ export interface ReviewLoopTimelineSegment {
146
+ kind: ReviewLoopTimelineSegmentKind;
147
+ loopNumber: number;
148
+ runner?: string | null;
149
+ model?: string | null;
150
+ startedAt: string;
151
+ completedAt?: string;
152
+ durationMs?: number;
153
+ verdict?: IndependentReviewAttempt['verdict'];
154
+ unresolvedCount?: number;
155
+ artifactPaths?: string[];
156
+ }
157
+ export interface IndependentReviewAttempt {
158
+ loopNumber: number;
159
+ verdict: 'pending' | 'pass' | 'issues' | 'failed' | 'cancelled' | 'skipped';
160
+ unresolvedCount: number;
161
+ issues?: SelfReviewIssue[];
162
+ validationDepth?: ReviewValidationDepth;
163
+ usage?: RunnerSessionUsage;
164
+ reviewSnapshot?: ReviewDiffSnapshot;
165
+ fixDelta?: ReviewFixDeltaSnapshot;
166
+ artifactPaths?: string[];
167
+ taskProgressArtifactPath?: string;
168
+ timeline?: ReviewLoopTimelineSegment[];
169
+ startedAt?: string;
170
+ completedAt?: string;
171
+ }
172
+ export interface IndependentReviewStatus {
173
+ id: string;
174
+ source?: 'dispatch' | 'human-gate' | 'self-review';
175
+ runner?: string | null;
176
+ model?: string | null;
177
+ reviewerSessionId?: string | null;
178
+ crossRunner: boolean;
179
+ loopNumber: number;
180
+ verdict: 'pending' | 'pass' | 'issues' | 'failed' | 'cancelled' | 'skipped';
181
+ unresolvedCount: number;
182
+ issues?: SelfReviewIssue[];
183
+ validationDepth?: ReviewValidationDepth;
184
+ usage?: RunnerSessionUsage;
185
+ feedbackSent?: boolean;
186
+ attempts?: IndependentReviewAttempt[];
187
+ artifactPaths?: string[];
188
+ taskProgressArtifactPath?: string;
189
+ timeline?: ReviewLoopTimelineSegment[];
190
+ reviewSnapshot?: ReviewDiffSnapshot;
191
+ reviewedHeadSha?: string | null;
192
+ reviewedPackageInputHash?: string | null;
193
+ reviewedReviewSubjectHash?: string | null;
194
+ fixDelta?: ReviewFixDeltaSnapshot;
195
+ stale?: boolean;
196
+ startedAt?: string;
197
+ completedAt?: string;
198
+ }
199
+ export interface GatePolicy {
200
+ owner: 'human' | 'agent';
201
+ dispatchMode?: 'interactive' | 'autonomous' | 'validation';
202
+ publishAuthority: 'human' | 'agent';
203
+ reason: string;
204
+ }
205
+ export interface ReadyGatePrPackage {
206
+ id: string;
207
+ packageHash: string;
208
+ packageInputHash?: string;
209
+ reviewSubjectHash?: string;
210
+ artifactPath: string;
211
+ branch: string;
212
+ remoteBranchRef?: string | null;
213
+ headSha?: string;
214
+ diffStat: DiffStat;
215
+ draftTitle: string;
216
+ draftBody: string;
217
+ evidenceManifest?: EvidenceManifestEntry[];
218
+ selectedEvidenceKeys?: string[];
219
+ validationSummaryPath?: string | null;
220
+ validationSummaryHash?: string | null;
221
+ reviewArtifactIds: string[];
222
+ dispatchMode?: 'interactive' | 'autonomous' | 'validation';
223
+ gatePolicy: GatePolicy;
224
+ /** Frozen at package preparation time so approval/review policy cannot drift with config edits. */
225
+ reviewDepth?: ReviewDepthPolicy;
226
+ publicationTarget: PublicationTarget;
227
+ publicationStatus: PublicationStatus;
228
+ supersededByPackageId?: string | null;
229
+ createdAt: string;
230
+ approvedAt?: string;
231
+ }
232
+ export interface ReadyGateInputSnapshot {
233
+ ticketData?: RunTicketData;
234
+ taskFile?: string | null;
235
+ taskPrompt?: string;
236
+ initialContext?: string;
237
+ checklist?: string[];
238
+ templateProvenance?: TemplateProvenance | null;
239
+ }
240
+ export interface ReadyGatePayload {
241
+ kind: 'ready';
242
+ prNumber: number | null;
243
+ repo: string | null;
244
+ diffStat: DiffStat;
245
+ workerReport: string;
246
+ branch: string;
247
+ slotId?: string;
248
+ /**
249
+ * Commit SHA the slot's branch pointed at when this gate was created.
250
+ * Persisted so post-hoc viewers of a resolved gate know whether the
251
+ * slot has moved on — the live diff in `ready-workspace` is against the
252
+ * current HEAD, which may differ from what was reviewed. Undefined on
253
+ * gates created before this field was introduced.
254
+ */
255
+ headSha?: string;
256
+ recipeJson?: string;
257
+ recipeQualityArtifact?: RecipeQualityArtifact | null;
258
+ qualityReport?: EvidenceQualityReport | null;
259
+ artifactManifest?: EvidenceManifestEntry[];
260
+ selfReviewVerdict?: string;
261
+ selfReviewSummary?: string;
262
+ workerLearnings?: string;
263
+ ciChecks?: Array<{
264
+ name: string;
265
+ status: string;
266
+ conclusion: string | null;
267
+ }>;
268
+ acceptanceCriteria?: string[];
269
+ inputSnapshot?: ReadyGateInputSnapshot;
270
+ prPackage?: ReadyGatePrPackage;
271
+ reviewDepth?: ReviewDepthPolicy;
272
+ independentReviews?: IndependentReviewStatus[];
273
+ gatePolicy?: GatePolicy;
274
+ validationSummary?: string;
275
+ publicationTarget?: PublicationTarget;
276
+ publicationStatus?: PublicationStatus;
277
+ stale?: boolean;
278
+ draftEdits?: {
279
+ title?: string;
280
+ body?: string;
281
+ selectedEvidenceKeys?: string[];
282
+ };
283
+ }
284
+ export interface NoChangeGatePayload {
285
+ kind: 'no-change';
286
+ disposition: WorkerTerminalDisposition;
287
+ reason?: string;
288
+ evidence?: WorkerTerminalEvidence;
289
+ workerReport?: string;
290
+ artifactManifest?: EvidenceManifestEntry[];
291
+ }
292
+ export interface SlotPickerPayload {
293
+ kind: 'slot_picker';
294
+ project: string;
295
+ candidates: Array<{
296
+ slotId: string;
297
+ score: number;
298
+ branch: string;
299
+ lifecycle: string;
300
+ health: SlotHealth;
301
+ machine: string;
302
+ }>;
303
+ reason: 'no_free_slots' | 'all_stale' | 'all_unhealthy';
304
+ }
305
+ /**
306
+ * Branch-affinity nudge — surfaced when a busy slot is already on the target PR's branch
307
+ * and the operator can reuse its loaded context instead of dispatching fresh on a stale slot.
308
+ *
309
+ * Emitted by FIND_SLOT only for headless entry points (CI-watch chained pr-complete after CI
310
+ * fail, CLI dispatch, gateway restart recovery). The dispatch wizard surfaces the same data
311
+ * inline via DispatchCandidatesResult.nudgeMeta and bypasses this card entirely.
312
+ */
313
+ export interface BranchAffinityNudgePayload {
314
+ kind: 'branch_affinity_nudge';
315
+ project: string;
316
+ ticketOrPr: string;
317
+ prNumber?: number | null;
318
+ candidate: {
319
+ slotId: string;
320
+ machine: string;
321
+ branch: string;
322
+ /** Runner currently active in the slot. Should always be populated when the candidate is
323
+ * surfaced (the eligibility gate requires a runner with `supportsTmuxNudges`), but typed
324
+ * as nullable to mirror `SlotStatus.runner` and avoid empty-string sentinels. */
325
+ runner: string | null;
326
+ /** Model of the prior worker, when known. Often null for legacy slots that never recorded one. */
327
+ model: string | null;
328
+ nudgeCount: number;
329
+ /** Runner context-window usage percentage (0-100). Runner-agnostic; populated by whichever
330
+ * node-side adapter knows how to read the active runner's status surface. Null when the
331
+ * runner does not expose a value or the parse failed. */
332
+ ctxPct: number | null;
333
+ agentStatus: string;
334
+ dispatchedAt: string | null;
335
+ /** Run id currently bound to the slot — i.e., the prior run that nudge would supersede.
336
+ * Read this as "priorRunId" at decision time; the field is named `currentRunId` to mirror
337
+ * `SlotStatus.currentRunId` so wire-format consumers don't have to think about renames. */
338
+ currentRunId: string | null;
339
+ currentFlowType: string | null;
340
+ uncommittedCount: number;
341
+ /** First 10 paths from `git status --porcelain`. */
342
+ uncommittedFiles: string[];
343
+ /** Whether the match is an authoritative `prHealth.pr === prNumber` hit or a softer branch-slug-only match. */
344
+ prMatchKind: 'pr-number' | 'branch-slug';
345
+ /** True when the slot's runner supports tmux send-keys nudges. UI uses this to disable the
346
+ * Nudge action button when false — only Fresh dispatch is offered for codex / opencode. */
347
+ canNudge: boolean;
348
+ };
349
+ /** Free-slot fallback list. Reused from {@link SlotPickerPayload.candidates} so the 'pick'
350
+ * action renders through the existing slot-picker UI without a second payload type. The
351
+ * type alias is intentional: if SlotPicker's row shape evolves the nudge card inherits the
352
+ * change. If they need to diverge, peel the alias and add explicit fields here. */
353
+ freeSlotCandidates: SlotPickerPayload['candidates'];
354
+ /** Soft warnings (e.g. 'family-mismatch', 'high-nudge-count', 'high-ctx-pct'). */
355
+ riskFlags: string[];
356
+ }
357
+ export interface ImprovementFileChange {
358
+ filePath: string;
359
+ before: string;
360
+ after: string;
361
+ }
362
+ export interface ImprovementDiffPayload {
363
+ kind: 'improvement';
364
+ learningContent: string;
365
+ proposedChanges: ImprovementFileChange[];
366
+ rationale: string;
367
+ sourceRunId: string;
368
+ project: string;
369
+ analysisStatus?: 'analyzing' | 'completed' | 'no-content' | 'no-changes' | 'error';
370
+ analysisStartedAt?: string;
371
+ analysisError?: string;
372
+ }
373
+ export interface CommentsTriageSummary {
374
+ total: number;
375
+ real: number;
376
+ falsePositive: number;
377
+ outOfScope: number;
378
+ fixed: number;
379
+ botAddressed?: number;
380
+ humanReviewersRequestingChanges?: number;
381
+ humanCommentsAddressed?: number;
382
+ unknownSource?: number;
383
+ actionablePaths?: string[];
384
+ }
385
+ export interface RetrospectivePayload {
386
+ kind: 'retrospective';
387
+ outcome: 'success' | 'failure' | 'partial' | 'cancelled' | 'unknown';
388
+ whatThisIs: string;
389
+ selfReviewVerdict?: string;
390
+ selfReviewSummary?: string;
391
+ workerLearnings?: string;
392
+ reportExcerpt?: string;
393
+ ciWatch?: {
394
+ result?: string;
395
+ passed?: number;
396
+ failed?: number;
397
+ pending?: number;
398
+ total?: number;
399
+ };
400
+ actionEffects: Array<{
401
+ actionId: string;
402
+ summary: string;
403
+ }>;
404
+ rootRunId?: string;
405
+ rootLearnings?: string;
406
+ deltaLearnings?: string;
407
+ commentsTriageSummary?: CommentsTriageSummary;
408
+ }
409
+ /** Engine-collision decision payload — surfaces the prior runs that own the colliding
410
+ * task dirs so UI can deep-link to them (and let the operator retry from there)
411
+ * instead of forking a new family via `create-new`. priorRunIds is ordered newest-first.
412
+ * dirOwners maps each colliding dir to the owning run id (when resolved at decision
413
+ * creation); UI uses it to render per-dir chip links without re-scanning state and
414
+ * without risking cross-project taskFile substring collisions. */
415
+ export interface CollisionPayload {
416
+ kind: 'collision';
417
+ ticketSlug: string;
418
+ existingDirs: string[];
419
+ priorRunIds: string[];
420
+ /** Pre-resolved owner run id per colliding dir. Absent on legacy decisions —
421
+ * UI should fall back to its own state scan when this field is missing. */
422
+ dirOwners?: Record<string, string>;
423
+ }
424
+ export type RunDecisionPayload = ReviewGatePayload | ReadyGatePayload | NoChangeGatePayload | SlotPickerPayload | BranchAffinityNudgePayload | ImprovementDiffPayload | RetrospectivePayload | CollisionPayload;
425
+ export interface RunDecision {
426
+ id: string;
427
+ type: DecisionType;
428
+ title: string;
429
+ description: string;
430
+ actions: DecisionAction[];
431
+ createdAt: string;
432
+ resolvedAt?: string;
433
+ resolvedAction?: string;
434
+ payload?: RunDecisionPayload;
435
+ selectionData?: Record<string, unknown>;
436
+ context?: Record<string, unknown>;
437
+ }
438
+ /** A single ticket referenced by a PR (linked from PR body, commit trailers, etc.) */
439
+ export interface LinkedTicket {
440
+ ref: string;
441
+ url: string;
442
+ title: string;
443
+ description: string;
444
+ source: 'jira' | 'github';
445
+ }
446
+ export interface RunTicketData {
447
+ source: 'jira' | 'github' | 'both' | 'manual';
448
+ issueType?: string;
449
+ title: string;
450
+ description: string;
451
+ acceptanceCriteria: string[];
452
+ affectedArea: string;
453
+ stepsToReproduce: string[];
454
+ screenshots: string[];
455
+ labels: string[];
456
+ jiraKey?: string;
457
+ githubIssue?: string;
458
+ comments?: string[];
459
+ /**
460
+ * Tickets referenced by a PR (review-pr flow only).
461
+ * Multiple keys are supported — PRs often fix several tickets at once.
462
+ * Each entry is pre-fetched from its source so templates can render without
463
+ * extra round-trips.
464
+ */
465
+ linkedTickets?: LinkedTicket[];
466
+ }
467
+ export interface RunGrade {
468
+ difficulty: 'low' | 'medium' | 'high' | 'extreme';
469
+ rationale: string;
470
+ modelRecommendation: string;
471
+ score?: number;
472
+ }
473
+ export interface ProofTargetVerdict {
474
+ id: string;
475
+ target: string;
476
+ verdict: 'pass' | 'fail' | 'not-applicable';
477
+ note?: string;
478
+ }
479
+ export interface HumanGrade {
480
+ recipe_semantic: 'good' | 'ok' | 'bad';
481
+ reasoning: string;
482
+ graded_by: string;
483
+ graded_at: string;
484
+ proof_target_verdicts?: ProofTargetVerdict[];
485
+ }
486
+ export declare const DEFAULT_GRADER_ID = "unknown";
487
+ export type RunFamilyCompletionState = 'active' | 'complete' | 'failed' | 'mixed';
488
+ export type RunSelfLearningEligibilityState = 'eligible' | 'blocked' | 'unknown';
489
+ export declare const RUN_SELF_LEARNING_MISSING_SIGNALS: readonly ["missing-evidence-signal", "missing-learnings-signal", "missing-recipe-signal", "missing-diff-signal"];
490
+ export type RunSelfLearningMissingSignal = (typeof RUN_SELF_LEARNING_MISSING_SIGNALS)[number];
491
+ export declare const RUN_SELF_LEARNING_BLOCK_REASONS: readonly ["active-runs", "pending-decisions", "no-successful-run"];
492
+ export type RunSelfLearningBlockReason = (typeof RUN_SELF_LEARNING_BLOCK_REASONS)[number];
493
+ export interface RunSelfLearningEligibility {
494
+ state: RunSelfLearningEligibilityState;
495
+ reasons: RunSelfLearningBlockReason[];
496
+ missingSignals: RunSelfLearningMissingSignal[];
497
+ }
498
+ export interface RunFamilyReadinessSummary {
499
+ familyId: string;
500
+ familyRootTicketOrPr: string;
501
+ project: string;
502
+ latestRunId: string;
503
+ latestRunAt: string;
504
+ runCount: number;
505
+ terminalRunCount: number;
506
+ activeRunCount: number;
507
+ failedRunCount: number;
508
+ completionPercent: number;
509
+ completionState: RunFamilyCompletionState;
510
+ eligibility: RunSelfLearningEligibility;
511
+ }
512
+ export interface RunProjectAnalyticsSummary {
513
+ project: string;
514
+ familyCount: number;
515
+ runCount: number;
516
+ activeFamilyCount: number;
517
+ completedFamilyCount: number;
518
+ eligibleFamilyCount: number;
519
+ blockedFamilyCount: number;
520
+ unknownFamilyCount: number;
521
+ latestRunAt: string;
522
+ }
523
+ export interface RunListSummaryMeta {
524
+ /** First PR summaries describe only the runs returned in this run.list response after filters, sorting, and limit. */
525
+ scope: 'returned-runs';
526
+ /** Number of returned runs used to compute family/project summaries. */
527
+ summaryRunCount: number;
528
+ /** Matching run count before run.list limit truncation; mirrors RunListResult.totalCount. */
529
+ totalCount: number;
530
+ /** True when the returned-run summary is a partial view of the matching result set. */
531
+ isTruncated: boolean;
532
+ }
533
+ export interface RunMetrics {
534
+ durationMs?: number;
535
+ nudgeCount: number;
536
+ model: string | null;
537
+ runner: string | null;
538
+ runnerSessionId?: string | null;
539
+ runnerSessionPath?: string | null;
540
+ outcome?: 'success' | 'failure' | 'partial' | 'cancelled';
541
+ disposition?: WorkerTerminalDisposition;
542
+ terminalEvidence?: WorkerTerminalEvidence;
543
+ costEstimate?: number;
544
+ sessionTurns?: number;
545
+ sessionInputTokens?: number;
546
+ sessionOutputTokens?: number;
547
+ sessionCacheCreation?: number;
548
+ sessionCacheRead?: number;
549
+ sessionTotalTokens?: number;
550
+ actualModel?: string;
551
+ }
552
+ export type RunCompletionPolicy = 'default' | 'artifact-only';
553
+ export type RunStartRefSource = {
554
+ kind: 'manual';
555
+ } | {
556
+ kind: 'package';
557
+ packagePath: string;
558
+ } | {
559
+ kind: 'merged-pr';
560
+ repo?: string;
561
+ prNumber?: number;
562
+ } | {
563
+ kind: 'git-ref';
564
+ repository?: string;
565
+ ref?: string;
566
+ };
567
+ export interface RunStartRefProvenance {
568
+ requestedRef: string;
569
+ resolvedSha?: string;
570
+ resolvedAt?: string;
571
+ source?: RunStartRefSource;
572
+ }
573
+ export interface SlotRunHistoryEntry {
574
+ runId: string;
575
+ familyId: string;
576
+ status: RunStatus;
577
+ flowType: FlowType;
578
+ ticketOrPr: string;
579
+ summary?: string;
580
+ project: string;
581
+ branch: string | null;
582
+ createdAt: string;
583
+ updatedAt: string;
584
+ completedAt?: string;
585
+ durationMs?: number;
586
+ runner: string | null;
587
+ model: string | null;
588
+ actualModel?: string;
589
+ runnerSessionId?: string | null;
590
+ runnerSessionPath?: string | null;
591
+ taskFile: string | null;
592
+ taskDir: string | null;
593
+ artifactDir: string | null;
594
+ /** PR opened or reviewed by this run, when known. Slot history uses this to keep historical workspace cards linkable. */
595
+ prNumber: number | null;
596
+ /** Best-known contribution diff summary from retained run metadata. Used by compact workspace clients without fetching the full run. */
597
+ diffStat: DiffStat & {
598
+ available: boolean;
599
+ };
600
+ /** Number of retained before/after visual evidence pairs for compact slot-history clients. */
601
+ visualPairCount: number;
602
+ links?: RunLink[];
603
+ runRecordPath: string;
604
+ currentForSlot: boolean;
605
+ }
606
+ export type WorkerTerminalDisposition = 'fixed' | 'already_fixed' | 'not_reproducible' | 'blocked' | 'failed';
607
+ export interface WorkerTerminalEvidence {
608
+ reportPath?: string;
609
+ artifacts?: string[];
610
+ confidence?: 'low' | 'medium' | 'high';
611
+ noCodeChange?: boolean;
612
+ reproductionAttempted?: boolean;
613
+ }
614
+ /**
615
+ * Compare the dispatched model short-name (e.g. "sonnet") against the actual
616
+ * model reported by the worker's session transcript (e.g. "claude-sonnet-4-6").
617
+ * Returns true if they refer to the same family. Used to detect model drift
618
+ * caused by fast-mode / `/model` sticky config overriding the --model flag.
619
+ */
620
+ export declare function modelsMatch(dispatched: string | null | undefined, actual: string | null | undefined): boolean;
621
+ /**
622
+ * Tag a comparison-lane sibling with a `<runner>-<safe(model)>` variant so
623
+ * the duplicate-run guard (assertDuplicateRunAllowed in run.ts) sees it as
624
+ * distinct from any existing sibling in the family. The format is shared
625
+ * between the dispatch wizard's submit handler and run-detail's "Re-run
626
+ * alongside" href builder — keeping it in protocol prevents the two from
627
+ * silently drifting apart, which would let the duplicate guard reject runs
628
+ * that were supposed to be valid forks.
629
+ *
630
+ * Returns an empty string when either input is falsy so callers can keep a
631
+ * fallback to URL-prefilled values without crashing on partial state.
632
+ */
633
+ export declare function buildComparisonVariant(runner: string | null | undefined, model: string | null | undefined): string;
634
+ /**
635
+ * Pick the next free comparison-lane variant tag for a (runner, model) pair
636
+ * within a family. Returns `buildComparisonVariant(runner, model)` when no
637
+ * sibling already uses that tag; otherwise appends `-v2`, `-v3`, … until a
638
+ * free slot is found. Used by the dispatch wizard's same-runner+same-model
639
+ * comparison flow (e.g. operator edited templates and wants to re-run with
640
+ * the same model) so the duplicate-run guard at run.ts:assertDuplicateRunAllowed
641
+ * accepts the new sibling.
642
+ */
643
+ export declare function nextFreeComparisonVariant(familyRuns: ReadonlyArray<{
644
+ variant?: string | null;
645
+ }>, runner: string | null | undefined, model: string | null | undefined): string;
646
+ export interface RunMonitorState {
647
+ nudgeCount: number;
648
+ lastPollAt: string;
649
+ startedAt: string;
650
+ lastPaneHash?: string;
651
+ }
652
+ export interface RunLink {
653
+ label: string;
654
+ url: string;
655
+ }
656
+ export type RunAutoRecoveryProposalStatus = 'idle' | 'manual-in-progress' | 'auto-in-progress' | 'disabled';
657
+ export interface RunRecoveryRuntimeProposal {
658
+ status: RunAutoRecoveryProposalStatus;
659
+ proposalId?: string;
660
+ generation: number;
661
+ }
662
+ export interface RunReplayStep {
663
+ id: string;
664
+ attempt: number;
665
+ stepName: string;
666
+ startedAt: string;
667
+ completedAt?: string;
668
+ status: 'started' | 'completed' | 'failed' | 'cancelled';
669
+ triggeredBy: 'auto-recovery' | 'operator';
670
+ intelligenceActionId?: string;
671
+ }
672
+ export declare const INTELLIGENCE_ACTION_ACTORS: readonly ["auto-recovery", "auto-grade", "auto-nudge"];
673
+ export type IntelligenceActionActor = (typeof INTELLIGENCE_ACTION_ACTORS)[number];
674
+ export declare const INTELLIGENCE_ACTION_TIERS: readonly ["deterministic", "llm-refined", "hybrid"];
675
+ export type IntelligenceActionTier = (typeof INTELLIGENCE_ACTION_TIERS)[number];
676
+ export declare const INTELLIGENCE_ACTION_OUTCOMES: readonly ["applied", "proposed", "skipped", "errored"];
677
+ export type IntelligenceActionOutcome = (typeof INTELLIGENCE_ACTION_OUTCOMES)[number];
678
+ export declare const INTELLIGENCE_ACTION_OUTCOME_REASONS: readonly ["max_attempts_per_step", "family_cap", "cooldown_active", "non_recoverable_category", "low_confidence", "budget_exceeded", "pattern_disabled", "manual_in_progress", "dead_letter"];
679
+ export type IntelligenceActionOutcomeReason = (typeof INTELLIGENCE_ACTION_OUTCOME_REASONS)[number];
680
+ export declare const INTELLIGENCE_ACTION_FOLLOWUPS: readonly ["recovered", "failed-again", "human-overrode", "cancelled"];
681
+ export type IntelligenceActionFollowup = (typeof INTELLIGENCE_ACTION_FOLLOWUPS)[number];
682
+ export declare const INTELLIGENCE_ACTION_PROPOSED_TYPES: readonly ["run.replayStep", "slot.reset", "slot.cleanupProcesses", "slot.fixtureRefresh", "tmux.send"];
683
+ export type IntelligenceActionProposedType = (typeof INTELLIGENCE_ACTION_PROPOSED_TYPES)[number];
684
+ export interface IntelligenceActionGuard {
685
+ name: string;
686
+ passed: boolean;
687
+ reason?: string;
688
+ }
689
+ export interface IntelligenceAction {
690
+ id: string;
691
+ timestamp: string;
692
+ decidedAt: string;
693
+ runId: string;
694
+ familyId?: string;
695
+ project?: string;
696
+ stepName?: string;
697
+ actor: IntelligenceActionActor;
698
+ verdict: {
699
+ category?: FailureCategory;
700
+ patternId?: string;
701
+ confidence: RunRecoveryProposalConfidence;
702
+ rationale?: string;
703
+ };
704
+ guards: IntelligenceActionGuard[];
705
+ outcome: IntelligenceActionOutcome;
706
+ outcomeReason?: IntelligenceActionOutcomeReason;
707
+ latencyMs?: number;
708
+ appliedAction?: {
709
+ type: IntelligenceActionProposedType;
710
+ stepName?: string;
711
+ replayRunId?: string;
712
+ tmuxKeys?: string;
713
+ };
714
+ followupOutcome?: IntelligenceActionFollowup;
715
+ tier: IntelligenceActionTier;
716
+ costUsd: number;
717
+ }
718
+ export interface IntelligenceActionsSummary {
719
+ /** Count of records after date filtering; independent from the returned page size. */
720
+ total: number;
721
+ byActor: Record<string, number>;
722
+ byOutcome: Record<string, number>;
723
+ /** Most recent records after date filtering, capped by request limit. */
724
+ records: IntelligenceAction[];
725
+ metadata: {
726
+ parseFailures: number;
727
+ shapeDriftFailures: number;
728
+ };
729
+ }
730
+ export interface Run {
731
+ id: string;
732
+ familyId: string;
733
+ parentRunId?: string | null;
734
+ familyRootTicketOrPr?: string;
735
+ /** Run policy bucket: production, validation, or comparison. Not a flow type and not an eval identity. */
736
+ lane: RunLane;
737
+ /** Required only for comparison-lane sibling attempts; never a mode. */
738
+ variant?: string | null;
739
+ /** Selected project-owned worker template version for this run. */
740
+ taskTemplate?: TaskTemplateSelection;
741
+ /** Worker pipeline/template carrier. Eval candidates may use dev as a carrier while taskProfile stores rubric semantics. */
742
+ flowType: FlowType;
743
+ /** Operator/autonomy behavior preset. mode='validation' implies lane='validation' and is not used for comparison siblings. */
744
+ mode?: 'interactive' | 'autonomous' | 'validation';
745
+ /** Dev-only interactive policy. Keeps flowType='dev' while allowing flexible human-steered runs. */
746
+ devInteractiveProfile?: DevInteractiveProfile;
747
+ status: RunStatus;
748
+ project: string;
749
+ ticketOrPr: string;
750
+ app?: string;
751
+ effort?: string;
752
+ slotId: string | null;
753
+ branch: string | null;
754
+ /** Completion side-effect policy; artifact-only suppresses publication/PR mutation paths. */
755
+ completionPolicy?: RunCompletionPolicy;
756
+ /** Requested/resolved base ref for artifact-only comparison replay runs. */
757
+ startRef?: RunStartRefProvenance | null;
758
+ /** Gateway-captured template provenance for the rendered worker task. */
759
+ templateProvenance?: TemplateProvenance | null;
760
+ taskFile: string | null;
761
+ activeTaskFile?: string;
762
+ agentContexts?: AgentContext[];
763
+ prNumber?: number;
764
+ steps: RunStep[];
765
+ decisions: RunDecision[];
766
+ metrics: RunMetrics;
767
+ createdAt: string;
768
+ updatedAt: string;
769
+ ticketData?: RunTicketData;
770
+ grade?: RunGrade;
771
+ humanGrade?: HumanGrade;
772
+ links?: RunLink[];
773
+ summary?: string;
774
+ reviewTier?: string;
775
+ safetyTier?: SafetyTier;
776
+ /**
777
+ * Slots the run is allowed to land on, resolved from the UI's global filters
778
+ * (e.g. machines, future filter dimensions) at dispatch time. `null` = unrestricted.
779
+ * Honored by FIND_SLOT, affinity reuse, and chained runs. Strictly narrower than
780
+ * the project-wide pool but wider than `slotId`, which pins a single slot.
781
+ */
782
+ allowedSlots?: string[] | null;
783
+ /** Internal backlog handoff link, persisted so backlog delete/reconcile can find runs. */
784
+ backlogItemId?: string;
785
+ completedAt?: string;
786
+ error?: string;
787
+ /**
788
+ * When set, this run was cancelled because the engine forked it into another run
789
+ * (e.g. the collision → comparison-lane redirect at WRITE_TASK). UI surfaces this as
790
+ * an info banner with a link to the successor instead of treating the run as a failure.
791
+ */
792
+ redirectedToRunId?: string | null;
793
+ monitorState?: RunMonitorState;
794
+ /** CI-watch inline-fix dedup + counters. Persisted so the circuit breaker survives gateway restart (ADR-027). */
795
+ ciWatchState?: RunCiWatchState;
796
+ /** Run-engine runtime flags + replay generation counter. Persisted so warm-recovery hints
797
+ * and stale-loop guards survive gateway restart (ADR-027). */
798
+ engineState?: RunEngineState;
799
+ /** Provenance-aware live recipe context used by slot-view/dev harness surfaces. */
800
+ liveRecipeContext?: LiveRecipeContext | null;
801
+ recoveryAttempts?: RunReplayStep[];
802
+ recoveryProposal?: RunRecoveryRuntimeProposal;
803
+ autoRecoveryDisabled?: boolean;
804
+ }
805
+ export declare function isLightweightInteractiveDevRun(run: Pick<Run, 'flowType' | 'mode' | 'devInteractiveProfile'>): boolean;
806
+ export declare function isInteractiveDevRun(run: Pick<Run, 'flowType' | 'mode'>): boolean;
807
+ /** Persisted run-engine state — see ADR-027. */
808
+ export interface RunEngineState {
809
+ /** Runtime hints set by dispatch UI (e.g. skipPrepare) or engine (warmRecovery on crash resume).
810
+ * `nudgeReuse` is set when the operator picks "Nudge worker" in the dispatch wizard or the
811
+ * branch-affinity decision card; FIND_SLOT honors it to bind the busy slot, and DISPATCH
812
+ * routes through `nudgeDispatch` (skip PREPARE, send-keys to existing tmux session) instead
813
+ * of `dispatchExecute` (kill + relaunch). `freshReuse` is the "Kill & dispatch fresh"
814
+ * sibling — FIND_SLOT hard-kills the prior worker BEFORE PREPARE so git reset / checkout /
815
+ * dependency install don't race a still-writing worker in the same worktree. */
816
+ flags?: {
817
+ skipPrepare?: boolean;
818
+ warmRecovery?: boolean;
819
+ nudgeReuse?: boolean;
820
+ freshReuse?: boolean;
821
+ };
822
+ /** Monotonic replay generation counter; startRun bails if the run has been superseded. */
823
+ generation?: number;
824
+ autoRecoveryDeadLetter?: string;
825
+ intelligenceAuditDegraded?: boolean;
826
+ /** Local-first publication gate metadata. Stored on the run JSON snapshot; no DB migration. */
827
+ publishGate?: {
828
+ packageId?: string;
829
+ packageHash?: string;
830
+ packageInputHash?: string;
831
+ reviewSubjectHash?: string;
832
+ packageArtifactPath?: string;
833
+ approvedPackageHash?: string;
834
+ approvedAt?: string;
835
+ publicationTarget?: PublicationTarget;
836
+ publicationStatus?: PublicationStatus;
837
+ prNumber?: number | null;
838
+ reviewDepth?: ReviewDepthPolicy;
839
+ pendingReviewPlan?: ReviewLoopRequest[];
840
+ independentReviews?: IndependentReviewStatus[];
841
+ supersededPackageIds?: string[];
842
+ feedbackArtifactPath?: string;
843
+ };
844
+ /** Artifact-first experiment trial linkage for artifact-only reference/template regression candidates. */
845
+ evalExperiment?: {
846
+ /** Matrix/suite-wide cap group for eval queue accounting across per-case experiments. */
847
+ capGroupId?: string;
848
+ suiteId?: string;
849
+ experimentId: string;
850
+ experimentKey: string;
851
+ experimentManifestPath: string;
852
+ packagePath: string;
853
+ candidateStrategyFingerprint: string;
854
+ trialId: string;
855
+ };
856
+ /** Interactive dev operator workflow metadata and terminal action history. */
857
+ interactiveDev?: {
858
+ profile?: DevInteractiveProfile;
859
+ initialContext?: string;
860
+ checklist?: string[];
861
+ terminalActions?: DevInteractiveActionRecord[];
862
+ };
863
+ }
864
+ /**
865
+ * Per-run CI-watch inline-fix state — persisted on {@link Run} so dedup signatures
866
+ * and attempt counters survive gateway restart (ADR-027).
867
+ */
868
+ export interface RunCiWatchState {
869
+ /** Last successfully-dispatched fix fingerprint (bot-comment signature + HEAD sha). */
870
+ dedup?: {
871
+ signature: string;
872
+ commitSha: string;
873
+ };
874
+ /** When the current no-progress timeout window started. */
875
+ timeoutWindowStartedAt?: string;
876
+ /** Last observed progress in watched CI status or PR head. */
877
+ lastProgressAt?: string;
878
+ /** Human-readable reason for the last progress reset. */
879
+ lastProgressReason?: string;
880
+ /** Last watched-check status fingerprint used to detect progress. */
881
+ lastCheckFingerprint?: string;
882
+ /** Last observed local PR head SHA used to detect new commits. */
883
+ lastHeadSha?: string | null;
884
+ /** Consecutive-failure counter; resets on success. Gates consecutive fallback (MAX_INLINE_CI_FIX_ATTEMPTS). */
885
+ consecutiveAttempts: number;
886
+ /** Lifetime attempt counter; never resets. Gates hard ceiling (MAX_INLINE_CI_FIX_TOTAL). */
887
+ totalAttempts: number;
888
+ /** Count of dedup-filtered skips, surfaced in step outputs. */
889
+ skips: number;
890
+ }
891
+ export type FamilyDiffProvenanceSource = 'artifact' | 'legacy-step-output' | 'unavailable';
892
+ export type FamilyDiffKind = 'contribution' | 'review-input' | 'legacy';
893
+ export interface FamilyDiffProvenance {
894
+ source: FamilyDiffProvenanceSource;
895
+ available: boolean;
896
+ files: number;
897
+ additions: number;
898
+ deletions: number;
899
+ partialStat?: DiffStat;
900
+ kind: FamilyDiffKind;
901
+ filter?: 'source-code';
902
+ artifactPath?: string;
903
+ baseRef?: string;
904
+ baseSha?: string;
905
+ headRef?: string;
906
+ headSha?: string;
907
+ capturedAt?: string;
908
+ configSource?: 'project' | 'gateway-default';
909
+ configFallbackReason?: string;
910
+ configFallbackError?: string;
911
+ missingReason?: string;
912
+ error?: string;
913
+ repository?: string;
914
+ prNumber?: number;
915
+ }
916
+ export declare function isFamilyDiffProvenance(value: unknown): value is FamilyDiffProvenance;
917
+ export interface FamilyInputCommitMetadata {
918
+ repository?: string;
919
+ prNumber?: number;
920
+ baseRef?: string;
921
+ baseSha?: string;
922
+ headRef?: string;
923
+ headSha?: string;
924
+ capturedAt: string;
925
+ source: 'github-pr' | 'local-git' | 'unavailable';
926
+ missingReason?: string;
927
+ error?: string;
928
+ }
929
+ export interface FamilyReviewSignalSummary {
930
+ total: number;
931
+ real: number;
932
+ fixed: number;
933
+ botAddressed: number;
934
+ humanReviewersRequestingChanges: number;
935
+ humanCommentsAddressed: number;
936
+ unknownSource: number;
937
+ }
938
+ export interface FamilyArtifactBucketSummary {
939
+ key: string;
940
+ count: number;
941
+ bytes: number;
942
+ }
943
+ export interface FamilyArtifactFootprint {
944
+ count: number;
945
+ bytes: number;
946
+ byPurpose: FamilyArtifactBucketSummary[];
947
+ bySource: FamilyArtifactBucketSummary[];
948
+ byExtension: FamilyArtifactBucketSummary[];
949
+ }
950
+ export interface FamilyObservabilityArtifact {
951
+ runId: string;
952
+ familyId: string;
953
+ sourceRunId?: string;
954
+ sourceFamilyId?: string;
955
+ stepName?: string | null;
956
+ path: string;
957
+ purpose: string;
958
+ sha256?: string;
959
+ sizeBytes?: number;
960
+ source: 'artifact-manifest' | 'step-output' | 'task-artifact' | 'task-input' | 'inherited-context' | 'recovered-provenance';
961
+ }
962
+ export interface FamilyChangeLedgerEntry {
963
+ runId: string;
964
+ familyId: string;
965
+ parentRunId?: string | null;
966
+ familyRootTicketOrPr: string;
967
+ lane: RunLane;
968
+ variant?: string | null;
969
+ flowType: FlowType;
970
+ project: string;
971
+ ticketOrPr: string;
972
+ branch: string | null;
973
+ prNumber: number | null;
974
+ createdAt: string;
975
+ completedAt?: string;
976
+ changeKind: 'contribution' | 'review-input' | 'follow-up' | 'legacy' | 'none';
977
+ contributionDiff: FamilyDiffProvenance;
978
+ inputDiff?: FamilyDiffProvenance;
979
+ legacyDiffFallback?: FamilyDiffProvenance;
980
+ inputCommit?: FamilyInputCommitMetadata;
981
+ reviewSignals?: FamilyReviewSignalSummary;
982
+ artifactFootprint: FamilyArtifactFootprint;
983
+ taskInputArtifacts: FamilyObservabilityArtifact[];
984
+ missingData: string[];
985
+ }
986
+ export interface FamilyChangeLedgerSummary {
987
+ /** Runs with any captured contribution or reviewed-input diff. A run counts once even when both kinds are present. */
988
+ runsWithDiff: number;
989
+ /** Runs with neither contribution diff nor reviewed-input provenance; explicit empty/unavailable review input is counted in review-input buckets instead. */
990
+ runsMissingDiff: number;
991
+ /** Runs with available contribution diff stats, including oversized diffs with partial numstat totals. */
992
+ runsWithContributionDiff: number;
993
+ runsWithReviewInputDiff: number;
994
+ runsWithEmptyReviewInputDiff: number;
995
+ runsWithUnavailableReviewInputDiff: number;
996
+ totalContributionFiles: number;
997
+ totalContributionAdditions: number;
998
+ totalContributionDeletions: number;
999
+ reviewRounds: number;
1000
+ bugbotFindingsAddressed: number;
1001
+ humanReviewersRequestingChanges: number;
1002
+ humanCommentsAddressed: number;
1003
+ artifactFootprint: FamilyArtifactFootprint;
1004
+ }
1005
+ export interface FamilyChangeLedger {
1006
+ summary: FamilyChangeLedgerSummary;
1007
+ entries: FamilyChangeLedgerEntry[];
1008
+ }
1009
+ export type FlowType = 'fix-bug' | 'review-pr' | 'dev' | 'pr-complete' | 'merge-main';
1010
+ export type RunLane = 'production' | 'validation' | 'comparison';
1011
+ export type DevInteractiveProfile = 'lightweight' | 'reviewed';
1012
+ export declare const DEFAULT_DEV_INTERACTIVE_PROFILE: DevInteractiveProfile;
1013
+ export type DevInteractiveCompletionAction = 'done-no-pr' | 'detect-pr-and-ci-watch' | 'link-pr-and-ci-watch' | 'link-pr-and-pr-complete' | 'run-self-review' | 'blocked' | 'failed' | 'abort';
1014
+ export interface DevInteractiveActionRecord {
1015
+ action: DevInteractiveCompletionAction;
1016
+ source: 'operator';
1017
+ timestamp: string;
1018
+ reason?: string;
1019
+ prRef?: string;
1020
+ }
1021
+ /** Pipeline step names — single source of truth. Use these instead of string literals. */
1022
+ export declare const PipelineSteps: {
1023
+ readonly GRADE: "grade";
1024
+ readonly FIND_SLOT: "find-slot";
1025
+ readonly WRITE_TASK: "write-task";
1026
+ readonly PREPARE: "prepare";
1027
+ readonly DISPATCH: "dispatch";
1028
+ readonly MONITOR: "monitor";
1029
+ readonly SELF_REVIEW: "self-review";
1030
+ readonly COMPLETE: "complete";
1031
+ readonly HUMAN_GATE: "human-gate";
1032
+ readonly FINALIZE: "finalize";
1033
+ readonly CI_WATCH: "ci-watch";
1034
+ };
1035
+ export type PipelineStep = (typeof PipelineSteps)[keyof typeof PipelineSteps];
1036
+ export declare const FLOW_STEPS: Record<FlowType, PipelineStep[]>;
1037
+ /**
1038
+ * Worker report artifact filename(s) per flow type, ordered by preference.
1039
+ * The retrospective decision reads the first non-empty match.
1040
+ *
1041
+ * - `fix-bug` / `dev` workers write `report.md` (build, fixes, validation summary)
1042
+ * - `pr-complete` worker writes `comments-report.md` (triage table, replies, fix commit)
1043
+ * - `review-pr` worker writes `review.md` (verdict + line comments)
1044
+ *
1045
+ * Adding a new flow = add an entry. Adding a new artifact = prepend to the list.
1046
+ * Falls back to `report.md` for any flow not listed.
1047
+ */
1048
+ export declare const FLOW_WORKER_REPORT_ARTIFACTS: Record<FlowType, string[]>;
1049
+ /** Default branch fallback. Projects should set `default_branch` in project.json. */
1050
+ export declare const DEFAULT_BRANCH = "main";
1051
+ /** Default worker task directory (relative to repo root). Projects can override via `task_dir` in project.json. */
1052
+ export declare const DEFAULT_TASK_DIR = ".task";
1053
+ /** Default Claude model used when no slot/task/project/user override is set.
1054
+ * Changing this value alters defaults across the dispatch wizard and gateway
1055
+ * dispatch path — verify all `DEFAULT_CLAUDE_MODEL` callers when touching it. */
1056
+ export declare const DEFAULT_CLAUDE_MODEL = "opus";
1057
+ /** Default Cursor Agent model used when no slot/task/project/user override is set. */
1058
+ export declare const DEFAULT_CURSOR_MODEL = "composer-2";
1059
+ export type DecisionType = 'collision_check' | 'plan_confirmation' | 'retrospective' | 'review_posting' | 'blocked_alert' | 'review_comments' | 'improvement' | 'recipe_strategy' | `engine_${string}` | `monitor_${string}` | `ci_${string}`;
1060
+ /** Lightweight run summary for contextual display (e.g. decision cards). Derived from Run + RunMetrics. */
1061
+ export interface RunMeta {
1062
+ runId: string;
1063
+ familyId?: string;
1064
+ flowType: FlowType;
1065
+ ticketOrPr: string;
1066
+ prNumber?: number;
1067
+ branch?: string;
1068
+ runner?: string;
1069
+ model?: string;
1070
+ summary?: string;
1071
+ }
1072
+ export interface PendingDecision {
1073
+ id: string;
1074
+ type: DecisionType;
1075
+ slotId: string | null;
1076
+ title: string;
1077
+ description: string;
1078
+ context: Record<string, unknown>;
1079
+ actions: DecisionAction[];
1080
+ createdAt: string;
1081
+ runMeta?: RunMeta;
1082
+ payload?: RunDecisionPayload;
1083
+ }
1084
+ export interface DecisionAction {
1085
+ id: string;
1086
+ label: string;
1087
+ style: 'primary' | 'secondary' | 'danger';
1088
+ /** Optional one-line explanation of what this action does and when to pick it. Renders as
1089
+ * hover tooltip + inline subtext under the button so operators don't have to guess. */
1090
+ description?: string;
1091
+ }
1092
+ export interface ScriptOutput {
1093
+ requestId: string;
1094
+ stream: 'stdout' | 'stderr';
1095
+ data: string;
1096
+ timestamp: number;
1097
+ }
1098
+ export interface ScriptComplete {
1099
+ requestId: string;
1100
+ exitCode: number;
1101
+ duration: number;
1102
+ error?: string;
1103
+ artifactRoot?: string;
1104
+ }
1105
+ //# sourceMappingURL=runs.d.ts.map