@telora/daemon 0.23.0 → 0.23.5

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 (317) hide show
  1. package/build-info.json +6 -3
  2. package/dist/completion/review-exit/review-census-record.d.ts.map +1 -1
  3. package/dist/completion/review-exit/review-census-record.js +1 -0
  4. package/dist/completion/review-exit/review-census-record.js.map +1 -1
  5. package/dist/completion/review-exit/review-exit-deps.d.ts +2 -1
  6. package/dist/completion/review-exit/review-exit-deps.d.ts.map +1 -1
  7. package/dist/completion/review-exit/review-exit-phase.d.ts +9 -0
  8. package/dist/completion/review-exit/review-exit-phase.d.ts.map +1 -1
  9. package/dist/completion/review-exit/review-exit-phase.js +5 -4
  10. package/dist/completion/review-exit/review-exit-phase.js.map +1 -1
  11. package/dist/completion/review-exit-holds/commit-verdict-release.d.ts.map +1 -1
  12. package/dist/completion/review-exit-holds/commit-verdict-release.js +34 -12
  13. package/dist/completion/review-exit-holds/commit-verdict-release.js.map +1 -1
  14. package/dist/completion/review-exit-holds/review-exit-verdict-gate.d.ts +35 -2
  15. package/dist/completion/review-exit-holds/review-exit-verdict-gate.d.ts.map +1 -1
  16. package/dist/completion/review-exit-holds/review-exit-verdict-gate.js +38 -6
  17. package/dist/completion/review-exit-holds/review-exit-verdict-gate.js.map +1 -1
  18. package/dist/completion/state-cascade/review-approved-head-gate.d.ts +6 -0
  19. package/dist/completion/state-cascade/review-approved-head-gate.d.ts.map +1 -1
  20. package/dist/completion/state-cascade/review-approved-head-gate.js +2 -1
  21. package/dist/completion/state-cascade/review-approved-head-gate.js.map +1 -1
  22. package/dist/completion/state-cascade/review-next-step.d.ts.map +1 -1
  23. package/dist/completion/state-cascade/review-next-step.js +15 -8
  24. package/dist/completion/state-cascade/review-next-step.js.map +1 -1
  25. package/dist/completion/state-cascade/standing-approval-convergence.d.ts.map +1 -1
  26. package/dist/completion/state-cascade/standing-approval-convergence.js +24 -12
  27. package/dist/completion/state-cascade/standing-approval-convergence.js.map +1 -1
  28. package/dist/completion/team-exit/status-advance-phase.d.ts.map +1 -1
  29. package/dist/completion/team-exit/status-advance-phase.js +6 -6
  30. package/dist/completion/team-exit/status-advance-phase.js.map +1 -1
  31. package/dist/completion/team-liveness/supervision-firing-record.d.ts +6 -0
  32. package/dist/completion/team-liveness/supervision-firing-record.d.ts.map +1 -1
  33. package/dist/completion/team-liveness/supervision-firing-record.js +10 -1
  34. package/dist/completion/team-liveness/supervision-firing-record.js.map +1 -1
  35. package/dist/completion/team-outcome/apply-advance.d.ts.map +1 -1
  36. package/dist/completion/team-outcome/apply-advance.js +3 -2
  37. package/dist/completion/team-outcome/apply-advance.js.map +1 -1
  38. package/dist/completion/team-outcome/decide-close-rows.d.ts +9 -0
  39. package/dist/completion/team-outcome/decide-close-rows.d.ts.map +1 -1
  40. package/dist/completion/team-outcome/decide-close-rows.js +18 -4
  41. package/dist/completion/team-outcome/decide-close-rows.js.map +1 -1
  42. package/dist/completion/team-outcome/delivery-advance-types.d.ts +19 -2
  43. package/dist/completion/team-outcome/delivery-advance-types.d.ts.map +1 -1
  44. package/dist/composition/completion-event-context.js +2 -2
  45. package/dist/composition/completion-event-context.js.map +1 -1
  46. package/dist/composition/daemon-contexts.d.ts.map +1 -1
  47. package/dist/composition/daemon-contexts.js +5 -1
  48. package/dist/composition/daemon-contexts.js.map +1 -1
  49. package/dist/composition/engine-start-context.d.ts +3 -0
  50. package/dist/composition/engine-start-context.d.ts.map +1 -0
  51. package/dist/composition/engine-start-context.js +24 -0
  52. package/dist/composition/engine-start-context.js.map +1 -0
  53. package/dist/composition/execution-spawn-context.d.ts.map +1 -1
  54. package/dist/composition/execution-spawn-context.js +13 -1
  55. package/dist/composition/execution-spawn-context.js.map +1 -1
  56. package/dist/composition/runtime-delivery-advance-context.js +3 -3
  57. package/dist/composition/runtime-delivery-advance-context.js.map +1 -1
  58. package/dist/composition/runtime-heartbeat-context.d.ts.map +1 -1
  59. package/dist/composition/runtime-heartbeat-context.js +3 -0
  60. package/dist/composition/runtime-heartbeat-context.js.map +1 -1
  61. package/dist/composition/runtime-poll-context.d.ts +29 -2
  62. package/dist/composition/runtime-poll-context.d.ts.map +1 -1
  63. package/dist/composition/runtime-poll-context.js +51 -4
  64. package/dist/composition/runtime-poll-context.js.map +1 -1
  65. package/dist/composition/runtime-prd-context.d.ts.map +1 -1
  66. package/dist/composition/runtime-prd-context.js +25 -1
  67. package/dist/composition/runtime-prd-context.js.map +1 -1
  68. package/dist/composition/runtime-spawn-pass-context.js +1 -1
  69. package/dist/composition/runtime-spawn-pass-context.js.map +1 -1
  70. package/dist/composition/spawn-pass-deps.d.ts +1 -1
  71. package/dist/composition/spawn-pass-deps.d.ts.map +1 -1
  72. package/dist/composition/spawn-pass-deps.js +3 -0
  73. package/dist/composition/spawn-pass-deps.js.map +1 -1
  74. package/dist/composition/standing-approval-context.d.ts.map +1 -1
  75. package/dist/composition/standing-approval-context.js +2 -1
  76. package/dist/composition/standing-approval-context.js.map +1 -1
  77. package/dist/composition/state-cascade-context.js +1 -1
  78. package/dist/composition/state-cascade-context.js.map +1 -1
  79. package/dist/composition/tower-pass-context.d.ts +9 -0
  80. package/dist/composition/tower-pass-context.d.ts.map +1 -0
  81. package/dist/composition/tower-pass-context.js +53 -0
  82. package/dist/composition/tower-pass-context.js.map +1 -0
  83. package/dist/composition/verify-rework-context.d.ts +26 -2
  84. package/dist/composition/verify-rework-context.d.ts.map +1 -1
  85. package/dist/composition/verify-rework-context.js +34 -10
  86. package/dist/composition/verify-rework-context.js.map +1 -1
  87. package/dist/config/live-daemon-config.d.ts.map +1 -1
  88. package/dist/config/live-daemon-config.js +1 -19
  89. package/dist/config/live-daemon-config.js.map +1 -1
  90. package/dist/daemon-state/awaiting-slot.d.ts.map +1 -1
  91. package/dist/daemon-state/awaiting-slot.js +2 -1
  92. package/dist/daemon-state/awaiting-slot.js.map +1 -1
  93. package/dist/daemon-state/focus-team-state.js +1 -1
  94. package/dist/daemon-state/intake-control.d.ts.map +1 -1
  95. package/dist/daemon-state/intake-control.js +2 -1
  96. package/dist/daemon-state/intake-control.js.map +1 -1
  97. package/dist/delivery/recorded-concerns.d.ts +19 -2
  98. package/dist/delivery/recorded-concerns.d.ts.map +1 -1
  99. package/dist/delivery/recorded-concerns.js +32 -6
  100. package/dist/delivery/recorded-concerns.js.map +1 -1
  101. package/dist/directive/directive-queue.js +1 -1
  102. package/dist/focus/closed-review-window.d.ts +12 -0
  103. package/dist/focus/closed-review-window.d.ts.map +1 -1
  104. package/dist/focus/closed-review-window.js +18 -0
  105. package/dist/focus/closed-review-window.js.map +1 -1
  106. package/dist/focus/control-state.d.ts +30 -26
  107. package/dist/focus/control-state.d.ts.map +1 -1
  108. package/dist/focus/control-state.js +60 -46
  109. package/dist/focus/control-state.js.map +1 -1
  110. package/dist/focus/daemon-contexts.d.ts +23 -0
  111. package/dist/focus/daemon-contexts.d.ts.map +1 -1
  112. package/dist/focus/daemon-contexts.js +1 -1
  113. package/dist/focus/daemon-contexts.js.map +1 -1
  114. package/dist/focus/engine-ready-pass.d.ts +11 -0
  115. package/dist/focus/engine-ready-pass.d.ts.map +1 -0
  116. package/dist/focus/engine-ready-pass.js +25 -0
  117. package/dist/focus/engine-ready-pass.js.map +1 -0
  118. package/dist/focus/failed-head-wedge.d.ts +95 -0
  119. package/dist/focus/failed-head-wedge.d.ts.map +1 -0
  120. package/dist/focus/failed-head-wedge.js +85 -0
  121. package/dist/focus/failed-head-wedge.js.map +1 -0
  122. package/dist/focus/focus-engine.d.ts.map +1 -1
  123. package/dist/focus/focus-engine.js +20 -20
  124. package/dist/focus/focus-engine.js.map +1 -1
  125. package/dist/focus/focus-loop-registry.d.ts.map +1 -1
  126. package/dist/focus/focus-loop-registry.js +2 -1
  127. package/dist/focus/focus-loop-registry.js.map +1 -1
  128. package/dist/focus/focus-poller-auto-advance.d.ts.map +1 -1
  129. package/dist/focus/focus-poller-auto-advance.js +4 -4
  130. package/dist/focus/focus-poller-auto-advance.js.map +1 -1
  131. package/dist/focus/focus-poller-spawn.d.ts +42 -49
  132. package/dist/focus/focus-poller-spawn.d.ts.map +1 -1
  133. package/dist/focus/focus-poller-spawn.js +129 -83
  134. package/dist/focus/focus-poller-spawn.js.map +1 -1
  135. package/dist/focus/focus-poller-state.d.ts.map +1 -1
  136. package/dist/focus/focus-poller-state.js +1 -19
  137. package/dist/focus/focus-poller-state.js.map +1 -1
  138. package/dist/focus/focus-poller.d.ts.map +1 -1
  139. package/dist/focus/focus-poller.js +2 -1
  140. package/dist/focus/focus-poller.js.map +1 -1
  141. package/dist/focus/focus-respawn-guard.d.ts +7 -0
  142. package/dist/focus/focus-respawn-guard.d.ts.map +1 -1
  143. package/dist/focus/focus-respawn-guard.js +20 -1
  144. package/dist/focus/focus-respawn-guard.js.map +1 -1
  145. package/dist/focus/focus-spawn-decision.d.ts +11 -3
  146. package/dist/focus/focus-spawn-decision.d.ts.map +1 -1
  147. package/dist/focus/focus-spawn-decision.js +3 -1
  148. package/dist/focus/focus-spawn-decision.js.map +1 -1
  149. package/dist/focus/heartbeat-metadata.d.ts +3 -0
  150. package/dist/focus/heartbeat-metadata.d.ts.map +1 -1
  151. package/dist/focus/heartbeat-metadata.js +6 -1
  152. package/dist/focus/heartbeat-metadata.js.map +1 -1
  153. package/dist/focus/heartbeat.d.ts.map +1 -1
  154. package/dist/focus/heartbeat.js +2 -0
  155. package/dist/focus/heartbeat.js.map +1 -1
  156. package/dist/focus/pending-directive-gates.d.ts +47 -0
  157. package/dist/focus/pending-directive-gates.d.ts.map +1 -0
  158. package/dist/focus/pending-directive-gates.js +76 -0
  159. package/dist/focus/pending-directive-gates.js.map +1 -0
  160. package/dist/focus/pending-review-approved-head.d.ts +2 -1
  161. package/dist/focus/pending-review-approved-head.d.ts.map +1 -1
  162. package/dist/focus/pending-review-approved-head.js +3 -4
  163. package/dist/focus/pending-review-approved-head.js.map +1 -1
  164. package/dist/focus/pending-spawn-pass-deps.d.ts +5 -0
  165. package/dist/focus/pending-spawn-pass-deps.d.ts.map +1 -1
  166. package/dist/focus/pending-spawn-pass-deps.js +4 -1
  167. package/dist/focus/pending-spawn-pass-deps.js.map +1 -1
  168. package/dist/focus/pending-spawn-verify-hold.d.ts +13 -0
  169. package/dist/focus/pending-spawn-verify-hold.d.ts.map +1 -0
  170. package/dist/focus/pending-spawn-verify-hold.js +30 -0
  171. package/dist/focus/pending-spawn-verify-hold.js.map +1 -0
  172. package/dist/focus/ready-focus-spawn-action.d.ts +15 -2
  173. package/dist/focus/ready-focus-spawn-action.d.ts.map +1 -1
  174. package/dist/focus/ready-focus-spawn-action.js +25 -8
  175. package/dist/focus/ready-focus-spawn-action.js.map +1 -1
  176. package/dist/focus/spawn-demand-probe.d.ts +45 -0
  177. package/dist/focus/spawn-demand-probe.d.ts.map +1 -0
  178. package/dist/focus/spawn-demand-probe.js +74 -0
  179. package/dist/focus/spawn-demand-probe.js.map +1 -0
  180. package/dist/focus/stranded-review-reroute.d.ts.map +1 -1
  181. package/dist/focus/stranded-review-reroute.js +5 -3
  182. package/dist/focus/stranded-review-reroute.js.map +1 -1
  183. package/dist/focus/verify-routing-passes.d.ts +8 -3
  184. package/dist/focus/verify-routing-passes.d.ts.map +1 -1
  185. package/dist/focus/verify-routing-passes.js +1 -0
  186. package/dist/focus/verify-routing-passes.js.map +1 -1
  187. package/dist/git/focus-branch-containment.d.ts +39 -0
  188. package/dist/git/focus-branch-containment.d.ts.map +1 -0
  189. package/dist/git/focus-branch-containment.js +47 -0
  190. package/dist/git/focus-branch-containment.js.map +1 -0
  191. package/dist/git/types.d.ts.map +1 -1
  192. package/dist/git/types.js +1 -0
  193. package/dist/git/types.js.map +1 -1
  194. package/dist/poll-trigger.js +1 -1
  195. package/dist/poll-trigger.js.map +1 -1
  196. package/dist/prd/arm-readiness.d.ts.map +1 -1
  197. package/dist/prd/arm-readiness.js +2 -1
  198. package/dist/prd/arm-readiness.js.map +1 -1
  199. package/dist/prd/controller-shared.d.ts +32 -8
  200. package/dist/prd/controller-shared.d.ts.map +1 -1
  201. package/dist/prd/controller-shared.js +34 -18
  202. package/dist/prd/controller-shared.js.map +1 -1
  203. package/dist/prd/controller.d.ts.map +1 -1
  204. package/dist/prd/controller.js +3 -8
  205. package/dist/prd/controller.js.map +1 -1
  206. package/dist/prd/done-sweep.d.ts.map +1 -1
  207. package/dist/prd/done-sweep.js +2 -7
  208. package/dist/prd/done-sweep.js.map +1 -1
  209. package/dist/prd/frontier-arming.d.ts +13 -1
  210. package/dist/prd/frontier-arming.d.ts.map +1 -1
  211. package/dist/prd/frontier-arming.js +50 -2
  212. package/dist/prd/frontier-arming.js.map +1 -1
  213. package/dist/prd/index.d.ts.map +1 -1
  214. package/dist/prd/index.js +2 -1
  215. package/dist/prd/index.js.map +1 -1
  216. package/dist/queries/api-client/shared.d.ts +1 -0
  217. package/dist/queries/api-client/shared.d.ts.map +1 -1
  218. package/dist/queries/api-client/shared.js +16 -1
  219. package/dist/queries/api-client/shared.js.map +1 -1
  220. package/dist/queries/deliveries/issues.d.ts.map +1 -1
  221. package/dist/queries/deliveries/issues.js +3 -0
  222. package/dist/queries/deliveries/issues.js.map +1 -1
  223. package/dist/queries/focuses/focus-discovery.d.ts +15 -0
  224. package/dist/queries/focuses/focus-discovery.d.ts.map +1 -1
  225. package/dist/queries/focuses/focus-discovery.js +10 -1
  226. package/dist/queries/focuses/focus-discovery.js.map +1 -1
  227. package/dist/queries/prd/prd.d.ts.map +1 -1
  228. package/dist/queries/prd/prd.js +2 -1
  229. package/dist/queries/prd/prd.js.map +1 -1
  230. package/dist/queries/tower/tower-state.d.ts +56 -0
  231. package/dist/queries/tower/tower-state.d.ts.map +1 -0
  232. package/dist/queries/tower/tower-state.js +76 -0
  233. package/dist/queries/tower/tower-state.js.map +1 -0
  234. package/dist/queries/wire-schemas/schemas.d.ts +12 -0
  235. package/dist/queries/wire-schemas/schemas.d.ts.map +1 -1
  236. package/dist/queries/wire-schemas/schemas.js +11 -0
  237. package/dist/queries/wire-schemas/schemas.js.map +1 -1
  238. package/dist/spawn/lead-continuation.d.ts +9 -1
  239. package/dist/spawn/lead-continuation.d.ts.map +1 -1
  240. package/dist/spawn/lead-continuation.js +37 -11
  241. package/dist/spawn/lead-continuation.js.map +1 -1
  242. package/dist/spawn/spawn-decision.d.ts.map +1 -1
  243. package/dist/spawn/spawn-decision.js +4 -1
  244. package/dist/spawn/spawn-decision.js.map +1 -1
  245. package/dist/supervision/spawn-cooldown.js +1 -1
  246. package/dist/supervision/stop-rows-team-session.d.ts.map +1 -1
  247. package/dist/supervision/stop-rows-team-session.js +11 -10
  248. package/dist/supervision/stop-rows-team-session.js.map +1 -1
  249. package/dist/supervision/team-work.d.ts.map +1 -1
  250. package/dist/supervision/team-work.js +3 -1
  251. package/dist/supervision/team-work.js.map +1 -1
  252. package/dist/testing/fixtures/api-client.js +1 -1
  253. package/dist/testing/fixtures/approved-head-inert-deps.js +1 -1
  254. package/dist/testing/fixtures/approved-head-inert-deps.js.map +1 -1
  255. package/dist/testing/fixtures/index.js +1 -1
  256. package/dist/testing/fixtures/pending-spawn-world.d.ts.map +1 -1
  257. package/dist/testing/fixtures/pending-spawn-world.js +3 -1
  258. package/dist/testing/fixtures/pending-spawn-world.js.map +1 -1
  259. package/dist/testing/fixtures/review-exit-deps.js +1 -1
  260. package/dist/testing/fixtures/review-exit-deps.js.map +1 -1
  261. package/dist/testing/fixtures/verification-feedback-deps.d.ts.map +1 -1
  262. package/dist/testing/fixtures/verification-feedback-deps.js +2 -0
  263. package/dist/testing/fixtures/verification-feedback-deps.js.map +1 -1
  264. package/dist/tower/focus-landed.d.ts +4 -0
  265. package/dist/tower/focus-landed.d.ts.map +1 -0
  266. package/dist/tower/focus-landed.js +45 -0
  267. package/dist/tower/focus-landed.js.map +1 -0
  268. package/dist/tower/tower-admission.d.ts +91 -0
  269. package/dist/tower/tower-admission.d.ts.map +1 -0
  270. package/dist/tower/tower-admission.js +137 -0
  271. package/dist/tower/tower-admission.js.map +1 -0
  272. package/dist/tower/tower-graph.d.ts +23 -0
  273. package/dist/tower/tower-graph.d.ts.map +1 -0
  274. package/dist/tower/tower-graph.js +53 -0
  275. package/dist/tower/tower-graph.js.map +1 -0
  276. package/dist/tower/tower-heartbeat-status.d.ts +28 -0
  277. package/dist/tower/tower-heartbeat-status.d.ts.map +1 -0
  278. package/dist/tower/tower-heartbeat-status.js +11 -0
  279. package/dist/tower/tower-heartbeat-status.js.map +1 -0
  280. package/dist/tower/tower-mode.d.ts +9 -0
  281. package/dist/tower/tower-mode.d.ts.map +1 -0
  282. package/dist/tower/tower-mode.js +16 -0
  283. package/dist/tower/tower-mode.js.map +1 -0
  284. package/dist/tower/tower-pass-standing.d.ts +8 -0
  285. package/dist/tower/tower-pass-standing.d.ts.map +1 -0
  286. package/dist/tower/tower-pass-standing.js +50 -0
  287. package/dist/tower/tower-pass-standing.js.map +1 -0
  288. package/dist/tower/tower-pass.d.ts +55 -0
  289. package/dist/tower/tower-pass.d.ts.map +1 -0
  290. package/dist/tower/tower-pass.js +59 -0
  291. package/dist/tower/tower-pass.js.map +1 -0
  292. package/dist/tower/tower-production-pass.d.ts +3 -0
  293. package/dist/tower/tower-production-pass.d.ts.map +1 -0
  294. package/dist/tower/tower-production-pass.js +24 -0
  295. package/dist/tower/tower-production-pass.js.map +1 -0
  296. package/dist/tower/tower-spawn-intent.d.ts +72 -0
  297. package/dist/tower/tower-spawn-intent.d.ts.map +1 -0
  298. package/dist/tower/tower-spawn-intent.js +138 -0
  299. package/dist/tower/tower-spawn-intent.js.map +1 -0
  300. package/dist/tower/tower-verdicts.d.ts +81 -0
  301. package/dist/tower/tower-verdicts.d.ts.map +1 -0
  302. package/dist/tower/tower-verdicts.js +139 -0
  303. package/dist/tower/tower-verdicts.js.map +1 -0
  304. package/dist/types/index.js +1 -1
  305. package/dist/types/issue-status.d.ts +14 -0
  306. package/dist/types/issue-status.d.ts.map +1 -1
  307. package/dist/types/issue-status.js +14 -0
  308. package/dist/types/issue-status.js.map +1 -1
  309. package/dist/verify/gate-verdicts/commit-verdict-record.js +1 -1
  310. package/dist/verify/outcome-routing/verification-rework-issue.d.ts +44 -5
  311. package/dist/verify/outcome-routing/verification-rework-issue.d.ts.map +1 -1
  312. package/dist/verify/outcome-routing/verification-rework-issue.js +85 -27
  313. package/dist/verify/outcome-routing/verification-rework-issue.js.map +1 -1
  314. package/dist/worktree/focus-worktree-state.d.ts.map +1 -1
  315. package/dist/worktree/focus-worktree-state.js +1 -0
  316. package/dist/worktree/focus-worktree-state.js.map +1 -1
  317. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"review-exit-deps.js","sourceRoot":"","sources":["../../../src/testing/fixtures/review-exit-deps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"review-exit-deps.js","sourceRoot":"","sources":["../../../src/testing/fixtures/review-exit-deps.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"verification-feedback-deps.d.ts","sourceRoot":"","sources":["../../../src/testing/fixtures/verification-feedback-deps.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,uDAAuD,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2DAA2D,CAAC;AAEjG,iDAAiD;AACjD,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAE7D,2DAA2D;AAC3D,wBAAgB,6BAA6B,CAAC,SAAS,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAAG,wBAAwB,CAQzH;AAED,mGAAmG;AACnG,wBAAgB,yBAAyB,CAAC,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAAG,oBAAoB,CAS7G;AAED,oFAAoF;AACpF,wBAAgB,oBAAoB,CAAC,SAAS,GAAE,OAAO,CAAC,eAAe,CAAM,GAAG,eAAe,CAM9F;AAED,0GAA0G;AAC1G,wBAAgB,oCAAoC,CAClD,SAAS,GAAE,OAAO,CAAC,+BAA+B,CAAM,GACvD,+BAA+B,CAOjC;AAED,uFAAuF;AACvF,wBAAgB,oCAAoC,CAClD,SAAS,GAAE,OAAO,CAAC,oBAAoB,GAAG,eAAe,CAAM,GAC9D,oBAAoB,GAAG,eAAe,CAExC;AAED,8FAA8F;AAC9F,wBAAgB,6BAA6B,CAAC,SAAS,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAAG,wBAAwB,CAMzH;AAED,2GAA2G;AAC3G,wBAAgB,uBAAuB,CAAC,SAAS,GAAE,OAAO,CAAC,kBAAkB,CAAM,GAAG,kBAAkB,CAOvG"}
1
+ {"version":3,"file":"verification-feedback-deps.d.ts","sourceRoot":"","sources":["../../../src/testing/fixtures/verification-feedback-deps.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,uDAAuD,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2DAA2D,CAAC;AAGjG,iDAAiD;AACjD,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAE7D,2DAA2D;AAC3D,wBAAgB,6BAA6B,CAAC,SAAS,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAAG,wBAAwB,CAQzH;AAED,mGAAmG;AACnG,wBAAgB,yBAAyB,CAAC,SAAS,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAAG,oBAAoB,CAS7G;AAED,oFAAoF;AACpF,wBAAgB,oBAAoB,CAAC,SAAS,GAAE,OAAO,CAAC,eAAe,CAAM,GAAG,eAAe,CAO9F;AAED,0GAA0G;AAC1G,wBAAgB,oCAAoC,CAClD,SAAS,GAAE,OAAO,CAAC,+BAA+B,CAAM,GACvD,+BAA+B,CAOjC;AAED,uFAAuF;AACvF,wBAAgB,oCAAoC,CAClD,SAAS,GAAE,OAAO,CAAC,oBAAoB,GAAG,eAAe,CAAM,GAC9D,oBAAoB,GAAG,eAAe,CAExC;AAED,8FAA8F;AAC9F,wBAAgB,6BAA6B,CAAC,SAAS,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAAG,wBAAwB,CAMzH;AAED,2GAA2G;AAC3G,wBAAgB,uBAAuB,CAAC,SAAS,GAAE,OAAO,CAAC,kBAAkB,CAAM,GAAG,kBAAkB,CAOvG"}
@@ -39,6 +39,7 @@
39
39
  */
40
40
  import { resolveReconciledWrite } from '../../delivery/delivery-reconciler-apply.js';
41
41
  import { readVerificationLogText } from '../../verify/outcome-routing/failure-signature.js';
42
+ import { NO_RECORDED_CONCERNS } from '../../delivery/recorded-concerns.js';
42
43
  /** The fixed instant the inert clock answers. */
43
44
  export const INERT_FEEDBACK_NOW = '2026-01-01T00:00:00.000Z';
44
45
  /** Inert gate_state write, no live team, a fixed clock. */
@@ -67,6 +68,7 @@ export function inertReworkIssueDeps(overrides = {}) {
67
68
  return {
68
69
  getDeliveryIssues: async () => [],
69
70
  createIssue: async () => 'inert-rework-issue',
71
+ readRecordedConcernIds: async () => NO_RECORDED_CONCERNS,
70
72
  ...overrides,
71
73
  };
72
74
  }
@@ -1 +1 @@
1
- {"version":3,"file":"verification-feedback-deps.js","sourceRoot":"","sources":["../../../src/testing/fixtures/verification-feedback-deps.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,6EAA6E;AAC7E,2EAA2E;AAC3E,2EAA2E;AAC3E,gFAAgF;AAChF,4FAA4F;AAC5F,sEAAsE;AACtE,6EAA6E;AAC7E,gFAAgF;AAChF,yEAAyE;AACzE,6DAA6D;AAC7D,uEAAuE;AACvE,2EAA2E;AAC3E,8EAA8E;AAC9E,oFAAoF;AACpF,8EAA8E;AAC9E,0EAA0E;AAC1E,6EAA6E;AAC7E,oEAAoE;AACpE,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAU5F,iDAAiD;AACjD,MAAM,CAAC,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAE7D,2DAA2D;AAC3D,MAAM,UAAU,6BAA6B,CAAC,YAA+C,EAAE;IAC7F,OAAO;QACL,cAAc,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC9B,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE;QAC/B,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI;QACvB,GAAG,EAAE,GAAG,EAAE,CAAC,kBAAkB;QAC7B,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,yBAAyB,CAAC,YAA2C,EAAE;IACrF,OAAO;QACL,GAAG,6BAA6B,EAAE;QAClC,kBAAkB,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAClC,sBAAsB;QACtB,kBAAkB,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;QACpC,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI;QAC3B,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,oBAAoB,CAAC,YAAsC,EAAE;IAC3E,OAAO;QACL,iBAAiB,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QACjC,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,oBAAoB;QAC7C,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,0GAA0G;AAC1G,MAAM,UAAU,oCAAoC,CAClD,YAAsD,EAAE;IAExD,OAAO;QACL,GAAG,yBAAyB,EAAE;QAC9B,WAAW,EAAE,uBAAuB;QACpC,GAAG,oBAAoB,EAAE;QACzB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,oCAAoC,CAClD,YAA6D,EAAE;IAE/D,OAAO,EAAE,GAAG,yBAAyB,EAAE,EAAE,GAAG,oBAAoB,EAAE,EAAE,GAAG,SAAS,EAAE,CAAC;AACrF,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,6BAA6B,CAAC,YAA+C,EAAE;IAC7F,OAAO;QACL,GAAG,6BAA6B,EAAE;QAClC,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QACrF,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,uBAAuB,CAAC,YAAyC,EAAE;IACjF,OAAO;QACL,GAAG,yBAAyB,EAAE;QAC9B,GAAG,6BAA6B,EAAE;QAClC,gBAAgB,EAAE,GAAG,EAAE,CAAC,IAAI;QAC5B,GAAG,SAAS;KACb,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"verification-feedback-deps.js","sourceRoot":"","sources":["../../../src/testing/fixtures/verification-feedback-deps.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,6EAA6E;AAC7E,2EAA2E;AAC3E,2EAA2E;AAC3E,gFAAgF;AAChF,4FAA4F;AAC5F,sEAAsE;AACtE,6EAA6E;AAC7E,gFAAgF;AAChF,yEAAyE;AACzE,6DAA6D;AAC7D,uEAAuE;AACvE,2EAA2E;AAC3E,8EAA8E;AAC9E,oFAAoF;AACpF,8EAA8E;AAC9E,0EAA0E;AAC1E,6EAA6E;AAC7E,oEAAoE;AACpE,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAS5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,iDAAiD;AACjD,MAAM,CAAC,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAE7D,2DAA2D;AAC3D,MAAM,UAAU,6BAA6B,CAAC,YAA+C,EAAE;IAC7F,OAAO;QACL,cAAc,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC9B,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE;QAC/B,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI;QACvB,GAAG,EAAE,GAAG,EAAE,CAAC,kBAAkB;QAC7B,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,yBAAyB,CAAC,YAA2C,EAAE;IACrF,OAAO;QACL,GAAG,6BAA6B,EAAE;QAClC,kBAAkB,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAClC,sBAAsB;QACtB,kBAAkB,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;QACpC,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI;QAC3B,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,oBAAoB,CAAC,YAAsC,EAAE;IAC3E,OAAO;QACL,iBAAiB,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;QACjC,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,oBAAoB;QAC7C,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,oBAAoB;QACxD,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,0GAA0G;AAC1G,MAAM,UAAU,oCAAoC,CAClD,YAAsD,EAAE;IAExD,OAAO;QACL,GAAG,yBAAyB,EAAE;QAC9B,WAAW,EAAE,uBAAuB;QACpC,GAAG,oBAAoB,EAAE;QACzB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,oCAAoC,CAClD,YAA6D,EAAE;IAE/D,OAAO,EAAE,GAAG,yBAAyB,EAAE,EAAE,GAAG,oBAAoB,EAAE,EAAE,GAAG,SAAS,EAAE,CAAC;AACrF,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,6BAA6B,CAAC,YAA+C,EAAE;IAC7F,OAAO;QACL,GAAG,6BAA6B,EAAE;QAClC,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QACrF,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,uBAAuB,CAAC,YAAyC,EAAE;IACjF,OAAO;QACL,GAAG,yBAAyB,EAAE;QAC9B,GAAG,6BAA6B,EAAE;QAClC,gBAAgB,EAAE,GAAG,EAAE,CAAC,IAAI;QAC5B,GAAG,SAAS;KACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { FocusBranchContainment } from '../git/focus-branch-containment.js';
2
+ export type FocusLanded = 'landed' | 'not_landed' | 'unknown';
3
+ export declare function judgeFocusLanded(deliveryStatuses: readonly string[], branch: FocusBranchContainment): FocusLanded;
4
+ //# sourceMappingURL=focus-landed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-landed.d.ts","sourceRoot":"","sources":["../../src/tower/focus-landed.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAEjF,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,SAAS,CAAC;AAE9D,wBAAgB,gBAAgB,CAC9B,gBAAgB,EAAE,SAAS,MAAM,EAAE,EACnC,MAAM,EAAE,sBAAsB,GAC7B,WAAW,CAcb"}
@@ -0,0 +1,45 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/tower/focus-landed.test.ts
3
+ // PINNED-BY-END
4
+ /**
5
+ * LANDED: the ONE definition of "this focus's work has landed", judged by the
6
+ * daemon with no human close. Shared by the tower (a depends_on successor waits
7
+ * until its predecessor has landed) and the PRD frontier's completion signal
8
+ * (prd/controller-shared.ts computeCompletedFocusIds), so the two can never
9
+ * disagree about whether a focus is finished.
10
+ *
11
+ * A focus has LANDED when
12
+ * 1. it has at least one delivery, and
13
+ * 2. every non-cancelled delivery is done, at least one of them (a focus whose
14
+ * every delivery was cancelled landed nothing), and
15
+ * 3. its branch tip is contained in the integration branch -- or the branch is
16
+ * gone AND the focus's merge record names a merge commit integration
17
+ * contains (the daemon removes a branch only after merging it, and records
18
+ * the merge; git/focus-branch-containment.ts). A gone branch with no such
19
+ * record is unproven: unknown.
20
+ *
21
+ * NOT_LANDED when any of those is definitely false. UNKNOWN when 1-2 hold but
22
+ * git could not answer 3: never read as landed and never as not landed -- the
23
+ * tower leaves the dependent focus's verdict unavailable (fail open), and the
24
+ * PRD frontier does not clear the obstacle this tick.
25
+ */
26
+ import { DELIVERY_STATUS } from '@telora/daemon-core';
27
+ export function judgeFocusLanded(deliveryStatuses, branch) {
28
+ if (deliveryStatuses.length === 0)
29
+ return 'not_landed';
30
+ const live = deliveryStatuses.filter((s) => s !== DELIVERY_STATUS.CANCELLED);
31
+ if (live.length === 0)
32
+ return 'not_landed';
33
+ if (!live.every((s) => s === DELIVERY_STATUS.DONE))
34
+ return 'not_landed';
35
+ switch (branch) {
36
+ case 'contained':
37
+ case 'merged_removed':
38
+ return 'landed';
39
+ case 'not_contained':
40
+ return 'not_landed';
41
+ case 'unknown':
42
+ return 'unknown';
43
+ }
44
+ }
45
+ //# sourceMappingURL=focus-landed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-landed.js","sourceRoot":"","sources":["../../src/tower/focus-landed.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,4DAA4D;AAC5D,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAKtD,MAAM,UAAU,gBAAgB,CAC9B,gBAAmC,EACnC,MAA8B;IAE9B,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,YAAY,CAAC;IACvD,MAAM,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,eAAe,CAAC,SAAS,CAAC,CAAC;IAC7E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,YAAY,CAAC;IAC3C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,eAAe,CAAC,IAAI,CAAC;QAAE,OAAO,YAAY,CAAC;IACxE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW,CAAC;QACjB,KAAK,gBAAgB;YACnB,OAAO,QAAQ,CAAC;QAClB,KAAK,eAAe;YAClB,OAAO,YAAY,CAAC;QACtB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Spawn admission through the tower: what the spawn passes ask before they
3
+ * start a coding or review team for an armed focus.
4
+ *
5
+ * THE RULE (docs/runbook-tower.md):
6
+ * off -- the tower is not consulted; spawning is exactly as before it.
7
+ * observe -- the verdict is read and never obeyed; a spawn decision enforce
8
+ * would have made differently is LOGGED (focus, verdict, the
9
+ * decision taken), so an operator judges the verdicts on real
10
+ * foci before enforcing.
11
+ * enforce -- a holding verdict that is FRESH holds the spawn.
12
+ *
13
+ * FAIL OPEN. Only an available, holding verdict ever holds, and only while
14
+ * this daemon's tower pass for the focus's product is standing
15
+ * (tower-pass-standing.ts): a pass that failed, or has not yet succeeded,
16
+ * leaves every verdict of that product unobeyed at once. A verdict that is
17
+ * missing, malformed, older than the bounded age or written under an earlier
18
+ * arm is no verdict (daemon-core readTowerVerdict). Either way the focus
19
+ * spawns as it would with the tower off, and the daemon says so. Admission fails open while
20
+ * the merge gates fail closed because the failures are not symmetric: a wrongly
21
+ * blocked merge is visible (a held delivery, a red gate), a wrongly held spawn
22
+ * is SILENT (a focus that simply never runs).
23
+ *
24
+ * The decision is pure (decideTowerAdmission); noteTowerAdmission logs it and
25
+ * records the focus's spawn intent once the spawn gate's final action is known.
26
+ */
27
+ import { type TowerMode, type TowerVerdictReading } from '@telora/daemon-core';
28
+ import { type SpawnIntentSource } from './tower-spawn-intent.js';
29
+ import type { TowerPassStanding } from './tower-pass-standing.js';
30
+ /** The focus row fields admission reads (ready and active focus rows both carry them). */
31
+ export interface TowerAdmissionFocus {
32
+ focus_id: string;
33
+ focus_name: string;
34
+ product_id?: string | null;
35
+ agent_assigned_at?: string | null;
36
+ tower_verdict?: unknown;
37
+ }
38
+ export interface TowerAdmission {
39
+ mode: TowerMode;
40
+ /** The spawn is held (enforce + an available holding verdict). */
41
+ holds: boolean;
42
+ /** What enforce would do with this verdict: hold. */
43
+ enforceWouldHold: boolean;
44
+ /** The verdict as read; null in off mode (the tower is not consulted). */
45
+ reading: TowerVerdictReading | null;
46
+ /** The product's pass is not standing: every verdict is unobeyed (fail open). Null when it stands. */
47
+ passNotStanding: Exclude<TowerPassStanding, 'ok'> | null;
48
+ }
49
+ /** What admission reads of the tower each pass (the spawn passes' deps; composition/spawn-pass-deps.ts). */
50
+ export interface TowerAdmissionDeps {
51
+ /** TELORA_TOWER_MODE. */
52
+ mode: () => TowerMode;
53
+ /** This daemon's pass standing for a product (tower-pass-standing.ts). */
54
+ passStanding: (productId: string | null | undefined) => TowerPassStanding;
55
+ }
56
+ export declare function decideTowerAdmission(focus: TowerAdmissionFocus, tower: TowerAdmissionDeps, nowMs: number): TowerAdmission;
57
+ /** The outcome the spawn gate reached for a focus, after the tower was consulted. */
58
+ export type TowerGateOutcome = 'spawn' | 'tower_hold' | 'capacity' | 'not_wanting';
59
+ /** The line a decision produces, or null when it is not worth a line. Exported for tests. */
60
+ export declare function towerAdmissionMessage(focus: TowerAdmissionFocus, admission: TowerAdmission, outcome: TowerGateOutcome): string | null;
61
+ /**
62
+ * Log the admission (once per distinct line) and record the focus's spawn
63
+ * intent for the tower's next pass. Never throws: admission bookkeeping must
64
+ * not cost a spawn.
65
+ */
66
+ export declare function noteTowerAdmission(focus: TowerAdmissionFocus, admission: TowerAdmission, outcome: TowerGateOutcome, nowMs?: number, source?: SpawnIntentSource): void;
67
+ /**
68
+ * The order the spawn pass offers ready foci to the host governor: in enforce,
69
+ * focus rank order (lowest priority_rank first, stable); otherwise the order the
70
+ * API returned them, exactly as before the tower.
71
+ */
72
+ export declare function orderForTower<T extends {
73
+ priority_rank?: number | null;
74
+ }>(foci: readonly T[], mode: TowerMode): T[];
75
+ /**
76
+ * A spawn pass's offer: opens the pass's demand record over every focus it
77
+ * offers (tower-spawn-intent.ts beginSpawnIntentPass -- a focus some earlier
78
+ * gate stops is committed as not wanting) and returns them in orderForTower's
79
+ * order. The pass's runner commits it (focus/focus-poller-spawn.ts).
80
+ */
81
+ export declare function offerForTower<T extends {
82
+ priority_rank?: number | null;
83
+ }>(source: SpawnIntentSource, foci: readonly T[], idOf: (f: T) => string, mode: TowerMode): T[];
84
+ /**
85
+ * The pending-spawn pass's tower check (a queued directive -- e.g. a review --
86
+ * on an armed focus): consulted after the cooldown and before the host cap,
87
+ * exactly where the ready pass consults it. True = held; the directive stays
88
+ * queued.
89
+ */
90
+ export declare function pendingSpawnHeldByTower(focus: TowerAdmissionFocus, atHostCapacity: boolean, tower: TowerAdmissionDeps, nowMs: number): boolean;
91
+ //# sourceMappingURL=tower-admission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tower-admission.d.ts","sourceRoot":"","sources":["../../src/tower/tower-admission.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,mBAAmB,EACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAA2C,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC1G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAIlE,0FAA0F;AAC1F,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,kEAAkE;IAClE,KAAK,EAAE,OAAO,CAAC;IACf,qDAAqD;IACrD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,0EAA0E;IAC1E,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACpC,sGAAsG;IACtG,eAAe,EAAE,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC;CAC1D;AAED,4GAA4G;AAC5G,MAAM,WAAW,kBAAkB;IACjC,yBAAyB;IACzB,IAAI,EAAE,MAAM,SAAS,CAAC;IACtB,0EAA0E;IAC1E,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,KAAK,iBAAiB,CAAC;CAC3E;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAQzH;AAED,qFAAqF;AACrF,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,YAAY,GAAG,UAAU,GAAG,aAAa,CAAC;AAYnF,6FAA6F;AAC7F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAsBrI;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,gBAAgB,EACzB,KAAK,GAAE,MAAmB,EAC1B,MAAM,GAAE,iBAA2B,GAClC,IAAI,CAWN;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,CAAC,EAAE,CAInH;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EACvE,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EACtB,IAAI,EAAE,SAAS,GACd,CAAC,EAAE,CAGL;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,mBAAmB,EAC1B,cAAc,EAAE,OAAO,EACvB,KAAK,EAAE,kBAAkB,EACzB,KAAK,EAAE,MAAM,GACZ,OAAO,CAIT"}
@@ -0,0 +1,137 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/tower/tower-pass.test.ts
3
+ // PINNED-BY-END
4
+ /**
5
+ * Spawn admission through the tower: what the spawn passes ask before they
6
+ * start a coding or review team for an armed focus.
7
+ *
8
+ * THE RULE (docs/runbook-tower.md):
9
+ * off -- the tower is not consulted; spawning is exactly as before it.
10
+ * observe -- the verdict is read and never obeyed; a spawn decision enforce
11
+ * would have made differently is LOGGED (focus, verdict, the
12
+ * decision taken), so an operator judges the verdicts on real
13
+ * foci before enforcing.
14
+ * enforce -- a holding verdict that is FRESH holds the spawn.
15
+ *
16
+ * FAIL OPEN. Only an available, holding verdict ever holds, and only while
17
+ * this daemon's tower pass for the focus's product is standing
18
+ * (tower-pass-standing.ts): a pass that failed, or has not yet succeeded,
19
+ * leaves every verdict of that product unobeyed at once. A verdict that is
20
+ * missing, malformed, older than the bounded age or written under an earlier
21
+ * arm is no verdict (daemon-core readTowerVerdict). Either way the focus
22
+ * spawns as it would with the tower off, and the daemon says so. Admission fails open while
23
+ * the merge gates fail closed because the failures are not symmetric: a wrongly
24
+ * blocked merge is visible (a held delivery, a red gate), a wrongly held spawn
25
+ * is SILENT (a focus that simply never runs).
26
+ *
27
+ * The decision is pure (decideTowerAdmission); noteTowerAdmission logs it and
28
+ * records the focus's spawn intent once the spawn gate's final action is known.
29
+ */
30
+ import { describeTowerHold, describeTowerUnavailable, readTowerVerdict, towerReadingHolds, } from '@telora/daemon-core';
31
+ import { createLogger } from '../log/daemon-log.js';
32
+ import { beginSpawnIntentPass, recordSpawnIntent } from './tower-spawn-intent.js';
33
+ const log = createLogger({ module: 'tower' });
34
+ export function decideTowerAdmission(focus, tower, nowMs) {
35
+ const mode = tower.mode();
36
+ if (mode === 'off')
37
+ return { mode, holds: false, enforceWouldHold: false, reading: null, passNotStanding: null };
38
+ const reading = readTowerVerdict(focus.tower_verdict ?? null, { armedAt: focus.agent_assigned_at ?? null }, nowMs);
39
+ const standing = tower.passStanding(focus.product_id);
40
+ if (standing !== 'ok')
41
+ return { mode, holds: false, enforceWouldHold: false, reading, passNotStanding: standing };
42
+ const enforceWouldHold = towerReadingHolds(reading);
43
+ return { mode, holds: mode === 'enforce' && enforceWouldHold, enforceWouldHold, reading, passNotStanding: null };
44
+ }
45
+ /** One log line per focus per distinct message (a held focus is not re-logged every poll). */
46
+ const lastLogged = new Map();
47
+ function logOnce(focusId, message, level) {
48
+ if (lastLogged.get(focusId) === message)
49
+ return;
50
+ lastLogged.set(focusId, message);
51
+ if (level === 'warn')
52
+ log.warn(message);
53
+ else
54
+ log.info(message);
55
+ }
56
+ /** The line a decision produces, or null when it is not worth a line. Exported for tests. */
57
+ export function towerAdmissionMessage(focus, admission, outcome) {
58
+ const { reading } = admission;
59
+ if (!reading || outcome === 'not_wanting')
60
+ return null;
61
+ const name = `"${focus.focus_name}" (${focus.focus_id.slice(0, 8)})`;
62
+ if (admission.passNotStanding) {
63
+ if (admission.mode !== 'enforce')
64
+ return null;
65
+ const why = admission.passNotStanding === 'failed' ? 'its product\'s tower pass failed' : 'its product\'s tower pass has not succeeded yet';
66
+ return `[tower] ${name}: ${why} -- failing open, spawning as with the tower off`;
67
+ }
68
+ if (reading.status === 'unavailable') {
69
+ if (admission.mode !== 'enforce')
70
+ return null;
71
+ return `[tower] ${name}: ${describeTowerUnavailable(reading.why)} -- failing open, spawning as with the tower off`;
72
+ }
73
+ const v = reading.verdict;
74
+ if (v.state !== 'holding')
75
+ return null;
76
+ const why = `${describeTowerHold(v)} since ${v.since}`;
77
+ if (outcome === 'tower_hold')
78
+ return `[tower] holding ${name}: ${why}`;
79
+ if (admission.mode === 'observe') {
80
+ const taken = outcome === 'spawn' ? 'spawned' : 'left waiting for a host slot';
81
+ return `[tower] observe: enforce would hold ${name} (${why}); decision taken: ${taken}`;
82
+ }
83
+ return null;
84
+ }
85
+ /**
86
+ * Log the admission (once per distinct line) and record the focus's spawn
87
+ * intent for the tower's next pass. Never throws: admission bookkeeping must
88
+ * not cost a spawn.
89
+ */
90
+ export function noteTowerAdmission(focus, admission, outcome, nowMs = Date.now(), source = 'ready') {
91
+ try {
92
+ // Open demand only: a spawned focus's demand is met (its team holds the slot).
93
+ recordSpawnIntent(focus.focus_id, outcome === 'tower_hold' || outcome === 'capacity', nowMs, source);
94
+ const message = towerAdmissionMessage(focus, admission, outcome);
95
+ const failingOpen = admission.passNotStanding !== null || admission.reading?.status === 'unavailable';
96
+ if (message)
97
+ logOnce(focus.focus_id, message, failingOpen ? 'warn' : 'info');
98
+ else
99
+ lastLogged.delete(focus.focus_id);
100
+ }
101
+ catch {
102
+ // Bookkeeping only.
103
+ }
104
+ }
105
+ /**
106
+ * The order the spawn pass offers ready foci to the host governor: in enforce,
107
+ * focus rank order (lowest priority_rank first, stable); otherwise the order the
108
+ * API returned them, exactly as before the tower.
109
+ */
110
+ export function orderForTower(foci, mode) {
111
+ if (mode !== 'enforce')
112
+ return [...foci];
113
+ const rank = (f) => f.priority_rank ?? Number.MAX_SAFE_INTEGER;
114
+ return [...foci].map((f, i) => ({ f, i })).sort((a, b) => rank(a.f) - rank(b.f) || a.i - b.i).map((x) => x.f);
115
+ }
116
+ /**
117
+ * A spawn pass's offer: opens the pass's demand record over every focus it
118
+ * offers (tower-spawn-intent.ts beginSpawnIntentPass -- a focus some earlier
119
+ * gate stops is committed as not wanting) and returns them in orderForTower's
120
+ * order. The pass's runner commits it (focus/focus-poller-spawn.ts).
121
+ */
122
+ export function offerForTower(source, foci, idOf, mode) {
123
+ beginSpawnIntentPass(source, foci.map(idOf));
124
+ return orderForTower(foci, mode);
125
+ }
126
+ /**
127
+ * The pending-spawn pass's tower check (a queued directive -- e.g. a review --
128
+ * on an armed focus): consulted after the cooldown and before the host cap,
129
+ * exactly where the ready pass consults it. True = held; the directive stays
130
+ * queued.
131
+ */
132
+ export function pendingSpawnHeldByTower(focus, atHostCapacity, tower, nowMs) {
133
+ const admission = decideTowerAdmission(focus, tower, nowMs);
134
+ noteTowerAdmission(focus, admission, admission.holds ? 'tower_hold' : atHostCapacity ? 'capacity' : 'spawn', nowMs, 'pending');
135
+ return admission.holds;
136
+ }
137
+ //# sourceMappingURL=tower-admission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tower-admission.js","sourceRoot":"","sources":["../../src/tower/tower-admission.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The tower graph, judged for one product's pass: which armed foci wait on an
3
+ * unlanded depends_on predecessor, which are joined by an excludes edge to
4
+ * which other foci, and which cannot be judged at all.
5
+ *
6
+ * depends_on (from -> to): `to` waits until `from` has LANDED
7
+ * (tower/focus-landed.ts, the definition the PRD frontier shares). A
8
+ * predecessor that has definitely not landed holds the successor with
9
+ * `waits_on`; one whose landed state git could not answer -- with none
10
+ * definitely unlanded -- leaves the successor UNAVAILABLE (no verdict, fail
11
+ * open), never holding.
12
+ * excludes (a <-> b): each side lists the other with the edge's evidence;
13
+ * tower-verdicts.ts holds whichever is reached second while the first runs or
14
+ * is cleared.
15
+ *
16
+ * Git is read only for a predecessor whose deliveries say it could have landed.
17
+ */
18
+ import type { FocusBranchContainment } from '../git/focus-branch-containment.js';
19
+ import type { TowerProductState } from '../queries/tower/tower-state.js';
20
+ import type { TowerComputeInput } from './tower-verdicts.js';
21
+ export type TowerGraphInputs = Pick<TowerComputeInput, 'waitsOn' | 'excludes' | 'unavailableFocusIds'>;
22
+ export declare function judgeTowerGraph(state: Pick<TowerProductState, 'foci' | 'edges' | 'graphFoci'>, containmentOf: (focus: TowerProductState['graphFoci'][number]) => FocusBranchContainment): TowerGraphInputs;
23
+ //# sourceMappingURL=tower-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tower-graph.d.ts","sourceRoot":"","sources":["../../src/tower/tower-graph.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,OAAO,KAAK,EAA4C,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEvG,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,UAAU,GAAG,qBAAqB,CAAC,CAAC;AAEvG,wBAAgB,eAAe,CAC7B,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC,EAC9D,aAAa,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,sBAAsB,GACvF,gBAAgB,CA0ClB"}
@@ -0,0 +1,53 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/tower/focus-landed.test.ts, packages/daemon/src/tower/tower-pass.test.ts,
3
+ // packages/daemon/src/tower/tower-state-ingestion.test.ts
4
+ // PINNED-BY-END
5
+ import { judgeFocusLanded } from './focus-landed.js';
6
+ export function judgeTowerGraph(state, containmentOf) {
7
+ const info = new Map(state.graphFoci.map((f) => [f.focusId, f]));
8
+ const landedCache = new Map();
9
+ const landed = (focusId) => {
10
+ const cached = landedCache.get(focusId);
11
+ if (cached)
12
+ return cached;
13
+ const f = info.get(focusId);
14
+ let result;
15
+ if (!f)
16
+ result = 'unknown';
17
+ else if (judgeFocusLanded(f.deliveryStatuses, 'contained') !== 'landed')
18
+ result = 'not_landed';
19
+ else
20
+ result = judgeFocusLanded(f.deliveryStatuses, containmentOf(f));
21
+ landedCache.set(focusId, result);
22
+ return result;
23
+ };
24
+ const nameOf = (focusId) => info.get(focusId)?.focusName ?? focusId.slice(0, 8);
25
+ const waitsOn = new Map();
26
+ const excludes = new Map();
27
+ const unavailableFocusIds = new Set();
28
+ const armed = new Set(state.foci.map((f) => f.focusId));
29
+ for (const focusId of armed) {
30
+ const predecessors = state.edges
31
+ .filter((e) => e.kind === 'depends_on' && e.toFocusId === focusId)
32
+ .map((e) => e.fromFocusId)
33
+ .sort((a, b) => nameOf(a).localeCompare(nameOf(b)));
34
+ const unlanded = predecessors.find((p) => landed(p) === 'not_landed');
35
+ if (unlanded)
36
+ waitsOn.set(focusId, { focusId: unlanded, focusName: nameOf(unlanded) });
37
+ else if (predecessors.some((p) => landed(p) === 'unknown'))
38
+ unavailableFocusIds.add(focusId);
39
+ }
40
+ for (const e of state.edges) {
41
+ if (e.kind !== 'excludes')
42
+ continue;
43
+ const add = (self, other) => {
44
+ const list = excludes.get(self) ?? [];
45
+ list.push({ otherFocusId: other, otherFocusName: nameOf(other), evidence: e.evidence });
46
+ excludes.set(self, list);
47
+ };
48
+ add(e.fromFocusId, e.toFocusId);
49
+ add(e.toFocusId, e.fromFocusId);
50
+ }
51
+ return { waitsOn, excludes, unavailableFocusIds };
52
+ }
53
+ //# sourceMappingURL=tower-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tower-graph.js","sourceRoot":"","sources":["../../src/tower/tower-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The tower's status per product, published on the daemon heartbeat as
3
+ * `metadata.tower` ({ [productId]: { mode, pass } }; product-scoped,
4
+ * docs/heartbeat-metadata-audit.md) -- what the dashboard needs to say whether
5
+ * the product's tower is running at all:
6
+ *
7
+ * mode -- TELORA_TOWER_MODE on this daemon. `off`: there is no tower; the
8
+ * dashboard shows no tower line.
9
+ * pass -- this daemon's pass standing for the product (tower-pass-standing.ts).
10
+ * Anything but `ok` means admission fails open on every focus of the
11
+ * product, whatever verdicts they carry -- the dashboard says so even
12
+ * when NO focus carries a verdict (the all-missing case after a start
13
+ * or a failed pass).
14
+ *
15
+ * Pure over its reads; bound at the composition root
16
+ * (composition/runtime-heartbeat-context.ts).
17
+ */
18
+ import type { TowerAdmissionDeps } from './tower-admission.js';
19
+ import type { TowerPassStanding } from './tower-pass-standing.js';
20
+ import type { TowerMode } from '@telora/daemon-core';
21
+ export interface TowerHeartbeatStatus {
22
+ mode: TowerMode;
23
+ pass: TowerPassStanding;
24
+ }
25
+ export declare function buildTowerStatusByProduct(products: ReadonlyArray<{
26
+ id: string;
27
+ }>, tower: TowerAdmissionDeps): Record<string, TowerHeartbeatStatus>;
28
+ //# sourceMappingURL=tower-heartbeat-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tower-heartbeat-status.d.ts","sourceRoot":"","sources":["../../src/tower/tower-heartbeat-status.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,EACvC,KAAK,EAAE,kBAAkB,GACxB,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAKtC"}
@@ -0,0 +1,11 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/tower/tower-heartbeat-status.test.ts
3
+ // PINNED-BY-END
4
+ export function buildTowerStatusByProduct(products, tower) {
5
+ const mode = tower.mode();
6
+ const out = {};
7
+ for (const p of products)
8
+ out[p.id] = { mode, pass: tower.passStanding(p.id) };
9
+ return out;
10
+ }
11
+ //# sourceMappingURL=tower-heartbeat-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tower-heartbeat-status.js","sourceRoot":"","sources":["../../src/tower/tower-heartbeat-status.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,sEAAsE;AACtE,gBAAgB;AA6BhB,MAAM,UAAU,yBAAyB,CACvC,QAAuC,EACvC,KAAyB;IAEzB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC1B,MAAM,GAAG,GAAyC,EAAE,CAAC;IACrD,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC/E,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The tower's rollout mode, TELORA_TOWER_MODE (declared, typed and validated in
3
+ * @telora/daemon-core env-config.ts): off | observe | enforce, default observe.
4
+ * See docs/runbook-tower.md for what each mode does and how a host moves from
5
+ * observe to enforce.
6
+ */
7
+ import { type TowerMode } from '@telora/daemon-core';
8
+ export declare function resolveTowerMode(env?: NodeJS.ProcessEnv): TowerMode;
9
+ //# sourceMappingURL=tower-mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tower-mode.d.ts","sourceRoot":"","sources":["../../src/tower/tower-mode.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEjF,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,SAAS,CAIhF"}
@@ -0,0 +1,16 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/tower/tower-production-pass.test.ts
3
+ // PINNED-BY-END
4
+ /**
5
+ * The tower's rollout mode, TELORA_TOWER_MODE (declared, typed and validated in
6
+ * @telora/daemon-core env-config.ts): off | observe | enforce, default observe.
7
+ * See docs/runbook-tower.md for what each mode does and how a host moves from
8
+ * observe to enforce.
9
+ */
10
+ import { isTowerMode, loadEnvConfig } from '@telora/daemon-core';
11
+ export function resolveTowerMode(env = process.env) {
12
+ // env-config validates the value; the guard narrows its inferred string type.
13
+ const mode = loadEnvConfig(env).TELORA_TOWER_MODE;
14
+ return isTowerMode(mode) ? mode : 'observe';
15
+ }
16
+ //# sourceMappingURL=tower-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tower-mode.js","sourceRoot":"","sources":["../../src/tower/tower-mode.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,qEAAqE;AACrE,gBAAgB;AAEhB;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAkB,MAAM,qBAAqB,CAAC;AAEjF,MAAM,UAAU,gBAAgB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACnE,8EAA8E;IAC9E,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC;IAClD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,8 @@
1
+ export type TowerPassStanding = 'ok' | 'failed' | 'not_run';
2
+ /** Record one product pass's outcome (tower-pass.ts runTowerPass). */
3
+ export declare function recordTowerPassOutcome(productId: string, ok: boolean, nowMs?: number): void;
4
+ /** The product's pass standing now. A focus with no product cannot be judged: not_run. */
5
+ export declare function towerPassStanding(productId: string | null | undefined, nowMs?: number): TowerPassStanding;
6
+ /** Test-only reset. */
7
+ export declare function resetTowerPassStanding(): void;
8
+ //# sourceMappingURL=tower-pass-standing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tower-pass-standing.d.ts","sourceRoot":"","sources":["../../src/tower/tower-pass-standing.ts"],"names":[],"mappings":"AAgCA,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,QAAQ,GAAG,SAAS,CAAC;AAI5D,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,GAAE,MAAmB,GAAG,IAAI,CAEvG;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,GAAE,MAAmB,GAAG,iBAAiB,CAMrH;AAED,uBAAuB;AACvB,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -0,0 +1,50 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/tower/tower-entrypoints.test.ts,
3
+ // packages/daemon/src/tower/tower-heartbeat-status.test.ts, packages/daemon/src/tower/tower-pass.test.ts,
4
+ // packages/daemon/src/tower/tower-prd-arm.test.ts,
5
+ // packages/daemon/src/tower/tower-ready-row-ingestion.test.ts,
6
+ // packages/daemon/src/tower/tower-spawn-modes.test.ts
7
+ // PINNED-BY-END
8
+ /**
9
+ * Whether this daemon's tower pass for a product is STANDING -- the condition
10
+ * under which admission may obey a stored verdict at all.
11
+ *
12
+ * A stored verdict was written by some pass; it is only as good as the pass
13
+ * that keeps confirming it. When this process's most recent pass for the
14
+ * product failed -- or no pass for it has succeeded yet -- a still-fresh
15
+ * holding verdict in the database is a leftover, not a decision: admission
16
+ * fails open on it IMMEDIATELY (tower-admission.ts), rather than enforcing it
17
+ * until it ages out of the freshness bound. Another product's standing is
18
+ * untouched.
19
+ *
20
+ * ok -- the most recent pass for the product succeeded, within the
21
+ * freshness bound (TOWER_VERDICT_MAX_AGE_MS).
22
+ * failed -- the most recent pass for the product threw.
23
+ * not_run -- no pass for the product has succeeded within the bound (daemon
24
+ * start before the first pass, or a pass that stopped running).
25
+ *
26
+ * A leaf: in-process state, written by tower-pass.ts and read by admission
27
+ * through the spawn passes' deps (composition/spawn-pass-deps.ts).
28
+ */
29
+ import { TOWER_VERDICT_MAX_AGE_MS } from '@telora/daemon-core';
30
+ const lastOutcome = new Map();
31
+ /** Record one product pass's outcome (tower-pass.ts runTowerPass). */
32
+ export function recordTowerPassOutcome(productId, ok, nowMs = Date.now()) {
33
+ lastOutcome.set(productId, { ok, atMs: nowMs });
34
+ }
35
+ /** The product's pass standing now. A focus with no product cannot be judged: not_run. */
36
+ export function towerPassStanding(productId, nowMs = Date.now()) {
37
+ if (!productId)
38
+ return 'not_run';
39
+ const last = lastOutcome.get(productId);
40
+ if (!last)
41
+ return 'not_run';
42
+ if (!last.ok)
43
+ return 'failed';
44
+ return nowMs - last.atMs > TOWER_VERDICT_MAX_AGE_MS ? 'not_run' : 'ok';
45
+ }
46
+ /** Test-only reset. */
47
+ export function resetTowerPassStanding() {
48
+ lastOutcome.clear();
49
+ }
50
+ //# sourceMappingURL=tower-pass-standing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tower-pass-standing.js","sourceRoot":"","sources":["../../src/tower/tower-pass-standing.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,kEAAkE;AAClE,4GAA4G;AAC5G,qDAAqD;AACrD,iEAAiE;AACjE,wDAAwD;AACxD,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAI/D,MAAM,WAAW,GAAG,IAAI,GAAG,EAAyC,CAAC;AAErE,sEAAsE;AACtE,MAAM,UAAU,sBAAsB,CAAC,SAAiB,EAAE,EAAW,EAAE,QAAgB,IAAI,CAAC,GAAG,EAAE;IAC/F,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,iBAAiB,CAAC,SAAoC,EAAE,QAAgB,IAAI,CAAC,GAAG,EAAE;IAChG,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,QAAQ,CAAC;IAC9B,OAAO,KAAK,GAAG,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACzE,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,sBAAsB;IACpC,WAAW,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC"}