ai-foreman 1.7.29 → 2.0.1

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 (156) hide show
  1. package/README.md +1 -1
  2. package/dist/adapters/claude.d.ts +23 -12
  3. package/dist/adapters/claude.js +231 -26
  4. package/dist/adapters/codex.d.ts +19 -7
  5. package/dist/adapters/codex.js +202 -19
  6. package/dist/adapters/recovering.d.ts +2 -0
  7. package/dist/adapters/recovering.js +5 -1
  8. package/dist/adapters/structured.d.ts +71 -0
  9. package/dist/adapters/structured.js +213 -0
  10. package/dist/adapters/types.d.ts +85 -9
  11. package/dist/agentRun.d.ts +2 -0
  12. package/dist/agentRun.js +2 -1
  13. package/dist/boundedTurnEvidence.d.ts +18 -0
  14. package/dist/boundedTurnEvidence.js +76 -0
  15. package/dist/branch/currentGuard.d.ts +2 -0
  16. package/dist/branch/currentGuard.js +2 -0
  17. package/dist/branch/git.js +3 -8
  18. package/dist/branch/planner.js +1 -4
  19. package/dist/branch/runner.d.ts +2 -1
  20. package/dist/branch/runner.js +10 -7
  21. package/dist/buildAdmission.js +4 -0
  22. package/dist/buildApproval.d.ts +15 -0
  23. package/dist/buildApproval.js +28 -9
  24. package/dist/buildAssignment.d.ts +1 -0
  25. package/dist/buildAssignment.js +82 -23
  26. package/dist/buildInterventions.d.ts +2 -2
  27. package/dist/buildInterventions.js +11 -4
  28. package/dist/buildLaunchGate.js +3 -2
  29. package/dist/buildRuns.d.ts +1 -0
  30. package/dist/buildRuns.js +6 -1
  31. package/dist/builderGuidanceFollowup.js +17 -6
  32. package/dist/cli/doctor.js +3 -1
  33. package/dist/cli/manager.js +22 -20
  34. package/dist/cli/start.js +85 -39
  35. package/dist/cli/tickets.d.ts +0 -8
  36. package/dist/cli/tickets.js +50 -60
  37. package/dist/continuity.d.ts +10 -16
  38. package/dist/continuity.js +223 -208
  39. package/dist/continuityOrigin.d.ts +13 -0
  40. package/dist/continuityOrigin.js +91 -0
  41. package/dist/dispatchNotSent.d.ts +4 -0
  42. package/dist/dispatchNotSent.js +10 -0
  43. package/dist/foreman.d.ts +15 -16
  44. package/dist/foreman.js +70 -278
  45. package/dist/gitExclude.d.ts +16 -0
  46. package/dist/gitExclude.js +46 -0
  47. package/dist/graph/boundary.d.ts +1 -1
  48. package/dist/graph/boundary.js +1 -1
  49. package/dist/graph/host.js +8 -19
  50. package/dist/graph/manager.d.ts +1 -1
  51. package/dist/graph/manager.js +1 -1
  52. package/dist/graph/preparation.d.ts +38 -0
  53. package/dist/graph/preparation.js +7 -6
  54. package/dist/graph/semantic.d.ts +1 -0
  55. package/dist/graph/semantic.js +4 -1
  56. package/dist/graph/session.js +7 -2
  57. package/dist/graph/turn.d.ts +3 -4
  58. package/dist/graph/turn.js +29 -41
  59. package/dist/handoffProtocol.js +2 -2
  60. package/dist/handoffs.d.ts +5 -3
  61. package/dist/handoffs.js +92 -88
  62. package/dist/hostGraphApplicability.d.ts +2 -1
  63. package/dist/hostGraphApplicability.js +17 -19
  64. package/dist/hostQaAugmentation.js +21 -4
  65. package/dist/hostQaComparison.d.ts +21 -2
  66. package/dist/hostQaComparison.js +43 -29
  67. package/dist/hostSourcePreservation.d.ts +38 -0
  68. package/dist/hostSourcePreservation.js +72 -0
  69. package/dist/humanDecision.d.ts +7 -0
  70. package/dist/humanDecision.js +11 -0
  71. package/dist/interviews.d.ts +7 -0
  72. package/dist/interviews.js +18 -1
  73. package/dist/legacyCommunicationDisplay.d.ts +2 -0
  74. package/dist/legacyCommunicationDisplay.js +2 -0
  75. package/dist/managerPacket.js +3 -3
  76. package/dist/markers.d.ts +4 -3
  77. package/dist/markers.js +4 -20
  78. package/dist/observability.js +3 -8
  79. package/dist/probeIpc.d.ts +14 -0
  80. package/dist/probeIpc.js +29 -0
  81. package/dist/qaBuildGate.d.ts +21 -0
  82. package/dist/qaBuildGate.js +60 -13
  83. package/dist/qaBuilderCoverage.js +22 -13
  84. package/dist/qaBuilderEvidence.d.ts +16 -1
  85. package/dist/qaBuilderEvidence.js +48 -8
  86. package/dist/qaContractCoverage.d.ts +2 -2
  87. package/dist/qaContractCoverage.js +4 -9
  88. package/dist/qaContractDelivery.js +34 -20
  89. package/dist/qaCoverageAssembly.d.ts +22 -0
  90. package/dist/qaCoverageAssembly.js +16 -0
  91. package/dist/qaDeliveryJournal.d.ts +2 -0
  92. package/dist/qaDeliveryJournal.js +19 -0
  93. package/dist/qaFailureDelivery.js +97 -85
  94. package/dist/qaHostTransformation.d.ts +26 -0
  95. package/dist/qaHostTransformation.js +100 -0
  96. package/dist/qaPreparation.d.ts +8 -20
  97. package/dist/qaPreparation.js +153 -254
  98. package/dist/qaPreparationInputs.js +19 -0
  99. package/dist/qaPreparationStore.d.ts +11 -0
  100. package/dist/qaPreparationStore.js +44 -4
  101. package/dist/qaPrerequisites.d.ts +2 -1
  102. package/dist/qaPrerequisites.js +21 -1
  103. package/dist/qaProtocolV2.d.ts +15 -0
  104. package/dist/qaRecovery.d.ts +0 -3
  105. package/dist/qaRecovery.js +21 -27
  106. package/dist/qaReview.js +241 -406
  107. package/dist/qaReviewEvidence.d.ts +7 -3
  108. package/dist/qaReviewEvidence.js +15 -4
  109. package/dist/qaRuntime.js +1 -1
  110. package/dist/qaSnapshot.js +76 -21
  111. package/dist/qaStructuredResponse.d.ts +18 -0
  112. package/dist/qaStructuredResponse.js +81 -0
  113. package/dist/qaTimeline.js +2 -2
  114. package/dist/qaVerificationContract.d.ts +1 -2
  115. package/dist/qaVerificationContract.js +24 -35
  116. package/dist/readinessGate.js +5 -4
  117. package/dist/recoveryOwners.d.ts +32 -0
  118. package/dist/recoveryOwners.js +87 -0
  119. package/dist/runtimePreflight.d.ts +11 -0
  120. package/dist/runtimePreflight.js +77 -0
  121. package/dist/runtimeReadiness.js +23 -15
  122. package/dist/sources/sourceRegistry.d.ts +0 -3
  123. package/dist/sources/sourceRegistry.js +0 -42
  124. package/dist/statusReporter.d.ts +2 -0
  125. package/dist/statusReporter.js +2 -0
  126. package/dist/structuredCutover.d.ts +31 -0
  127. package/dist/structuredCutover.js +510 -0
  128. package/dist/structuredCutoverFiles.d.ts +10 -0
  129. package/dist/structuredCutoverFiles.js +181 -0
  130. package/dist/structuredDispatchAuthority.d.ts +22 -0
  131. package/dist/structuredDispatchAuthority.js +110 -0
  132. package/dist/structuredDispatchRecord.d.ts +29 -0
  133. package/dist/structuredDispatchRecord.js +36 -0
  134. package/dist/structuredLiveBudget.d.ts +2 -0
  135. package/dist/structuredLiveBudget.js +23 -0
  136. package/dist/structuredOperation.d.ts +18 -0
  137. package/dist/structuredOperation.js +279 -0
  138. package/dist/supervisedStart.js +35 -21
  139. package/dist/ticketPlanning.d.ts +1 -376
  140. package/dist/ticketPlanning.js +2 -49
  141. package/dist/ticketPopulation.d.ts +0 -3
  142. package/dist/ticketPopulation.js +4 -21
  143. package/dist/ticketPopulationPageAuthority.d.ts +13 -0
  144. package/dist/ticketPopulationPageAuthority.js +30 -0
  145. package/dist/ticketPopulationPaging.d.ts +27 -0
  146. package/dist/ticketPopulationPaging.js +127 -0
  147. package/dist/tickets/renderMarkdown.d.ts +14 -0
  148. package/dist/tickets/renderMarkdown.js +39 -5
  149. package/dist/tickets/ticketLoader.js +10 -0
  150. package/dist/tickets/ticketSchema.d.ts +107 -0
  151. package/dist/tickets/ticketSchema.js +4 -1
  152. package/dist/workflowDb.d.ts +116 -3
  153. package/dist/workflowDb.js +852 -61
  154. package/dist/workflowReader.d.ts +1 -0
  155. package/dist/workflowReader.js +9 -0
  156. package/package.json +23 -7
@@ -2,9 +2,6 @@ import type { TicketDef } from "./tickets/ticketSchema.js";
2
2
  import { type TicketStatus } from "./tickets/stateDb.js";
3
3
  import { type DeliveryConfig } from "./tickets/delivery.js";
4
4
  import { type TicketBuildSetupConfig } from "./tickets/setupConfig.js";
5
- import { z } from "zod";
6
- export declare const PROPOSAL_START = "RAFI_PROPOSAL_START";
7
- export declare const PROPOSAL_END = "RAFI_PROPOSAL_END";
8
5
  export interface TicketEdit {
9
6
  id: string;
10
7
  patch: Partial<Omit<TicketDef, "id">>;
@@ -69,382 +66,10 @@ export interface TicketPlanningContext {
69
66
  export interface TicketPlanValidationContext {
70
67
  futureWorkIds?: Iterable<number>;
71
68
  }
72
- export declare const ticketPlanProposalV1Schema: z.ZodObject<{
73
- version: z.ZodLiteral<1>;
74
- title: z.ZodString;
75
- markdown: z.ZodString;
76
- additions: z.ZodArray<z.ZodObject<{
77
- qa_preparation: z.ZodOptional<z.ZodObject<{
78
- version: z.ZodLiteral<1>;
79
- decisionId: z.ZodString;
80
- level: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>, z.ZodLiteral<4>, z.ZodLiteral<5>]>;
81
- rationale: z.ZodString;
82
- riskFactors: z.ZodArray<z.ZodObject<{
83
- category: z.ZodEnum<{
84
- interaction: "interaction";
85
- compatibility: "compatibility";
86
- "state-transition": "state-transition";
87
- "external-dependency": "external-dependency";
88
- authorization: "authorization";
89
- security: "security";
90
- "data-integrity": "data-integrity";
91
- migration: "migration";
92
- concurrency: "concurrency";
93
- recovery: "recovery";
94
- deployment: "deployment";
95
- "architecture-uncertainty": "architecture-uncertainty";
96
- }>;
97
- rationale: z.ZodString;
98
- references: z.ZodArray<z.ZodString>;
99
- }, z.core.$strict>>;
100
- lowRisk: z.ZodOptional<z.ZodObject<{
101
- narrowBehavior: z.ZodString;
102
- understoodDependencies: z.ZodString;
103
- adequateVerification: z.ZodString;
104
- }, z.core.$strict>>;
105
- policyVersion: z.ZodLiteral<"qa-preparation-v1">;
106
- plannerOperationId: z.ZodString;
107
- plannerIdentity: z.ZodString;
108
- timestamp: z.ZodString;
109
- minimumLevel: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>, z.ZodLiteral<4>, z.ZodLiteral<5>]>;
110
- minimumReasons: z.ZodArray<z.ZodString>;
111
- predecessorDecisionId: z.ZodOptional<z.ZodString>;
112
- }, z.core.$strict>>;
113
- id: z.ZodString;
114
- order: z.ZodNumber;
115
- documentation: z.ZodOptional<z.ZodObject<{
116
- required: z.ZodBoolean;
117
- targets: z.ZodArray<z.ZodString>;
118
- criteria: z.ZodArray<z.ZodString>;
119
- }, z.core.$strict>>;
120
- title: z.ZodString;
121
- area: z.ZodString;
122
- priority: z.ZodEnum<{
123
- P0: "P0";
124
- P1: "P1";
125
- P2: "P2";
126
- P3: "P3";
127
- }>;
128
- size: z.ZodEnum<{
129
- XS: "XS";
130
- S: "S";
131
- M: "M";
132
- L: "L";
133
- XL: "XL";
134
- }>;
135
- risk: z.ZodEnum<{
136
- Low: "Low";
137
- Medium: "Medium";
138
- High: "High";
139
- }>;
140
- depends_on: z.ZodArray<z.ZodString>;
141
- summary: z.ZodString;
142
- acceptance: z.ZodArray<z.ZodString>;
143
- required_tests: z.ZodArray<z.ZodString>;
144
- likely_files: z.ZodArray<z.ZodString>;
145
- rollback: z.ZodOptional<z.ZodNullable<z.ZodString>>;
146
- notes: z.ZodOptional<z.ZodNullable<z.ZodString>>;
147
- external_refs: z.ZodOptional<z.ZodArray<z.ZodObject<{
148
- provider: z.ZodString;
149
- id: z.ZodString;
150
- key: z.ZodOptional<z.ZodNullable<z.ZodString>>;
151
- url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
152
- }, z.core.$strict>>>;
153
- source_refs: z.ZodOptional<z.ZodArray<z.ZodObject<{
154
- source: z.ZodString;
155
- item: z.ZodString;
156
- source_id: z.ZodOptional<z.ZodString>;
157
- url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
158
- fingerprint: z.ZodOptional<z.ZodNullable<z.ZodString>>;
159
- note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
160
- }, z.core.$strict>>>;
161
- superseded_by: z.ZodOptional<z.ZodArray<z.ZodString>>;
162
- supersedes: z.ZodOptional<z.ZodArray<z.ZodString>>;
163
- plan_ref: z.ZodOptional<z.ZodObject<{
164
- plan_id: z.ZodString;
165
- revision: z.ZodNumber;
166
- slice_ref: z.ZodString;
167
- }, z.core.$strict>>;
168
- }, z.core.$strict>>;
169
- edits: z.ZodArray<z.ZodObject<{
170
- id: z.ZodString;
171
- patch: z.ZodObject<{
172
- qa_preparation: z.ZodOptional<z.ZodOptional<z.ZodObject<{
173
- version: z.ZodLiteral<1>;
174
- decisionId: z.ZodString;
175
- level: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>, z.ZodLiteral<4>, z.ZodLiteral<5>]>;
176
- rationale: z.ZodString;
177
- riskFactors: z.ZodArray<z.ZodObject<{
178
- category: z.ZodEnum<{
179
- interaction: "interaction";
180
- compatibility: "compatibility";
181
- "state-transition": "state-transition";
182
- "external-dependency": "external-dependency";
183
- authorization: "authorization";
184
- security: "security";
185
- "data-integrity": "data-integrity";
186
- migration: "migration";
187
- concurrency: "concurrency";
188
- recovery: "recovery";
189
- deployment: "deployment";
190
- "architecture-uncertainty": "architecture-uncertainty";
191
- }>;
192
- rationale: z.ZodString;
193
- references: z.ZodArray<z.ZodString>;
194
- }, z.core.$strict>>;
195
- lowRisk: z.ZodOptional<z.ZodObject<{
196
- narrowBehavior: z.ZodString;
197
- understoodDependencies: z.ZodString;
198
- adequateVerification: z.ZodString;
199
- }, z.core.$strict>>;
200
- policyVersion: z.ZodLiteral<"qa-preparation-v1">;
201
- plannerOperationId: z.ZodString;
202
- plannerIdentity: z.ZodString;
203
- timestamp: z.ZodString;
204
- minimumLevel: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>, z.ZodLiteral<4>, z.ZodLiteral<5>]>;
205
- minimumReasons: z.ZodArray<z.ZodString>;
206
- predecessorDecisionId: z.ZodOptional<z.ZodString>;
207
- }, z.core.$strict>>>;
208
- id: z.ZodOptional<z.ZodString>;
209
- order: z.ZodOptional<z.ZodNumber>;
210
- documentation: z.ZodOptional<z.ZodOptional<z.ZodObject<{
211
- required: z.ZodBoolean;
212
- targets: z.ZodArray<z.ZodString>;
213
- criteria: z.ZodArray<z.ZodString>;
214
- }, z.core.$strict>>>;
215
- title: z.ZodOptional<z.ZodString>;
216
- area: z.ZodOptional<z.ZodString>;
217
- priority: z.ZodOptional<z.ZodEnum<{
218
- P0: "P0";
219
- P1: "P1";
220
- P2: "P2";
221
- P3: "P3";
222
- }>>;
223
- size: z.ZodOptional<z.ZodEnum<{
224
- XS: "XS";
225
- S: "S";
226
- M: "M";
227
- L: "L";
228
- XL: "XL";
229
- }>>;
230
- risk: z.ZodOptional<z.ZodEnum<{
231
- Low: "Low";
232
- Medium: "Medium";
233
- High: "High";
234
- }>>;
235
- depends_on: z.ZodOptional<z.ZodArray<z.ZodString>>;
236
- summary: z.ZodOptional<z.ZodString>;
237
- acceptance: z.ZodOptional<z.ZodArray<z.ZodString>>;
238
- required_tests: z.ZodOptional<z.ZodArray<z.ZodString>>;
239
- likely_files: z.ZodOptional<z.ZodArray<z.ZodString>>;
240
- rollback: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
241
- notes: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
242
- external_refs: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodObject<{
243
- provider: z.ZodString;
244
- id: z.ZodString;
245
- key: z.ZodOptional<z.ZodNullable<z.ZodString>>;
246
- url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
247
- }, z.core.$strict>>>>;
248
- source_refs: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodObject<{
249
- source: z.ZodString;
250
- item: z.ZodString;
251
- source_id: z.ZodOptional<z.ZodString>;
252
- url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
253
- fingerprint: z.ZodOptional<z.ZodNullable<z.ZodString>>;
254
- note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
255
- }, z.core.$strict>>>>;
256
- superseded_by: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
257
- supersedes: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
258
- plan_ref: z.ZodOptional<z.ZodOptional<z.ZodObject<{
259
- plan_id: z.ZodString;
260
- revision: z.ZodNumber;
261
- slice_ref: z.ZodString;
262
- }, z.core.$strict>>>;
263
- }, z.core.$strict>;
264
- }, z.core.$strict>>;
265
- supersessions: z.ZodArray<z.ZodObject<{
266
- replaced: z.ZodArray<z.ZodString>;
267
- replacements: z.ZodArray<z.ZodString>;
268
- reason: z.ZodString;
269
- }, z.core.$strict>>;
270
- state_changes: z.ZodArray<z.ZodObject<{
271
- id: z.ZodString;
272
- status: z.ZodEnum<{
273
- blocked: "blocked";
274
- in_progress: "in_progress";
275
- done: "done";
276
- planned: "planned";
277
- next: "next";
278
- canceled: "canceled";
279
- obsolete: "obsolete";
280
- }>;
281
- reason: z.ZodString;
282
- }, z.core.$strict>>;
283
- source_reconciliation: z.ZodArray<z.ZodObject<{
284
- source: z.ZodString;
285
- item: z.ZodString;
286
- disposition: z.ZodEnum<{
287
- split: "split";
288
- deferred: "deferred";
289
- combined: "combined";
290
- mapped: "mapped";
291
- excluded: "excluded";
292
- }>;
293
- ticket_ids: z.ZodArray<z.ZodString>;
294
- reason: z.ZodOptional<z.ZodString>;
295
- }, z.core.$strict>>;
296
- delivery: z.ZodOptional<z.ZodNullable<z.ZodObject<{
297
- version: z.ZodLiteral<1>;
298
- plan: z.ZodOptional<z.ZodObject<{
299
- plan_id: z.ZodString;
300
- revision: z.ZodNumber;
301
- }, z.core.$strict>>;
302
- units: z.ZodArray<z.ZodObject<{
303
- id: z.ZodString;
304
- tickets: z.ZodArray<z.ZodString>;
305
- branch_mode: z.ZodEnum<{
306
- current: "current";
307
- "per-ticket": "per-ticket";
308
- shared: "shared";
309
- }>;
310
- completion: z.ZodOptional<z.ZodEnum<{
311
- none: "none";
312
- pr: "pr";
313
- "auto-merge": "auto-merge";
314
- "direct-merge": "direct-merge";
315
- }>>;
316
- provider: z.ZodOptional<z.ZodEnum<{
317
- auto: "auto";
318
- local: "local";
319
- github: "github";
320
- gitlab: "gitlab";
321
- }>>;
322
- pr_ready: z.ZodOptional<z.ZodBoolean>;
323
- merge_method: z.ZodOptional<z.ZodEnum<{
324
- squash: "squash";
325
- merge: "merge";
326
- rebase: "rebase";
327
- }>>;
328
- cleanup: z.ZodOptional<z.ZodBoolean>;
329
- depends_on: z.ZodOptional<z.ZodArray<z.ZodString>>;
330
- dependency_mode: z.ZodOptional<z.ZodEnum<{
331
- combine: "combine";
332
- wait: "wait";
333
- stack: "stack";
334
- }>>;
335
- }, z.core.$strict>>;
336
- stacks: z.ZodOptional<z.ZodArray<z.ZodObject<{
337
- id: z.ZodString;
338
- name: z.ZodString;
339
- units: z.ZodArray<z.ZodString>;
340
- status: z.ZodOptional<z.ZodEnum<{
341
- partial: "partial";
342
- blocked: "blocked";
343
- in_progress: "in_progress";
344
- planned: "planned";
345
- merged: "merged";
346
- awaiting_review: "awaiting_review";
347
- }>>;
348
- completed_prefix: z.ZodOptional<z.ZodArray<z.ZodString>>;
349
- next_ticket: z.ZodOptional<z.ZodString>;
350
- review_links: z.ZodOptional<z.ZodArray<z.ZodString>>;
351
- remote_checked_at: z.ZodOptional<z.ZodString>;
352
- remote_stale: z.ZodOptional<z.ZodBoolean>;
353
- published_branches: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
354
- }, z.core.$strict>>>;
355
- }, z.core.$strict>>>;
356
- build_defaults: z.ZodOptional<z.ZodNullable<z.ZodObject<{
357
- branch_strategy: z.ZodOptional<z.ZodOptional<z.ZodEnum<{
358
- current: "current";
359
- batch: "batch";
360
- "branch-per-ticket": "branch-per-ticket";
361
- }>>>;
362
- completion: z.ZodOptional<z.ZodOptional<z.ZodEnum<{
363
- none: "none";
364
- pr: "pr";
365
- "auto-merge": "auto-merge";
366
- "direct-merge": "direct-merge";
367
- }>>>;
368
- provider: z.ZodOptional<z.ZodOptional<z.ZodEnum<{
369
- auto: "auto";
370
- local: "local";
371
- github: "github";
372
- gitlab: "gitlab";
373
- }>>>;
374
- pr_ready: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
375
- merge_method: z.ZodOptional<z.ZodOptional<z.ZodEnum<{
376
- squash: "squash";
377
- merge: "merge";
378
- rebase: "rebase";
379
- }>>>;
380
- cleanup: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
381
- auto_merge_wait: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
382
- auto_merge_timeout_minutes: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodNumber>>>;
383
- base_branch: z.ZodOptional<z.ZodOptional<z.ZodString>>;
384
- branch_prefix: z.ZodOptional<z.ZodOptional<z.ZodString>>;
385
- branch_policy: z.ZodOptional<z.ZodOptional<z.ZodObject<{
386
- mode: z.ZodEnum<{
387
- size: "size";
388
- global: "global";
389
- }>;
390
- global_strategy: z.ZodEnum<{
391
- current: "current";
392
- batch: "batch";
393
- "branch-per-ticket": "branch-per-ticket";
394
- }>;
395
- by_size: z.ZodObject<{
396
- XS: z.ZodEnum<{
397
- "per-ticket": "per-ticket";
398
- shared: "shared";
399
- }>;
400
- S: z.ZodEnum<{
401
- "per-ticket": "per-ticket";
402
- shared: "shared";
403
- }>;
404
- M: z.ZodEnum<{
405
- "per-ticket": "per-ticket";
406
- shared: "shared";
407
- }>;
408
- L: z.ZodEnum<{
409
- "per-ticket": "per-ticket";
410
- shared: "shared";
411
- }>;
412
- XL: z.ZodEnum<{
413
- "per-ticket": "per-ticket";
414
- shared: "shared";
415
- }>;
416
- }, z.core.$strict>;
417
- }, z.core.$strict>>>;
418
- review: z.ZodOptional<z.ZodOptional<z.ZodObject<{
419
- title_style: z.ZodEnum<{
420
- none: "none";
421
- custom: "custom";
422
- "ticket-title": "ticket-title";
423
- conventional: "conventional";
424
- }>;
425
- title_template: z.ZodNullable<z.ZodString>;
426
- description_sections: z.ZodArray<z.ZodString>;
427
- }, z.core.$strict>>>;
428
- validation_checklist: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
429
- }, z.core.$strict>>>;
430
- future_work: z.ZodArray<z.ZodObject<{
431
- id: z.ZodNumber;
432
- disposition: z.ZodEnum<{
433
- rejected: "rejected";
434
- accepted: "accepted";
435
- merged: "merged";
436
- queued: "queued";
437
- }>;
438
- }, z.core.$strict>>;
439
- next: z.ZodObject<{
440
- ticket_ids: z.ZodArray<z.ZodString>;
441
- replace_existing: z.ZodBoolean;
442
- }, z.core.$strict>;
443
- }, z.core.$strict>;
69
+ export { ticketPlanProposalV1Schema } from "rafi-spec";
444
70
  export declare function readTicketPlanningContext(projectDir: string): TicketPlanningContext;
445
71
  export declare function ticketPlanningFingerprint(projectDir: string): PlanningFingerprint[];
446
72
  export declare function planningFingerprintChanges(projectDir: string, expected: PlanningFingerprint[]): string[];
447
- export declare function extractTicketPlanProposal(output: string, existingTickets?: TicketDef[], context?: TicketPlanValidationContext): TicketPlanProposal;
448
73
  export declare function validateTicketPlanProposal(value: unknown, existingTickets?: TicketDef[], context?: TicketPlanValidationContext): string[];
449
74
  export interface ApplyTicketPlanOptions {
450
75
  expectedFingerprint: PlanningFingerprint[];
@@ -10,34 +10,8 @@ import { renderAndWrite } from "./tickets/renderMarkdown.js";
10
10
  import { runAllValidation } from "./tickets/validate.js";
11
11
  import { normalizeDeliveryConfig, validateDeliveryConfig } from "./tickets/delivery.js";
12
12
  import { loadTicketSetupConfig, mergeTicketSetup, saveTicketSetupConfig } from "./tickets/setupConfig.js";
13
- import { z } from "zod";
14
- import { documentationPolicyV1ZodSchema as documentationPolicyZodSchema, qaPreparationDepthDecisionZodSchema, zodIssues } from "rafi-spec";
15
- export const PROPOSAL_START = "RAFI_PROPOSAL_START";
16
- export const PROPOSAL_END = "RAFI_PROPOSAL_END";
17
- const providerText = (max = 20_000) => z.string().trim().min(1).max(max);
18
- const identifier = z.string().regex(/^[A-Za-z][A-Za-z0-9-_]{0,127}$/);
19
- const ticketSourceRef = z.strictObject({ source: providerText(500), item: providerText(2_000), source_id: identifier.optional(), url: z.string().url().nullable().optional(), fingerprint: z.string().regex(/^[a-f0-9]{64}$/).nullable().optional(), note: providerText(2_000).nullable().optional() });
20
- const ticketDefinitionProposal = z.strictObject({
21
- qa_preparation: qaPreparationDepthDecisionZodSchema.optional(), id: identifier, order: z.number().int().min(0),
22
- documentation: documentationPolicyZodSchema.optional(),
23
- title: providerText(500), area: providerText(500), priority: z.enum(["P0", "P1", "P2", "P3"]), size: z.enum(["XS", "S", "M", "L", "XL"]), risk: z.enum(["Low", "Medium", "High"]),
24
- depends_on: z.array(identifier).max(200), summary: providerText(), acceptance: z.array(providerText()).min(1).max(200), required_tests: z.array(providerText()).min(1).max(200), likely_files: z.array(providerText(1_000)).max(200),
25
- rollback: z.string().max(20_000).nullable().optional(), notes: z.string().max(20_000).nullable().optional(),
26
- external_refs: z.array(z.strictObject({ provider: providerText(100), id: providerText(500), key: providerText(500).nullable().optional(), url: z.string().url().nullable().optional() })).max(100).optional(),
27
- source_refs: z.array(ticketSourceRef).max(100).optional(), superseded_by: z.array(identifier).max(200).optional(), supersedes: z.array(identifier).max(200).optional(),
28
- plan_ref: z.strictObject({ plan_id: identifier, revision: z.number().int().min(1), slice_ref: identifier }).optional(),
29
- });
30
- const deliveryConfigProposal = z.strictObject({
31
- version: z.literal(1), plan: z.strictObject({ plan_id: identifier, revision: z.number().int().min(1) }).optional(),
32
- units: z.array(z.strictObject({ id: identifier, tickets: z.array(identifier).min(1).max(200), branch_mode: z.enum(["current", "per-ticket", "shared"]), completion: z.enum(["pr", "auto-merge", "direct-merge", "none"]).optional(), provider: z.enum(["auto", "github", "gitlab", "local"]).optional(), pr_ready: z.boolean().optional(), merge_method: z.enum(["squash", "merge", "rebase"]).optional(), cleanup: z.boolean().optional(), depends_on: z.array(identifier).max(200).optional(), dependency_mode: z.enum(["combine", "wait", "stack"]).optional() })).max(200),
33
- stacks: z.array(z.strictObject({ id: identifier, name: providerText(500), units: z.array(identifier).min(1).max(5), status: z.enum(["planned", "in_progress", "partial", "blocked", "awaiting_review", "merged"]).optional(), completed_prefix: z.array(identifier).max(5).optional(), next_ticket: identifier.optional(), review_links: z.array(z.string().url()).max(20).optional(), remote_checked_at: z.string().datetime().optional(), remote_stale: z.boolean().optional(), published_branches: z.record(identifier, providerText(500)).optional() })).max(200).optional(),
34
- });
35
- const buildDefaultsProposal = z.strictObject({
36
- branch_strategy: z.enum(["current", "batch", "branch-per-ticket"]).optional(), completion: z.enum(["pr", "auto-merge", "direct-merge", "none"]).optional(), provider: z.enum(["auto", "github", "gitlab", "local"]).optional(), pr_ready: z.boolean().optional(), merge_method: z.enum(["squash", "merge", "rebase"]).optional(), cleanup: z.boolean().optional(), auto_merge_wait: z.boolean().optional(), auto_merge_timeout_minutes: z.number().int().min(0).nullable().optional(), base_branch: providerText(500).optional(), branch_prefix: providerText(500).optional(), branch_policy: z.strictObject({ mode: z.enum(["global", "size"]), global_strategy: z.enum(["current", "batch", "branch-per-ticket"]), by_size: z.strictObject({ XS: z.enum(["shared", "per-ticket"]), S: z.enum(["shared", "per-ticket"]), M: z.enum(["shared", "per-ticket"]), L: z.enum(["shared", "per-ticket"]), XL: z.enum(["shared", "per-ticket"]) }) }).optional(), review: z.strictObject({ title_style: z.enum(["ticket-title", "conventional", "none", "custom"]), title_template: z.string().max(500).nullable(), description_sections: z.array(providerText(500)).max(50) }).optional(), validation_checklist: z.array(providerText(500)).max(100).optional(),
37
- });
38
- export const ticketPlanProposalV1Schema = z.strictObject({
39
- version: z.literal(1), title: providerText(500), markdown: providerText(100_000), additions: z.array(ticketDefinitionProposal).max(200), edits: z.array(z.strictObject({ id: identifier, patch: ticketDefinitionProposal.partial() })).max(200), supersessions: z.array(z.strictObject({ replaced: z.array(identifier).min(1).max(200), replacements: z.array(identifier).min(1).max(200), reason: providerText() })).max(200), state_changes: z.array(z.strictObject({ id: identifier, status: z.enum(["planned", "next", "in_progress", "blocked", "done", "canceled", "obsolete"]), reason: providerText() })).max(200), source_reconciliation: z.array(z.strictObject({ source: providerText(500), item: providerText(2_000), disposition: z.enum(["mapped", "split", "combined", "deferred", "excluded"]), ticket_ids: z.array(identifier).max(200), reason: providerText().optional() })).max(500), delivery: deliveryConfigProposal.nullable().optional(), build_defaults: buildDefaultsProposal.partial().nullable().optional(), future_work: z.array(z.strictObject({ id: z.number().int().min(0), disposition: z.enum(["accepted", "rejected", "merged", "queued"]) })).max(500), next: z.strictObject({ ticket_ids: z.array(identifier).max(200), replace_existing: z.boolean() }),
40
- });
13
+ import { ticketPlanProposalV1Schema, zodIssues } from "rafi-spec";
14
+ export { ticketPlanProposalV1Schema } from "rafi-spec";
41
15
  const TICKET_STATUSES = new Set([
42
16
  "planned", "next", "in_progress", "blocked", "done", "canceled", "obsolete",
43
17
  ]);
@@ -70,27 +44,6 @@ export function ticketPlanningFingerprint(projectDir) {
70
44
  export function planningFingerprintChanges(projectDir, expected) {
71
45
  return expected.filter((item) => fileHash(join(projectDir, item.path)) !== item.sha256).map((item) => item.path);
72
46
  }
73
- export function extractTicketPlanProposal(output, existingTickets = [], context = {}) {
74
- const start = output.lastIndexOf(PROPOSAL_START);
75
- const end = output.lastIndexOf(PROPOSAL_END);
76
- if (start < 0 || end <= start)
77
- throw new Error(`planner output is missing ${PROPOSAL_START}/${PROPOSAL_END}`);
78
- const raw = output.slice(start + PROPOSAL_START.length, end).trim().replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/, "");
79
- let parsed;
80
- try {
81
- parsed = JSON.parse(raw);
82
- }
83
- catch (err) {
84
- throw new Error(`planner proposal is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
85
- }
86
- const contract = ticketPlanProposalV1Schema.safeParse(parsed);
87
- if (!contract.success)
88
- throw new Error(`planner proposal contract validation failed:\n${zodIssues(contract.error).map((issue) => `- ${issue}`).join("\n")}`);
89
- const issues = validateTicketPlanProposal(contract.data, existingTickets, context);
90
- if (issues.length)
91
- throw new Error(`invalid planner proposal:\n${issues.map((issue) => `- ${issue}`).join("\n")}`);
92
- return contract.data;
93
- }
94
47
  export function validateTicketPlanProposal(value, existingTickets = [], context = {}) {
95
48
  const issues = [];
96
49
  const contract = ticketPlanProposalV1Schema.safeParse(value);
@@ -32,8 +32,6 @@ export interface TicketPopulationProposalV1 {
32
32
  tickets: TicketSliceProposal[];
33
33
  retirements: string[];
34
34
  }
35
- export declare const TICKET_POPULATION_PROPOSAL_START = "RAFI_TICKET_POPULATION_PROPOSAL_START";
36
- export declare const TICKET_POPULATION_PROPOSAL_END = "RAFI_TICKET_POPULATION_PROPOSAL_END";
37
35
  export interface PopulationRiskWaiver {
38
36
  ticketId: string;
39
37
  reason: string;
@@ -57,7 +55,6 @@ export declare class TicketPopulationValidationError extends Error {
57
55
  }
58
56
  /** Reject a correction that attempts to turn a risk-note repair into a new plan. */
59
57
  export declare function assertRiskPlanOnlyCorrection(previous: TicketPopulationProposalV1, corrected: TicketPopulationProposalV1, permittedSliceRefs: string[]): void;
60
- export declare function extractTicketPopulationProposal(output: string): TicketPopulationProposalV1;
61
58
  export declare function validateTicketPopulationProposal(proposal: TicketPopulationProposalV1, plan: StructuredPlanV1, existing: TicketDef[], options?: {
62
59
  branchStrategy?: PopulationBranchStrategy;
63
60
  }): string[];
@@ -11,8 +11,6 @@ import { normalizeDeliveryConfig, validateDeliveryConfig } from "./tickets/deliv
11
11
  import { loadTicketsConfig, resolveTicketPaths } from "./tickets/config.js";
12
12
  import { StateDb } from "./tickets/stateDb.js";
13
13
  import { ticketDefinitionDigest } from "./tickets/riskWaivers.js";
14
- export const TICKET_POPULATION_PROPOSAL_START = "RAFI_TICKET_POPULATION_PROPOSAL_START";
15
- export const TICKET_POPULATION_PROPOSAL_END = "RAFI_TICKET_POPULATION_PROPOSAL_END";
16
14
  function additiveAbsenceRequirement(text) {
17
15
  return [
18
16
  /\bslice alone\b/i,
@@ -81,24 +79,6 @@ function stableJson(value) {
81
79
  }
82
80
  return JSON.stringify(value);
83
81
  }
84
- export function extractTicketPopulationProposal(output) {
85
- const start = output.lastIndexOf(TICKET_POPULATION_PROPOSAL_START);
86
- const end = output.lastIndexOf(TICKET_POPULATION_PROPOSAL_END);
87
- if (start < 0 || end <= start)
88
- throw new Error(`ticket-maker output is missing ${TICKET_POPULATION_PROPOSAL_START}/${TICKET_POPULATION_PROPOSAL_END}`);
89
- const raw = output.slice(start + TICKET_POPULATION_PROPOSAL_START.length, end).trim().replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/, "");
90
- let parsed;
91
- try {
92
- parsed = JSON.parse(raw);
93
- }
94
- catch (error) {
95
- throw new Error(`ticket-maker proposal is invalid JSON: ${error instanceof Error ? error.message : String(error)}`);
96
- }
97
- const validated = ticketPopulationProposalV1Schema.safeParse(parsed);
98
- if (!validated.success)
99
- throw new Error(`ticket-maker proposal contract validation failed:\n${zodIssues(validated.error).map((issue) => `- ${issue}`).join("\n")}`);
100
- return validated.data;
101
- }
102
82
  export function validateTicketPopulationProposal(proposal, plan, existing, options = {}) {
103
83
  const issues = [];
104
84
  const contract = ticketPopulationProposalV1Schema.safeParse(proposal);
@@ -156,7 +136,10 @@ export function materializeTicketPopulation(proposal, plan, existing, options =
156
136
  title: slice.title, area: slice.area, priority: slice.priority, size: slice.size, risk: slice.risk,
157
137
  depends_on: slice.depends_on.map((ref) => sliceToTicket.get(ref)), summary: slice.summary,
158
138
  acceptance: [...slice.acceptance], required_tests: [...slice.required_tests], likely_files: [...slice.likely_files],
159
- documentation: structuredClone(slice.documentation ?? plan.slices.find(item => item.slice_ref === slice.slice_ref)?.documentation ?? { required: false, targets: [], criteria: [] }),
139
+ ...(plan.slices.find(item => item.slice_ref === slice.slice_ref)?.verification_version === 2
140
+ ? { verification_version: 2, verification_requirements: structuredClone(plan.slices.find(item => item.slice_ref === slice.slice_ref).verification_requirements) }
141
+ : {}),
142
+ documentation: structuredClone(plan.slices.find(item => item.slice_ref === slice.slice_ref)?.documentation ?? { required: false, targets: [], criteria: [] }),
160
143
  rollback: slice.rollback, notes: slice.notes, plan_ref: { plan_id: plan.plan_id, revision: plan.revision, slice_ref: slice.slice_ref },
161
144
  source_refs: (plan.slices.find((item) => item.slice_ref === slice.slice_ref)?.source_refs ?? slice.source_refs)?.map((ref) => ({
162
145
  source: ref.source_id, item: ref.item ?? "document", source_id: ref.source_id, fingerprint: ref.fingerprint,
@@ -0,0 +1,13 @@
1
+ import type { SelectedDispatchTupleV2 } from "rafi-spec";
2
+ import type { WorkflowDb } from "./workflowDb.js";
3
+ export interface TicketPopulationPageScope {
4
+ readonly projectDir: string;
5
+ readonly artifactId: string;
6
+ readonly runId: string;
7
+ readonly lineageId: string;
8
+ readonly leaseId: string;
9
+ }
10
+ export declare function withTicketPopulationPage<T>(scope: TicketPopulationPageScope, dispatch: () => Promise<T>): Promise<T>;
11
+ /** Only the population owner with a persisted artifact intent may select a page. */
12
+ export declare function sealTicketPopulationPage(db: WorkflowDb, root: string, tuple: SelectedDispatchTupleV2): void;
13
+ export declare function assertTicketPopulationPageBinding(db: WorkflowDb, scope: TicketPopulationPageScope, tuple: SelectedDispatchTupleV2): void;
@@ -0,0 +1,30 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ const populationPage = new AsyncLocalStorage();
3
+ export function withTicketPopulationPage(scope, dispatch) {
4
+ return populationPage.run(Object.freeze({ ...scope }), dispatch);
5
+ }
6
+ /** Only the population owner with a persisted artifact intent may select a page. */
7
+ export function sealTicketPopulationPage(db, root, tuple) {
8
+ if (tuple.operation !== "ticket-population-page")
9
+ return;
10
+ const scope = populationPage.getStore();
11
+ const artifact = scope && db.operation(scope.artifactId);
12
+ if (!scope || scope.projectDir !== root || !artifact || artifact.kind !== "ticket-population-artifact" ||
13
+ artifact.runId !== scope.runId || artifact.status !== "in_progress" ||
14
+ artifact.intent.lineageId !== scope.lineageId ||
15
+ artifact.intent.leaseId !== scope.leaseId)
16
+ throw new Error("Ticket population pages require their active persisted artifact owner");
17
+ const prior = db.populationPageLedger(scope.artifactId);
18
+ if (prior && prior.state !== "open")
19
+ throw new Error("Ticket population artifact is already terminal");
20
+ db.beginPageLedger({ ...scope, tupleDigest: prior?.tupleDigest ?? tuple.digest });
21
+ db.planOperation({ runId: scope.runId, idempotencyKey: `${scope.artifactId}:page:${tuple.dispatchId}`,
22
+ kind: "ticket-population-page-binding", intent: { ...scope, tupleDigest: tuple.digest } });
23
+ }
24
+ export function assertTicketPopulationPageBinding(db, scope, tuple) {
25
+ const binding = db.operation(`${scope.artifactId}:page:${tuple.dispatchId}`);
26
+ const intent = binding?.intent;
27
+ if (!intent || binding?.kind !== "ticket-population-page-binding" || binding.runId !== scope.runId ||
28
+ intent.tupleDigest !== tuple.digest || intent.lineageId !== scope.lineageId || intent.leaseId !== scope.leaseId)
29
+ throw new Error("Ticket page receipt belongs to another artifact or lineage");
30
+ }
@@ -0,0 +1,27 @@
1
+ import { type OutputContract, type TicketPopulationProposalV1Contract } from "rafi-spec";
2
+ import type { TurnRequest, TurnResult } from "./adapters/types.js";
3
+ import { type TicketPopulationPageScope } from "./ticketPopulationPageAuthority.js";
4
+ type PageTurn = {
5
+ result: TurnResult;
6
+ status: {
7
+ kind: string;
8
+ reason?: string;
9
+ error?: string;
10
+ summary?: string;
11
+ };
12
+ };
13
+ /** Each provider page is sealed and durably appended before aggregate interpretation. */
14
+ export declare function streamTicketPopulation(input: {
15
+ projectDir: string;
16
+ interviewId: string;
17
+ correction: number;
18
+ instruction: string;
19
+ checkpoint(scope: TicketPopulationPageScope): void;
20
+ dispatch(instruction: string, policy: TurnRequest & {
21
+ output: OutputContract;
22
+ }): Promise<PageTurn>;
23
+ }): Promise<{
24
+ proposal: TicketPopulationProposalV1Contract;
25
+ turn: PageTurn;
26
+ }>;
27
+ export {};