ai-foreman 1.7.29 → 2.0.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 (136) hide show
  1. package/README.md +1 -1
  2. package/dist/adapters/claude.d.ts +23 -12
  3. package/dist/adapters/claude.js +227 -23
  4. package/dist/adapters/codex.d.ts +17 -7
  5. package/dist/adapters/codex.js +195 -17
  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/planner.js +1 -4
  18. package/dist/branch/runner.d.ts +2 -1
  19. package/dist/branch/runner.js +10 -7
  20. package/dist/buildAdmission.js +4 -0
  21. package/dist/buildApproval.d.ts +15 -0
  22. package/dist/buildApproval.js +25 -0
  23. package/dist/buildAssignment.d.ts +1 -0
  24. package/dist/buildAssignment.js +82 -23
  25. package/dist/buildInterventions.d.ts +2 -2
  26. package/dist/buildInterventions.js +11 -4
  27. package/dist/buildLaunchGate.js +3 -2
  28. package/dist/builderGuidanceFollowup.js +17 -6
  29. package/dist/cli/manager.js +22 -20
  30. package/dist/cli/start.js +22 -26
  31. package/dist/cli/tickets.d.ts +0 -7
  32. package/dist/cli/tickets.js +41 -40
  33. package/dist/continuity.d.ts +10 -14
  34. package/dist/continuity.js +198 -179
  35. package/dist/continuityOrigin.d.ts +13 -0
  36. package/dist/continuityOrigin.js +91 -0
  37. package/dist/foreman.d.ts +10 -4
  38. package/dist/foreman.js +51 -193
  39. package/dist/graph/boundary.d.ts +1 -1
  40. package/dist/graph/boundary.js +1 -1
  41. package/dist/graph/host.js +8 -19
  42. package/dist/graph/manager.d.ts +1 -1
  43. package/dist/graph/manager.js +1 -1
  44. package/dist/graph/preparation.d.ts +38 -0
  45. package/dist/graph/preparation.js +7 -6
  46. package/dist/graph/semantic.d.ts +1 -0
  47. package/dist/graph/semantic.js +4 -1
  48. package/dist/graph/session.js +7 -2
  49. package/dist/graph/turn.d.ts +2 -3
  50. package/dist/graph/turn.js +28 -40
  51. package/dist/handoffProtocol.js +2 -2
  52. package/dist/handoffs.d.ts +3 -1
  53. package/dist/handoffs.js +90 -59
  54. package/dist/hostGraphApplicability.d.ts +2 -1
  55. package/dist/hostGraphApplicability.js +17 -19
  56. package/dist/hostQaAugmentation.js +21 -4
  57. package/dist/hostQaComparison.d.ts +21 -2
  58. package/dist/hostQaComparison.js +43 -29
  59. package/dist/hostSourcePreservation.d.ts +38 -0
  60. package/dist/hostSourcePreservation.js +72 -0
  61. package/dist/interviews.d.ts +7 -0
  62. package/dist/interviews.js +18 -1
  63. package/dist/legacyCommunicationDisplay.d.ts +2 -0
  64. package/dist/legacyCommunicationDisplay.js +2 -0
  65. package/dist/managerPacket.js +3 -3
  66. package/dist/markers.d.ts +4 -3
  67. package/dist/markers.js +4 -20
  68. package/dist/probeIpc.d.ts +14 -0
  69. package/dist/probeIpc.js +29 -0
  70. package/dist/qaBuildGate.d.ts +21 -0
  71. package/dist/qaBuildGate.js +47 -12
  72. package/dist/qaBuilderCoverage.js +22 -13
  73. package/dist/qaBuilderEvidence.d.ts +16 -1
  74. package/dist/qaBuilderEvidence.js +48 -8
  75. package/dist/qaContractCoverage.d.ts +2 -2
  76. package/dist/qaContractCoverage.js +4 -9
  77. package/dist/qaContractDelivery.js +34 -20
  78. package/dist/qaCoverageAssembly.d.ts +22 -0
  79. package/dist/qaCoverageAssembly.js +16 -0
  80. package/dist/qaDeliveryJournal.d.ts +2 -0
  81. package/dist/qaDeliveryJournal.js +19 -0
  82. package/dist/qaFailureDelivery.js +97 -85
  83. package/dist/qaHostTransformation.d.ts +26 -0
  84. package/dist/qaHostTransformation.js +100 -0
  85. package/dist/qaPreparation.d.ts +8 -20
  86. package/dist/qaPreparation.js +133 -248
  87. package/dist/qaPreparationInputs.js +19 -0
  88. package/dist/qaPrerequisites.d.ts +2 -1
  89. package/dist/qaPrerequisites.js +21 -1
  90. package/dist/qaProtocolV2.d.ts +15 -0
  91. package/dist/qaRecovery.js +21 -4
  92. package/dist/qaReview.js +220 -395
  93. package/dist/qaReviewEvidence.d.ts +7 -3
  94. package/dist/qaReviewEvidence.js +15 -4
  95. package/dist/qaRuntime.js +1 -1
  96. package/dist/qaSnapshot.js +71 -21
  97. package/dist/qaStructuredResponse.d.ts +10 -0
  98. package/dist/qaStructuredResponse.js +57 -0
  99. package/dist/qaTimeline.js +5 -3
  100. package/dist/qaVerificationContract.d.ts +1 -2
  101. package/dist/qaVerificationContract.js +24 -35
  102. package/dist/readinessGate.js +5 -4
  103. package/dist/runtimeReadiness.js +23 -15
  104. package/dist/statusReporter.d.ts +2 -0
  105. package/dist/statusReporter.js +2 -0
  106. package/dist/structuredCutover.d.ts +31 -0
  107. package/dist/structuredCutover.js +510 -0
  108. package/dist/structuredCutoverFiles.d.ts +10 -0
  109. package/dist/structuredCutoverFiles.js +181 -0
  110. package/dist/structuredDispatchAuthority.d.ts +22 -0
  111. package/dist/structuredDispatchAuthority.js +110 -0
  112. package/dist/structuredDispatchRecord.d.ts +29 -0
  113. package/dist/structuredDispatchRecord.js +36 -0
  114. package/dist/structuredLiveBudget.d.ts +2 -0
  115. package/dist/structuredLiveBudget.js +23 -0
  116. package/dist/structuredOperation.d.ts +18 -0
  117. package/dist/structuredOperation.js +257 -0
  118. package/dist/supervisedStart.js +35 -21
  119. package/dist/ticketPlanning.d.ts +1 -373
  120. package/dist/ticketPlanning.js +2 -26
  121. package/dist/ticketPopulation.d.ts +0 -3
  122. package/dist/ticketPopulation.js +4 -21
  123. package/dist/ticketPopulationPageAuthority.d.ts +13 -0
  124. package/dist/ticketPopulationPageAuthority.js +30 -0
  125. package/dist/ticketPopulationPaging.d.ts +27 -0
  126. package/dist/ticketPopulationPaging.js +105 -0
  127. package/dist/tickets/renderMarkdown.d.ts +14 -0
  128. package/dist/tickets/renderMarkdown.js +39 -5
  129. package/dist/tickets/ticketLoader.js +10 -0
  130. package/dist/tickets/ticketSchema.d.ts +107 -0
  131. package/dist/tickets/ticketSchema.js +4 -1
  132. package/dist/workflowDb.d.ts +100 -2
  133. package/dist/workflowDb.js +763 -39
  134. package/dist/workflowReader.d.ts +1 -0
  135. package/dist/workflowReader.js +9 -0
  136. package/package.json +15 -7
@@ -2,7 +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
5
  export declare const PROPOSAL_START = "RAFI_PROPOSAL_START";
7
6
  export declare const PROPOSAL_END = "RAFI_PROPOSAL_END";
8
7
  export interface TicketEdit {
@@ -69,378 +68,7 @@ export interface TicketPlanningContext {
69
68
  export interface TicketPlanValidationContext {
70
69
  futureWorkIds?: Iterable<number>;
71
70
  }
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>;
71
+ export { ticketPlanProposalV1Schema } from "rafi-spec";
444
72
  export declare function readTicketPlanningContext(projectDir: string): TicketPlanningContext;
445
73
  export declare function ticketPlanningFingerprint(projectDir: string): PlanningFingerprint[];
446
74
  export declare function planningFingerprintChanges(projectDir: string, expected: PlanningFingerprint[]): string[];
@@ -10,34 +10,10 @@ 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";
13
+ import { ticketPlanProposalV1Schema, zodIssues } from "rafi-spec";
15
14
  export const PROPOSAL_START = "RAFI_PROPOSAL_START";
16
15
  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
- });
16
+ export { ticketPlanProposalV1Schema } from "rafi-spec";
41
17
  const TICKET_STATUSES = new Set([
42
18
  "planned", "next", "in_progress", "blocked", "done", "canceled", "obsolete",
43
19
  ]);
@@ -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 {};