@telora/daemon 0.20.32 → 0.20.54

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 (203) hide show
  1. package/build-info.json +2 -2
  2. package/dist/agent-state.d.ts +4 -6
  3. package/dist/agent-state.d.ts.map +1 -1
  4. package/dist/agent-state.js +4 -10
  5. package/dist/agent-state.js.map +1 -1
  6. package/dist/branch-status.d.ts +25 -3
  7. package/dist/branch-status.d.ts.map +1 -1
  8. package/dist/branch-status.js +130 -59
  9. package/dist/branch-status.js.map +1 -1
  10. package/dist/completion/completion-decision.d.ts +29 -3
  11. package/dist/completion/completion-decision.d.ts.map +1 -1
  12. package/dist/completion/completion-decision.js +15 -3
  13. package/dist/completion/completion-decision.js.map +1 -1
  14. package/dist/completion/event-entry-phases.d.ts +57 -0
  15. package/dist/completion/event-entry-phases.d.ts.map +1 -0
  16. package/dist/completion/event-entry-phases.js +205 -0
  17. package/dist/completion/event-entry-phases.js.map +1 -0
  18. package/dist/completion/event-phases.d.ts +14 -42
  19. package/dist/completion/event-phases.d.ts.map +1 -1
  20. package/dist/completion/event-phases.js +63 -190
  21. package/dist/completion/event-phases.js.map +1 -1
  22. package/dist/completion/event.d.ts +11 -1
  23. package/dist/completion/event.d.ts.map +1 -1
  24. package/dist/completion/event.js +5 -2
  25. package/dist/completion/event.js.map +1 -1
  26. package/dist/completion/index.d.ts +0 -3
  27. package/dist/completion/index.d.ts.map +1 -1
  28. package/dist/completion/index.js +0 -3
  29. package/dist/completion/index.js.map +1 -1
  30. package/dist/completion/review-exit-phase.d.ts +2 -1
  31. package/dist/completion/review-exit-phase.d.ts.map +1 -1
  32. package/dist/completion/review-exit-phase.js +41 -1
  33. package/dist/completion/review-exit-phase.js.map +1 -1
  34. package/dist/completion/status-advance-phase.d.ts +2 -0
  35. package/dist/completion/status-advance-phase.d.ts.map +1 -1
  36. package/dist/completion/status-advance-phase.js +14 -28
  37. package/dist/completion/status-advance-phase.js.map +1 -1
  38. package/dist/completion/team-completion.js +1 -1
  39. package/dist/completion/team-completion.js.map +1 -1
  40. package/dist/completion/terminated-work-reconcile.d.ts.map +1 -1
  41. package/dist/completion/terminated-work-reconcile.js +10 -0
  42. package/dist/completion/terminated-work-reconcile.js.map +1 -1
  43. package/dist/constants.d.ts +0 -8
  44. package/dist/constants.d.ts.map +1 -1
  45. package/dist/constants.js +0 -8
  46. package/dist/constants.js.map +1 -1
  47. package/dist/delivery-close-actions.d.ts +39 -0
  48. package/dist/delivery-close-actions.d.ts.map +1 -0
  49. package/dist/delivery-close-actions.js +53 -0
  50. package/dist/delivery-close-actions.js.map +1 -0
  51. package/dist/delivery-lifecycle.d.ts +11 -0
  52. package/dist/delivery-lifecycle.d.ts.map +1 -1
  53. package/dist/delivery-lifecycle.js +13 -14
  54. package/dist/delivery-lifecycle.js.map +1 -1
  55. package/dist/delivery-reconciler.d.ts +18 -4
  56. package/dist/delivery-reconciler.d.ts.map +1 -1
  57. package/dist/delivery-reconciler.js +18 -4
  58. package/dist/delivery-reconciler.js.map +1 -1
  59. package/dist/directive-executor.d.ts +1 -1
  60. package/dist/directive-executor.js +1 -1
  61. package/dist/discovery-fetch.d.ts +76 -0
  62. package/dist/discovery-fetch.d.ts.map +1 -0
  63. package/dist/discovery-fetch.js +206 -0
  64. package/dist/discovery-fetch.js.map +1 -0
  65. package/dist/discovery-poll.d.ts +1 -51
  66. package/dist/discovery-poll.d.ts.map +1 -1
  67. package/dist/discovery-poll.js +10 -192
  68. package/dist/discovery-poll.js.map +1 -1
  69. package/dist/drain-teardown.d.ts +11 -6
  70. package/dist/drain-teardown.d.ts.map +1 -1
  71. package/dist/drain-teardown.js +3 -2
  72. package/dist/drain-teardown.js.map +1 -1
  73. package/dist/focus-branch-ahead.d.ts +42 -0
  74. package/dist/focus-branch-ahead.d.ts.map +1 -0
  75. package/dist/focus-branch-ahead.js +45 -0
  76. package/dist/focus-branch-ahead.js.map +1 -0
  77. package/dist/focus-engine.d.ts.map +1 -1
  78. package/dist/focus-engine.js +21 -43
  79. package/dist/focus-engine.js.map +1 -1
  80. package/dist/focus-executor.js +2 -2
  81. package/dist/focus-executor.js.map +1 -1
  82. package/dist/focus-lifecycle.d.ts.map +1 -1
  83. package/dist/focus-lifecycle.js +32 -3
  84. package/dist/focus-lifecycle.js.map +1 -1
  85. package/dist/focus-loop.d.ts +34 -12
  86. package/dist/focus-loop.d.ts.map +1 -1
  87. package/dist/focus-loop.js +78 -15
  88. package/dist/focus-loop.js.map +1 -1
  89. package/dist/focus-merge.d.ts.map +1 -1
  90. package/dist/focus-merge.js +6 -1
  91. package/dist/focus-merge.js.map +1 -1
  92. package/dist/focus-phase.d.ts +18 -3
  93. package/dist/focus-phase.d.ts.map +1 -1
  94. package/dist/focus-phase.js +85 -31
  95. package/dist/focus-phase.js.map +1 -1
  96. package/dist/focus-prompt-builder.d.ts.map +1 -1
  97. package/dist/focus-prompt-builder.js +8 -0
  98. package/dist/focus-prompt-builder.js.map +1 -1
  99. package/dist/focus-provisioning.d.ts.map +1 -1
  100. package/dist/focus-provisioning.js +4 -0
  101. package/dist/focus-provisioning.js.map +1 -1
  102. package/dist/focus-stage-lifecycle/planning-release.d.ts +35 -17
  103. package/dist/focus-stage-lifecycle/planning-release.d.ts.map +1 -1
  104. package/dist/focus-stage-lifecycle/planning-release.js +53 -22
  105. package/dist/focus-stage-lifecycle/planning-release.js.map +1 -1
  106. package/dist/focus-worktree-state.d.ts +17 -6
  107. package/dist/focus-worktree-state.d.ts.map +1 -1
  108. package/dist/focus-worktree-state.js +21 -11
  109. package/dist/focus-worktree-state.js.map +1 -1
  110. package/dist/guard-engine.d.ts +1 -2
  111. package/dist/guard-engine.d.ts.map +1 -1
  112. package/dist/guard-engine.js +1 -2
  113. package/dist/guard-engine.js.map +1 -1
  114. package/dist/health-events.d.ts +10 -0
  115. package/dist/health-events.d.ts.map +1 -0
  116. package/dist/health-events.js +10 -0
  117. package/dist/health-events.js.map +1 -0
  118. package/dist/heartbeat.d.ts +19 -0
  119. package/dist/heartbeat.d.ts.map +1 -1
  120. package/dist/heartbeat.js +58 -22
  121. package/dist/heartbeat.js.map +1 -1
  122. package/dist/host-control/catalog.d.ts.map +1 -1
  123. package/dist/host-control/catalog.js +4 -1
  124. package/dist/host-control/catalog.js.map +1 -1
  125. package/dist/host-control/client.d.ts +3 -4
  126. package/dist/host-control/client.d.ts.map +1 -1
  127. package/dist/host-control/client.js +4 -5
  128. package/dist/host-control/client.js.map +1 -1
  129. package/dist/listener-auto-advance.d.ts +2 -1
  130. package/dist/listener-auto-advance.d.ts.map +1 -1
  131. package/dist/listener-auto-advance.js +36 -40
  132. package/dist/listener-auto-advance.js.map +1 -1
  133. package/dist/listener.d.ts +2 -7
  134. package/dist/listener.d.ts.map +1 -1
  135. package/dist/listener.js +11 -9
  136. package/dist/listener.js.map +1 -1
  137. package/dist/operator-hold.d.ts +66 -0
  138. package/dist/operator-hold.d.ts.map +1 -0
  139. package/dist/operator-hold.js +99 -0
  140. package/dist/operator-hold.js.map +1 -0
  141. package/dist/poll-trigger.d.ts +28 -0
  142. package/dist/poll-trigger.d.ts.map +1 -0
  143. package/dist/poll-trigger.js +31 -0
  144. package/dist/poll-trigger.js.map +1 -0
  145. package/dist/prompt-listing.js +6 -0
  146. package/dist/prompt-listing.js.map +1 -1
  147. package/dist/prompt-sections/execution-sections.d.ts.map +1 -1
  148. package/dist/prompt-sections/execution-sections.js +24 -0
  149. package/dist/prompt-sections/execution-sections.js.map +1 -1
  150. package/dist/queries/context-lock-queries.d.ts.map +1 -1
  151. package/dist/queries/context-lock-queries.js +4 -1
  152. package/dist/queries/context-lock-queries.js.map +1 -1
  153. package/dist/queries/deliveries.d.ts +17 -0
  154. package/dist/queries/deliveries.d.ts.map +1 -1
  155. package/dist/queries/deliveries.js.map +1 -1
  156. package/dist/queries/issues.d.ts +98 -0
  157. package/dist/queries/issues.d.ts.map +1 -1
  158. package/dist/queries/issues.js +135 -0
  159. package/dist/queries/issues.js.map +1 -1
  160. package/dist/queries/schemas.d.ts +3 -3
  161. package/dist/spawn/worktree-session.d.ts.map +1 -1
  162. package/dist/spawn/worktree-session.js +2 -0
  163. package/dist/spawn/worktree-session.js.map +1 -1
  164. package/dist/spawner/index.d.ts +7 -9
  165. package/dist/spawner/index.d.ts.map +1 -1
  166. package/dist/spawner/index.js +13 -11
  167. package/dist/spawner/index.js.map +1 -1
  168. package/dist/spawner/lifecycle.d.ts +1 -18
  169. package/dist/spawner/lifecycle.d.ts.map +1 -1
  170. package/dist/spawner/lifecycle.js +1 -54
  171. package/dist/spawner/lifecycle.js.map +1 -1
  172. package/dist/spawner/liveness.d.ts +5 -14
  173. package/dist/spawner/liveness.d.ts.map +1 -1
  174. package/dist/spawner/liveness.js +5 -67
  175. package/dist/spawner/liveness.js.map +1 -1
  176. package/dist/spawner/state.d.ts +8 -20
  177. package/dist/spawner/state.d.ts.map +1 -1
  178. package/dist/spawner/state.js +8 -34
  179. package/dist/spawner/state.js.map +1 -1
  180. package/dist/types/focus.d.ts +9 -0
  181. package/dist/types/focus.d.ts.map +1 -1
  182. package/dist/types/session.d.ts +0 -44
  183. package/dist/types/session.d.ts.map +1 -1
  184. package/dist/unified-shell.d.ts.map +1 -1
  185. package/dist/unified-shell.js +8 -0
  186. package/dist/unified-shell.js.map +1 -1
  187. package/package.json +1 -2
  188. package/dist/completion/agent-completion.d.ts +0 -48
  189. package/dist/completion/agent-completion.d.ts.map +0 -1
  190. package/dist/completion/agent-completion.js +0 -205
  191. package/dist/completion/agent-completion.js.map +0 -1
  192. package/dist/delivery-guards.d.ts +0 -41
  193. package/dist/delivery-guards.d.ts.map +0 -1
  194. package/dist/delivery-guards.js +0 -200
  195. package/dist/delivery-guards.js.map +0 -1
  196. package/dist/spawner/spawn-team.d.ts +0 -20
  197. package/dist/spawner/spawn-team.d.ts.map +0 -1
  198. package/dist/spawner/spawn-team.js +0 -19
  199. package/dist/spawner/spawn-team.js.map +0 -1
  200. package/dist/spawner/timeout.d.ts +0 -32
  201. package/dist/spawner/timeout.d.ts.map +0 -1
  202. package/dist/spawner/timeout.js +0 -126
  203. package/dist/spawner/timeout.js.map +0 -1
package/build-info.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "commitSha": "6ba60c2ca",
3
- "builtAt": "2026-07-25T01:48:56.881Z",
2
+ "commitSha": "ef44c4aab",
3
+ "builtAt": "2026-07-26T13:06:17.133Z",
4
4
  "expectedMigrations": [
5
5
  "20250829113330_create_org_nodes_table.sql",
6
6
  "20250829113402_fix_function_security_search_path.sql",
@@ -3,15 +3,13 @@
3
3
  * heartbeat.ts and spawner.ts by centralizing state that both modules need.
4
4
  *
5
5
  * Contains:
6
- * - Running agents map (read by heartbeat, written by spawner)
7
6
  * - Session completion counters (written by spawner/completion-handler, read by heartbeat)
8
7
  * - Activity tracking (written by spawner/listener, read by heartbeat)
8
+ *
9
+ * The legacy per-delivery `runningAgents` map was removed: the only live spawn
10
+ * path (`spawnFocusTeam`) tracks team leads in `activeTeams`, reaped by the
11
+ * single `reapWorkerFleet` teardown. See packages/daemon/CLAUDE.md.
9
12
  */
10
- import type { RunningAgent } from './types.js';
11
- /**
12
- * Get map of running agents.
13
- */
14
- export declare function getRunningAgents(): Map<string, RunningAgent>;
15
13
  /**
16
14
  * Record a completed session (called by spawner when an agent finishes).
17
15
  */
@@ -1 +1 @@
1
- {"version":3,"file":"agent-state.d.ts","sourceRoot":"","sources":["../src/agent-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAO/C;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAE5D;AAQD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAIzE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI;IACpC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB,CAEA;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE;IAC3C,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,IAAI,CAIP;AAMD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
1
+ {"version":3,"file":"agent-state.d.ts","sourceRoot":"","sources":["../src/agent-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAIzE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI;IACpC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB,CAEA;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE;IAC3C,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,IAAI,CAIP;AAMD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
@@ -3,19 +3,13 @@
3
3
  * heartbeat.ts and spawner.ts by centralizing state that both modules need.
4
4
  *
5
5
  * Contains:
6
- * - Running agents map (read by heartbeat, written by spawner)
7
6
  * - Session completion counters (written by spawner/completion-handler, read by heartbeat)
8
7
  * - Activity tracking (written by spawner/listener, read by heartbeat)
8
+ *
9
+ * The legacy per-delivery `runningAgents` map was removed: the only live spawn
10
+ * path (`spawnFocusTeam`) tracks team leads in `activeTeams`, reaped by the
11
+ * single `reapWorkerFleet` teardown. See packages/daemon/CLAUDE.md.
9
12
  */
10
- // ── Running agents map ──────────────────────────────────────────────
11
- /** Running agents map: sessionId -> RunningAgent */
12
- const runningAgents = new Map();
13
- /**
14
- * Get map of running agents.
15
- */
16
- export function getRunningAgents() {
17
- return runningAgents;
18
- }
19
13
  // ── Session completion counters ─────────────────────────────────────
20
14
  let completedSessionCount = 0;
21
15
  let totalTokensUsed = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-state.js","sourceRoot":"","sources":["../src/agent-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,uEAAuE;AAEvE,oDAAoD;AACpD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAwB,CAAC;AAEtD;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,uEAAuE;AAEvE,IAAI,qBAAqB,GAAG,CAAC,CAAC;AAC9B,IAAI,eAAe,GAAG,CAAC,CAAC;AACxB,IAAI,SAAS,GAAG,CAAC,CAAC;AAElB;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAc,EAAE,IAAY;IACjE,qBAAqB,EAAE,CAAC;IACxB,eAAe,IAAI,MAAM,CAAC;IAC1B,SAAS,IAAI,IAAI,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAKhC,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAIlC;IACC,qBAAqB,GAAG,QAAQ,CAAC,qBAAqB,CAAC;IACvD,eAAe,GAAG,QAAQ,CAAC,eAAe,CAAC;IAC3C,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;AACjC,CAAC;AAED,uEAAuE;AAEvE,IAAI,cAAc,GAAG,IAAI,IAAI,EAAE,CAAC;AAEhC;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,cAAc,GAAG,IAAI,IAAI,EAAE,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,cAAc,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"agent-state.js","sourceRoot":"","sources":["../src/agent-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,uEAAuE;AAEvE,IAAI,qBAAqB,GAAG,CAAC,CAAC;AAC9B,IAAI,eAAe,GAAG,CAAC,CAAC;AACxB,IAAI,SAAS,GAAG,CAAC,CAAC;AAElB;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAc,EAAE,IAAY;IACjE,qBAAqB,EAAE,CAAC;IACxB,eAAe,IAAI,MAAM,CAAC;IAC1B,SAAS,IAAI,IAAI,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAKhC,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAIlC;IACC,qBAAqB,GAAG,QAAQ,CAAC,qBAAqB,CAAC;IACvD,eAAe,GAAG,QAAQ,CAAC,eAAe,CAAC;IAC3C,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;AACjC,CAAC;AAED,uEAAuE;AAEvE,IAAI,cAAc,GAAG,IAAI,IAAI,EAAE,CAAC;AAEhC;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,cAAc,GAAG,IAAI,IAAI,EAAE,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,cAAc,CAAC;AACxB,CAAC"}
@@ -7,10 +7,30 @@
7
7
  * 3. Each focus worktree vs integration
8
8
  *
9
9
  * Results ride in the heartbeat metadata field (no new tables).
10
+ *
11
+ * Multi-product: computeBranchStatus is called once per configured product
12
+ * with a product-scoped config (configForProduct). The focus worktree map
13
+ * spans all products, so this module scopes it by each entry's productId and
14
+ * runs git against the entry's own repoPath — evaluating a worktree against
15
+ * a repository that does not own it is unrepresentable here. All caches are
16
+ * keyed per product so one product's tick cannot evict another's state.
17
+ *
18
+ * Failure semantics (two distinct kinds, deliberately kept apart):
19
+ * - TRANSIENT git failures (lock contention, mid-rebase, timeouts) fall
20
+ * back to the last good cached status without raising anything — this
21
+ * tolerance predates this module split and prevents UI flicker.
22
+ * - PERMANENT failures (unknown revision, not a git repository, bad
23
+ * object) mean the branch we believe exists cannot be resolved where we
24
+ * looked: an attribution error, not contention. These are surfaced via
25
+ * a healthEvent + error log (once per focus per daemon run) instead of
26
+ * silently rendering identically to "no worktree". A worktree entry in
27
+ * the map IS the claim that its branch should exist; a legitimately
28
+ * deleted branch is removed from the map (removeFocusWorktree) before
29
+ * ever being evaluated here, so ordinary deletions raise no events.
10
30
  */
11
31
  import type { DaemonConfig } from './types.js';
12
32
  import type { BranchMonitorEntry } from './queries/products.js';
13
- /** Reset the cache. Exported for tests only. */
33
+ /** Reset all caches. Exported for tests only. */
14
34
  export declare function resetBranchStatusCache(): void;
15
35
  export type BranchHealth = 'clean' | 'dirty' | 'conflict';
16
36
  export interface IntegrationBranchStatus {
@@ -44,13 +64,15 @@ export interface BranchStatusOptions {
44
64
  branchMonitors?: BranchMonitorEntry[];
45
65
  }
46
66
  /**
47
- * Compute branch status for all three tiers.
67
+ * Compute branch status for all three tiers of ONE product.
48
68
  *
49
69
  * Safe to call from the heartbeat loop: uses short git timeouts
50
70
  * and catches all errors so a single failure skips that entry
51
71
  * rather than failing the entire heartbeat.
52
72
  *
53
- * @param config - Daemon config (provides repoPath, integrationBranch)
73
+ * @param config - Product-scoped daemon config (configForProduct); provides
74
+ * productId, repoPath, integrationBranch. Only worktrees owned by
75
+ * config.productId are evaluated, each against its own repoPath.
54
76
  * @param options - Optional overrides for mainBranch and branchMonitors from the product record
55
77
  */
56
78
  export declare function computeBranchStatus(config: DaemonConfig, options?: BranchStatusOptions): BranchStatusPayload;
@@ -1 +1 @@
1
- {"version":3,"file":"branch-status.d.ts","sourceRoot":"","sources":["../src/branch-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAyBhE,gDAAgD;AAChD,wBAAgB,sBAAsB,IAAI,IAAI,CAI7C;AAID,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;AAE1D,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC5C,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,kDAAkD;AAClD,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACvC;AA2BD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,CA4K5G"}
1
+ {"version":3,"file":"branch-status.d.ts","sourceRoot":"","sources":["../src/branch-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAsChE,iDAAiD;AACjD,wBAAgB,sBAAsB,IAAI,IAAI,CAG7C;AAID,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;AAE1D,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC5C,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,kDAAkD;AAClD,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACvC;AA6ED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,CAuM5G"}
@@ -7,42 +7,67 @@
7
7
  * 3. Each focus worktree vs integration
8
8
  *
9
9
  * Results ride in the heartbeat metadata field (no new tables).
10
+ *
11
+ * Multi-product: computeBranchStatus is called once per configured product
12
+ * with a product-scoped config (configForProduct). The focus worktree map
13
+ * spans all products, so this module scopes it by each entry's productId and
14
+ * runs git against the entry's own repoPath — evaluating a worktree against
15
+ * a repository that does not own it is unrepresentable here. All caches are
16
+ * keyed per product so one product's tick cannot evict another's state.
17
+ *
18
+ * Failure semantics (two distinct kinds, deliberately kept apart):
19
+ * - TRANSIENT git failures (lock contention, mid-rebase, timeouts) fall
20
+ * back to the last good cached status without raising anything — this
21
+ * tolerance predates this module split and prevents UI flicker.
22
+ * - PERMANENT failures (unknown revision, not a git repository, bad
23
+ * object) mean the branch we believe exists cannot be resolved where we
24
+ * looked: an attribution error, not contention. These are surfaced via
25
+ * a healthEvent + error log (once per focus per daemon run) instead of
26
+ * silently rendering identically to "no worktree". A worktree entry in
27
+ * the map IS the claim that its branch should exist; a legitimately
28
+ * deleted branch is removed from the map (removeFocusWorktree) before
29
+ * ever being evaluated here, so ordinary deletions raise no events.
10
30
  */
11
31
  import { runGitSync } from './git/index.js';
12
32
  import { getDefaultBranch } from './git/index.js';
13
33
  import { getAllFocusWorktrees } from './focus-worktree-state.js';
14
34
  import { getActiveTeams } from './focus-team-state.js';
35
+ import { healthEvents } from './health-events.js';
36
+ import { createLogger } from './log.js';
37
+ const log = createLogger({ module: 'branch-status' });
15
38
  /** Short timeout for git commands to avoid blocking the heartbeat. */
16
39
  const BRANCH_STATUS_GIT_TIMEOUT_MS = 5_000;
40
+ const cachesByProduct = new Map();
17
41
  /**
18
- * Cache of last successful integration branch status.
19
- * Reused when a transient git failure (lock contention, mid-rebase)
20
- * prevents computing fresh status, avoiding UI flicker.
21
- */
22
- let lastGoodIntegrationStatus = null;
23
- /**
24
- * Cache of last successful focus branch status per focus ID.
25
- * Reused when a transient git failure (lock contention, mid-rebase)
26
- * prevents computing fresh status, avoiding UI flicker.
42
+ * Focus IDs whose permanent-failure health event has already been emitted
43
+ * this daemon run one event per focus, not one per heartbeat tick.
27
44
  */
28
- const lastGoodFocusStatus = new Map();
29
- /**
30
- * Cache of last successful remote branch status per remote ref.
31
- * Reused when a transient git failure prevents computing fresh status.
32
- */
33
- const lastGoodRemoteStatus = new Map();
34
- /** Reset the cache. Exported for tests only. */
45
+ const permanentFailureEmitted = new Set();
46
+ function cacheForProduct(key) {
47
+ let cache = cachesByProduct.get(key);
48
+ if (!cache) {
49
+ cache = { integration: null, focus: new Map(), remote: new Map() };
50
+ cachesByProduct.set(key, cache);
51
+ }
52
+ return cache;
53
+ }
54
+ /** Reset all caches. Exported for tests only. */
35
55
  export function resetBranchStatusCache() {
36
- lastGoodIntegrationStatus = null;
37
- lastGoodFocusStatus.clear();
38
- lastGoodRemoteStatus.clear();
56
+ cachesByProduct.clear();
57
+ permanentFailureEmitted.clear();
39
58
  }
40
59
  // ── Helpers ──────────────────────────────────────────────────────────
41
60
  const gitOpts = { timeoutMs: BRANCH_STATUS_GIT_TIMEOUT_MS };
61
+ /**
62
+ * Git stderr patterns that mean the ref/repository itself is unresolvable —
63
+ * a permanent condition no retry will fix, as opposed to contention.
64
+ */
65
+ const PERMANENT_GIT_FAILURE_RE = /unknown revision|bad revision|ambiguous argument|not a git repository|bad object|invalid ref/i;
42
66
  /**
43
67
  * Count commits in A that are not in B: `git rev-list --count B..A`.
44
- * Returns null on any failure so callers can distinguish "actually zero"
45
- * from "git was busy" and fall back to cached data.
68
+ * Returns a null count on failure, classified as transient (git was busy —
69
+ * fall back to cached data) or permanent (the ref cannot resolve where we
70
+ * looked — an attribution error to surface, not to swallow).
46
71
  *
47
72
  * @param noMerges - When true, adds `--no-merges` to skip merge commits.
48
73
  * Useful for remote monitors where "Merge main into qa" commits are
@@ -54,24 +79,51 @@ function revListCount(refA, refB, cwd, noMerges) {
54
79
  args.push('--no-merges');
55
80
  args.push(`${refB}..${refA}`);
56
81
  const result = runGitSync(args, cwd, gitOpts);
57
- if (!result.success)
58
- return null;
82
+ if (!result.success) {
83
+ return PERMANENT_GIT_FAILURE_RE.test(result.error)
84
+ ? { count: null, failure: 'permanent', message: result.error }
85
+ : { count: null, failure: 'transient' };
86
+ }
59
87
  const n = parseInt(result.output, 10);
60
- return Number.isNaN(n) ? null : n;
88
+ return Number.isNaN(n) ? { count: null, failure: 'transient' } : { count: n };
89
+ }
90
+ /**
91
+ * Surface a permanent branch-resolution failure for a focus: error log plus
92
+ * a healthEvent (rides in heartbeat metadata), emitted once per focus per
93
+ * daemon run. This is the channel that distinguishes "could not determine"
94
+ * from "no worktree" — the payload entry falls back to cache (or is omitted),
95
+ * but the failure is never silent.
96
+ */
97
+ function surfacePermanentFocusFailure(focusId, branch, repoPath, productId, message) {
98
+ log.error(`Permanent branch-status failure for focus ${focusId}: ` +
99
+ `cannot resolve ${branch} in ${repoPath}: ${message}`);
100
+ if (permanentFailureEmitted.has(focusId))
101
+ return;
102
+ permanentFailureEmitted.add(focusId);
103
+ healthEvents.emit({
104
+ severity: 'warn',
105
+ source: 'branch-status',
106
+ code: 'branch_status.attribution_error',
107
+ message: `Branch ${branch} for focus ${focusId} cannot be resolved in ${repoPath}: ${message}`,
108
+ productId,
109
+ });
61
110
  }
62
111
  // ── Main ─────────────────────────────────────────────────────────────
63
112
  /**
64
- * Compute branch status for all three tiers.
113
+ * Compute branch status for all three tiers of ONE product.
65
114
  *
66
115
  * Safe to call from the heartbeat loop: uses short git timeouts
67
116
  * and catches all errors so a single failure skips that entry
68
117
  * rather than failing the entire heartbeat.
69
118
  *
70
- * @param config - Daemon config (provides repoPath, integrationBranch)
119
+ * @param config - Product-scoped daemon config (configForProduct); provides
120
+ * productId, repoPath, integrationBranch. Only worktrees owned by
121
+ * config.productId are evaluated, each against its own repoPath.
71
122
  * @param options - Optional overrides for mainBranch and branchMonitors from the product record
72
123
  */
73
124
  export function computeBranchStatus(config, options) {
74
- const { repoPath, integrationBranch } = config;
125
+ const { repoPath, integrationBranch, productId } = config;
126
+ const cache = cacheForProduct(productId || repoPath);
75
127
  const mainBranch = options?.mainBranch || getDefaultBranch(repoPath);
76
128
  const monitors = options?.branchMonitors?.length
77
129
  ? options.branchMonitors
@@ -86,31 +138,31 @@ export function computeBranchStatus(config, options) {
86
138
  // not new code. Without this, integration perpetually shows as "ahead".
87
139
  const aheadOfMain = revListCount(integrationBranch, mainBranch, repoPath, true);
88
140
  const behindMain = revListCount(mainBranch, integrationBranch, repoPath);
89
- if (aheadOfMain === null || behindMain === null) {
141
+ if (aheadOfMain.count === null || behindMain.count === null) {
90
142
  // Transient git failure (lock contention, mid-rebase) — use cached status
91
- integration = lastGoodIntegrationStatus;
143
+ integration = cache.integration;
92
144
  }
93
145
  else {
94
146
  let health = 'clean';
95
- if (aheadOfMain > 0 && behindMain > 0) {
147
+ if (aheadOfMain.count > 0 && behindMain.count > 0) {
96
148
  health = 'conflict'; // truly diverged — both directions have commits
97
149
  }
98
- else if (aheadOfMain > 0 || behindMain > 0) {
150
+ else if (aheadOfMain.count > 0 || behindMain.count > 0) {
99
151
  health = 'dirty';
100
152
  }
101
153
  integration = {
102
154
  branch: integrationBranch,
103
155
  health,
104
- aheadOfMain,
105
- behindMain,
156
+ aheadOfMain: aheadOfMain.count,
157
+ behindMain: behindMain.count,
106
158
  };
107
- lastGoodIntegrationStatus = integration;
159
+ cache.integration = integration;
108
160
  }
109
161
  }
110
162
  }
111
163
  catch {
112
164
  // Non-fatal: use cached integration status if available
113
- integration = lastGoodIntegrationStatus;
165
+ integration = cache.integration;
114
166
  }
115
167
  // ── Remote branch monitors ──────────────────────────────────────
116
168
  const remotes = [];
@@ -123,61 +175,78 @@ export function computeBranchStatus(config, options) {
123
175
  const aheadOfMain = revListCount(monitor.ref, mainBranch, repoPath, true);
124
176
  // behindMain: commits in main not in remote (remote is behind)
125
177
  const behindMain = revListCount(mainBranch, monitor.ref, repoPath);
126
- if (aheadOfMain === null || behindMain === null) {
178
+ if (aheadOfMain.count === null || behindMain.count === null) {
127
179
  // Transient git failure — use cached status
128
- const cached = lastGoodRemoteStatus.get(monitor.ref);
180
+ const cached = cache.remote.get(monitor.ref);
129
181
  remotes.push(cached ?? { ref: monitor.ref, label: monitor.label, aheadOfMain: null, behindMain: null });
130
182
  }
131
183
  else {
132
184
  const entry = {
133
185
  ref: monitor.ref,
134
186
  label: monitor.label,
135
- aheadOfMain,
136
- behindMain,
187
+ aheadOfMain: aheadOfMain.count,
188
+ behindMain: behindMain.count,
137
189
  };
138
- lastGoodRemoteStatus.set(monitor.ref, entry);
190
+ cache.remote.set(monitor.ref, entry);
139
191
  remotes.push(entry);
140
192
  }
141
193
  }
142
194
  else {
143
195
  // Ref doesn't exist — use cached if available, otherwise emit grey sentinel
144
- const cached = lastGoodRemoteStatus.get(monitor.ref);
196
+ const cached = cache.remote.get(monitor.ref);
145
197
  remotes.push(cached ?? { ref: monitor.ref, label: monitor.label, aheadOfMain: null, behindMain: null });
146
198
  }
147
199
  }
148
200
  catch {
149
201
  // Non-fatal: use cached status if available, otherwise emit grey sentinel
150
- const cached = lastGoodRemoteStatus.get(monitor.ref);
202
+ const cached = cache.remote.get(monitor.ref);
151
203
  remotes.push(cached ?? { ref: monitor.ref, label: monitor.label, aheadOfMain: null, behindMain: null });
152
204
  }
153
205
  }
154
206
  // Evict remote cache entries for monitors no longer configured
155
207
  const monitorRefs = new Set(monitors.map(m => m.ref));
156
- for (const cachedRef of lastGoodRemoteStatus.keys()) {
208
+ for (const cachedRef of cache.remote.keys()) {
157
209
  if (!monitorRefs.has(cachedRef)) {
158
- lastGoodRemoteStatus.delete(cachedRef);
210
+ cache.remote.delete(cachedRef);
159
211
  }
160
212
  }
161
213
  // ── Focus worktree statuses ───────────────────────────────────
162
214
  const focuses = [];
163
215
  const worktrees = getAllFocusWorktrees();
164
216
  const teams = getActiveTeams();
217
+ const ownFocusIds = new Set();
165
218
  for (const [focusId, info] of worktrees) {
219
+ // The worktree map is cross-product; only evaluate worktrees this
220
+ // product owns, and evaluate them against the entry's OWN repo.
221
+ if (info.productId !== productId)
222
+ continue;
223
+ ownFocusIds.add(focusId);
224
+ const focusRepoPath = info.repoPath || repoPath;
166
225
  try {
167
226
  const headResult = runGitSync(['rev-parse', 'HEAD'], info.worktreePath, gitOpts);
168
227
  if (!headResult.success) {
169
228
  // Transient failure — use cached status if available
170
- const cached = lastGoodFocusStatus.get(focusId);
229
+ const cached = cache.focus.get(focusId);
171
230
  if (cached)
172
231
  focuses.push(cached);
173
232
  continue;
174
233
  }
175
234
  const headSha = headResult.output;
176
- const aheadOfIntegration = revListCount(info.branchName, integrationBranch, repoPath, true);
177
- const behindIntegration = revListCount(integrationBranch, info.branchName, repoPath);
178
- if (aheadOfIntegration === null || behindIntegration === null) {
179
- // Transient git failure on rev-list use cached status
180
- const cached = lastGoodFocusStatus.get(focusId);
235
+ const aheadOfIntegration = revListCount(info.branchName, integrationBranch, focusRepoPath, true);
236
+ const behindIntegration = revListCount(integrationBranch, info.branchName, focusRepoPath);
237
+ if (aheadOfIntegration.count === null || behindIntegration.count === null) {
238
+ const permanent = aheadOfIntegration.failure === 'permanent' ? aheadOfIntegration :
239
+ behindIntegration.failure === 'permanent' ? behindIntegration :
240
+ null;
241
+ if (permanent) {
242
+ // The branch this worktree entry claims exists cannot be resolved
243
+ // in its own repository: an attribution error, not contention.
244
+ surfacePermanentFocusFailure(focusId, info.branchName, focusRepoPath, productId, permanent.message ?? 'unknown git error');
245
+ }
246
+ // Either way, fall back to cached status (transient tolerance for
247
+ // contention; last-known-good rather than a wrong fresh value for
248
+ // permanent failures — the healthEvent above carries the error).
249
+ const cached = cache.focus.get(focusId);
181
250
  if (cached)
182
251
  focuses.push(cached);
183
252
  continue;
@@ -189,7 +258,7 @@ export function computeBranchStatus(config, options) {
189
258
  if (isConflicting) {
190
259
  health = 'conflict';
191
260
  }
192
- else if (aheadOfIntegration > 0) {
261
+ else if (aheadOfIntegration.count > 0) {
193
262
  health = 'dirty';
194
263
  }
195
264
  const entry = {
@@ -197,23 +266,25 @@ export function computeBranchStatus(config, options) {
197
266
  branch: info.branchName,
198
267
  headSha,
199
268
  health,
200
- aheadOfIntegration,
201
- behindIntegration,
269
+ aheadOfIntegration: aheadOfIntegration.count,
270
+ behindIntegration: behindIntegration.count,
202
271
  };
203
- lastGoodFocusStatus.set(focusId, entry);
272
+ cache.focus.set(focusId, entry);
204
273
  focuses.push(entry);
205
274
  }
206
275
  catch {
207
276
  // Transient failure — use cached status if available
208
- const cached = lastGoodFocusStatus.get(focusId);
277
+ const cached = cache.focus.get(focusId);
209
278
  if (cached)
210
279
  focuses.push(cached);
211
280
  }
212
281
  }
213
- // Evict cache entries for worktrees that no longer exist
214
- for (const cachedId of lastGoodFocusStatus.keys()) {
215
- if (!worktrees.has(cachedId)) {
216
- lastGoodFocusStatus.delete(cachedId);
282
+ // Evict cache entries for THIS product's worktrees that no longer exist.
283
+ // (Other products' focuses never enter this cache — it is per-product.)
284
+ for (const cachedId of cache.focus.keys()) {
285
+ if (!ownFocusIds.has(cachedId)) {
286
+ cache.focus.delete(cachedId);
287
+ permanentFailureEmitted.delete(cachedId);
217
288
  }
218
289
  }
219
290
  return { integration, remotes, focuses };
@@ -1 +1 @@
1
- {"version":3,"file":"branch-status.js","sourceRoot":"","sources":["../src/branch-status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"branch-status.js","sourceRoot":"","sources":["../src/branch-status.ts"],"names":[],"mappings":"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"}
@@ -12,10 +12,16 @@
12
12
  * and terminate
13
13
  * 2. team has NO actionable work -> terminate cleanly (daemon/review-
14
14
  * managed states move the remaining deliveries)
15
- * 3. no-progress counter crossed the limit -> escalate and terminate
16
- * 4. actionable deliveries carry open issues -> mid-focus handoff with
15
+ * 3. team is blocked on an unanswered DIRECTED escalation (needs_intent /
16
+ * needs_clarification) anchored to a delivery it is working -> hold: do
17
+ * NOT escalate, do NOT re-engage. It is waiting on a human, not stalling.
18
+ * This precedes the no-progress and handoff/re-engage branches so a
19
+ * blocked team is never counted as a stall (its own park is the signal a
20
+ * human already sees).
21
+ * 4. no-progress counter crossed the limit -> escalate and terminate
22
+ * 5. actionable deliveries carry open issues -> mid-focus handoff with
17
23
  * the new work
18
- * 5. otherwise (planning deliveries remain) -> re-engagement nudge
24
+ * 6. otherwise (planning deliveries remain) -> re-engagement nudge
19
25
  */
20
26
  /** Facts the decision is made from. All computed post-self-heal-advance. */
21
27
  export interface CompletionDecisionFacts {
@@ -45,6 +51,16 @@ export interface CompletionDecisionFacts {
45
51
  noProgressLimit: number;
46
52
  /** At least one agent-actionable delivery carries an open issue. */
47
53
  hasActionableOpenIssues: boolean;
54
+ /**
55
+ * An agent-actionable delivery the team is working carries an OPEN, unanswered
56
+ * DIRECTED escalation (disposition needs_intent / needs_clarification). The
57
+ * team is blocked on a human answer, not stalling. Computed fail-OPEN: a
58
+ * lookup error resolves to false, so a genuine stall is never masked by a
59
+ * failed check. Only consulted on the teamHasActionableWork path (a team with
60
+ * nothing to do is handled by the terminate branches above, where a block is
61
+ * moot).
62
+ */
63
+ blockedOnDirectedEscalation: boolean;
48
64
  }
49
65
  /** The action handleCompletionEvent executes for this cycle. */
50
66
  export type CompletionAction =
@@ -67,6 +83,16 @@ export type CompletionAction =
67
83
  /** Planning deliveries remain: send a re-engagement nudge to scope them. */
68
84
  | {
69
85
  kind: 'reengage';
86
+ }
87
+ /**
88
+ * Team is blocked on an unanswered directed escalation: hold in place. No
89
+ * escalation filed, no wake message sent, no termination -- the open question
90
+ * is the single signal a human needs, and re-engaging would only burn model
91
+ * spend rediscovering it. The team resumes when the escalation is answered
92
+ * (the answer read-back path re-engages it).
93
+ */
94
+ | {
95
+ kind: 'hold_blocked_on_directed_escalation';
70
96
  };
71
97
  /**
72
98
  * Whether the (async, workflow-fetching) non-advanceability lookup should run
@@ -1 +1 @@
1
- {"version":3,"file":"completion-decision.d.ts","sourceRoot":"","sources":["../../src/completion/completion-decision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,4EAA4E;AAC5E,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,qBAAqB,EAAE,OAAO,CAAC;IAC/B;;;;;OAKG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,eAAe,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAED,gEAAgE;AAChE,MAAM,MAAM,gBAAgB;AAC1B,6EAA6E;AAC3E;IAAE,IAAI,EAAE,wCAAwC,CAAA;CAAE;AACpD,0EAA0E;GACxE;IAAE,IAAI,EAAE,8BAA8B,CAAA;CAAE;AAC1C,0EAA0E;GACxE;IAAE,IAAI,EAAE,oCAAoC,CAAA;CAAE;AAChD,qEAAqE;GACnE;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE;AAC9B,4EAA4E;GAC1E;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;AAEzB;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,IAAI,CAAC,uBAAuB,EAAE,uBAAuB,GAAG,mBAAmB,CAAC,GAClF,OAAO,CAET;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,uBAAuB,GAAG,gBAAgB,CAcvF"}
1
+ {"version":3,"file":"completion-decision.d.ts","sourceRoot":"","sources":["../../src/completion/completion-decision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,4EAA4E;AAC5E,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,qBAAqB,EAAE,OAAO,CAAC;IAC/B;;;;;OAKG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,eAAe,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,uBAAuB,EAAE,OAAO,CAAC;IACjC;;;;;;;;OAQG;IACH,2BAA2B,EAAE,OAAO,CAAC;CACtC;AAED,gEAAgE;AAChE,MAAM,MAAM,gBAAgB;AAC1B,6EAA6E;AAC3E;IAAE,IAAI,EAAE,wCAAwC,CAAA;CAAE;AACpD,0EAA0E;GACxE;IAAE,IAAI,EAAE,8BAA8B,CAAA;CAAE;AAC1C,0EAA0E;GACxE;IAAE,IAAI,EAAE,oCAAoC,CAAA;CAAE;AAChD,qEAAqE;GACnE;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE;AAC9B,4EAA4E;GAC1E;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE;AACtB;;;;;;GAMG;GACD;IAAE,IAAI,EAAE,qCAAqC,CAAA;CAAE,CAAC;AAEpD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,IAAI,CAAC,uBAAuB,EAAE,uBAAuB,GAAG,mBAAmB,CAAC,GAClF,OAAO,CAET;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,uBAAuB,GAAG,gBAAgB,CAoBvF"}
@@ -12,10 +12,16 @@
12
12
  * and terminate
13
13
  * 2. team has NO actionable work -> terminate cleanly (daemon/review-
14
14
  * managed states move the remaining deliveries)
15
- * 3. no-progress counter crossed the limit -> escalate and terminate
16
- * 4. actionable deliveries carry open issues -> mid-focus handoff with
15
+ * 3. team is blocked on an unanswered DIRECTED escalation (needs_intent /
16
+ * needs_clarification) anchored to a delivery it is working -> hold: do
17
+ * NOT escalate, do NOT re-engage. It is waiting on a human, not stalling.
18
+ * This precedes the no-progress and handoff/re-engage branches so a
19
+ * blocked team is never counted as a stall (its own park is the signal a
20
+ * human already sees).
21
+ * 4. no-progress counter crossed the limit -> escalate and terminate
22
+ * 5. actionable deliveries carry open issues -> mid-focus handoff with
17
23
  * the new work
18
- * 5. otherwise (planning deliveries remain) -> re-engagement nudge
24
+ * 6. otherwise (planning deliveries remain) -> re-engagement nudge
19
25
  */
20
26
  /**
21
27
  * Whether the (async, workflow-fetching) non-advanceability lookup should run
@@ -37,6 +43,12 @@ export function decideCompletionAction(facts) {
37
43
  }
38
44
  return { kind: 'terminate_no_actionable_work' };
39
45
  }
46
+ // A team parked on its own unanswered directed escalation is blocked, not
47
+ // stalled: hold ahead of the no-progress and handoff/re-engage branches so it
48
+ // is neither escalated nor re-engaged while the question is open.
49
+ if (facts.blockedOnDirectedEscalation) {
50
+ return { kind: 'hold_blocked_on_directed_escalation' };
51
+ }
40
52
  if (facts.noProgressCycles >= facts.noProgressLimit) {
41
53
  return { kind: 'escalate_no_progress_and_terminate' };
42
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"completion-decision.js","sourceRoot":"","sources":["../../src/completion/completion-decision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AA6CH;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,KAAmF;IAEnF,OAAO,CAAC,KAAK,CAAC,qBAAqB,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAA8B;IACnE,IAAI,CAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,KAAK,CAAC,sBAAsB,EAAE,CAAC;YAC7D,OAAO,EAAE,IAAI,EAAE,wCAAwC,EAAE,CAAC;QAC5D,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,8BAA8B,EAAE,CAAC;IAClD,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QACpD,OAAO,EAAE,IAAI,EAAE,oCAAoC,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,KAAK,CAAC,uBAAuB,EAAE,CAAC;QAClC,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC;IACtC,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"completion-decision.js","sourceRoot":"","sources":["../../src/completion/completion-decision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AA+DH;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,KAAmF;IAEnF,OAAO,CAAC,KAAK,CAAC,qBAAqB,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAA8B;IACnE,IAAI,CAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,KAAK,CAAC,sBAAsB,EAAE,CAAC;YAC7D,OAAO,EAAE,IAAI,EAAE,wCAAwC,EAAE,CAAC;QAC5D,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,8BAA8B,EAAE,CAAC;IAClD,CAAC;IACD,0EAA0E;IAC1E,8EAA8E;IAC9E,kEAAkE;IAClE,IAAI,KAAK,CAAC,2BAA2B,EAAE,CAAC;QACtC,OAAO,EAAE,IAAI,EAAE,qCAAqC,EAAE,CAAC;IACzD,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QACpD,OAAO,EAAE,IAAI,EAAE,oCAAoC,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,KAAK,CAAC,uBAAuB,EAAE,CAAC;QAClC,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC;IACtC,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAC9B,CAAC"}