elanous 0.2.9 → 0.2.11

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 (694) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/Y4zKzL62sakG5momz3SoQ/_buildManifest.js +1 -0
  4. package/apps/pwa/out/_next/static/chunks/1159-0c5ef8bc21cb6afb.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/1394-556de6d71bbdb0fb.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1452.93700483b9d4fc61.js +9 -0
  7. package/apps/pwa/out/_next/static/chunks/{6062-73e68343a9814f6a.js → 1829-b453a1b22d3999bb.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/2176-c379e3ebce874151.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/2310-7a59f043f6db207e.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/2426.8c6ee0c668d53def.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/2548-6e316138d347cefe.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/3170-7ec60a56fa0e4728.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/3278-ae6ef084769f6195.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/3454-988a53dac60a1763.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/3638-aa80b4641ea439db.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/3735-fe3402553ac1c9c6.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/3869-a39d1d9921e10d43.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/390.c373e31b3b9d0c41.js +5 -0
  19. package/apps/pwa/out/_next/static/chunks/3992-2e522a8ac5f2afde.js +25 -0
  20. package/apps/pwa/out/_next/static/chunks/4215-c9d91dd644ec1719.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/4508-5d0161d1e724d735.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/4685-c3c1c625b71accd1.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/4733-623a79345b171e1c.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/4883.3bd969ea1d3aaaff.js +2 -0
  25. package/apps/pwa/out/_next/static/chunks/507-5acd98bd6dab2d8a.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/5445-745eb795c5963d79.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/5532.6899a12958a89b72.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/5845-e6c003ce8d5fd36a.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/5978-b27004c677119115.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/{8046cadf-211ca3c0e00f2b72.js → 5cd7e3a9-404fd6b8d0ecd44c.js} +1 -1
  31. package/apps/pwa/out/_next/static/chunks/6048-4c5c33579bc4ef78.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/6303-422dbf0f67c72aac.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/6751-bb3595948b2e311b.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/7274-19b7279f18b47ab3.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/{4323.c5dfb6f503304775.js → 7334.a6679d9168f37aa8.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/7551-a0e0707b79164ddd.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/7777-79f845045aa1ed86.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/79f8be9e-957d68913b590b08.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/8025-cc24ee5d8f2fb6f8.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/8039-df92e08fede5de8f.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/8206-c6684dcde12be721.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/8421-1c4acfb1395a0edf.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/8605-ea5bee9dfae512c7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/8725.bf46bb1395dd0fa2.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/8734-252d511cd276c0dc.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/8834-ca1cb09c1cb1a6bf.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{2415.ed6428ff334c7ce2.js → 9269.d2a4795bc6812717.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/9538-2816b90923606459.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/9656-c1540088f5859c80.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/9906-482c6619b3fdda20.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d16993889b125c42.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/app/approvals/page-1dcdc58fc2de2454.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-6a061bd97f0b9398.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/app/board/page-cb95a7432c9ee744.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-f972fc1c00a62e88.js → page-b12b6d2f8d2d1aea.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/app/bots/page-b9efe868bfd36255.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/app/chat/page-7c97dcdfe2e37a60.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/app/consult/page-8fd36984f549270a.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/app/control/page-5721537ca8a3598c.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/app/design-check/page-b654240a572e4c48.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/app/editor/page-b9750abc897508c3.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/app/exec/page-4cd1de371f8ad048.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/app/field/page-d99f89657828421c.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d16993889b125c42.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/app/inside/page-50cb2a0eb15e6c83.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/app/intake/page-c8b1ccda6ba7ae98.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/app/layout-d6b1d156fb95e74b.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/app/live/page-2a9932ddb62d76bd.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/app/market/page-9688f5b4f1ff950f.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-6b15dd6456c5df09.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/app/morning/{page-adfbd2ba9598e59a.js → page-35414e0a007b4082.js} +1 -1
  72. package/apps/pwa/out/_next/static/chunks/app/not-found-e7a529e0507ac86c.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/app/observatory/page-e001823c35c9dd67.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-371423d1a573d64b.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4b764b125339ac17.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cdf8e4b01067bcf1.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3a24072b35470157.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/app/page-94c82eb0ae5abb32.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/app/reflection/page-0be8d4b2ced75ba0.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d37cb0d52f9b6bd5.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/app/sessions/page-686da0df9bf23e5c.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-4dc614f3ce043e63.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/app/settings/page-53f80edc6b8dc07c.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-d02c782fc792e2af.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d16993889b125c42.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/app/setup/page-239c17b911b84e72.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/app/share/page-dc6a79fb003f746c.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/app/showroom/page-0fffb84cafdc9da6.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/app/tasks/page-1218753c82d585f6.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/app/term/page-4b5935e67531efb5.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/app/today/page-3285bc87caf1eaa5.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/app/trace/page-ad553b0e06505ecd.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/app/vault/page-fca096e3e860306f.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ebfa78f0d9885c3.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/app/workflows/page-3dc5f21f7e39622d.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/app/workspace/page-c6da2b468454532d.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-93bc70e36f595414.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{2ea96958-e8c7e112de50b067.js → f48170cc-d05d28bf87a43bf4.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/framework-172630e6aa5e2d7f.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/main-app-f0fe2d7477845181.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/main-fc98ac70b44eccb0.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/pages/_app-5bd7f10271f72413.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/pages/_error-97d0d85ea05fef9b.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/webpack-9e4d02d567b98240.js +1 -0
  105. package/apps/pwa/out/_next/static/css/543f56bcb1f79fca.css +1 -0
  106. package/apps/pwa/out/approvals/index.html +1 -1
  107. package/apps/pwa/out/approvals/index.txt +23 -23
  108. package/apps/pwa/out/autopilot/index.html +1 -1
  109. package/apps/pwa/out/autopilot/index.txt +23 -23
  110. package/apps/pwa/out/board/index.html +1 -1
  111. package/apps/pwa/out/board/index.txt +23 -23
  112. package/apps/pwa/out/botlab/index.html +1 -1
  113. package/apps/pwa/out/botlab/index.txt +22 -22
  114. package/apps/pwa/out/bots/index.html +1 -1
  115. package/apps/pwa/out/bots/index.txt +22 -22
  116. package/apps/pwa/out/chat/index.html +1 -1
  117. package/apps/pwa/out/chat/index.txt +22 -22
  118. package/apps/pwa/out/consult/index.html +1 -1
  119. package/apps/pwa/out/consult/index.txt +23 -23
  120. package/apps/pwa/out/control/index.html +1 -1
  121. package/apps/pwa/out/control/index.txt +23 -23
  122. package/apps/pwa/out/design-check/index.html +1 -1
  123. package/apps/pwa/out/design-check/index.txt +23 -23
  124. package/apps/pwa/out/editor/index.html +1 -1
  125. package/apps/pwa/out/editor/index.txt +23 -23
  126. package/apps/pwa/out/exec/index.html +1 -1
  127. package/apps/pwa/out/exec/index.txt +23 -23
  128. package/apps/pwa/out/field/index.html +1 -1
  129. package/apps/pwa/out/field/index.txt +23 -23
  130. package/apps/pwa/out/healthz +1 -1
  131. package/apps/pwa/out/index.html +1 -1
  132. package/apps/pwa/out/index.txt +22 -22
  133. package/apps/pwa/out/inside/index.html +1 -0
  134. package/apps/pwa/out/inside/index.txt +31 -0
  135. package/apps/pwa/out/intake/index.html +1 -1
  136. package/apps/pwa/out/intake/index.txt +23 -23
  137. package/apps/pwa/out/live/index.html +1 -1
  138. package/apps/pwa/out/live/index.txt +23 -23
  139. package/apps/pwa/out/market/index.html +1 -1
  140. package/apps/pwa/out/market/index.txt +22 -22
  141. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  142. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  143. package/apps/pwa/out/morning/index.html +1 -1
  144. package/apps/pwa/out/morning/index.txt +23 -23
  145. package/apps/pwa/out/observatory/index.html +1 -1
  146. package/apps/pwa/out/observatory/index.txt +23 -23
  147. package/apps/pwa/out/ops/checklist/index.html +1 -1
  148. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  149. package/apps/pwa/out/ops/release/index.html +1 -1
  150. package/apps/pwa/out/ops/release/index.txt +22 -22
  151. package/apps/pwa/out/ops/seats/index.html +1 -0
  152. package/apps/pwa/out/ops/seats/index.txt +30 -0
  153. package/apps/pwa/out/outputs/index.html +1 -0
  154. package/apps/pwa/out/outputs/index.txt +30 -0
  155. package/apps/pwa/out/reflection/index.html +1 -1
  156. package/apps/pwa/out/reflection/index.txt +23 -23
  157. package/apps/pwa/out/scheduler/index.html +1 -1
  158. package/apps/pwa/out/scheduler/index.txt +23 -23
  159. package/apps/pwa/out/sessions/index.html +1 -1
  160. package/apps/pwa/out/sessions/index.txt +22 -22
  161. package/apps/pwa/out/settings/devices/index.html +1 -1
  162. package/apps/pwa/out/settings/devices/index.txt +23 -23
  163. package/apps/pwa/out/settings/index.html +1 -1
  164. package/apps/pwa/out/settings/index.txt +23 -23
  165. package/apps/pwa/out/setup/done/index.html +1 -1
  166. package/apps/pwa/out/setup/done/index.txt +23 -23
  167. package/apps/pwa/out/setup/index.html +1 -1
  168. package/apps/pwa/out/setup/index.txt +23 -23
  169. package/apps/pwa/out/share/index.html +1 -1
  170. package/apps/pwa/out/share/index.txt +23 -23
  171. package/apps/pwa/out/showroom/index.html +1 -1
  172. package/apps/pwa/out/showroom/index.txt +22 -22
  173. package/apps/pwa/out/tasks/index.html +1 -1
  174. package/apps/pwa/out/tasks/index.txt +23 -23
  175. package/apps/pwa/out/term/index.html +1 -1
  176. package/apps/pwa/out/term/index.txt +23 -24
  177. package/apps/pwa/out/today/index.html +1 -0
  178. package/apps/pwa/out/today/index.txt +33 -0
  179. package/apps/pwa/out/trace/index.html +1 -1
  180. package/apps/pwa/out/trace/index.txt +23 -23
  181. package/apps/pwa/out/vault/index.html +1 -1
  182. package/apps/pwa/out/vault/index.txt +23 -23
  183. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  184. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  185. package/apps/pwa/out/workflows/index.html +1 -1
  186. package/apps/pwa/out/workflows/index.txt +23 -23
  187. package/apps/pwa/out/workspace/index.html +1 -1
  188. package/apps/pwa/out/workspace/index.txt +23 -24
  189. package/apps/pwa/out/worktrees/index.html +1 -1
  190. package/apps/pwa/out/worktrees/index.txt +23 -23
  191. package/graphs/drafts/draft-cleanup.yaml +19 -0
  192. package/graphs/drafts/recipes.yaml +23 -0
  193. package/graphs/field/field-feed.yaml +2 -0
  194. package/graphs/implement-loop.yaml +1 -1
  195. package/graphs/intake/intake-daily.yaml +2 -1
  196. package/graphs/ops/recipes.yaml +3 -0
  197. package/graphs/ops/secret-exposure.yaml +24 -0
  198. package/graphs/release/recipes.yaml +3 -0
  199. package/graphs/release/release-loop.yaml +4 -1
  200. package/graphs/video/explainer-line.yaml +2 -2
  201. package/package.json +2 -1
  202. package/plugins/card-followup/graphs/run-step.ts +48 -13
  203. package/plugins/doc-draft/graphs/doc-draft.yaml +3 -3
  204. package/plugins/doc-draft/graphs/run-step.ts +13 -6
  205. package/plugins/elanous-hwp/README.md +25 -0
  206. package/plugins/elanous-hwp/cli.ts +22 -0
  207. package/plugins/elanous-hwp/converter.ts +237 -0
  208. package/plugins/elanous-hwp/fixtures/fixed-controls.hwpx +0 -0
  209. package/plugins/elanous-hwp/fixtures/fixed-table-controls.hwpx +0 -0
  210. package/plugins/elanous-hwp/fixtures/fixed.hwpx +0 -0
  211. package/plugins/elanous-hwp/plugin.json +16 -0
  212. package/plugins/elanous-hwp/plugin.ts +40 -0
  213. package/scripts/ci-public-export-leak-gate.ts +75 -14
  214. package/scripts/ci-public-leak-gate.ts +44 -9
  215. package/scripts/ci-pwa-build-gate.ts +160 -0
  216. package/scripts/context-hooks/claude-stop.sh +4 -0
  217. package/scripts/context-hooks/emit.ts +24 -0
  218. package/scripts/context-hooks/post-tool-use.sh +4 -0
  219. package/scripts/coord-channel-watch.sh +54 -8
  220. package/scripts/coord-digest.ts +199 -0
  221. package/scripts/coord-post.sh +60 -3
  222. package/scripts/coord-requests-bridge.ts +143 -0
  223. package/scripts/field-feed/lib.ts +4 -0
  224. package/scripts/fleet/node-setup.sh +20 -3
  225. package/scripts/homebrew-formula-bump.ts +69 -0
  226. package/scripts/install.ps1 +68 -9
  227. package/scripts/install.sh +39 -12
  228. package/scripts/lib/pwa-scenarios/scenarios.ts +20 -0
  229. package/scripts/lib/tui-regress-checks.ts +146 -0
  230. package/scripts/marketing/measure-site-numbers.ts +169 -0
  231. package/scripts/measure-gate-shards.ts +309 -0
  232. package/scripts/memory-lifecycle-cycle.ts +2 -2
  233. package/scripts/mission-request-judge.ts +31 -1
  234. package/scripts/morning-report.ts +2 -2
  235. package/scripts/opportunity-scan.ts +1 -1
  236. package/scripts/ops-now-probe.ts +327 -0
  237. package/scripts/publish-internal-dist.ts +11 -1
  238. package/scripts/release-loop/auto-approve-node.ts +21 -4
  239. package/scripts/release-loop/cut-branch.ts +84 -0
  240. package/scripts/release-loop/cutoff.ts +19 -8
  241. package/scripts/release-loop/gate-node.ts +14 -13
  242. package/scripts/release-loop/mac-smoke-node.ts +229 -0
  243. package/scripts/release-loop/node-verdict.ts +3 -3
  244. package/scripts/release-loop/ops-upgrade-node.ts +72 -16
  245. package/scripts/release-loop/release-readiness.ts +9 -0
  246. package/scripts/release-loop/tui-node-checks.ts +42 -0
  247. package/scripts/release-loop/tui-sim-node.ts +32 -8
  248. package/scripts/release-loop/unattended-release.ts +5 -3
  249. package/scripts/release-loop/version-node.ts +112 -13
  250. package/scripts/repo-watch-cycle.ts +1 -1
  251. package/scripts/retro-cycle.ts +2 -2
  252. package/scripts/schedule-health-report.ts +1 -1
  253. package/scripts/signal-digest-cycle.ts +2 -7
  254. package/scripts/signal-digest-photo.ts +11 -0
  255. package/scripts/storyboard/storyboard.ts +5 -161
  256. package/scripts/tech1-public-measure.ts +94 -0
  257. package/scripts/test-diet/lib.ts +30 -1
  258. package/scripts/test-diet/node.ts +83 -8
  259. package/scripts/test-timeout-audit.ts +114 -0
  260. package/scripts/tree-sync-alert.ts +1 -1
  261. package/scripts/tui-regress.ts +71 -0
  262. package/scripts/ux/demo-rehearsal.ts +243 -0
  263. package/scripts/ux/lib/rehearsal-verdict.ts +73 -0
  264. package/scripts/waitlist-daily-digest.ts +1 -1
  265. package/skills/diagram-master/SKILL.md +366 -0
  266. package/skills/diagram-master/references/engines/excalidraw/color-palette.md +67 -0
  267. package/skills/diagram-master/references/engines/excalidraw/element-templates.md +182 -0
  268. package/skills/diagram-master/references/engines/excalidraw/json-schema.md +71 -0
  269. package/skills/diagram-master/references/engines/excalidraw/render_excalidraw.py +189 -0
  270. package/skills/diagram-master/references/engines/excalidraw/render_template.html +57 -0
  271. package/skills/diagram-master/references/engines/matplotlib/matplotlib-patterns.md +235 -0
  272. package/skills/diagram-master/references/engines/matplotlib/render_matplotlib.py +184 -0
  273. package/skills/diagram-master/references/engines/mermaid/domain-templates.md +435 -0
  274. package/skills/diagram-master/references/engines/mermaid/render_mermaid.py +116 -0
  275. package/skills/diagram-master/references/engines/mermaid/syntax-reference.md +2247 -0
  276. package/skills/diagram-master/references/engines/nanobannana/render_nanobannana2.py +168 -0
  277. package/skills/diagram-master/references/engines/svg/color-palette.md +188 -0
  278. package/skills/diagram-master/references/engines/svg/html-base-template.html +332 -0
  279. package/skills/diagram-master/references/engines/svg/interactivity-patterns.md +435 -0
  280. package/skills/diagram-master/references/engines/svg/render_interactive_svg.py +212 -0
  281. package/skills/diagram-master/references/engines/svg/svg-element-templates.md +349 -0
  282. package/skills/diagram-master/references/examples/README.md +69 -0
  283. package/skills/diagram-master/references/examples/ref_grid_architecture.png +0 -0
  284. package/skills/diagram-master/references/examples/ref_layered_flow.png +0 -0
  285. package/skills/diagram-master/references/pyproject.toml +16 -0
  286. package/skills/diagram-master/references/quality-checklist.md +33 -0
  287. package/skills/diagram-master/references/routing-guide.md +164 -0
  288. package/skills/diagram-master/references/uv.lock +1356 -0
  289. package/skills/explainer-video/SKILL.md +4 -0
  290. package/skills/explainer-video/engine/reel.mjs +18 -13
  291. package/skills/explainer-video/engine/reel.sh +24 -5
  292. package/skills/explainer-video/engine/stitch.mjs +145 -0
  293. package/skills/google-workspace/SKILL.md +33 -0
  294. package/skills/google-workspace/scripts/gws-safe.sh +177 -0
  295. package/skills/grill-me/SKILL.md +1 -1
  296. package/skills/lecture-note-digitizer/SKILL.md +926 -0
  297. package/skills/lecture-note-digitizer/references/convert_to_pdf.py +30 -0
  298. package/skills/lecture-note-digitizer/references/extract_slide_diagram.py +73 -0
  299. package/skills/lecture-note-digitizer/references/html-template.md +167 -0
  300. package/skills/lecture-note-digitizer/references/katex-style-guide.md +165 -0
  301. package/skills/omni-crawl/SKILL.md +21 -11
  302. package/skills/omni-crawl/scripts/main.ts +6 -6
  303. package/skills/omni-crawl/src/router.ts +3 -3
  304. package/skills/omni-digest/SKILL.md +17 -9
  305. package/skills/omni-digest/digest.md +2 -2
  306. package/skills/omni-digest/src/fetch.ts +30 -3
  307. package/skills/pitch-deck/SKILL.md +36 -0
  308. package/skills/pitch-deck/template.html +80 -0
  309. package/skills/youtube-master/SKILL.md +163 -0
  310. package/skills/youtube-master/package-lock.json +558 -0
  311. package/skills/youtube-master/package.json +13 -0
  312. package/skills/youtube-master/references/study-note-template.md +124 -0
  313. package/skills/youtube-master/scripts/main.ts +435 -0
  314. package/skills/youtube-master/scripts/transcribe-local.ts +24 -0
  315. package/skills/youtube-master/src/audio.ts +63 -0
  316. package/skills/youtube-master/src/domain-staging.ts +50 -0
  317. package/skills/youtube-master/src/env.ts +36 -0
  318. package/skills/youtube-master/src/obsidian.ts +155 -0
  319. package/skills/youtube-master/src/router.ts +110 -0
  320. package/skills/youtube-master/src/stt.ts +199 -0
  321. package/skills/youtube-master/src/study-note.ts +175 -0
  322. package/skills/youtube-master/src/summarize.ts +358 -0
  323. package/skills/youtube-master/src/transcript.ts +76 -0
  324. package/skills/youtube-master/src/types.ts +91 -0
  325. package/skills/youtube-master/src/util.ts +93 -0
  326. package/skills/youtube-master/src/youtube.ts +70 -0
  327. package/skills/youtube-master/tsconfig.json +13 -0
  328. package/src/acp/codex-approval-adapter.ts +9 -3
  329. package/src/acp/core-turn-bridge.ts +117 -18
  330. package/src/acp/fact-question.ts +11 -0
  331. package/src/acp/server.ts +53 -9
  332. package/src/acp/tool-approval.ts +126 -0
  333. package/src/acp/turn-runner.ts +36 -0
  334. package/src/agent/monad-agent-turn.ts +8 -0
  335. package/src/agent-mission/driver.ts +80 -10
  336. package/src/agent-mission/pty-decision.ts +71 -0
  337. package/src/agent-mission/review-loop.ts +30 -0
  338. package/src/ask-user-question/pending-questions.ts +25 -10
  339. package/src/ask-user-question/types.ts +9 -0
  340. package/src/auth/setup-link-tokens.ts +16 -5
  341. package/src/autopilot/build/integrity-gate.ts +12 -0
  342. package/src/autopilot/build/llm-conflict-merge.ts +16 -3
  343. package/src/autopilot/tool-registry.ts +2 -0
  344. package/src/boot/daemon-prompt-turn.ts +8 -0
  345. package/src/boot/daemon-runtime.ts +9 -3
  346. package/src/boot/daemon-tools/index.ts +8 -0
  347. package/src/boot/daemon-tools/types.ts +2 -0
  348. package/src/boot/daemon-tools/web-search.ts +4 -0
  349. package/src/card-followup/core.ts +109 -0
  350. package/src/chat/ctrl-c-in-input.ts +14 -0
  351. package/src/chat/index.ts +53 -0
  352. package/src/chat/pickers/state.ts +6 -2
  353. package/src/cli/agent-cli.ts +7 -0
  354. package/src/cli/decisions-cli.ts +25 -3
  355. package/src/cli/doctor-bundle-upload.ts +68 -0
  356. package/src/cli/doctor-cli.ts +38 -4
  357. package/src/cli/drive-input-jail.ts +101 -0
  358. package/src/cli/hooks-cli.ts +17 -3
  359. package/src/cli/make-cli.ts +43 -0
  360. package/src/cli/ops-cli.ts +20 -0
  361. package/src/cli/persona-cli.ts +90 -4
  362. package/src/cli/plugin-cli.ts +31 -22
  363. package/src/cli/pod-cli.ts +61 -2
  364. package/src/cli/pr-cli.ts +82 -17
  365. package/src/cli/pty-drive-cli.ts +41 -7
  366. package/src/cli/pty-drive-verdict.ts +40 -0
  367. package/src/cli/pwa-stop.ts +163 -13
  368. package/src/cli/pwa-test.ts +3 -0
  369. package/src/cli/release-cli.ts +80 -24
  370. package/src/cli/self-update.ts +14 -0
  371. package/src/cli/setup-cli.ts +43 -1
  372. package/src/cli/skills-cli.ts +17 -1
  373. package/src/cli/storyboard-cli.ts +37 -0
  374. package/src/cli/test-state-dir-flag.ts +11 -4
  375. package/src/connectors/linear.ts +146 -0
  376. package/src/context-bus/claude-hooks-install.ts +10 -0
  377. package/src/context-bus/context-now-surfaces.ts +48 -0
  378. package/src/context-bus/context-now.ts +104 -0
  379. package/src/context-bus/coord-events.ts +115 -0
  380. package/src/context-bus/external-events.ts +52 -0
  381. package/src/context-bus/long-term-memory.ts +108 -0
  382. package/src/dashboard/dashboard-boot-fixture.ts +23 -0
  383. package/src/dashboard/index.ts +63 -21
  384. package/src/dashboard/slash-runtime/dashboard-handlers.ts +14 -1
  385. package/src/dashboard/slash-runtime/help-from-registry.ts +43 -28
  386. package/src/decisions/decision-cards.ts +58 -3
  387. package/src/decisions/decision-ledger.ts +85 -6
  388. package/src/decisions/decision-linear-projection.ts +157 -0
  389. package/src/decisions/web-push-decision-cards.ts +50 -0
  390. package/src/directive/interpretation-card.ts +36 -0
  391. package/src/discord/sprint21-runtime.ts +5 -1
  392. package/src/discord-self-message.ts +32 -0
  393. package/src/discord-slash-wire.ts +5 -1
  394. package/src/discord.ts +19 -2
  395. package/src/domains/coo-admin-tool.ts +62 -0
  396. package/src/domains/core-tools.ts +13 -4
  397. package/src/domains/elanous-card.ts +29 -0
  398. package/src/domains/ops-facts-tool.ts +76 -0
  399. package/src/domains/outbound-alert.ts +46 -13
  400. package/src/domains/release-tool.ts +168 -0
  401. package/src/domains/telegram-kind-route.ts +65 -9
  402. package/src/exec-requests/default-outputs.ts +25 -0
  403. package/src/exec-requests/planner.ts +106 -28
  404. package/src/exec-requests/runner.ts +123 -12
  405. package/src/exec-requests/store.ts +11 -2
  406. package/src/execution-loop/launch-gate.ts +100 -0
  407. package/src/field/field-media.ts +10 -7
  408. package/src/field/field-reel.ts +19 -5
  409. package/src/field-note/index.ts +201 -0
  410. package/src/field-note/transcribe.ts +248 -0
  411. package/src/git-fs/worktree.ts +45 -6
  412. package/src/graph-kinds/registry.ts +3 -3
  413. package/src/graph-runner/graph-approval-card.ts +113 -0
  414. package/src/graph-runner/graph-cli.ts +189 -4
  415. package/src/graph-runner/graph-grow-llm.ts +37 -0
  416. package/src/graph-runner/graph-grow.ts +47 -0
  417. package/src/graph-runner/graph-notify.ts +25 -3
  418. package/src/graph-runner/runner.ts +453 -35
  419. package/src/grok/agent-search.ts +8 -2
  420. package/src/guardian/secret-exposure-scan.ts +101 -0
  421. package/src/harness/browser-verify.ts +25 -2
  422. package/src/harness/harness-cli-command.ts +478 -42
  423. package/src/harness/harness-incidents-writer.fixture.ts +24 -0
  424. package/src/harness/harness-incidents.ts +129 -0
  425. package/src/harness/harness-pod-dispatch.ts +43 -23
  426. package/src/harness/harness-seams.ts +38 -4
  427. package/src/harness/harness-stop.ts +75 -6
  428. package/src/harness/launch-registry.ts +91 -0
  429. package/src/harness/process-garbage.ts +5 -3
  430. package/src/hitl/clarification-policy.ts +3 -1
  431. package/src/hooks/dispatch.ts +82 -0
  432. package/src/hooks/expose.ts +254 -0
  433. package/src/hooks/github-shadow.ts +108 -0
  434. package/src/hooks/providers.ts +71 -5
  435. package/src/hooks/queue.ts +1 -1
  436. package/src/hooks/receiver.ts +21 -20
  437. package/src/index.ts +206 -49
  438. package/src/intake-plane/author-goals.ts +37 -4
  439. package/src/intake-plane/categorize.ts +18 -46
  440. package/src/intake-plane/check.ts +3 -0
  441. package/src/intake-plane/discord-seat-work.ts +57 -2
  442. package/src/intake-plane/front-route-classifier.ts +33 -39
  443. package/src/intake-plane/persona-answer.ts +30 -0
  444. package/src/intake-plane/runtime-callables.ts +8 -1
  445. package/src/intake-plane/seat-doc-route.ts +170 -6
  446. package/src/intake-plane/telegram-seat-work.ts +80 -4
  447. package/src/intake-plane/telegram-work.ts +1 -0
  448. package/src/intake-plane/wish-folder.ts +67 -0
  449. package/src/intent-gate/gate.ts +30 -10
  450. package/src/live/detail-switch.ts +5 -0
  451. package/src/llm/difficulty.ts +57 -0
  452. package/src/llm/judge-layer.ts +101 -0
  453. package/src/llm/mission-router.ts +33 -19
  454. package/src/loops/contract/examples/cmo-seat.loop.yaml +51 -0
  455. package/src/loops/contract/examples/orchestrator.loop.yaml +57 -0
  456. package/src/loops/contract/examples/steward.loop.yaml +50 -0
  457. package/src/loops/contract/loop-agent.schema.json +138 -0
  458. package/src/loops/contract/validate.ts +64 -0
  459. package/src/loops/registry.ts +20 -6
  460. package/src/market/signed-index.ts +4 -0
  461. package/src/maturity/bot-command-maturity.ts +45 -0
  462. package/src/maturity/cli-maturity.ts +34 -0
  463. package/src/maturity/feature-maturity.ts +120 -1
  464. package/src/maturity/tui-slash-maturity.ts +31 -0
  465. package/src/memory.ts +32 -4
  466. package/src/model-tier/index.ts +2 -2
  467. package/src/model-tier/tier-resolver.ts +20 -20
  468. package/src/model-tier/types.ts +6 -6
  469. package/src/mss/logging/log-store.ts +15 -0
  470. package/src/nexus/api/config-model-tier.ts +5 -4
  471. package/src/nexus/api/exec-requests.ts +33 -3
  472. package/src/nexus/api/fabric-plans.ts +53 -0
  473. package/src/nexus/api/harness-api.ts +5 -1
  474. package/src/nexus/api/health.ts +2 -0
  475. package/src/nexus/api/http-server.ts +89 -1
  476. package/src/nexus/api/inside-events.ts +226 -0
  477. package/src/nexus/api/meta-api.ts +32 -8
  478. package/src/nexus/api/missions.ts +6 -1
  479. package/src/nexus/api/ops-api.ts +10 -1
  480. package/src/nexus/api/ops-seats-sources.ts +37 -7
  481. package/src/nexus/api/ops-seats.ts +49 -6
  482. package/src/nexus/api/outputs-route.ts +44 -0
  483. package/src/nexus/api/seat-requests.ts +132 -10
  484. package/src/nexus/api/sessions-store.ts +42 -0
  485. package/src/nexus/api/setup-codex-login.ts +160 -0
  486. package/src/nexus/api/sub-seat-charters.ts +34 -0
  487. package/src/nexus/api/tabs-mutations.ts +3 -1
  488. package/src/nexus/api/trace.ts +18 -6
  489. package/src/nexus/api/usage-api.ts +102 -0
  490. package/src/nexus/api/workflow-run-event-bridge.ts +1 -0
  491. package/src/nexus/api/workflows.ts +80 -6
  492. package/src/nexus/index.ts +47 -4
  493. package/src/nexus/kinds/webterm.ts +2 -1
  494. package/src/nexus/webterm/pty.ts +6 -2
  495. package/src/onboarding/cli-auth-status.ts +80 -0
  496. package/src/onboarding/first-run.ts +89 -0
  497. package/src/onboarding/lan-address.ts +45 -0
  498. package/src/onboarding/voice-ai.ts +3 -3
  499. package/src/onboarding/web-first.ts +119 -24
  500. package/src/onboarding.ts +4 -0
  501. package/src/ops-now/ops-now-refresh.ts +100 -0
  502. package/src/org/seat-budget.ts +48 -0
  503. package/src/org/stall-escalation.ts +63 -0
  504. package/src/outputs/ledger.ts +120 -0
  505. package/src/persona/persona-todo.ts +79 -0
  506. package/src/persona/presets.ts +116 -2
  507. package/src/persona/team-set.ts +155 -0
  508. package/src/plugins/install/plugin-install.ts +14 -0
  509. package/src/plugins/maker/market-bundle.ts +109 -0
  510. package/src/plugins/maker/plugin-maker.ts +254 -11
  511. package/src/plugins/maker/wizard-generate.ts +103 -0
  512. package/src/pod-lease/admission.ts +150 -0
  513. package/src/pod-lease/dependency-state.ts +85 -0
  514. package/src/pod-lease/host-lease.ts +127 -0
  515. package/src/project/project-store.ts +115 -0
  516. package/src/project/project-suggestion.ts +16 -0
  517. package/src/project/session-context.ts +24 -0
  518. package/src/release-loop/checklist.ts +79 -5
  519. package/src/release-loop/feature-store.ts +159 -24
  520. package/src/release-loop/next-md-merge.ts +58 -0
  521. package/src/release-loop/release-note.ts +59 -4
  522. package/src/release-loop/release-schedule.ts +53 -0
  523. package/src/repl/index.ts +7 -0
  524. package/src/seat-dispatch/ceo-commands.ts +41 -8
  525. package/src/seat-dispatch/ceo-intent.ts +38 -0
  526. package/src/seat-dispatch/seat-ask.ts +130 -0
  527. package/src/seat-dispatch/seat-questions.ts +100 -0
  528. package/src/seat-loop/seat-loop.ts +750 -0
  529. package/src/seat-loop/seat-report.ts +99 -0
  530. package/src/self-dev/decompose.ts +66 -11
  531. package/src/self-dev/dev-cli.ts +4 -1
  532. package/src/self-dev/dev-pipeline.ts +37 -1
  533. package/src/self-dev/draft-sweep.ts +38 -33
  534. package/src/self-dev/draft-triage-rules.ts +8 -5
  535. package/src/self-dev/fabric-plan-core.ts +297 -0
  536. package/src/self-dev/orchestrate.ts +36 -4
  537. package/src/self-dev/release-path-guard.ts +62 -0
  538. package/src/self-dev/run-store.ts +10 -1
  539. package/src/self-dev/shard-aggregate.ts +230 -0
  540. package/src/self-dev/shard-placement.ts +60 -0
  541. package/src/self-dev/shard-plan.ts +48 -0
  542. package/src/self-dev/shard-pod-run.ts +77 -0
  543. package/src/self-dev/shard-run.ts +105 -0
  544. package/src/self-implement/execution-clarification.ts +115 -0
  545. package/src/self-implement/gate-baseline.ts +1 -1
  546. package/src/self-implement/gate-cli.ts +46 -4
  547. package/src/self-implement/gate-scope.ts +37 -7
  548. package/src/self-implement/graph-variant.ts +171 -0
  549. package/src/self-implement/harness-policy-gates.ts +1 -1
  550. package/src/self-implement/headless-elanous-driver.ts +22 -3
  551. package/src/self-implement/host-regate.ts +22 -1
  552. package/src/self-implement/importer-test-index.ts +2 -1
  553. package/src/self-implement/l8-merge-queue.ts +130 -0
  554. package/src/self-implement/orchestrator.ts +279 -12
  555. package/src/self-implement/pipeline-shape.ts +1 -1
  556. package/src/self-implement/route-consumer-test-index.ts +122 -0
  557. package/src/self-implement/run-status-mapping.ts +5 -3
  558. package/src/self-implement/seams.ts +72 -11
  559. package/src/self-implement/test-seams.ts +1 -0
  560. package/src/self-implement/uncommitted-work.ts +59 -0
  561. package/src/session/chat.ts +2 -0
  562. package/src/session/index.ts +45 -13
  563. package/src/shell-env-bootstrap.ts +17 -0
  564. package/src/skills/gift-install.ts +215 -0
  565. package/src/skills/tools/web-search.ts +4 -1
  566. package/src/steward/directive.ts +51 -2
  567. package/src/steward/launch.ts +266 -0
  568. package/src/steward/outcome-notify.ts +115 -0
  569. package/src/steward/steward-cards.ts +25 -11
  570. package/src/steward/triage-plan.ts +32 -4
  571. package/src/steward/triage.ts +129 -13
  572. package/src/steward/working-backwards.ts +64 -0
  573. package/src/storyboard/storyboard.ts +141 -0
  574. package/src/task-cards/card-cli.ts +25 -1
  575. package/src/task-cards/card-store.ts +2 -2
  576. package/src/task-orchestrator/mission.ts +5 -0
  577. package/src/task-orchestrator/store.ts +12 -3
  578. package/src/task-orchestrator/surfaces/pod-command-job.ts +29 -7
  579. package/src/task-orchestrator/surfaces/pod-lease.ts +397 -0
  580. package/src/task-orchestrator/surfaces/pod-pool.ts +127 -26
  581. package/src/task-orchestrator/surfaces/self-implement-pod.ts +214 -40
  582. package/src/task-orchestrator/surfaces/self-implement.ts +15 -2
  583. package/src/task-orchestrator/types.ts +2 -0
  584. package/src/telegram-card-followup.ts +153 -0
  585. package/src/telegram-commands.ts +10 -1
  586. package/src/telegram-project-command.ts +71 -0
  587. package/src/telegram-report.ts +29 -19
  588. package/src/telegram-run.ts +7 -0
  589. package/src/telegram.ts +58 -11
  590. package/src/tool-runtime/self-cognition-runtimes.ts +13 -3
  591. package/src/tool-runtime/types.ts +4 -0
  592. package/src/tui-client/dashboard-session.ts +2 -0
  593. package/src/user-config.ts +216 -27
  594. package/src/version/packed-revision.json +1 -1
  595. package/src/web-push/notify-exec-request.ts +32 -0
  596. package/src/web-search/grok.ts +7 -1
  597. package/src/web-search/index.ts +28 -1
  598. package/src/web-search/provider.ts +4 -0
  599. package/src/web-search/x-intent.ts +5 -0
  600. package/src/workflow-runtime/executor.ts +277 -47
  601. package/src/workflow-runtime/index.ts +1 -0
  602. package/src/workflow-runtime/nodes/subworkflow.ts +60 -0
  603. package/src/workflow-runtime/plugin-kind-node.ts +1 -1
  604. package/src/workflow-runtime/schema.ts +79 -4
  605. package/src/workflow-runtime/types.ts +35 -4
  606. package/apps/pwa/out/_next/static/bFI5EEwg7T6aG88ibX4Zq/_buildManifest.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/1201-09613bce624467c0.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/1377-1efeffbbac0963ff.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/1470.98a6ab61ccb4131c.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/2375-cb6debea56cce4fb.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/2929-617f1e66a55be184.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/2977-e38442e86289f1d3.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/2982-2a2df543be3d2e5a.js +0 -25
  617. package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +0 -5
  618. package/apps/pwa/out/_next/static/chunks/3441-a1dd4acfeda14488.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/5080-1613752891fcadb4.js +0 -10
  622. package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/6090-85a3f05f954e5697.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/6284-69db415193d5f8bd.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/6416-505ba707cacafbba.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/7032-f4ef698518fba61c.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/7647.2fcd30d894d5ee30.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/8067-d976b441a104ab74.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/8519-5632377cce994f86.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/8630-cdfc61e82c653ffc.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/8894-e263b332208e3957.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/9454-139040d37c79dbc9.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/9740-8f5ff96c522b5f55.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/ae787e4c-f2998de7f1ba72a4.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fb7c2d458f32fcad.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-35e2713597dd24d1.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/board/page-918b656f064577ba.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/bots/page-5f30e00693527ebd.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/chat/page-7fbae173b3c103a7.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b4edcce364062ea.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/control/page-c5794f484c251f44.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/design-check/page-1130d8eefcd87e76.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/editor/page-973996d584f008c1.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/exec/page-016e2bda04eecb1f.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/field/page-b4d6d9a3b56f2940.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/intake/page-ec49a466121233ba.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/layout-f72db356744ceade.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/live/page-a6fd9b50d1b85378.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/market/page-8b0402a46a749a3d.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-037f83e2a1edc8e2.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/not-found-46fedff57d4bec67.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/observatory/page-0cf318e9dcee2bbf.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-899b327cb8b6845c.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6c1e6ba743a29dfe.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/page-1a8e4807292f6b17.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/reflection/page-28deba6bcb834916.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-de68e2205794037d.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/sessions/page-c71c33a573230672.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-0df30e0c7e50148a.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/settings/page-4fc56790fe0d2682.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-59df2aebb38a7c1e.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/setup/page-4647be5dbcbd0795.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/share/page-e025892bda74b743.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/showroom/page-a0955de73b89f078.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/tasks/page-369846d2921af584.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/term/page-72cbc1c8cdd0f65d.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/trace/page-77b28bfb0996d5ea.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/vault/page-3220c4934f49c6c2.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-90670589b87abea8.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/workflows/page-7df9243ed021a4cc.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/workspace/page-4498c3853f4f688d.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-35bedde6d885f08f.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/main-app-6870f30ea99f8346.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/webpack-e5bea36f183b25e6.js +0 -1
  692. package/apps/pwa/out/_next/static/css/f92f63a5df0ba229.css +0 -1
  693. package/src/dashboard/turn-typeahead-echo.ts +0 -23
  694. /package/apps/pwa/out/_next/static/{bFI5EEwg7T6aG88ibX4Zq → Y4zKzL62sakG5momz3SoQ}/_ssgManifest.js +0 -0
@@ -1,7 +1,15 @@
1
1
  import { execFileSync } from 'node:child_process';
2
+ import { dlopen, FFIType } from 'bun:ffi';
2
3
  import { createHash } from 'node:crypto';
3
- import { readFileSync } from 'node:fs';
4
- import { resolve } from 'node:path';
4
+ import { existsSync, readFileSync } from 'node:fs';
5
+ import { constants as osConstants } from 'node:os';
6
+ import { resolve, sep } from 'node:path';
7
+ import { findGitDir } from '../git-fs/locate.js';
8
+ import { LogStore, logsDbPath } from '../mss/logging/log-store.js';
9
+ import { loadSelfDevRun } from '../self-dev/run-store.js';
10
+ import { normalizeRunId } from './harness-space.js';
11
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
12
+ import { detectBursts, formatIncidentBurstWarning, readRunExits, recentBurst, recordRunExit } from './harness-incidents.js';
5
13
  import { Command, Option } from 'commander';
6
14
  import { runGitCommand } from '../git-fs/runner.js';
7
15
  import { GOAL_TYPES, lintGoalFile, parseGoalId, parseGoalType, tracedPathReferences, type GoalType } from '../self-implement/goal-author.js';
@@ -14,8 +22,10 @@ import { DevPipelineError } from '../self-dev/dev-pipeline.js';
14
22
  import { runDraftSweep, type DraftSweepAdapters, type DraftSweepResult, type SweepDraft, type SweepMergedPr } from '../self-dev/draft-sweep.js';
15
23
  import { debug } from '../debug/log.js';
16
24
  import { dispatchTask, type DispatchTaskInput, type DispatchTaskDeps } from '../execution-loop/dispatch-task.js';
25
+ import { launchRequestId, preLaunchGate, type PreLaunchGateDeps } from '../execution-loop/launch-gate.js';
17
26
  import { PR_LABELS } from '../github/pr-labels.js';
18
- import { decideBudget, readBudgetInputsLive, type BudgetDecision, type BudgetInputs } from '../self-implement/budget-gate.js';
27
+ import { CODEX_PROVIDER, GROK_PROVIDER, decideBudget, readBudgetInputsLive, type BudgetDecision, type BudgetInputs } from '../self-implement/budget-gate.js';
28
+ import { DEFAULT_FALLBACK_CHAIN } from '../oauth/fallback-chain.js';
19
29
  import { installDeliverableVerifyCliCommand, type InstallDeliverableVerifyCliDeps } from './deliverable-verify-cli.js';
20
30
  import { getUserConfig } from '../user-config.js';
21
31
  import { installHarnessCliSinkHook } from './harness-cli-sink.js';
@@ -86,6 +96,7 @@ export interface HarnessAskSayOptions {
86
96
  target?: string;
87
97
  yes?: boolean;
88
98
  forcePreflight?: boolean;
99
+ forceGate?: boolean;
89
100
  autoMerge?: boolean;
90
101
  mergeByHost?: boolean;
91
102
  observeOnly?: boolean;
@@ -243,12 +254,14 @@ function registerHarnessAskSayOptions(command: Command): Command {
243
254
  .option('--correlation <id>', '요청과 런을 잇는 불투명 correlation 값')
244
255
  .addOption(new Option('--goal-type <type>', `골 종류 (${GOAL_TYPES.join('|')})`).choices([...GOAL_TYPES]))
245
256
  .option('--force-preflight', '전제 검사 막힘을 명시 요청으로 우회(관측에 남음)')
257
+ .option('--force-gate', '같은 골 실행 중 막힘을 명시 요청으로 우회(관측에 남음; 예산 막힘은 우회 불가)')
246
258
  .option('--child-llm-provider <id>', 'self: 구현 자식 LLM provider(--child-llm-model과 함께)')
247
259
  .option('--child-llm-model <id>', 'self: 구현 자식 LLM model(--child-llm-provider와 함께)')
248
260
  .option('--child-llm-effort <level>', 'self: 구현 자식 추론 노력 minimal|low|medium|high|xhigh|max — 모델 상한을 넘으면 «거부»한다(--child-llm-provider와 함께)')
249
261
  .addOption(new Option('--substrate <kind>', '실행 칸 — local(설정 없을 때 기본 · 이 기계) | pod(k8s Pod · 같은 그래프가 원격에서 돈다)').choices(['local', 'pod']))
250
262
  .option('--pod-pool <spec>', 'pod: 풀 — 인자 > ELANOUS_POD_POOL > harness.podPool > 기존 pod.pool > 현재 컨텍스트')
251
- .addOption(new Option('--pod-memory <tier>', 'pod: 메모리 등급 — standard(16Gi) | high(32Gi) · 없으면 골 문면 `Pod 메모리: high` 줄 · 그것도 없으면 골이 apps/pwa/ 를 담을 때 high').choices(['standard', 'high']))
263
+ .addOption(new Option('--pod-memory <tier>', 'pod: 메모리 등급 — lite(2Gi · 문서·조사·네트워크 스킬 골 · OOM 이면 high 로 한 번 재시도) | standard(16Gi) | high(32Gi) · 없으면 골 문면 `Pod 메모리: <등급>` 한 줄 · 그것도 없으면 골이 apps/pwa/ 를 담을 때 high').choices(['lite', 'standard', 'high']))
264
+ .option('--after <goal-or-pr>', 'pod: 선행 — 이 골 ID(16자) 또는 PR(#N) 이 병합될 때까지 Pod 발사가 큐에서 이유와 함께 기다린다(병합 없이 닫히면 blocked) · 골 문면 `선행: #N` 한 줄과 같다 · 대상 파일만 겹치면 선행이 아니다(경고만)')
252
265
  .option('--source <spec>', 'pod: 원천 — commit:<40자 sha> | pr:<정수> | worktree:<경로> | files:<경로>[,<경로>…] · `--substrate pod` 와 함께');
253
266
  }
254
267
 
@@ -314,7 +327,7 @@ function assertHarnessChildLlmModel(opts: HarnessAskSayChildLlmOptions): void {
314
327
  }
315
328
 
316
329
  /** Shared post-parse gate: validate child model before any ask/say early return (including `--dry-run`). */
317
- type HarnessSubstrateOpts = { substrate?: 'local' | 'pod'; podPool?: string; podMemory?: string; autoMerge?: boolean; base?: string; json?: boolean; target?: string; source?: string };
330
+ type HarnessSubstrateOpts = { substrate?: 'local' | 'pod'; podPool?: string; podMemory?: string; after?: string; autoMerge?: boolean; base?: string; json?: boolean; target?: string; source?: string };
318
331
  function resolveLaunchSubstrate(opts: HarnessSubstrateOpts): ResolvedHarnessSubstrate {
319
332
  const resolved = resolveHarnessSubstrate({ flag: opts, config: getUserConfig(), env: process.env });
320
333
  debug.log('harness.substrate', 'resolved', resolved);
@@ -323,6 +336,191 @@ function resolveLaunchSubstrate(opts: HarnessSubstrateOpts): ResolvedHarnessSubs
323
336
  else console.log(head);
324
337
  return resolved;
325
338
  }
339
+ type PodExit = { status: number | null; signal?: string | null };
340
+ type PodExitReason = 'signal' | 'human-stop' | 'supervisor' | 'no-launch' | 'unknown';
341
+ const STOPPING_SUPERVISOR_VERDICTS = new Set(['UNCONVERGEABLE', 'CONTRACT-CONFLICT']);
342
+ // Ledger events that only exist once the child actually ran — any of them rules out «never reached the Pod».
343
+ const LAUNCH_EVIDENCE_EVENTS = new Set(['job-applied', 'pod-child-run', 'reviewed', 'rework-budget', 'pr-opened']);
344
+
345
+ /** Keep the run identity seen at launch even if the bounded output tail later drops it. */
346
+ export function harnessPodRunId(output: string): string | undefined {
347
+ return output.match(/\[self-dev\][^\r\n]*\brun\s+(run-[a-z0-9_-]{8,64})(?=\s|$)/i)?.[1];
348
+ }
349
+
350
+ /** Classify a missing Pod result from run-scoped evidence, never from a nonzero exit alone. */
351
+ export function classifyHarnessPodExit(
352
+ exit: PodExit,
353
+ output: string,
354
+ deps: {
355
+ loadLedger?: typeof loadRunLedger;
356
+ hasJobApplied?: (runId: string | undefined, output: string) => boolean | undefined;
357
+ supervisorDecision?: (runId: string) => { stopReason?: string; why?: string } | undefined;
358
+ loadCheckpoint?: typeof loadSelfDevRun;
359
+ runId?: string;
360
+ } = {},
361
+ ): { lines: string[]; reason: PodExitReason | 'pod-failure' } {
362
+ let podFailure: string | undefined;
363
+ let podJobFailed = false;
364
+ for (const line of output.split('\n').reverse()) {
365
+ if (!line.trimStart().startsWith('[{') || !line.includes('"error"')) continue;
366
+ try {
367
+ const results: unknown = JSON.parse(line);
368
+ if (!Array.isArray(results)) continue;
369
+ for (const result of results) {
370
+ if (!result || typeof result !== 'object') continue;
371
+ const error = (result as { error?: { code?: string; message?: string } }).error;
372
+ if (typeof error?.code !== 'string' || typeof error.message !== 'string' || !error.code.startsWith('pod-')) continue;
373
+ podFailure = error.message;
374
+ podJobFailed = error.code === 'pod-job-failed';
375
+ break;
376
+ }
377
+ } catch { /* Non-result stdout cannot establish that a Pod child ran. */ }
378
+ if (podFailure) break;
379
+ }
380
+ if (!podFailure) {
381
+ const summary = output.split('\n').find((line) => /\s❌\sfailed · .* — pod-[\w-]+: /.test(line));
382
+ podFailure = summary?.split(/\s❌\sfailed · .* — pod-[\w-]+: /)[1];
383
+ podJobFailed = summary?.includes(' — pod-job-failed: ') ?? false;
384
+ }
385
+ // Only the run announced at launch — another run id quoted in the output is not this run (review round 3).
386
+ const observedRunId = deps.runId ?? harnessPodRunId(output);
387
+ const runId = observedRunId ? normalizeRunId(observedRunId) : undefined;
388
+ if (podFailure) {
389
+ const childError = podJobFailed ? podFailure.split('childError=')[1]?.split('\\n', 1)[0]?.split('\n', 1)[0] : undefined;
390
+ try { debug.log('harness.pod', 'exit-classified', { runId, reason: 'pod-failure', status: exit.status, signal: exit.signal ?? null }); } catch { /* observation is fail-soft */ }
391
+ return { reason: 'pod-failure', lines: [podJobFailed && childError && childError !== 'no-result-line'
392
+ ? `Pod 안 자식이 실패했다 — ${childError}`
393
+ : `Pod 실행이 실패했다 — ${podFailure.split('\\n', 1)[0]}`] };
394
+ }
395
+ let ledger: ReturnType<typeof loadRunLedger> = null;
396
+ let ledgerReadable = false;
397
+ if (runId) {
398
+ try { ledger = (deps.loadLedger ?? loadRunLedger)(runId); ledgerReadable = ledger !== null; } catch { /* unreadable is not absent */ }
399
+ }
400
+ const signal = exit.signal ?? (exit.status !== null && exit.status > 128
401
+ ? Object.entries(osConstants.signals).find(([, number]) => number === exit.status! - 128)?.[0] : undefined);
402
+ const humanStop = ledger?.some((entry) => entry.event === 'human-stop');
403
+ // A continuing verdict (EXTEND · SUFFICIENT) is not why the run ended — only stopping verdicts count.
404
+ const supervisor = [...(ledger ?? [])].reverse().find((entry) =>
405
+ (entry.event === 'supervisor-decision' || entry.event === 'supervisor-verdict' || entry.event === 'rework-budget')
406
+ && STOPPING_SUPERVISOR_VERDICTS.has(String(entry.data.supervisorVerdict ?? entry.data.verdict))
407
+ || entry.event === 'run-status' && entry.data.stage === 'review-blocked');
408
+ let decision: { stopReason?: string; why?: string } | undefined;
409
+ if (runId) {
410
+ try { decision = (deps.supervisorDecision ?? lookupHarnessSupervisorDecision)(runId); } catch { /* unknown */ }
411
+ }
412
+ const verdict = decision?.stopReason ?? supervisor?.data.supervisorVerdict ?? supervisor?.data.verdict
413
+ ?? (supervisor?.event === 'run-status' ? supervisor.data.stage : undefined);
414
+ const reasonText = decision?.why ?? supervisor?.data.supervisorReason ?? supervisor?.data.reason;
415
+ const ledgerPrUrl = [...(ledger ?? [])].reverse().find((entry) => entry.event === 'pr-opened'
416
+ && (typeof entry.data.url === 'string' || typeof entry.data.prUrl === 'string'))?.data;
417
+ let checkpoint: ReturnType<typeof loadSelfDevRun> = null;
418
+ if (runId) {
419
+ try { checkpoint = (deps.loadCheckpoint ?? loadSelfDevRun)(runId); } catch { /* unreadable is not absent */ }
420
+ }
421
+ const pr = output.match(/https:\/\/github\.com\/[\w.-]+\/[\w.-]+\/pull\/\d+\b/)?.[0]
422
+ ?? (typeof ledgerPrUrl?.url === 'string' ? ledgerPrUrl.url
423
+ : typeof ledgerPrUrl?.prUrl === 'string' ? ledgerPrUrl.prUrl : undefined)
424
+ ?? checkpoint?.results.find((result) => result.prUrl)?.prUrl;
425
+ let reason: PodExitReason;
426
+ let line: string;
427
+ if (humanStop) {
428
+ reason = 'human-stop';
429
+ line = '사람이 멈춘 런이다';
430
+ } else if (signal) {
431
+ reason = 'signal';
432
+ line = `런이 멈췄다(${signal}) — \`harness stop\` 이나 세션 종료일 수 있다 · 그 전까지 만든 PR 은 남아 있다`;
433
+ } else if (typeof verdict === 'string' || checkpoint?.supervisorStopReason) {
434
+ reason = 'supervisor';
435
+ line = `감독 판정: ${verdict ?? checkpoint?.supervisorStopReason}${typeof reasonText === 'string' && reasonText.trim() ? ` — ${reasonText.trim().split(/\r?\n/, 1)[0]}` : ''}`;
436
+ } else {
437
+ let applied: boolean | undefined;
438
+ try { applied = (deps.hasJobApplied ?? hasHarnessPodJobApplied)(runId, output); } catch { /* unknown */ }
439
+ const noLaunch = ledgerReadable && !ledger?.some((entry) => LAUNCH_EVIDENCE_EVENTS.has(entry.event))
440
+ && applied === false && !pr;
441
+ reason = noLaunch ? 'no-launch' : 'unknown';
442
+ line = noLaunch
443
+ ? 'Pod 실행에 닿지 못했다 — 풀·컨텍스트·SSH 연결을 확인하거나 `--substrate local` 로 명시하라'
444
+ : 'Pod 실행 여부 또는 종료 이유를 확인하지 못했다';
445
+ }
446
+ try { debug.log('harness.pod', 'exit-classified', { runId, reason, status: exit.status, signal: signal ?? null }); } catch { /* observation is fail-soft */ }
447
+ return { reason, lines: [line, ...(pr ? [`PR 이 남아 있다: ${pr}`] : [])] };
448
+ }
449
+
450
+ /** The classified status is the same exit handed to the launcher; ledger failure is never an exit failure. */
451
+ export function recordClassifiedHarnessPodExit(runId: string | undefined, reason: string, status: number): void {
452
+ if (!runId) return;
453
+ try {
454
+ const signal = status > 128
455
+ ? Object.entries(osConstants.signals).find(([, number]) => number === status - 128)?.[0] ?? null : null;
456
+ recordRunExit({ runId, reason, status, signal, at: new Date().toISOString() }, effectiveInstanceRoot());
457
+ } catch { /* incident writes cannot change Pod output or exit */ }
458
+ }
459
+
460
+ /** Every Pod launch entrance (harness ask/say · dev ask --substrate pod) warns once after a recent burst; it never blocks the launch. */
461
+ export function warnRecentIncidentBurst(
462
+ root: string = effectiveInstanceRoot(), now: Date = new Date(), write: (line: string) => void = (line) => console.error(line),
463
+ ): boolean {
464
+ try {
465
+ const burst = recentBurst(root, now);
466
+ if (!burst) return false;
467
+ write(formatIncidentBurstWarning(burst));
468
+ try { debug.log('harness.incident', 'burst', { reason: burst.reason, count: burst.count }); } catch { /* observation is fail-soft */ }
469
+ return true;
470
+ } catch { return false; /* incident reads cannot block a launch */ }
471
+ }
472
+
473
+ function lookupHarnessSupervisorDecision(runId: string): { stopReason?: string; why?: string } | undefined {
474
+ const path = logsDbPath();
475
+ if (!existsSync(path)) return undefined;
476
+ const store = LogStore.openReadOnly(path);
477
+ try {
478
+ let beforeId: number | undefined;
479
+ for (;;) {
480
+ const rows = store.query({ exactCategories: ['self-dev.supervisor'], events: ['decision'], grep: runId,
481
+ limit: 1_000, ...(beforeId === undefined ? {} : { beforeId }) });
482
+ for (const row of rows) {
483
+ try {
484
+ const data = JSON.parse(row.data ?? '{}') as Record<string, unknown>;
485
+ if (data.runId !== runId) continue;
486
+ return data.action === 'stop' && typeof data.stopReason === 'string'
487
+ ? { stopReason: data.stopReason, ...(typeof data.why === 'string' ? { why: data.why } : {}) }
488
+ : undefined;
489
+ } catch { /* Malformed observation is not evidence. */ }
490
+ }
491
+ if (rows.length < 1_000) return undefined;
492
+ beforeId = rows.at(-1)!.id;
493
+ }
494
+ } finally { store.close(); }
495
+ }
496
+
497
+ function hasHarnessPodJobApplied(runId: string | undefined, output: string): boolean | undefined {
498
+ const job = output.match(/\bsi-[a-z0-9-]+\b/i)?.[0];
499
+ if (!runId && !job) return undefined;
500
+ const path = logsDbPath();
501
+ if (!existsSync(path)) return undefined;
502
+ const store = LogStore.openReadOnly(path);
503
+ try {
504
+ for (const needle of new Set([runId, job].filter((value): value is string => value !== undefined))) {
505
+ let beforeId: number | undefined;
506
+ for (;;) {
507
+ const rows = store.query({ exactCategories: ['self-implement.pod'], events: ['job-applied'],
508
+ grep: needle, limit: 1_000, ...(beforeId === undefined ? {} : { beforeId }) });
509
+ if (rows.some((row) => {
510
+ try {
511
+ const data = JSON.parse(row.data ?? '{}') as Record<string, unknown>;
512
+ return (runId !== undefined && data.runId === runId)
513
+ || (job !== undefined && data.job === job && (runId === undefined || data.runId === undefined || data.runId === runId));
514
+ } catch { return false; }
515
+ })) return true;
516
+ if (rows.length < 1_000) break;
517
+ beforeId = rows.at(-1)!.id;
518
+ }
519
+ }
520
+ return false;
521
+ } finally { store.close(); }
522
+ }
523
+
326
524
  /** ⭐ 런 계약의 실행 칸 = pod — 호스트는 그래프를 안 돌리고 Pod 로 보낸다(harness-pod-dispatch.ts). */
327
525
  async function onPod(opts: unknown, entrance: 'cli-harness-ask' | 'cli-harness-say', input: string, pool: string,
328
526
  recordDispatch: (input: DispatchTaskInput, deps?: DispatchTaskDeps) => ReturnType<typeof dispatchTask> = dispatchTask): Promise<void> {
@@ -334,6 +532,12 @@ async function onPod(opts: unknown, entrance: 'cli-harness-ask' | 'cli-harness-s
334
532
  process.exitCode = 2;
335
533
  return;
336
534
  }
535
+ if (o.after !== undefined && !/^(?:#?[1-9]\d*|[a-f0-9]{16})$/.test(o.after.trim())) {
536
+ console.error(`--after 는 PR 번호(#N) 또는 골 ID(16자 16진수)여야 한다: ${o.after}`);
537
+ process.exitCode = 2;
538
+ return;
539
+ }
540
+ warnRecentIncidentBurst();
337
541
  let dispatchRecorded = false;
338
542
  try {
339
543
  const goalText = entrance === 'cli-harness-ask' ? readFileSync(input, 'utf8') : input;
@@ -351,46 +555,66 @@ async function onPod(opts: unknown, entrance: 'cli-harness-ask' | 'cli-harness-s
351
555
  }
352
556
  const { dispatchHarnessOnPod } = await import('./harness-pod-dispatch.js');
353
557
  let output = '';
354
- const status = await dispatchHarnessOnPod({ entrance, input, podPool: pool, ...(dispatchRecorded ? { dispatchRecorded: true } : {}), ...(o.podMemory ? { podMemory: o.podMemory } : {}), ...(o.autoMerge === false ? { autoMerge: false } : {}), ...(o.base ? { base: o.base } : {}), ...(o.json ? { json: true } : {}), ...(o.source ? { source: o.source } : {}) },
355
- entrance === 'cli-harness-ask' ? { onOutput: (text) => { output = (output + text).slice(-16_000); } } : {});
558
+ let runId: string | undefined;
559
+ const status = await dispatchHarnessOnPod({ entrance, input, podPool: pool, ...(dispatchRecorded ? { dispatchRecorded: true } : {}), ...(o.podMemory ? { podMemory: o.podMemory } : {}), ...(o.after ? { after: o.after } : {}), ...(o.autoMerge === false ? { autoMerge: false } : {}), ...(o.base ? { base: o.base } : {}), ...(o.json ? { json: true } : {}), ...(o.source ? { source: o.source } : {}) },
560
+ { onOutput: (text) => {
561
+ runId ??= harnessPodRunId(output + text);
562
+ output = (output + text).slice(-16_000);
563
+ } });
356
564
  if (status !== 0) {
357
- let childError: string | undefined;
358
- let podFailure: string | undefined;
359
- let podJobFailed = false;
360
- if (entrance === 'cli-harness-ask') {
361
- for (const line of output.split('\n').reverse()) {
362
- if (!line.trimStart().startsWith('[{') || !line.includes('"error"')) continue;
363
- try {
364
- const results: unknown = JSON.parse(line);
365
- if (!Array.isArray(results)) continue;
366
- for (const result of results) {
367
- if (!result || typeof result !== 'object') continue;
368
- const error = (result as { error?: { code?: string; message?: string } }).error;
369
- if (typeof error?.code !== 'string' || typeof error.message !== 'string' || !error.code.startsWith('pod-')) continue;
370
- if (error.code === 'pod-job-failed') {
371
- podJobFailed = true;
372
- childError = error.message.split('childError=')[1]?.split('\n', 1)[0];
373
- }
374
- podFailure = error.message;
375
- break;
376
- }
377
- } catch { /* Non-result stdout cannot establish that a Pod child ran. */ }
378
- if (podFailure) break;
379
- }
380
- if (!podFailure) {
381
- const summary = output.split('\n').find((line) => /\s❌\sfailed · .* — pod-[\w-]+: /.test(line));
382
- podFailure = summary?.split(/\s❌\sfailed · .* — pod-[\w-]+: /)[1];
383
- podJobFailed = summary?.includes(' — pod-job-failed: ') ?? false;
384
- if (podJobFailed) childError = podFailure?.split('childError=')[1]?.split('\n', 1)[0];
385
- }
386
- }
387
- if (podJobFailed && childError && childError !== 'no-result-line') console.error(`Pod 안 자식이 실패했다 — ${childError}`);
388
- else if (podFailure) console.error(`Pod 실행이 실패했다 — ${podFailure.split('\n', 1)[0]}`);
389
- else console.error('Pod 실행에 닿지 못했다 — 풀·컨텍스트·SSH 연결을 확인하거나 `--substrate local` 로 명시하라');
565
+ const classified = classifyHarnessPodExit({ status }, output, { ...(runId ? { runId } : {}) });
566
+ recordClassifiedHarnessPodExit(runId ?? harnessPodRunId(output), classified.reason, status);
567
+ for (const line of classified.lines) console.error(line);
390
568
  process.exitCode = status;
391
569
  }
392
570
  }
393
571
 
572
+ const LAUNCH_BUDGET_PROVIDER: Readonly<Record<string, string>> = { 'codex-rotate': CODEX_PROVIDER, grok: GROK_PROVIDER };
573
+
574
+ /**
575
+ * L6 발사 관문의 예산 입력 보정 — 발사 우주의 config 에 체인이 없으면(작업 트리 = 시험 우주) 막지 않고
576
+ * 코드 기본 체인으로 판단한다. `--child-llm-provider` 를 명시했으면 그것이 체인이다(예산 판정 밖 provider 는 통과).
577
+ */
578
+ export function harnessLaunchBudgetDecision(
579
+ inputs: BudgetInputs,
580
+ opts: { readonly childLlmProvider?: string; readonly childLlmModel?: string } = {},
581
+ ): { readonly decision: BudgetDecision; readonly warning?: string } {
582
+ const explicit = opts.childLlmProvider?.trim();
583
+ if (explicit) {
584
+ if (explicit !== CODEX_PROVIDER && explicit !== GROK_PROVIDER) {
585
+ return {
586
+ decision: { action: 'proceed', provider: explicit, ...(opts.childLlmModel ? { model: opts.childLlmModel } : {}), reasons: [`${explicit}: 명시 provider — 예산 판정 밖`] },
587
+ warning: `budget: ${explicit} is outside the budget gate — launched as requested`,
588
+ };
589
+ }
590
+ const chain = [{ provider: explicit, ...(opts.childLlmModel ? { model: opts.childLlmModel } : {}) }];
591
+ return { decision: decideBudget({ ...inputs, preference: { ...inputs.preference, chain } }) };
592
+ }
593
+ if (inputs.preference.chain.length > 0) return { decision: decideBudget(inputs) };
594
+ const chain = DEFAULT_FALLBACK_CHAIN.map((step) => ({ provider: LAUNCH_BUDGET_PROVIDER[step] ?? step }));
595
+ return {
596
+ decision: decideBudget({ ...inputs, preference: { ...inputs.preference, chain } }),
597
+ warning: `budget: no chain in this universe's config — judged with the code default ${DEFAULT_FALLBACK_CHAIN.join(',')}`,
598
+ };
599
+ }
600
+
601
+ async function readHarnessLaunchBudget(
602
+ opts: { readonly childLlmProvider?: string; readonly childLlmModel?: string } = {},
603
+ ): Promise<BudgetDecision | 'unknown'> {
604
+ try {
605
+ const { decision, warning } = harnessLaunchBudgetDecision(await readBudgetInputsLive(), opts);
606
+ if (warning) {
607
+ console.error(`⚠️ launch gate: ${warning}`);
608
+ try { debug.log('execution-loop.launch-gate', 'budget-chain-defaulted', { warning, action: decision.action, provider: decision.provider }); } catch { /* observation is fail-soft */ }
609
+ }
610
+ return decision;
611
+ }
612
+ catch (error) {
613
+ try { debug.log('execution-loop.launch-gate', 'budget-unavailable', { reason: String(error) }); } catch { /* observation is fail-soft */ }
614
+ return 'unknown';
615
+ }
616
+ }
617
+
394
618
  async function dispatchHarnessAskSay(
395
619
  opts: HarnessAskSayChildLlmOptions & HarnessDryRunOpts,
396
620
  dryRunPreview: {
@@ -400,6 +624,7 @@ async function dispatchHarnessAskSay(
400
624
  readonly goalPath?: string;
401
625
  },
402
626
  dispatch: (resolved: ResolvedHarnessSubstrate) => Promise<void>,
627
+ gate: PreLaunchGateDeps & { readBudget?: () => Promise<BudgetDecision | 'unknown'> } = {},
403
628
  ): Promise<void> {
404
629
  await runInjectedHarnessHandler(async () => {
405
630
  assertHarnessChildLlmModel(opts);
@@ -408,6 +633,35 @@ async function dispatchHarnessAskSay(
408
633
  printHarnessLaunchDryRun(dryRunPreview);
409
634
  return;
410
635
  }
636
+ // Without a GoalId, match the request to a live run's exact verbatim original ask; still check budget.
637
+ let identity = dryRunPreview.input;
638
+ let goalId: string | null = null;
639
+ if (dryRunPreview.goalPath) {
640
+ try {
641
+ identity = readFileSync(dryRunPreview.goalPath, 'utf8');
642
+ goalId = parseGoalId(identity);
643
+ } catch { /* The launch handler owns file-read errors. */ }
644
+ }
645
+ goalId ??= launchRequestId(identity);
646
+ // Under bun test with no injected gate deps, skip the live reads (≈5 s of codex rotation + run scans) —
647
+ // CLI wiring tests time out on them. Gate tests inject deps and still run the gate (0.2.11 gate 10-03).
648
+ if (process.env.NODE_ENV === 'test' && Object.keys(gate).length === 0) {
649
+ try { debug.log('execution-loop.launch-gate', 'skipped-test-env', { goalId }); } catch { /* observation is fail-soft */ }
650
+ await dispatch(resolved);
651
+ return;
652
+ }
653
+ const budget = await (gate.readBudget ?? (() => readHarnessLaunchBudget(opts)))();
654
+ const decision = preLaunchGate({ goalId, budget, forceLaunch: opts.forceGate === true }, gate);
655
+ if (decision.action !== 'proceed') {
656
+ console.error(`❌ launch gate: ${decision.action} — ${decision.reason.split(/\r?\n/, 1)[0]}`);
657
+ process.exitCode = 3;
658
+ return;
659
+ }
660
+ const warnings = [
661
+ ...(decision.sameGoalActiveRuns === 'unknown' ? ['active runs unknown'] : []),
662
+ ...(decision.budget === 'unknown' ? ['budget unknown'] : decision.budget.action === 'next-provider' ? [decision.budget.reasons.join(' · ') || 'next-provider'] : []),
663
+ ];
664
+ if (warnings.length > 0) console.error(`⚠️ launch gate: ${warnings.join(' · ').split(/\r?\n/, 1)[0]}`);
411
665
  await dispatch(resolved);
412
666
  });
413
667
  }
@@ -541,6 +795,8 @@ export const HARNESS_PROCESS_LAST_ACTIVITY_SCOPE_LINE =
541
795
 
542
796
  export interface HarnessProcessLedgerEntry {
543
797
  readonly timestamp?: string;
798
+ readonly event?: string;
799
+ readonly data?: Record<string, unknown>;
544
800
  }
545
801
 
546
802
  export type HarnessProcessLedgerLookup = (
@@ -575,6 +831,9 @@ export interface HarnessProcessObservationDeps {
575
831
  listWorktrees?: () => HarnessWorktreeListObservation | readonly string[];
576
832
  observeLaunchdPids?: () => HarnessLaunchdPidObservation;
577
833
  lookupLedger?: HarnessProcessLedgerLookup;
834
+ openProcessHandle?: (pid: number) => HarnessProcessSignalHandle;
835
+ readStartTime?: (pid: number) => string;
836
+ repositoryRoot?: string;
578
837
  nowMs?: number;
579
838
  thresholds?: HarnessProcessClassificationThresholds;
580
839
  write?: (text: string) => void;
@@ -1548,6 +1807,140 @@ function installHarnessBudgetCommand(harnessCmd: Command): Command {
1548
1807
  });
1549
1808
  }
1550
1809
 
1810
+ export interface HarnessProcessSignalHandle {
1811
+ signal(signal: NodeJS.Signals): void;
1812
+ close(): void;
1813
+ }
1814
+
1815
+ // macOS has no pidfd: bind to the process by its microsecond start time (libproc PROC_PIDTBSDINFO) and
1816
+ // re-read it immediately before signalling — a reused pid within the same microsecond is not distinguishable, anything else is.
1817
+ function readDarwinStartMicros(pid: number): bigint | null {
1818
+ const libproc = dlopen('/usr/lib/libproc.dylib', {
1819
+ proc_pidinfo: { args: [FFIType.i32, FFIType.i32, FFIType.u64, FFIType.ptr, FFIType.i32], returns: FFIType.i32 },
1820
+ });
1821
+ try {
1822
+ const buf = new Uint8Array(136); // sizeof(struct proc_bsdinfo)
1823
+ const n = libproc.symbols.proc_pidinfo(pid, 3 /* PROC_PIDTBSDINFO */, 0n, buf, buf.length);
1824
+ if (n !== buf.length) return null;
1825
+ const view = new DataView(buf.buffer);
1826
+ if (view.getUint32(12, true) !== pid) return null; // pbi_pid
1827
+ return view.getBigUint64(120, true) * 1_000_000n + view.getBigUint64(128, true); // pbi_start_tvsec · pbi_start_tvusec
1828
+ } finally { libproc.close(); }
1829
+ }
1830
+
1831
+ function openDarwinProcessHandle(pid: number): HarnessProcessSignalHandle {
1832
+ const start = readDarwinStartMicros(pid);
1833
+ if (start === null) throw new Error('proc_pidinfo failed');
1834
+ let closed = false;
1835
+ return {
1836
+ signal(signal) {
1837
+ if (closed) throw new Error('process handle already closed');
1838
+ if (signal !== 'SIGTERM') throw new Error('only SIGTERM is supported');
1839
+ if (readDarwinStartMicros(pid) !== start) throw new Error('pid no longer names the same process');
1840
+ process.kill(pid, 'SIGTERM');
1841
+ },
1842
+ close() { closed = true; },
1843
+ };
1844
+ }
1845
+
1846
+ export function openHarnessProcessHandle(pid: number): HarnessProcessSignalHandle {
1847
+ if (process.platform === 'darwin') return openDarwinProcessHandle(pid);
1848
+ if (process.platform !== 'linux' || !['x64', 'arm64'].includes(process.arch)) {
1849
+ throw new Error('pid-bound signaling unavailable on this platform');
1850
+ }
1851
+ const libc = dlopen('libc.so.6', {
1852
+ syscall: { args: [FFIType.i64, FFIType.i64, FFIType.i64, FFIType.i64, FFIType.i64], returns: FFIType.i64 },
1853
+ close: { args: [FFIType.i32], returns: FFIType.i32 },
1854
+ });
1855
+ const fd = Number(libc.symbols.syscall(434, pid, 0, 0, 0)); // pidfd_open
1856
+ if (fd < 0) {
1857
+ libc.close();
1858
+ throw new Error('pidfd_open failed');
1859
+ }
1860
+ let closed = false;
1861
+ return {
1862
+ signal(signal) {
1863
+ if (closed) throw new Error('pidfd already closed');
1864
+ if (signal !== 'SIGTERM' || libc.symbols.syscall(424, fd, osConstants.signals.SIGTERM, 0, 0) !== 0n) {
1865
+ throw new Error('pidfd_send_signal failed');
1866
+ }
1867
+ },
1868
+ close() {
1869
+ if (closed) return;
1870
+ closed = true;
1871
+ libc.symbols.close(fd);
1872
+ libc.close();
1873
+ },
1874
+ };
1875
+ }
1876
+
1877
+ export function killHarnessProcess(
1878
+ pid: number,
1879
+ force: boolean,
1880
+ deps: HarnessProcessObservationDeps = {},
1881
+ ): { outcome: 'sent' | 'refused'; owned: boolean; runState: string; reason: string } {
1882
+ const refuse = (reason: string, owned = false, runState = 'unknown') => ({ outcome: 'refused' as const, owned, runState, reason });
1883
+ let result: ReturnType<typeof refuse> | { outcome: 'sent'; owned: true; runState: string; reason: string };
1884
+ let handle: HarnessProcessSignalHandle | undefined;
1885
+ let handleFailure: string | undefined;
1886
+ if (Number.isSafeInteger(pid) && pid > 1) {
1887
+ try { handle = (deps.openProcessHandle ?? openHarnessProcessHandle)(pid); }
1888
+ catch (error) { handleFailure = observationFailureReason(error); }
1889
+ }
1890
+ try {
1891
+ const root = deps.repositoryRoot ?? findGitDir(process.cwd())?.root;
1892
+ const listed = normalizeProcessListObservation(deps.listProcesses?.() ?? defaultListHarnessProcesses());
1893
+ const row = listed.status === 'ok' ? listed.records.find((record) => record.pid === pid) : undefined;
1894
+ const prefix = root ? `${resolve(root)}${sep}` : '';
1895
+ const entry = prefix ? `${prefix}bin/elanous.mjs` : '';
1896
+ const argv = row?.command ?? '';
1897
+ const entryIndex = entry && [
1898
+ `bun ${entry} `, `${process.execPath} ${entry} `,
1899
+ `bun bin/elanous.mjs `,
1900
+ ].find((start) => argv.startsWith(start));
1901
+ const fromRepo = Boolean(entryIndex && (entryIndex !== 'bun bin/elanous.mjs ' || row?.cwd && resolve(row.cwd) === resolve(root!)));
1902
+ if (!Number.isSafeInteger(pid) || pid <= 1) result = refuse('invalid pid');
1903
+ else if (listed.status !== 'ok') result = refuse('process observation incomplete');
1904
+ else if (!row) result = refuse('pid not found in harness process population');
1905
+ else if (!fromRepo || !/\belanous\.mjs\s+(?:(?:--test|--config-dir\s+\S+)\s+)?(?:self\s+(?:orchestrate|implement)|harness\s+(?:ask|say))\b/.test(row.command)) result = refuse('not a harness process from this repository');
1906
+ else if (!handle) result = refuse(`pid-bound signaling unavailable: ${handleFailure ?? 'unknown failure'}`);
1907
+ else {
1908
+ let startTime: string | undefined;
1909
+ try {
1910
+ startTime = (deps.readStartTime ?? ((target) => execFileSync('ps', ['-p', String(target), '-o', 'lstart='], { encoding: 'utf8', timeout: 2_000 }).trim()))(pid);
1911
+ } catch { /* unavailable is not a timestamp */ }
1912
+ if (!startTime || !Number.isFinite(Date.parse(startTime))) result = refuse('process start time unreadable');
1913
+ else {
1914
+ const ownership = row.ownership ?? readProcessOwnership(pid);
1915
+ const runId = ownership.status === 'observed' ? ownership.runId : undefined;
1916
+ if (!runId) result = refuse('owning run unconfirmed');
1917
+ else {
1918
+ let ledger: readonly HarnessProcessLedgerEntry[] | null = null;
1919
+ try { ledger = (deps.lookupLedger ?? defaultLookupHarnessProcessLedger)(runId, ownership.status === 'observed' ? ownership.stateDir : undefined); }
1920
+ catch { /* fail closed */ }
1921
+ const last = [...(ledger ?? [])].reverse().find((entry) => entry.event === 'run-status');
1922
+ const runState = typeof last?.data?.runStatus === 'string' ? last.data.runStatus : 'unknown';
1923
+ if (!ledger || !last) result = refuse('owning run ledger unavailable', true, runState);
1924
+ else if (!['running', 'completed', 'failed', 'cancelled', 'abandoned'].includes(runState)) result = refuse('owning run status unconfirmed', true, runState);
1925
+ else if (runState === 'running' && !force) result = refuse('owning run is not terminal (use --force)', true, runState);
1926
+ else {
1927
+ try {
1928
+ const currentStart = (deps.readStartTime ?? ((target) => execFileSync('ps', ['-p', String(target), '-o', 'lstart='], { encoding: 'utf8', timeout: 2_000 }).trim()))(pid);
1929
+ if (currentStart !== startTime) result = refuse('pid start time changed', true, runState);
1930
+ else {
1931
+ handle.signal('SIGTERM');
1932
+ result = { outcome: 'sent', owned: true, runState, reason: 'SIGTERM sent' };
1933
+ }
1934
+ } catch (error) { result = refuse(`SIGTERM failed: ${observationFailureReason(error)}`, true, runState); }
1935
+ }
1936
+ }
1937
+ }
1938
+ }
1939
+ debug.log('harness.processes', 'kill', { pid, ...result });
1940
+ return result;
1941
+ } finally { handle?.close(); }
1942
+ }
1943
+
1551
1944
  function installHarnessProcessObservationCommand(
1552
1945
  harnessCmd: Command,
1553
1946
  deps: HarnessProcessObservationDeps = {},
@@ -1555,8 +1948,18 @@ function installHarnessProcessObservationCommand(
1555
1948
  const write = deps.write ?? ((text: string) => { console.log(text); });
1556
1949
  return harnessCmd
1557
1950
  .command('processes')
1558
- .description('이 저장소가 띄운 OS 프로세스를 읽기 전용으로 분류한다. 자원을 먹는 무리와 오래 떠 있는 무리를 가른다. 죽이지 않는다.')
1559
- .action(() => {
1951
+ .description('기본 읽기 전용 분류. --kill <pid> 는 소유 런 확인 후 단일 PID 에만 SIGTERM 한다.')
1952
+ .option('--kill <pid>', '소유 런을 확인한 뒤 지정한 PID 하나만 SIGTERM')
1953
+ .option('--force', '소유 런이 진행 중이어도 지정한 PID 하나를 종료')
1954
+ .action((opts: { kill?: string; force?: boolean }) => {
1955
+ if (opts.kill !== undefined) {
1956
+ const pid = Number(opts.kill);
1957
+ const result = killHarnessProcess(pid, opts.force === true, deps);
1958
+ write(`pid=${opts.kill} ${result.outcome}: ${result.reason}`);
1959
+ if (result.outcome === 'refused') process.exitCode = 1;
1960
+ return;
1961
+ }
1962
+ if (opts.force) { write('--force requires --kill <pid>'); process.exitCode = 2; return; }
1560
1963
  const records = deps.listProcesses?.() ?? defaultListHarnessProcesses();
1561
1964
  const worktrees = deps.listWorktrees?.() ?? defaultListHarnessWorktreePaths();
1562
1965
  const launchd = deps.observeLaunchdPids?.() ?? observeHarnessLaunchdPids();
@@ -1583,6 +1986,7 @@ export interface HarnessCliCommandDeps {
1583
1986
  say?: HarnessSayHandler;
1584
1987
  /** Observe-only Pod host dispatch seam. */
1585
1988
  podDispatchTask?: (input: DispatchTaskInput, deps?: DispatchTaskDeps) => ReturnType<typeof dispatchTask>;
1989
+ launchGate?: PreLaunchGateDeps & { readBudget?: () => Promise<BudgetDecision | 'unknown'> };
1586
1990
  plan?: HarnessPlanHandler;
1587
1991
  /** ⭐ `plan` 주입이 «없을 때» 가는 기본 분기. 시험이 이 자리로 «CLI 의 기본 배선»을 문다
1588
1992
  * (⛔ 주입된 `plan` 이 파일을 스스로 만들면 그 시험은 배선을 «못 답한다» — 무인 리뷰 GOODHART 지적). */
@@ -1596,6 +2000,36 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
1596
2000
  .command('harness')
1597
2001
  .description('dev-harness worktree 수명 — 워크트리 생성(worktree add)·조회(worktrees)·정리(clean)·프로세스 관찰(processes)');
1598
2002
  installHarnessCliSinkHook(harnessCmd, deps.registerSink, deps.resolveSurface);
2003
+ harnessCmd.command('incidents').description('최근 하니스 Pod 종료 사고 원장을 읽는다')
2004
+ .option('--since <minutes>', '최근 몇 분의 종료를 볼지 (기본 15분)', '15')
2005
+ .option('--json', '구조화 출력')
2006
+ .action((opts: { since: string; json?: boolean }) => {
2007
+ const since = Number(opts.since);
2008
+ if (!Number.isFinite(since) || since < 0) {
2009
+ console.error('❌ --since 는 0 이상의 분이어야 합니다');
2010
+ process.exitCode = 2;
2011
+ return;
2012
+ }
2013
+ try {
2014
+ const root = effectiveInstanceRoot();
2015
+ const rows = readRunExits(root);
2016
+ if (rows.length === 0) {
2017
+ console.log(opts.json ? JSON.stringify({ rows: [], bursts: [] }) : '기록 없음 — 사고 0 이 아니라 아직 기록이 없다');
2018
+ return;
2019
+ }
2020
+ const now = Date.now();
2021
+ const selected = rows.filter((row) => Date.parse(row.at) >= now - since * 60_000 && Date.parse(row.at) <= now);
2022
+ const bursts = detectBursts(rows).filter((burst) => Date.parse(burst.lastAt) >= now - since * 60_000 && Date.parse(burst.lastAt) <= now);
2023
+ if (opts.json) console.log(JSON.stringify({ rows: selected, bursts }));
2024
+ else {
2025
+ for (const row of selected) console.log(`${row.at} run ${row.runId} · ${row.reason} · status=${row.status} signal=${row.signal ?? '-'}`);
2026
+ for (const burst of bursts) console.log(`${burst.firstAt}–${burst.lastAt} 묶음 ${burst.reason} ×${burst.count} · ${burst.runIds.join(', ')}`);
2027
+ }
2028
+ } catch (error) {
2029
+ console.error(humanErrorLine(error));
2030
+ process.exitCode = 1;
2031
+ }
2032
+ });
1599
2033
  installDeliverableVerifyCliCommand(harnessCmd, deps.deliverableVerify);
1600
2034
  installHarnessProcessObservationCommand(harnessCmd, deps.processObservation);
1601
2035
  installHarnessBudgetCommand(harnessCmd);
@@ -1623,6 +2057,7 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
1623
2057
  }
1624
2058
  return resolved.substrate === 'pod' ? onPod(opts, 'cli-harness-ask', goalPath, resolved.pool!, deps.podDispatchTask) : ask(goalPath, normalizeHarnessAskSayOptions(opts));
1625
2059
  },
2060
+ deps.launchGate,
1626
2061
  );
1627
2062
  });
1628
2063
  }
@@ -1647,6 +2082,7 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
1647
2082
  }
1648
2083
  return resolved.substrate === 'pod' ? onPod(opts, 'cli-harness-say', sentence.join(' '), resolved.pool!, deps.podDispatchTask) : say(sentence, normalizeHarnessAskSayOptions(opts));
1649
2084
  },
2085
+ deps.launchGate,
1650
2086
  );
1651
2087
  });
1652
2088
  }