crewly 1.20.204 → 1.20.205

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 (190) hide show
  1. package/config/skills/_common/lib.sh +4 -3
  2. package/config/skills/agent/core/project-tickets/SKILL.md +13 -1
  3. package/config/skills/agent/core/project-tickets/execute.sh +20 -6
  4. package/config/skills/agent/core/project-tickets/execute.test.sh +8 -2
  5. package/dist/backend/backend/src/constants.d.ts +64 -0
  6. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  7. package/dist/backend/backend/src/constants.js +70 -0
  8. package/dist/backend/backend/src/constants.js.map +1 -1
  9. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts +1 -1
  10. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts.map +1 -1
  11. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js +9 -1
  12. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js.map +1 -1
  13. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.d.ts +1 -1
  14. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.js +1 -1
  15. package/dist/backend/backend/src/controllers/settings/role.controller.d.ts.map +1 -1
  16. package/dist/backend/backend/src/controllers/settings/role.controller.js +21 -7
  17. package/dist/backend/backend/src/controllers/settings/role.controller.js.map +1 -1
  18. package/dist/backend/backend/src/controllers/settings/settings.controller.d.ts.map +1 -1
  19. package/dist/backend/backend/src/controllers/settings/settings.controller.js +26 -20
  20. package/dist/backend/backend/src/controllers/settings/settings.controller.js.map +1 -1
  21. package/dist/backend/backend/src/controllers/skill/skill.controller.d.ts +13 -0
  22. package/dist/backend/backend/src/controllers/skill/skill.controller.d.ts.map +1 -1
  23. package/dist/backend/backend/src/controllers/skill/skill.controller.js +21 -0
  24. package/dist/backend/backend/src/controllers/skill/skill.controller.js.map +1 -1
  25. package/dist/backend/backend/src/controllers/system/system-control.controller.d.ts +11 -1
  26. package/dist/backend/backend/src/controllers/system/system-control.controller.d.ts.map +1 -1
  27. package/dist/backend/backend/src/controllers/system/system-control.controller.js +36 -2
  28. package/dist/backend/backend/src/controllers/system/system-control.controller.js.map +1 -1
  29. package/dist/backend/backend/src/index.d.ts +9 -0
  30. package/dist/backend/backend/src/index.d.ts.map +1 -1
  31. package/dist/backend/backend/src/index.js +28 -0
  32. package/dist/backend/backend/src/index.js.map +1 -1
  33. package/dist/backend/backend/src/middleware/agent-origin.middleware.d.ts +3 -2
  34. package/dist/backend/backend/src/middleware/agent-origin.middleware.d.ts.map +1 -1
  35. package/dist/backend/backend/src/middleware/agent-origin.middleware.js +5 -3
  36. package/dist/backend/backend/src/middleware/agent-origin.middleware.js.map +1 -1
  37. package/dist/backend/backend/src/middleware/caller-identity.middleware.d.ts +36 -0
  38. package/dist/backend/backend/src/middleware/caller-identity.middleware.d.ts.map +1 -1
  39. package/dist/backend/backend/src/middleware/caller-identity.middleware.js +97 -1
  40. package/dist/backend/backend/src/middleware/caller-identity.middleware.js.map +1 -1
  41. package/dist/backend/backend/src/routes/modules/terminal.routes.d.ts +4 -0
  42. package/dist/backend/backend/src/routes/modules/terminal.routes.d.ts.map +1 -1
  43. package/dist/backend/backend/src/routes/modules/terminal.routes.js +19 -5
  44. package/dist/backend/backend/src/routes/modules/terminal.routes.js.map +1 -1
  45. package/dist/backend/backend/src/scripts/input-guard-classify.d.ts +44 -0
  46. package/dist/backend/backend/src/scripts/input-guard-classify.d.ts.map +1 -0
  47. package/dist/backend/backend/src/scripts/input-guard-classify.js +116 -0
  48. package/dist/backend/backend/src/scripts/input-guard-classify.js.map +1 -0
  49. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts +8 -0
  50. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  51. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +10 -0
  52. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  53. package/dist/backend/backend/src/services/agent/crewly-agent/in-process-runtime-registry.d.ts +8 -0
  54. package/dist/backend/backend/src/services/agent/crewly-agent/in-process-runtime-registry.d.ts.map +1 -1
  55. package/dist/backend/backend/src/services/agent/crewly-agent/in-process-runtime-registry.js +21 -0
  56. package/dist/backend/backend/src/services/agent/crewly-agent/in-process-runtime-registry.js.map +1 -1
  57. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
  58. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js +13 -27
  59. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
  60. package/dist/backend/backend/src/services/messaging/forced-delivery.d.ts +75 -0
  61. package/dist/backend/backend/src/services/messaging/forced-delivery.d.ts.map +1 -0
  62. package/dist/backend/backend/src/services/messaging/forced-delivery.js +87 -0
  63. package/dist/backend/backend/src/services/messaging/forced-delivery.js.map +1 -0
  64. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts +130 -4
  65. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts.map +1 -1
  66. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js +115 -3
  67. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js.map +1 -1
  68. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-goal.d.ts +122 -0
  69. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-goal.d.ts.map +1 -0
  70. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-goal.js +274 -0
  71. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-goal.js.map +1 -0
  72. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts +34 -2
  73. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts.map +1 -1
  74. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js +59 -2
  75. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js.map +1 -1
  76. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-retro.js +1 -1
  77. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-retro.js.map +1 -1
  78. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-stats.d.ts +6 -1
  79. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-stats.d.ts.map +1 -1
  80. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-stats.js +9 -1
  81. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-stats.js.map +1 -1
  82. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-trace.d.ts +13 -3
  83. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-trace.d.ts.map +1 -1
  84. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-trace.js +28 -2
  85. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-trace.js.map +1 -1
  86. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts +92 -7
  87. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts.map +1 -1
  88. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js +316 -41
  89. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js.map +1 -1
  90. package/dist/backend/backend/src/services/settings/api-key-access.service.d.ts +126 -0
  91. package/dist/backend/backend/src/services/settings/api-key-access.service.d.ts.map +1 -0
  92. package/dist/backend/backend/src/services/settings/api-key-access.service.js +223 -0
  93. package/dist/backend/backend/src/services/settings/api-key-access.service.js.map +1 -0
  94. package/dist/backend/backend/src/services/skill/skill-executor.service.d.ts.map +1 -1
  95. package/dist/backend/backend/src/services/skill/skill-executor.service.js +17 -0
  96. package/dist/backend/backend/src/services/skill/skill-executor.service.js.map +1 -1
  97. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  98. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +29 -8
  99. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  100. package/dist/backend/backend/src/services/system/auto-update.service.d.ts +24 -0
  101. package/dist/backend/backend/src/services/system/auto-update.service.d.ts.map +1 -1
  102. package/dist/backend/backend/src/services/system/auto-update.service.js +78 -8
  103. package/dist/backend/backend/src/services/system/auto-update.service.js.map +1 -1
  104. package/dist/backend/backend/src/services/system/auto-update.utils.d.ts +1 -1
  105. package/dist/backend/backend/src/services/system/auto-update.utils.d.ts.map +1 -1
  106. package/dist/backend/backend/src/services/system/auto-update.utils.js.map +1 -1
  107. package/dist/backend/backend/src/services/system/input-guard-release-check.d.ts +162 -0
  108. package/dist/backend/backend/src/services/system/input-guard-release-check.d.ts.map +1 -0
  109. package/dist/backend/backend/src/services/system/input-guard-release-check.js +264 -0
  110. package/dist/backend/backend/src/services/system/input-guard-release-check.js.map +1 -0
  111. package/dist/backend/backend/src/services/system/system-control.service.d.ts +36 -0
  112. package/dist/backend/backend/src/services/system/system-control.service.d.ts.map +1 -1
  113. package/dist/backend/backend/src/services/system/system-control.service.js +109 -10
  114. package/dist/backend/backend/src/services/system/system-control.service.js.map +1 -1
  115. package/dist/backend/backend/src/types/skill.types.d.ts +16 -0
  116. package/dist/backend/backend/src/types/skill.types.d.ts.map +1 -1
  117. package/dist/backend/backend/src/types/skill.types.js.map +1 -1
  118. package/dist/backend/backend/src/types/ticket-autopilot.types.d.ts +21 -0
  119. package/dist/backend/backend/src/types/ticket-autopilot.types.d.ts.map +1 -1
  120. package/dist/backend/backend/src/types/ticket-autopilot.types.js +48 -0
  121. package/dist/backend/backend/src/types/ticket-autopilot.types.js.map +1 -1
  122. package/dist/backend/backend/src/types/v2/work-item.types.d.ts +1 -1
  123. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  124. package/dist/backend/backend/src/types/v2/work-item.types.js +1 -0
  125. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  126. package/dist/backend/build-info.json +2 -2
  127. package/dist/cli/backend/src/constants.d.ts +64 -0
  128. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  129. package/dist/cli/backend/src/constants.js +70 -0
  130. package/dist/cli/backend/src/constants.js.map +1 -1
  131. package/dist/cli/backend/src/scripts/input-guard-classify.d.ts +44 -0
  132. package/dist/cli/backend/src/scripts/input-guard-classify.d.ts.map +1 -0
  133. package/dist/cli/backend/src/scripts/input-guard-classify.js +116 -0
  134. package/dist/cli/backend/src/scripts/input-guard-classify.js.map +1 -0
  135. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts +8 -0
  136. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.d.ts.map +1 -1
  137. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js +10 -0
  138. package/dist/cli/backend/src/services/agent/crewly-agent/crewly-agent-external-runtime.service.js.map +1 -1
  139. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-runtime-registry.d.ts +8 -0
  140. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-runtime-registry.d.ts.map +1 -1
  141. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-runtime-registry.js +21 -0
  142. package/dist/cli/backend/src/services/agent/crewly-agent/in-process-runtime-registry.js.map +1 -1
  143. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
  144. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js +13 -27
  145. package/dist/cli/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
  146. package/dist/cli/backend/src/services/messaging/drain-queued-delivery.d.ts +59 -0
  147. package/dist/cli/backend/src/services/messaging/drain-queued-delivery.d.ts.map +1 -0
  148. package/dist/cli/backend/src/services/messaging/drain-queued-delivery.js +70 -0
  149. package/dist/cli/backend/src/services/messaging/drain-queued-delivery.js.map +1 -0
  150. package/dist/cli/backend/src/services/messaging/forced-delivery.d.ts +75 -0
  151. package/dist/cli/backend/src/services/messaging/forced-delivery.d.ts.map +1 -0
  152. package/dist/cli/backend/src/services/messaging/forced-delivery.js +87 -0
  153. package/dist/cli/backend/src/services/messaging/forced-delivery.js.map +1 -0
  154. package/dist/cli/backend/src/services/messaging/spend-capped-delivery.d.ts +54 -0
  155. package/dist/cli/backend/src/services/messaging/spend-capped-delivery.d.ts.map +1 -0
  156. package/dist/cli/backend/src/services/messaging/spend-capped-delivery.js +65 -0
  157. package/dist/cli/backend/src/services/messaging/spend-capped-delivery.js.map +1 -0
  158. package/dist/cli/backend/src/services/skill/skill-executor.service.d.ts.map +1 -1
  159. package/dist/cli/backend/src/services/skill/skill-executor.service.js +17 -0
  160. package/dist/cli/backend/src/services/skill/skill-executor.service.js.map +1 -1
  161. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  162. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +29 -8
  163. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  164. package/dist/cli/backend/src/services/system/auto-update.utils.d.ts +1 -1
  165. package/dist/cli/backend/src/services/system/auto-update.utils.d.ts.map +1 -1
  166. package/dist/cli/backend/src/services/system/auto-update.utils.js.map +1 -1
  167. package/dist/cli/backend/src/services/system/input-guard-release-check.d.ts +162 -0
  168. package/dist/cli/backend/src/services/system/input-guard-release-check.d.ts.map +1 -0
  169. package/dist/cli/backend/src/services/system/input-guard-release-check.js +264 -0
  170. package/dist/cli/backend/src/services/system/input-guard-release-check.js.map +1 -0
  171. package/dist/cli/backend/src/types/skill.types.d.ts +16 -0
  172. package/dist/cli/backend/src/types/skill.types.d.ts.map +1 -1
  173. package/dist/cli/backend/src/types/skill.types.js.map +1 -1
  174. package/dist/cli/backend/src/types/ticket-autopilot.types.d.ts +21 -0
  175. package/dist/cli/backend/src/types/ticket-autopilot.types.d.ts.map +1 -1
  176. package/dist/cli/backend/src/types/ticket-autopilot.types.js +48 -0
  177. package/dist/cli/backend/src/types/ticket-autopilot.types.js.map +1 -1
  178. package/dist/cli/backend/src/types/v2/work-item.types.d.ts +1 -1
  179. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  180. package/dist/cli/backend/src/types/v2/work-item.types.js +1 -0
  181. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  182. package/dist/cli/cli/src/commands/doctor.d.ts +20 -0
  183. package/dist/cli/cli/src/commands/doctor.d.ts.map +1 -1
  184. package/dist/cli/cli/src/commands/doctor.js +49 -0
  185. package/dist/cli/cli/src/commands/doctor.js.map +1 -1
  186. package/dist/cli/cli/src/index.js +9 -2
  187. package/dist/cli/cli/src/index.js.map +1 -1
  188. package/frontend/dist/assets/{index-63a33dbf.js → index-f64b333a.js} +258 -258
  189. package/frontend/dist/index.html +1 -1
  190. package/package.json +2 -1
@@ -6,6 +6,8 @@
6
6
  * pool, a filesystem or timers:
7
7
  * - which tickets need the driver's triage ({@link selectTriageCandidates});
8
8
  * - whether to wake the driver now ({@link decideTriage});
9
+ * - whether to wake the driver to plan toward the goal when nothing is left
10
+ * to triage ({@link decideReplan}, specs/2026-10-04-autopilot-goal-replan.md);
9
11
  * - whether to send the owner the evening digest ({@link decideDigest}).
10
12
  *
11
13
  * @module services/project-tickets/ticket-autopilot-decision
@@ -61,6 +63,13 @@ export interface TriageDecisionInput {
61
63
  candidateCount: number;
62
64
  /** A triage WorkItem of this project is still live */
63
65
  liveTriage: boolean;
66
+ /**
67
+ * When the project's live goal replan was created (epoch ms), absent when
68
+ * none is live. It holds triage while the driver is opening tickets, but
69
+ * yields once there are tickets to triage and it is older than
70
+ * {@link TICKET_AUTOPILOT_CONSTANTS.REPLAN_YIELD_AFTER_MS}.
71
+ */
72
+ liveReplanAt?: number;
64
73
  /** When the last triage item was created (epoch ms) */
65
74
  lastTriageAt?: number;
66
75
  /** A member of the project's teams (or the driver) is idle */
@@ -71,7 +80,7 @@ export interface TriageDecisionInput {
71
80
  dailyBudgetTokens: number;
72
81
  }
73
82
  /** Why the driver is not woken. */
74
- export type TriageSkipReason = 'off' | 'no_driver' | 'budget_reached' | 'triage_in_flight' | 'nothing_to_triage' | 'nobody_idle' | 'too_soon';
83
+ export type TriageSkipReason = 'off' | 'no_driver' | 'budget_reached' | 'triage_in_flight' | 'replan_in_flight' | 'nothing_to_triage' | 'nobody_idle' | 'too_soon';
75
84
  /** Outcome of {@link decideTriage}. */
76
85
  export type TriageDecision = {
77
86
  action: 'triage';
@@ -160,15 +169,132 @@ export declare function hasPossibleTaker(ticket: Pick<ProjectTicket, 'team'>, te
160
169
  export declare function selectTriageCandidates(input: SelectTriageInput): TriageSelection;
161
170
  /**
162
171
  * Whether to wake the driver with a triage item now. Checked in order:
163
- * switch off → no driver → budget reached → a triage already live → nothing
164
- * to triage → nobody idle → too soon since the last one (30 min on the
165
- * periodic tick, {@link TICKET_AUTOPILOT_CONSTANTS.IDLE_TRIGGER_MIN_INTERVAL_MS}
172
+ * switch off → no driver → budget reached → a triage already live → a goal
173
+ * replan live (the driver is opening tickets in that turn; it yields after
174
+ * an hour once there are tickets to triage) → nothing to triage → nobody
175
+ * idle → too soon since the last one (30 min on the periodic tick, {@link TICKET_AUTOPILOT_CONSTANTS.IDLE_TRIGGER_MIN_INTERVAL_MS}
166
176
  * when a member just went idle with nothing ready).
167
177
  *
168
178
  * @param input - State of the project
169
179
  * @returns `triage`, or `skip` with the reason
170
180
  */
171
181
  export declare function decideTriage(input: TriageDecisionInput): TriageDecision;
182
+ /** Inputs of {@link decideReplan}. */
183
+ export interface ReplanDecisionInput {
184
+ enabled: boolean;
185
+ /** Resolved driver session, or null when the project has no lead */
186
+ driver: string | null;
187
+ /**
188
+ * The project has an active goal (goals log or an active project OKR).
189
+ * Checked last: the service reads the goal only after every other gate passed.
190
+ */
191
+ hasGoal: boolean;
192
+ /** Backing off after replans that opened no tickets (see {@link replanBackoffDays}) */
193
+ backedOff: boolean;
194
+ /** Replans allowed per local day (the `replansPerDay` setting; 0 = off) */
195
+ maxReplansPerDay: number;
196
+ /** Replans already created today (local day) */
197
+ replansToday: number;
198
+ /** Tokens used today by the project's team agents */
199
+ usedTodayTokens: number;
200
+ /** Daily budget in tokens (boosts included); Infinity = unlimited today */
201
+ dailyBudgetTokens: number;
202
+ /** A triage WorkItem of this project is still live */
203
+ liveTriage: boolean;
204
+ /** A replan WorkItem of this project is still live */
205
+ liveReplan: boolean;
206
+ /** Tickets that need triage (after de-duplication) */
207
+ candidateCount: number;
208
+ /** A member of the project's teams is idle */
209
+ anyoneIdle: boolean;
210
+ /** An idle member holds fewer in-progress tickets than the per-member cap */
211
+ idleWithRoom: boolean;
212
+ }
213
+ /** Why the driver is not woken to replan. */
214
+ export type ReplanSkipReason = 'off' | 'no_driver' | 'no_goal' | 'replan_off' | 'budget_reached' | 'triage_in_flight' | 'replan_in_flight' | 'tickets_to_triage' | 'nobody_idle' | 'at_capacity' | 'replanned_today' | 'backed_off';
215
+ /** Outcome of {@link decideReplan}. */
216
+ export type ReplanDecision = {
217
+ action: 'replan';
218
+ } | {
219
+ action: 'skip';
220
+ reason: ReplanSkipReason;
221
+ };
222
+ /**
223
+ * Whether to wake the driver with a goal replan now: the project has a goal
224
+ * but nothing is left to triage, so nobody would otherwise plan the next
225
+ * step (specs/2026-10-04-autopilot-goal-replan.md). Checked in order,
226
+ * cheapest first: switch off → no driver → replans set to 0 → budget
227
+ * reached → a triage live → a replan live → tickets to triage → nobody idle
228
+ * → every idle member at the in-progress cap → today's replans used up →
229
+ * backing off → no goal (the only gate that reads files).
230
+ *
231
+ * The autopilot only wakes the driver; the driver opens the tickets. It never
232
+ * makes a ticket ready or starts work.
233
+ *
234
+ * @param input - State of the project
235
+ * @returns `replan`, or `skip` with the reason
236
+ */
237
+ export declare function decideReplan(input: ReplanDecisionInput): ReplanDecision;
238
+ /**
239
+ * Days skipped after the n-th replan in a row that opened no tickets:
240
+ * 2, 4, then 7 (doubling, capped at REPLAN_BACKOFF_MAX_DAYS).
241
+ *
242
+ * @param streak - Empty replans in a row (≥ 1)
243
+ * @returns Days to skip after the replan's day
244
+ */
245
+ export declare function replanBackoffDays(streak: number): number;
246
+ /** The replan backoff as the autopilot remembers it. */
247
+ export interface ReplanBackoff {
248
+ /** Empty replans in a row */
249
+ streak: number;
250
+ /** When it started (epoch ms): goal changes and tickets created after this lift it */
251
+ since: number;
252
+ /** First local day a replan may run again (YYYY-MM-DD) */
253
+ resumeDay: string;
254
+ }
255
+ /**
256
+ * The backoff after a finished replan: none when it opened a ticket (any
257
+ * ticket created since the replan was queued), else one step longer.
258
+ *
259
+ * @param input - The replan, the tickets, the previous backoff, the clock
260
+ * @returns The new backoff, or null (no backoff)
261
+ */
262
+ export declare function nextReplanBackoff(input: {
263
+ /** When the replan was queued (epoch ms) */
264
+ replanAt: number;
265
+ /** Its local day */
266
+ replanDay: string;
267
+ tickets: Array<Pick<ProjectTicket, 'createdAt'>>;
268
+ previous?: ReplanBackoff | null;
269
+ now: number;
270
+ }): ReplanBackoff | null;
271
+ /**
272
+ * Where a stored backoff stands today:
273
+ * - `holds` — skip replans today;
274
+ * - `lifted` — a ticket was created, or the goal / an OKR changed, after it
275
+ * started: drop it and its streak;
276
+ * - `elapsed` — its days are over: replans may run again, but the streak is
277
+ * kept so the next empty replan backs off longer;
278
+ * - `none` — no backoff.
279
+ *
280
+ * @param backoff - The stored backoff
281
+ * @param input - Today, the tickets, when the goal last changed
282
+ * @returns State
283
+ */
284
+ export declare function replanBackoffState(backoff: ReplanBackoff | null | undefined, input: {
285
+ today: string;
286
+ tickets: Array<Pick<ProjectTicket, 'createdAt'>>;
287
+ goalChangedAt?: number | null;
288
+ }): 'holds' | 'lifted' | 'elapsed' | 'none';
289
+ /**
290
+ * Tickets closed (done or cancelled) since a moment, newest first.
291
+ *
292
+ * @param tickets - Tickets of a project
293
+ * @param sinceMs - Lower bound (epoch ms) on the ticket's `updatedAt`
294
+ * @param max - Most tickets returned
295
+ * @returns Closed tickets
296
+ */
297
+ export declare function closedTicketsSince(tickets: ProjectTicket[], sinceMs: number, max: number): ProjectTicket[];
172
298
  /** Inputs of {@link decideDigest}. */
173
299
  export interface DigestDecisionInput {
174
300
  now: Date;
@@ -1 +1 @@
1
- {"version":3,"file":"ticket-autopilot-decision.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/ticket-autopilot-decision.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ticket-autopilot-decision.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/ticket-autopilot-decision.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,8 @@
6
6
  * pool, a filesystem or timers:
7
7
  * - which tickets need the driver's triage ({@link selectTriageCandidates});
8
8
  * - whether to wake the driver now ({@link decideTriage});
9
+ * - whether to wake the driver to plan toward the goal when nothing is left
10
+ * to triage ({@link decideReplan}, specs/2026-10-04-autopilot-goal-replan.md);
9
11
  * - whether to send the owner the evening digest ({@link decideDigest}).
10
12
  *
11
13
  * @module services/project-tickets/ticket-autopilot-decision
@@ -174,9 +176,10 @@ export function selectTriageCandidates(input) {
174
176
  }
175
177
  /**
176
178
  * Whether to wake the driver with a triage item now. Checked in order:
177
- * switch off → no driver → budget reached → a triage already live → nothing
178
- * to triage → nobody idle → too soon since the last one (30 min on the
179
- * periodic tick, {@link TICKET_AUTOPILOT_CONSTANTS.IDLE_TRIGGER_MIN_INTERVAL_MS}
179
+ * switch off → no driver → budget reached → a triage already live → a goal
180
+ * replan live (the driver is opening tickets in that turn; it yields after
181
+ * an hour once there are tickets to triage) → nothing to triage → nobody
182
+ * idle → too soon since the last one (30 min on the periodic tick, {@link TICKET_AUTOPILOT_CONSTANTS.IDLE_TRIGGER_MIN_INTERVAL_MS}
180
183
  * when a member just went idle with nothing ready).
181
184
  *
182
185
  * @param input - State of the project
@@ -191,6 +194,10 @@ export function decideTriage(input) {
191
194
  return { action: 'skip', reason: 'budget_reached' };
192
195
  if (input.liveTriage)
193
196
  return { action: 'skip', reason: 'triage_in_flight' };
197
+ if (input.liveReplanAt !== undefined &&
198
+ (input.candidateCount === 0 || input.now - input.liveReplanAt < TICKET_AUTOPILOT_CONSTANTS.REPLAN_YIELD_AFTER_MS)) {
199
+ return { action: 'skip', reason: 'replan_in_flight' };
200
+ }
194
201
  if (input.candidateCount === 0)
195
202
  return { action: 'skip', reason: 'nothing_to_triage' };
196
203
  if (!input.anyoneIdle)
@@ -200,6 +207,111 @@ export function decideTriage(input) {
200
207
  return { action: 'skip', reason: 'too_soon' };
201
208
  return { action: 'triage' };
202
209
  }
210
+ /**
211
+ * Whether to wake the driver with a goal replan now: the project has a goal
212
+ * but nothing is left to triage, so nobody would otherwise plan the next
213
+ * step (specs/2026-10-04-autopilot-goal-replan.md). Checked in order,
214
+ * cheapest first: switch off → no driver → replans set to 0 → budget
215
+ * reached → a triage live → a replan live → tickets to triage → nobody idle
216
+ * → every idle member at the in-progress cap → today's replans used up →
217
+ * backing off → no goal (the only gate that reads files).
218
+ *
219
+ * The autopilot only wakes the driver; the driver opens the tickets. It never
220
+ * makes a ticket ready or starts work.
221
+ *
222
+ * @param input - State of the project
223
+ * @returns `replan`, or `skip` with the reason
224
+ */
225
+ export function decideReplan(input) {
226
+ if (!input.enabled)
227
+ return { action: 'skip', reason: 'off' };
228
+ if (!input.driver)
229
+ return { action: 'skip', reason: 'no_driver' };
230
+ if (!(input.maxReplansPerDay > 0))
231
+ return { action: 'skip', reason: 'replan_off' };
232
+ if (input.usedTodayTokens >= input.dailyBudgetTokens)
233
+ return { action: 'skip', reason: 'budget_reached' };
234
+ if (input.liveTriage)
235
+ return { action: 'skip', reason: 'triage_in_flight' };
236
+ if (input.liveReplan)
237
+ return { action: 'skip', reason: 'replan_in_flight' };
238
+ if (input.candidateCount > 0)
239
+ return { action: 'skip', reason: 'tickets_to_triage' };
240
+ if (!input.anyoneIdle)
241
+ return { action: 'skip', reason: 'nobody_idle' };
242
+ if (!input.idleWithRoom)
243
+ return { action: 'skip', reason: 'at_capacity' };
244
+ if (input.replansToday >= input.maxReplansPerDay)
245
+ return { action: 'skip', reason: 'replanned_today' };
246
+ if (input.backedOff)
247
+ return { action: 'skip', reason: 'backed_off' };
248
+ if (!input.hasGoal)
249
+ return { action: 'skip', reason: 'no_goal' };
250
+ return { action: 'replan' };
251
+ }
252
+ /**
253
+ * Days skipped after the n-th replan in a row that opened no tickets:
254
+ * 2, 4, then 7 (doubling, capped at REPLAN_BACKOFF_MAX_DAYS).
255
+ *
256
+ * @param streak - Empty replans in a row (≥ 1)
257
+ * @returns Days to skip after the replan's day
258
+ */
259
+ export function replanBackoffDays(streak) {
260
+ const C = TICKET_AUTOPILOT_CONSTANTS;
261
+ return Math.min(C.REPLAN_BACKOFF_MAX_DAYS, C.REPLAN_BACKOFF_FIRST_DAYS * 2 ** Math.max(0, streak - 1));
262
+ }
263
+ /**
264
+ * The backoff after a finished replan: none when it opened a ticket (any
265
+ * ticket created since the replan was queued), else one step longer.
266
+ *
267
+ * @param input - The replan, the tickets, the previous backoff, the clock
268
+ * @returns The new backoff, or null (no backoff)
269
+ */
270
+ export function nextReplanBackoff(input) {
271
+ const opened = input.tickets.some((t) => (Date.parse(t.createdAt) || 0) >= input.replanAt);
272
+ if (opened)
273
+ return null;
274
+ const streak = (input.previous?.streak ?? 0) + 1;
275
+ const [y, m, d] = input.replanDay.split('-').map(Number);
276
+ const resume = localDateKey(new Date(y, m - 1, d + replanBackoffDays(streak) + 1, 12));
277
+ return { streak, since: input.now, resumeDay: resume };
278
+ }
279
+ /**
280
+ * Where a stored backoff stands today:
281
+ * - `holds` — skip replans today;
282
+ * - `lifted` — a ticket was created, or the goal / an OKR changed, after it
283
+ * started: drop it and its streak;
284
+ * - `elapsed` — its days are over: replans may run again, but the streak is
285
+ * kept so the next empty replan backs off longer;
286
+ * - `none` — no backoff.
287
+ *
288
+ * @param backoff - The stored backoff
289
+ * @param input - Today, the tickets, when the goal last changed
290
+ * @returns State
291
+ */
292
+ export function replanBackoffState(backoff, input) {
293
+ if (!backoff)
294
+ return 'none';
295
+ if (input.tickets.some((t) => (Date.parse(t.createdAt) || 0) > backoff.since))
296
+ return 'lifted';
297
+ if (typeof input.goalChangedAt === 'number' && input.goalChangedAt > backoff.since)
298
+ return 'lifted';
299
+ return input.today >= backoff.resumeDay ? 'elapsed' : 'holds';
300
+ }
301
+ /**
302
+ * Tickets closed (done or cancelled) since a moment, newest first.
303
+ *
304
+ * @param tickets - Tickets of a project
305
+ * @param sinceMs - Lower bound (epoch ms) on the ticket's `updatedAt`
306
+ * @param max - Most tickets returned
307
+ * @returns Closed tickets
308
+ */
309
+ export function closedTicketsSince(tickets, sinceMs, max) {
310
+ return tickets
311
+ .filter((t) => (t.status === 'done' || t.status === 'cancelled') && (Date.parse(t.updatedAt) || 0) >= sinceMs)
312
+ .sort((a, b) => (Date.parse(b.updatedAt) || 0) - (Date.parse(a.updatedAt) || 0) || a.id.localeCompare(b.id))
313
+ .slice(0, Math.max(0, max));
314
+ }
203
315
  /**
204
316
  * Whether to send the daily digest now: once per local day, at or after
205
317
  * {@link TICKET_AUTOPILOT_CONSTANTS.DIGEST_HOUR_LOCAL}, and only when some
@@ -1 +1 @@
1
- {"version":3,"file":"ticket-autopilot-decision.js","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/ticket-autopilot-decision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AACrH,OAAO,EAAE,yBAAyB,EAAsB,MAAM,qCAAqC,CAAC;AAEpG,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAiFvD;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAqC;IACtE,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAC,iBAAiB,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAkC;IAClE,MAAM,MAAM,GAAG,0BAA0B,CAAC,yBAAyB,CAAC;IACpE,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5D,IAAI,IAAI;gBAAE,OAAO,IAAI,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,MAAqC,EAAE,KAAa;IAClF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACrD,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,yBAAyB;QAAE,OAAO,KAAK,CAAC;IACpE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YACnC,IAAI,CAAC,CAAC,CAAC,WAAW,KAAK,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QAChG,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAyD;IACpF,OAAO,CAAC,MAAM,CAAC,WAAW,KAAK,QAAQ,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,IAAI,MAAM,CAAC,aAAa,KAAK,MAAM,CAAC;AAClH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAyD;IAC1F,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC;IAClC,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,aAAa,KAAK,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;IACpH,IAAI,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,YAAY;QAAE,OAAO,MAAM,CAAC;IACpE,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAmD,EACnD,eAA+B;IAE/B,MAAM,GAAG,GAAG,MAAM,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;IAC1C,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IACpB,MAAM,SAAS,GAAG,eAAe,EAAE,IAAI,EAAE,CAAC;IAC1C,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAChC,OAAO,0BAA0B,CAAC,6BAA6B,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;AAC7F,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAmC,EAAE,KAAa;IACjF,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,IAAI,CAAC;SACnD,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QACV,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAwB;IAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;IAClC,MAAM,GAAG,GAAsB,EAAE,CAAC;IAClC,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnC,IAAI,MAAM,GAAwB,IAAI,CAAC;QACvC,iFAAiF;QACjF,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAC,mBAAmB,CAAC;YAAE,SAAS;QACrF,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/D,MAAM,GAAG,SAAS,CAAC;QACrB,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;YACpE,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC;gBAAE,MAAM,GAAG,gBAAgB,CAAC;iBACjE,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC,cAAc;gBAAE,MAAM,GAAG,aAAa,CAAC;QACxI,CAAC;QACD,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,0BAA0B,CAAC,sBAAsB;YAAE,SAAS;QACrI,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC;IACD,GAAG,CAAC,IAAI,CACN,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,yBAAyB,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,yBAAyB,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC3F,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC7E,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CACzC,CAAC;IACF,MAAM,GAAG,GAAG,0BAA0B,CAAC,kBAAkB,CAAC;IAC1D,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC;AAChF,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,KAA0B;IACrD,IAAI,CAAC,KAAK,CAAC,OAAO;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC7D,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAClE,IAAI,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,iBAAiB;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC1G,IAAI,KAAK,CAAC,UAAU;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC5E,IAAI,KAAK,CAAC,cAAc,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IACvF,IAAI,CAAC,KAAK,CAAC,UAAU;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IACxE,MAAM,GAAG,GACP,KAAK,CAAC,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,0BAA0B,CAAC,4BAA4B,CAAC,CAAC,CAAC,0BAA0B,CAAC,sBAAsB,CAAC;IAChJ,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,YAAY,GAAG,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC5H,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAaD;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,KAA0B;IACrD,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,0BAA0B,CAAC,iBAAiB;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACnH,IAAI,KAAK,CAAC,YAAY,KAAK,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IACnG,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC5E,IAAI,CAAC,CAAC,KAAK,CAAC,oBAAoB,GAAG,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC7F,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,GAAS;IACrC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAClC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACvB,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,GAAS;IACpC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,OAAO,GAAG,GAAG,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;AACjF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAwB;IACzD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,MAAM,KAAK,aAAa,IAAI,CAAC,CAAC,QAAQ;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,wFAAwF;AACxF,MAAM,CAAC,MAAM,oBAAoB,GAAwB,IAAI,GAAG,CAC9D,wBAAwB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,WAAW,CAAC,CACnF,CAAC"}
1
+ {"version":3,"file":"ticket-autopilot-decision.js","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/ticket-autopilot-decision.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Ticket autopilot — the project's goal and open experiments for the goal
3
+ * replan (specs/2026-10-04-autopilot-goal-replan.md).
4
+ *
5
+ * The goal comes from the two places project goals live today:
6
+ * - the goals log `<project>/.crewly/goals/goals.md` (`set_goal` writes it,
7
+ * `get_goals` and the mission card read it): its entries of the last 30
8
+ * days, newest first (the log is append-only, so older ones are history);
9
+ * - active project OKRs: missions with `status: active`, this project's id,
10
+ * and approval absent or approved.
11
+ *
12
+ * The parsing is pure (unit-tested); {@link readProjectGoal} does the reads
13
+ * and never throws (a read failure is "no goal").
14
+ *
15
+ * @module services/project-tickets/ticket-autopilot-goal
16
+ */
17
+ import { type Mission } from '../../types/v2/mission.types.js';
18
+ import type { Experiment } from '../../types/experiment.types.js';
19
+ /** A project's active goal, as the replan brief quotes it. */
20
+ export interface ProjectGoal {
21
+ /** Goal text (markdown, already capped) */
22
+ text: string;
23
+ /** Where it came from */
24
+ sources: Array<'goals_log' | 'okr'>;
25
+ }
26
+ /** An open experiment card, as the replan brief lists it. */
27
+ export interface ReplanExperiment {
28
+ id: string;
29
+ title: string;
30
+ hypothesis: string;
31
+ status: string;
32
+ /** When its result can be measured */
33
+ dueAt?: string;
34
+ }
35
+ /** The part of a project the goal reader needs. */
36
+ export interface GoalProject {
37
+ id: string;
38
+ name: string;
39
+ path: string;
40
+ }
41
+ /**
42
+ * The newest entries of a goals log (`goals.md`), newest first.
43
+ *
44
+ * Entries are `### [<iso>] Set by <who>` blocks. A file with only its
45
+ * `# Project Goals` header (or blank) has no goal. Text without entry
46
+ * headers is taken as one goal.
47
+ *
48
+ * The log is append-only, so with a `window` only entries from the last
49
+ * {@link TICKET_AUTOPILOT_CONSTANTS.REPLAN_GOAL_ACTIVE_DAYS} days count as
50
+ * active; an entry (or a header-less file) without a readable date uses the
51
+ * file's modification time, and is kept when that is unknown too.
52
+ *
53
+ * @param raw - File contents (null = no file)
54
+ * @param maxEntries - Most entries kept
55
+ * @param maxChars - Most characters returned
56
+ * @param window - Clock, the file's mtime, and the active window (days)
57
+ * @returns Goal markdown, or null when there is none
58
+ */
59
+ export declare function goalFromGoalsLog(raw: string | null | undefined, maxEntries?: number, maxChars?: number, window?: {
60
+ now: number;
61
+ fileMtimeMs?: number | null;
62
+ activeDays?: number;
63
+ }): string | null;
64
+ /**
65
+ * The active OKRs of a project: active missions with its id whose approval
66
+ * is absent or approved, highest priority (then newest) first.
67
+ *
68
+ * @param missions - Missions read from the store(s)
69
+ * @param projectId - Project id
70
+ * @returns Active project missions
71
+ */
72
+ export declare function activeProjectMissions(missions: Mission[], projectId: string): Mission[];
73
+ /**
74
+ * Missions as goal text: the objective and its success criteria.
75
+ *
76
+ * @param missions - Active project missions
77
+ * @param maxChars - Most characters
78
+ * @returns Markdown, or null with none
79
+ */
80
+ export declare function goalFromMissions(missions: Mission[], maxChars?: number): string | null;
81
+ /**
82
+ * Combine the goals log and the OKRs into one goal.
83
+ *
84
+ * @param log - Goal text from goals.md
85
+ * @param okr - Goal text from the missions
86
+ * @returns Goal, or null when neither has one
87
+ */
88
+ export declare function combineGoal(log: string | null, okr: string | null): ProjectGoal | null;
89
+ /**
90
+ * When the project's goal last changed, from file times only (no reads):
91
+ * the goals log, and the missions folders (a mission written or replaced
92
+ * renames into its folder). Lifts a replan backoff. A change to another
93
+ * project's mission in the shared store also counts: that only lifts a
94
+ * backoff early, never holds one.
95
+ *
96
+ * @param project - Project path
97
+ * @returns Epoch ms, or null when nothing exists
98
+ */
99
+ export declare function goalChangedAt(project: Pick<GoalProject, 'path'>): Promise<number | null>;
100
+ /**
101
+ * The project's active goal: the goals-log entries of the last
102
+ * REPLAN_GOAL_ACTIVE_DAYS days (newest first) plus its active OKRs (the
103
+ * project's missions folder and the shared store; their own status
104
+ * decides). Never throws.
105
+ *
106
+ * @param project - Project id and path
107
+ * @param now - Clock
108
+ * @returns Goal, or null when the project has none
109
+ */
110
+ export declare function readProjectGoal(project: GoalProject, now?: Date): Promise<ProjectGoal | null>;
111
+ /**
112
+ * Open experiment cards (planned or running) of a project: its autopilot
113
+ * scope is the project, or its ticket link names the project (id, name or
114
+ * path).
115
+ *
116
+ * @param experiments - Every experiment
117
+ * @param project - Project
118
+ * @param max - Most returned
119
+ * @returns Cards for the replan brief, newest first
120
+ */
121
+ export declare function openExperimentsOf(experiments: Experiment[], project: GoalProject, max?: number): ReplanExperiment[];
122
+ //# sourceMappingURL=ticket-autopilot-goal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket-autopilot-goal.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/ticket-autopilot-goal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAA0B,KAAK,OAAO,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAIlE,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,OAAO,EAAE,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;CACrC;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAaD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC9B,UAAU,GAAE,MAA2D,EACvE,QAAQ,GAAE,MAAyD,EACnE,MAAM,CAAC,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACzE,MAAM,GAAG,IAAI,CAmCf;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,CASvF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,QAAQ,GAAE,MAAyD,GAAG,MAAM,GAAG,IAAI,CAQxI;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,GAAG,IAAI,CAatF;AAmDD;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAI9F;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAqB/G;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,UAAU,EAAE,EACzB,OAAO,EAAE,WAAW,EACpB,GAAG,GAAE,MAA0D,GAC9D,gBAAgB,EAAE,CAWpB"}