elanous 0.2.20 → 0.2.22

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 (456) 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/aBi6EyMtLsrl7J8eH4kF7/_buildManifest.js +1 -0
  4. package/apps/pwa/out/_next/static/chunks/088d8e8a.8069543d082bec12.js +160 -0
  5. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +148 -0
  6. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +32 -0
  7. package/apps/pwa/out/_next/static/chunks/119fc678.6f591cdb84ca5791.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +309 -0
  9. package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +122 -0
  11. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +149 -0
  12. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +79 -0
  13. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +24 -0
  15. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +27 -0
  19. package/apps/pwa/out/_next/static/chunks/1948.5f35b39eef222a94.js +5 -0
  20. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +36 -0
  25. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +286 -0
  26. package/apps/pwa/out/_next/static/chunks/{2489-ff55a35b202c0f94.js → 2489-d238d3e2eb5b2bf5.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +94 -0
  34. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3522-1de1319d028ac89c.js +25 -0
  38. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +74 -0
  41. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +34 -0
  45. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +115 -0
  47. package/apps/pwa/out/_next/static/chunks/4588.ad3364cb7fb97ada.js +86 -0
  48. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +77 -0
  50. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +90 -0
  55. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +8 -0
  60. package/apps/pwa/out/_next/static/chunks/{6158.af2e93b7adff709b.js → 6158.566c890adc06a459.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +64 -0
  62. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +287 -0
  64. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +226 -0
  65. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6767.8e6c5f6e744fcd9f.js +38 -0
  67. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/7175-350f4ce2873bc038.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +41 -0
  74. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +24 -0
  75. package/apps/pwa/out/_next/static/chunks/7630.2b9a68659053ff4e.js +193 -0
  76. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/7899.597af4a9996c907f.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/79b78388.663188133449d707.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/8194.484f51e273d9abd2.js +217 -0
  82. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +104 -0
  83. package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/88729267.9c6c000157c83f2f.js +62 -0
  85. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +93 -0
  87. package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +23 -0
  89. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +62 -0
  90. package/apps/pwa/out/_next/static/chunks/9832.2ab2e818013574c7.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/a9f2b54d-40c16bd0efdb04b8.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/app/approvals/{page-c855c24de7db74fe.js → page-88459e0903da2803.js} +1 -1
  93. package/apps/pwa/out/_next/static/chunks/app/autopilot/{page-85b316bb4235980b.js → page-d85c43f46f58716b.js} +1 -1
  94. package/apps/pwa/out/_next/static/chunks/app/board/{page-9b2b26a33cb2cd42.js → page-4e645600579ae952.js} +1 -1
  95. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-c9955fde67b1bcb5.js → page-87edbfd19117823b.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/app/chat/{page-4ba4abe096b6c2a8.js → page-cbaf66b1e1804adf.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/app/consult/{page-575d4a8b4f7becb2.js → page-80ed511e02c81412.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/app/control/{page-f5d56ff5f45ad164.js → page-9f5610caaa06178c.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/app/decisions/{page-2260e9eef0357421.js → page-ec8f3575e339de74.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/app/exec/{page-466bf0ee16ad1432.js → page-2a19c5cd3b562580.js} +1 -1
  105. package/apps/pwa/out/_next/static/chunks/app/field/{page-a23bc71713bcc08f.js → page-b6a09cde2e07521a.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/app/loops/{page-35bfec2e631d3eae.js → page-abd86cd832aaa011.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/{page-f9ccb1b1adbea14d.js → page-8c3f168fc3f91939.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/app/morning/{page-ec102c9b8b691e37.js → page-786fb4504d0f2fa9.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/reflection/{page-db03ae3589a81c9e.js → page-7ec8e289b4c14df6.js} +1 -1
  123. package/apps/pwa/out/_next/static/chunks/app/scheduler/{page-4a6463b97f0ad94f.js → page-8c8ac17d52be2a79.js} +1 -1
  124. package/apps/pwa/out/_next/static/chunks/app/sessions/{page-75bffecc9aa1004e.js → page-d359ab048d63a9d9.js} +1 -1
  125. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/settings/{page-31d5b875760bb62d.js → page-f151cc10ad026940.js} +1 -1
  127. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/share/{page-46d5201d2207a511.js → page-bf495a1e284f4e00.js} +1 -1
  130. package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/term/{page-cf0a4b4abead71ea.js → page-9abcfac07e02a542.js} +1 -1
  133. package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/workflows/{page-0acc8e198f7b0dfb.js → page-69cb93d1a2e57e0e.js} +1 -1
  138. package/apps/pwa/out/_next/static/chunks/app/workspace/{page-34882c84f84021c5.js → page-72ec543928d67c3e.js} +1 -1
  139. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/d70879db.c66c56a95a91efc6.js +66 -0
  141. package/apps/pwa/out/_next/static/chunks/f8626309.a4e5d362b1d55e59.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +1 -0
  143. package/apps/pwa/out/_next/static/css/{d3427996da11e480.css → b9d8151e48998417.css} +1 -1
  144. package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +1 -0
  145. package/apps/pwa/out/approvals/index.html +1 -1
  146. package/apps/pwa/out/approvals/index.txt +14 -14
  147. package/apps/pwa/out/autopilot/index.html +1 -1
  148. package/apps/pwa/out/autopilot/index.txt +14 -14
  149. package/apps/pwa/out/board/index.html +1 -1
  150. package/apps/pwa/out/board/index.txt +14 -14
  151. package/apps/pwa/out/botlab/index.html +1 -1
  152. package/apps/pwa/out/botlab/index.txt +14 -14
  153. package/apps/pwa/out/bots/index.html +1 -1
  154. package/apps/pwa/out/bots/index.txt +14 -14
  155. package/apps/pwa/out/ceo/index.html +1 -1
  156. package/apps/pwa/out/ceo/index.txt +14 -14
  157. package/apps/pwa/out/chat/index.html +1 -1
  158. package/apps/pwa/out/chat/index.txt +14 -14
  159. package/apps/pwa/out/consult/index.html +1 -1
  160. package/apps/pwa/out/consult/index.txt +14 -14
  161. package/apps/pwa/out/control/index.html +1 -1
  162. package/apps/pwa/out/control/index.txt +14 -14
  163. package/apps/pwa/out/decisions/index.html +1 -1
  164. package/apps/pwa/out/decisions/index.txt +14 -14
  165. package/apps/pwa/out/design-check/index.html +1 -1
  166. package/apps/pwa/out/design-check/index.txt +14 -14
  167. package/apps/pwa/out/editor/index.html +1 -1
  168. package/apps/pwa/out/editor/index.txt +15 -15
  169. package/apps/pwa/out/exec/index.html +1 -1
  170. package/apps/pwa/out/exec/index.txt +14 -14
  171. package/apps/pwa/out/field/index.html +1 -1
  172. package/apps/pwa/out/field/index.txt +14 -14
  173. package/apps/pwa/out/healthz +1 -1
  174. package/apps/pwa/out/index.html +1 -1
  175. package/apps/pwa/out/index.txt +14 -14
  176. package/apps/pwa/out/inside/index.html +1 -1
  177. package/apps/pwa/out/inside/index.txt +15 -15
  178. package/apps/pwa/out/intake/index.html +1 -1
  179. package/apps/pwa/out/intake/index.txt +14 -14
  180. package/apps/pwa/out/live/index.html +1 -1
  181. package/apps/pwa/out/live/index.txt +14 -14
  182. package/apps/pwa/out/live-run/index.html +1 -0
  183. package/apps/pwa/out/live-run/index.txt +35 -0
  184. package/apps/pwa/out/loops/index.html +1 -1
  185. package/apps/pwa/out/loops/index.txt +14 -14
  186. package/apps/pwa/out/market/index.html +1 -1
  187. package/apps/pwa/out/market/index.txt +14 -14
  188. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  189. package/apps/pwa/out/missions/placeholder/index.txt +14 -14
  190. package/apps/pwa/out/morning/index.html +1 -1
  191. package/apps/pwa/out/morning/index.txt +14 -14
  192. package/apps/pwa/out/observatory/index.html +1 -1
  193. package/apps/pwa/out/observatory/index.txt +14 -14
  194. package/apps/pwa/out/ops/checklist/index.html +1 -1
  195. package/apps/pwa/out/ops/checklist/index.txt +14 -14
  196. package/apps/pwa/out/ops/release/index.html +1 -1
  197. package/apps/pwa/out/ops/release/index.txt +14 -14
  198. package/apps/pwa/out/ops/seats/index.html +1 -1
  199. package/apps/pwa/out/ops/seats/index.txt +14 -14
  200. package/apps/pwa/out/outputs/index.html +1 -1
  201. package/apps/pwa/out/outputs/index.txt +14 -14
  202. package/apps/pwa/out/reflection/index.html +1 -1
  203. package/apps/pwa/out/reflection/index.txt +15 -15
  204. package/apps/pwa/out/scheduler/index.html +1 -1
  205. package/apps/pwa/out/scheduler/index.txt +14 -14
  206. package/apps/pwa/out/sessions/index.html +1 -1
  207. package/apps/pwa/out/sessions/index.txt +14 -14
  208. package/apps/pwa/out/settings/devices/index.html +1 -1
  209. package/apps/pwa/out/settings/devices/index.txt +14 -14
  210. package/apps/pwa/out/settings/index.html +1 -1
  211. package/apps/pwa/out/settings/index.txt +14 -14
  212. package/apps/pwa/out/setup/done/index.html +1 -1
  213. package/apps/pwa/out/setup/done/index.txt +14 -14
  214. package/apps/pwa/out/setup/index.html +1 -1
  215. package/apps/pwa/out/setup/index.txt +14 -14
  216. package/apps/pwa/out/share/index.html +1 -1
  217. package/apps/pwa/out/share/index.txt +14 -14
  218. package/apps/pwa/out/showroom/index.html +1 -1
  219. package/apps/pwa/out/showroom/index.txt +14 -14
  220. package/apps/pwa/out/tasks/index.html +1 -1
  221. package/apps/pwa/out/tasks/index.txt +14 -14
  222. package/apps/pwa/out/term/index.html +1 -1
  223. package/apps/pwa/out/term/index.txt +14 -14
  224. package/apps/pwa/out/today/index.html +1 -1
  225. package/apps/pwa/out/today/index.txt +14 -14
  226. package/apps/pwa/out/trace/index.html +1 -1
  227. package/apps/pwa/out/trace/index.txt +14 -14
  228. package/apps/pwa/out/vault/index.html +1 -1
  229. package/apps/pwa/out/vault/index.txt +14 -14
  230. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  231. package/apps/pwa/out/workflows/chat-ui/index.txt +14 -14
  232. package/apps/pwa/out/workflows/index.html +1 -1
  233. package/apps/pwa/out/workflows/index.txt +14 -14
  234. package/apps/pwa/out/workspace/index.html +1 -1
  235. package/apps/pwa/out/workspace/index.txt +14 -14
  236. package/apps/pwa/out/worktrees/index.html +1 -1
  237. package/apps/pwa/out/worktrees/index.txt +14 -14
  238. package/graphs/catalog/catalog.yaml +1 -1
  239. package/graphs/drafts/recipes.yaml +6 -6
  240. package/graphs/implement-loop.yaml +277 -5
  241. package/graphs/test-diet/recipes.yaml +3 -0
  242. package/graphs/test-diet/test-diet.yaml +3 -1
  243. package/package.json +1 -1
  244. package/scripts/coord-channel-watch.sh +31 -4
  245. package/scripts/docs-lint.ts +4 -1
  246. package/scripts/f-session-monitor.ts +69 -0
  247. package/scripts/hq/standby-snapshot.ts +7 -3
  248. package/scripts/knowledge-compress.ts +11 -0
  249. package/scripts/marketing/generate-ax-brief.ts +18 -1
  250. package/scripts/measure-nl-routing-corpus.ts +11 -3
  251. package/scripts/nightly-docops.ts +90 -3
  252. package/scripts/release-loop/gate-node.ts +5 -5
  253. package/scripts/release-loop/shard-plan.ts +50 -5
  254. package/scripts/research-coo-admin-dates.ts +39 -0
  255. package/scripts/rhythm/daily.ts +2 -1
  256. package/scripts/skills/public-check.ts +7 -2
  257. package/scripts/smart-merge/resync-shadow.ts +5 -3
  258. package/scripts/test-diet/lib.ts +81 -1
  259. package/scripts/test-diet/node.ts +48 -2
  260. package/scripts/verify-coo-admin-evidence.ts +83 -0
  261. package/src/acp/client.ts +4 -2
  262. package/src/agent/run-context.ts +4 -0
  263. package/src/agent-env/profile.ts +25 -5
  264. package/src/agent-mission/driver.ts +26 -12
  265. package/src/agent-mission/supervisor-metrics.ts +17 -2
  266. package/src/agent-substrate/acp-reviewer.ts +12 -5
  267. package/src/agent-substrate/pr-reviewer.ts +11 -4
  268. package/src/agent-substrate/review-intent.ts +102 -3
  269. package/src/autopilot/build/llm-conflict-merge.ts +22 -8
  270. package/src/autopilot/pr-manager.ts +18 -8
  271. package/src/away/release-watch.ts +47 -8
  272. package/src/briefing/brief-items.ts +104 -11
  273. package/src/browser-cdp/client.ts +10 -5
  274. package/src/chat/index.ts +1 -0
  275. package/src/cli/brief-cli.ts +20 -2
  276. package/src/cli/config-classify.ts +83 -0
  277. package/src/cli/control-cli.ts +14 -0
  278. package/src/cli/decisions-cli.ts +26 -16
  279. package/src/cli/logs-model-input.ts +1 -1
  280. package/src/cli/ops-cli.ts +11 -0
  281. package/src/cli/ops-overview-cli.ts +50 -0
  282. package/src/cli/pod-cli.ts +1 -0
  283. package/src/cli/pr-cli.ts +65 -8
  284. package/src/cli/release-cli.ts +21 -4
  285. package/src/cli/tasks-cli.ts +214 -1
  286. package/src/connectors/types.ts +6 -6
  287. package/src/context-bus/context-now-surfaces.ts +18 -0
  288. package/src/context-bus/coord-events.ts +32 -4
  289. package/src/context-bus/long-term-memory.ts +23 -6
  290. package/src/context-bus/nightly-condense.ts +169 -21
  291. package/src/control/control-status.ts +87 -0
  292. package/src/control-plane/light-member.ts +5 -3
  293. package/src/control-plane/member.ts +172 -7
  294. package/src/core-turn/run-goal-loop.ts +22 -1
  295. package/src/dashboard/index.ts +40 -4
  296. package/src/dashboard/slash-runtime/dashboard-handlers.ts +9 -0
  297. package/src/decisions/decision-cards.ts +20 -1
  298. package/src/decisions/decision-ledger.ts +11 -8
  299. package/src/decisions/web-push-decision-cards.ts +19 -3
  300. package/src/discord-self-message.ts +2 -2
  301. package/src/domains/coo-admin-dates.evidence.json +876 -0
  302. package/src/domains/coo-admin-tool.ts +48 -14
  303. package/src/domains/ops-status.ts +53 -0
  304. package/src/domains/outbound-alert.ts +24 -1
  305. package/src/esc-abort-gate.ts +3 -1
  306. package/src/exec-requests/planner.ts +6 -0
  307. package/src/graph-kinds/registry.ts +6 -6
  308. package/src/graph-runner/graph-cli.ts +91 -2
  309. package/src/graph-runner/graph-run-api.ts +20 -0
  310. package/src/graph-runner/graph-tick.ts +73 -12
  311. package/src/graph-runner/runner.ts +43 -11
  312. package/src/graph-unify/wf-to-graph.ts +79 -0
  313. package/src/graph-wizard/archetypes.ts +88 -0
  314. package/src/graph-wizard/generate.ts +577 -0
  315. package/src/graph-wizard/saved-steps.ts +120 -0
  316. package/src/graph-wizard/steps.ts +206 -0
  317. package/src/harness/harness-cli-command.ts +186 -32
  318. package/src/harness/harness-queue.ts +58 -14
  319. package/src/harness/launch-advice.ts +23 -0
  320. package/src/index.ts +43 -11
  321. package/src/intake-plane/digest.ts +18 -11
  322. package/src/knowledge/conclusion-compress.ts +93 -0
  323. package/src/knowledge/know-find.ts +9 -2
  324. package/src/knowledge/query.ts +20 -0
  325. package/src/llm.ts +26 -16
  326. package/src/loops/neighbor-runtime.ts +88 -0
  327. package/src/loops/orchestrator/author-depth.ts +29 -11
  328. package/src/loops/orchestrator/overlap.ts +7 -1
  329. package/src/loops/orchestrator/resync-shadow.ts +1 -1
  330. package/src/loops/orchestrator/tick.ts +35 -2
  331. package/src/loops/orchestrator/traffic.ts +2 -0
  332. package/src/loops/registry.ts +5 -0
  333. package/src/market/publish.ts +17 -1
  334. package/src/maturity/feature-maturity.ts +4 -2
  335. package/src/mss/logging/redaction.ts +17 -0
  336. package/src/nexus/api/draft-metrics.ts +128 -0
  337. package/src/nexus/api/graph-peer-edit.ts +77 -0
  338. package/src/nexus/api/graph-wizard-api.ts +61 -0
  339. package/src/nexus/api/graphs-api.ts +193 -17
  340. package/src/nexus/api/harness-traversal.ts +205 -0
  341. package/src/nexus/api/http-server.ts +122 -6
  342. package/src/nexus/api/plugins-market.ts +24 -0
  343. package/src/nexus/index.ts +3 -2
  344. package/src/nexus/outbound/router.ts +28 -8
  345. package/src/oauth/claude-pty-maturity.ts +24 -0
  346. package/src/oauth/fallback-chain.ts +27 -14
  347. package/src/onboarding/first-run.ts +3 -0
  348. package/src/ops/overview-collect.ts +345 -0
  349. package/src/ops/overview-seat-era.ts +90 -0
  350. package/src/ops/overview.ts +223 -0
  351. package/src/plugins/maker/market-bundle.ts +9 -0
  352. package/src/plugins/maker/plugin-maker.ts +9 -3
  353. package/src/plugins/maker/wizard-generate.ts +73 -9
  354. package/src/policy/llm-policy.ts +11 -6
  355. package/src/release-loop/checklist-board.ts +27 -0
  356. package/src/release-loop/checklist.ts +38 -0
  357. package/src/release-loop/gate-shards.ts +7 -2
  358. package/src/seat-address/seat-address.ts +1 -0
  359. package/src/seat-loop/seat-loop.ts +174 -20
  360. package/src/seat-loop/seat-report.ts +29 -1
  361. package/src/self-dev/ask-launch-flow.ts +4 -2
  362. package/src/self-dev/ask-launch-io.ts +3 -1
  363. package/src/self-dev/dev-cli.ts +90 -8
  364. package/src/self-dev/dev-pipeline.ts +20 -1
  365. package/src/self-dev/draft-sweep.ts +45 -8
  366. package/src/self-dev/graph-journey-nodes.ts +157 -0
  367. package/src/self-dev/graph-journey-route.ts +105 -0
  368. package/src/self-dev/launch-preflight.ts +43 -3
  369. package/src/self-dev/orchestrate.ts +3 -0
  370. package/src/self-dev/release-path-guard.ts +7 -4
  371. package/src/self-dev/review-provider-fallback.ts +83 -0
  372. package/src/self-dev/run-supervisor.ts +5 -1
  373. package/src/self-implement/frozen-merges.ts +23 -0
  374. package/src/self-implement/goal-author.ts +14 -0
  375. package/src/self-implement/harness-policy-gates.ts +7 -5
  376. package/src/self-implement/heal-intake.ts +3 -0
  377. package/src/self-implement/host-regate.ts +28 -14
  378. package/src/self-implement/l8-merge-queue.ts +80 -8
  379. package/src/self-implement/orchestrator.ts +84 -28
  380. package/src/self-implement/seams.ts +8 -3
  381. package/src/self-implement/self-implement-cli.ts +4 -0
  382. package/src/self-implement/self-implement-runtime.ts +12 -0
  383. package/src/session-runtime/index.ts +5 -3
  384. package/src/shell-env-bootstrap.ts +35 -6
  385. package/src/steward/triage.ts +25 -8
  386. package/src/storage/file-lock.ts +33 -4
  387. package/src/task-agent/card-evidence.ts +6 -0
  388. package/src/task-agent/completion-evidence.ts +31 -3
  389. package/src/task-agent/cover.ts +61 -0
  390. package/src/task-agent/live-moves.ts +126 -3
  391. package/src/task-agent/parent-host.ts +315 -0
  392. package/src/task-agent/shadow.ts +19 -4
  393. package/src/task-agent/task-hand.ts +11 -2
  394. package/src/task-orchestrator/surfaces/pod-command-job.ts +41 -6
  395. package/src/task-orchestrator/surfaces/pod-gate-deps.ts +123 -0
  396. package/src/task-orchestrator/surfaces/pod-pool.ts +138 -15
  397. package/src/task-orchestrator/surfaces/self-implement-pod.ts +39 -6
  398. package/src/task-orchestrator/surfaces/self-implement.ts +7 -0
  399. package/src/telegram-commands.ts +8 -0
  400. package/src/telegram-project-command.ts +6 -0
  401. package/src/telegram.ts +2 -2
  402. package/src/tool-runtime/browser-runtime.ts +87 -3
  403. package/src/tool-runtime/index.ts +1 -0
  404. package/src/typecheck-ratchet.ts +2 -1
  405. package/src/user-config.ts +55 -8
  406. package/src/version/packed-revision.json +1 -1
  407. package/src/workflow-runtime/executor.ts +24 -2
  408. package/src/workflow-runtime/triggers/registry.ts +27 -0
  409. package/src/workflow-runtime/triggers/schedule-source.ts +30 -3
  410. package/apps/pwa/out/_next/static/Bam1YziK2iH9bN4K0utGk/_buildManifest.js +0 -1
  411. package/apps/pwa/out/_next/static/chunks/1307-77fad80cf54477c6.js +0 -1
  412. package/apps/pwa/out/_next/static/chunks/1612-f60c0c93ec773f81.js +0 -1
  413. package/apps/pwa/out/_next/static/chunks/1844-9ec4b1d12f6e80eb.js +0 -1
  414. package/apps/pwa/out/_next/static/chunks/1866-e7a6999f25548b30.js +0 -1
  415. package/apps/pwa/out/_next/static/chunks/1948.15f356b15a625597.js +0 -5
  416. package/apps/pwa/out/_next/static/chunks/2116-6429c188eb846ab8.js +0 -1
  417. package/apps/pwa/out/_next/static/chunks/224-e7be8f762fe74986.js +0 -1
  418. package/apps/pwa/out/_next/static/chunks/2549-89c518a4c8ed4d00.js +0 -1
  419. package/apps/pwa/out/_next/static/chunks/2957-96ffab3d521fb08f.js +0 -1
  420. package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +0 -1
  421. package/apps/pwa/out/_next/static/chunks/5360-be1f1d8f9fcc9755.js +0 -1
  422. package/apps/pwa/out/_next/static/chunks/5755-ea7ed88eb956f47b.js +0 -1
  423. package/apps/pwa/out/_next/static/chunks/5977-94ed6f78e9814b2b.js +0 -1
  424. package/apps/pwa/out/_next/static/chunks/7748-6e51bfe927019f5c.js +0 -25
  425. package/apps/pwa/out/_next/static/chunks/9247-c1753a059e7bac08.js +0 -1
  426. package/apps/pwa/out/_next/static/chunks/a9f2b54d-33c0689b70ed8cf3.js +0 -1
  427. package/apps/pwa/out/_next/static/chunks/app/bots/page-7a852956c74015a3.js +0 -1
  428. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c5a5c621be0e04ae.js +0 -1
  429. package/apps/pwa/out/_next/static/chunks/app/design-check/page-7c058069c5e7fa63.js +0 -1
  430. package/apps/pwa/out/_next/static/chunks/app/editor/page-dc5da0b8a2edb8a4.js +0 -1
  431. package/apps/pwa/out/_next/static/chunks/app/inside/page-ed4a6f799f005d09.js +0 -1
  432. package/apps/pwa/out/_next/static/chunks/app/intake/page-9cd565005b93aca6.js +0 -1
  433. package/apps/pwa/out/_next/static/chunks/app/layout-55f0f40c6db95f15.js +0 -1
  434. package/apps/pwa/out/_next/static/chunks/app/live/page-474cb5888ea0e8f3.js +0 -1
  435. package/apps/pwa/out/_next/static/chunks/app/market/page-9ca21f9ad3208a61.js +0 -1
  436. package/apps/pwa/out/_next/static/chunks/app/not-found-a9c2cfa8dda922a5.js +0 -1
  437. package/apps/pwa/out/_next/static/chunks/app/observatory/page-6da35144878feb6d.js +0 -1
  438. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-f6055495e9ed7ea8.js +0 -1
  439. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-25204694fa9984a5.js +0 -1
  440. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-a60e035f151d84d3.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/app/outputs/page-189c587f36874538.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/app/page-c56634bde705a65d.js +0 -1
  443. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a8d2fe0c669e0de4.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c26fa10aac6c21c4.js +0 -1
  445. package/apps/pwa/out/_next/static/chunks/app/setup/page-68793c6e10331d66.js +0 -1
  446. package/apps/pwa/out/_next/static/chunks/app/showroom/page-d81c07a7b4f618ae.js +0 -1
  447. package/apps/pwa/out/_next/static/chunks/app/tasks/page-be1c4e8697f22360.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/app/today/page-a4717e2c4bf7a28f.js +0 -1
  449. package/apps/pwa/out/_next/static/chunks/app/trace/page-0fd895fab9b62c1b.js +0 -1
  450. package/apps/pwa/out/_next/static/chunks/app/vault/page-8b6c1454a8e8f306.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c6e4364d9de8f717.js +0 -1
  452. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-0506a1e0e4bdb2f5.js +0 -1
  453. package/apps/pwa/out/_next/static/chunks/webpack-c260571513bf43c2.js +0 -1
  454. package/apps/pwa/out/_next/static/css/c23d959d3ee15e57.css +0 -1
  455. /package/apps/pwa/out/_next/static/{Bam1YziK2iH9bN4K0utGk → aBi6EyMtLsrl7J8eH4kF7}/_ssgManifest.js +0 -0
  456. /package/skills/project-onboarding/{skill.md → SKILL.md} +0 -0
@@ -180,6 +180,7 @@ export const GOAL_CONTINUATION_PROMPT = [
180
180
  '[continue]',
181
181
  '아직 목표가 완료로 증명되지 않았다. 완료를 미리 선언하지 말고, 현재 상태 대비 실제로 검증하라:',
182
182
  '남은 요구사항을 식별하고, 다음 최고가치 스텝을 지금 도구로 실행하라.',
183
+ '이미 사용자에게 한 답을 다시 쓰지 마라 — 새 사실이 없으면 텍스트 없이 update_goal 만 호출하라.',
183
184
  // evidence-audit(ref codex ext/goal continuation.md:41,51) — 스푸핑·조기완료 차단.
184
185
  '완료 증거로 의도/부분진전/이전 작업 기억/그럴듯한 답을 쓰지 마라. 현재 상태(파일·명령출력·테스트결과·PR·런타임 동작)를 실제로 확인한 증거만 인정한다.',
185
186
  '예산이 곧 소진된다거나 그만두고 싶다는 이유로 완료를 선언하지 마라.',
@@ -196,6 +197,7 @@ export const GOAL_READBACK_PROMPT = [
196
197
  '[finalize]',
197
198
  `완료를 텍스트로만 말했다. 텍스트 문장은 완료 신호가 아니다 — 완료가 사실이면 ${UPDATE_GOAL_TOOL_NAME} 도구를 status="complete" 로 호출하고 evidence 에 현재 상태에서 실제로 확인한 증거(파일·명령출력·테스트·PR)를 적어라.`,
198
199
  '아직 미충족 항목이 있으면 완료를 주장하지 말고 다음 스텝을 지금 실행하라.',
200
+ '이미 사용자에게 한 답을 다시 쓰지 마라 — 새 사실이 없으면 텍스트 없이 update_goal 만 호출하라.',
199
201
  ].join('\n');
200
202
 
201
203
  /** evidence 누락 complete 재주입 — update_goal(complete) 를 호출했으나 evidence 가 비었을 때. */
@@ -689,6 +691,7 @@ export async function runGoalLoop(
689
691
  },
690
692
  };
691
693
 
694
+ const previousFinalText = lastResult.finalText;
692
695
  try {
693
696
  lastResult = await runTurn(turnCtx);
694
697
  } finally {
@@ -786,8 +789,26 @@ export async function runGoalLoop(
786
789
  debug.log('goal.loop', 'complete', {
787
790
  sessionId: ctx.sessionId, ...runAttribution, iterations, via: 'update_goal', evidenceCheck,
788
791
  }, { level: 'info' });
792
+ const normalizeAnswer = (text: string) => text.trim().replace(/\s+/g, ' ');
793
+ const previousAnswer = normalizeAnswer(previousFinalText);
794
+ const completionAnswer = normalizeAnswer(lastResult.finalText);
795
+ const previousAt = previousAnswer ? completionAnswer.indexOf(previousAnswer) : -1;
796
+ const prefix = previousAt >= 0 ? completionAnswer.slice(0, previousAt).trim() : '';
797
+ const suffix = previousAt >= 0 ? completionAnswer.slice(previousAt + previousAnswer.length).trim() : '';
798
+ // Only a readback preface is non-factual; a new sentence before the old answer
799
+ // (including one joined by a colon) must survive just like a new suffix.
800
+ const readbackPreface = /^(?:확인 결과|(?:방금\s+)?다시\s+확인(?:했습니다|했지만|해보니|해 보니|해봤지만|해 봤지만|했으나|했는데))[\s::,.!?。!?-]*$/u;
801
+ const hasNewFact = (prefix.length > 0 && !readbackPreface.test(prefix)) || /\p{L}|\p{N}/u.test(suffix);
802
+ const duplicateAnswer = previousAnswer.length > 0 && (
803
+ completionAnswer.length === 0 || (previousAt >= 0 && !hasNewFact)
804
+ );
805
+ if (duplicateAnswer) {
806
+ debug.log('goal.loop', 'complete-duplicate-answer-suppressed', {
807
+ sessionId: ctx.sessionId, ...runAttribution, iterations, chars: lastResult.finalText.length,
808
+ });
809
+ }
789
810
  return finish(
790
- { finalText: lastResult.finalText, iterations, stopReason: 'goal_complete', goalComplete: true },
811
+ { finalText: duplicateAnswer ? previousFinalText : lastResult.finalText, iterations, stopReason: 'goal_complete', goalComplete: true },
791
812
  { summary: completionSummary, changedFiles: completionChangedFiles },
792
813
  );
793
814
  }
@@ -769,6 +769,15 @@ export function clearEscAbortToolState(toolState: EscAbortToolState): void {
769
769
  toolState.activeToolNamesByCallId.clear();
770
770
  }
771
771
 
772
+ export function activeEscHarnessSpace(
773
+ toolState: EscAbortToolState,
774
+ spacesByCallId: ReadonlyMap<string, string>,
775
+ ): string | null {
776
+ const active = [...toolState.activeToolNamesByCallId].filter(([, name]) =>
777
+ (SELF_IMPLEMENT_TOOL_NAMES as readonly string[]).includes(name));
778
+ return active.length === 1 ? spacesByCallId.get(active[0]![0]) ?? null : null;
779
+ }
780
+
772
781
  /** Reset per-turn ESC tool tracking before a new stream runtime begins. */
773
782
  export function createDashboardTurnStreamRuntimeEscBoundary(toolState: EscAbortToolState): void {
774
783
  clearEscAbortToolState(toolState);
@@ -1324,6 +1333,8 @@ import {
1324
1333
  PULSE_HALF_PERIOD_MS,
1325
1334
  } from '../agent-activity-hud.js';
1326
1335
  import { DASHBOARD_CLARIFICATION_REQUEST, consumeStreamingTopModalEscape, createEscAbortGate, createHarnessEscHint, routeStreamingEscapeKey } from '../esc-abort-gate.js';
1336
+ import { enqueueSoftStop, readSoftStopRequestStatus } from '../harness/control-inbox.js';
1337
+ import { setSelfImplementSoftStopSpaceObserver } from '../self-implement/self-implement-runtime.js';
1327
1338
  import { createViEditor, type ViEditorHandle } from '../vi-editor.js';
1328
1339
  import { launchEditor, canLaunchEditor } from '../editor-launcher.js';
1329
1340
  import { createSshPickerModal } from '../ssh/ssh-picker-modal.js';
@@ -6700,6 +6711,13 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6700
6711
  * this function is invoked.
6701
6712
  */
6702
6713
  const escAbortToolState = createEscAbortToolState();
6714
+ const escHarnessSpacesByCallId = new Map<string, string>();
6715
+ setSelfImplementSoftStopSpaceObserver((callId, spaceId) => {
6716
+ const toolName = escAbortToolState.activeToolNamesByCallId.get(callId);
6717
+ if (toolName && (SELF_IMPLEMENT_TOOL_NAMES as readonly string[]).includes(toolName)) {
6718
+ escHarnessSpacesByCallId.set(callId, spaceId);
6719
+ }
6720
+ });
6703
6721
  let clarificationModalId: string | null = null;
6704
6722
 
6705
6723
  const attachChatStreamingKeys = (abortCtrl: AbortController): () => void => {
@@ -6713,6 +6731,8 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6713
6731
  // so the user can make an informed call.
6714
6732
  let abortGateModalId: string | null = null;
6715
6733
  const showHarnessEscHint = createHarnessEscHint((line) => pushChatLine(line));
6734
+ let stoppedHarnessSpace: string | null = null;
6735
+ const activeHarnessSpace = (): string | null => activeEscHarnessSpace(escAbortToolState, escHarnessSpacesByCallId);
6716
6736
  const escGate = createEscAbortGate({
6717
6737
  abortCtrl,
6718
6738
  getRunningCount: () => getEscAbortRunningCount(escAbortToolState),
@@ -6726,14 +6746,25 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
6726
6746
  requestRedraw: () => draw(),
6727
6747
  getTheme: () => currentThemeTokens(),
6728
6748
  getWaitingTargetNames: () => getEscAbortWaitingToolNames(escAbortToolState),
6749
+ shouldAbortImmediately: () => activeHarnessSpace() !== null,
6729
6750
  onAbortPending: ({ targets }) => {
6730
- if (!showHarnessEscHint(targets)) {
6751
+ const spaceId = activeHarnessSpace();
6752
+ if (spaceId) {
6753
+ try {
6754
+ enqueueSoftStop(spaceId);
6755
+ if (readSoftStopRequestStatus(spaceId).status !== 'present') throw new Error('soft-stop marker not persisted');
6756
+ stoppedHarnessSpace = spaceId;
6757
+ pushChatLine(' ⏹ 멈췄다 — 해당 하니스 런에 중단 요청을 보냈습니다.');
6758
+ } catch {
6759
+ pushChatLine(' ⚠ 하니스 런 중단 요청을 보내지 못했습니다. /harness runs 에서 확인해 주세요.');
6760
+ }
6761
+ } else if (!showHarnessEscHint(targets)) {
6731
6762
  pushChatLine(` ⏳ 중단 요청됨 — ${formatEscAbortWaitingTargets(targets)} 종료를 기다리는 중입니다.`);
6732
6763
  }
6733
6764
  chatScrollOffset = -1;
6734
6765
  },
6735
6766
  onAbortRepeat: ({ repeat, targets }) => {
6736
- if (!showHarnessEscHint(targets)) {
6767
+ if (!stoppedHarnessSpace && !showHarnessEscHint(targets)) {
6737
6768
  pushChatLine(` ⏳ ESC 재시도 ${repeat}회 — ${formatEscAbortWaitingTargets(targets)} 종료를 기다리는 중입니다.`);
6738
6769
  }
6739
6770
  chatScrollOffset = -1;
@@ -7251,7 +7282,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
7251
7282
  return () => {
7252
7283
  cleanup();
7253
7284
  escGate.dispose();
7254
- settleEscAbortPendingLines(chatLines, chatLinesStartIndex);
7285
+ if (!stoppedHarnessSpace) settleEscAbortPendingLines(chatLines, chatLinesStartIndex);
7255
7286
  userScrolledDuringStream = false;
7256
7287
  streamingInFlight = false;
7257
7288
  };
@@ -15674,6 +15705,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15674
15705
  pushChatLine,
15675
15706
  draw,
15676
15707
  signal: acpTurnRef.abortCtrl?.signal ?? new AbortController().signal,
15708
+ toolCallId: ctx?.callId,
15677
15709
  // ⛔⭐ 폴백은 `''` 가 아니라 `undefined` 다 — 「안 넘김」과 「말했는데 어휘가 없음」은 «다른 값»이다.
15678
15710
  // harnessMentionState(session-runtime 소비처)는 `undefined → 'absent'` · `'' → 'not-matched'` 로
15679
15711
  // 가른다. `?? ''` 로 접으면 그 둘이 같은 값이 되고, 그것이 2026-08-06 에 「TUI 가 하니스에게
@@ -15695,9 +15727,10 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
15695
15727
  ptyDashboardOn:
15696
15728
  uc.shell.allowDashboardPty === true && (acpPtyAvailable?.() ?? false),
15697
15729
  getToolRuntime: (toolName) => runtime.getToolRuntime(toolName),
15698
- dispatchToolRuntime: (toolName, input) =>
15730
+ dispatchToolRuntime: (toolName, input, toolCallId) =>
15699
15731
  runtime.dispatchToolByName(toolName, input, {
15700
15732
  surface: 'tui',
15733
+ toolCallId,
15701
15734
  signal: acpTurnRef.abortCtrl?.signal,
15702
15735
  // ⭐ Agent-family context. Without these two the sub-agent runs
15703
15736
  // text-only (see getTools above). `agentDispatchTool` routes the
@@ -19171,6 +19204,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
19171
19204
  createTurnStreamRuntime: (initialAssistantStart) => {
19172
19205
  latestTurnUsage = undefined;
19173
19206
  createDashboardTurnStreamRuntimeEscBoundary(escAbortToolState);
19207
+ escHarnessSpacesByCallId.clear();
19174
19208
  liveTypeaheadEchoes.length = 0;
19175
19209
  const toolRendering = {
19176
19210
  ...getUserConfig().chat.rendering.tool,
@@ -19225,6 +19259,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
19225
19259
  const toolCall = call as DashboardTurnStreamCall;
19226
19260
  turnStreamRuntime.onToolResult(toolCall);
19227
19261
  settleEscAbortToolCall(escAbortToolState, toolCall);
19262
+ escHarnessSpacesByCallId.delete(toolCall.id);
19228
19263
  },
19229
19264
  };
19230
19265
  },
@@ -19524,6 +19559,7 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
19524
19559
  closeDashboardTui();
19525
19560
  throw err;
19526
19561
  } finally {
19562
+ setSelfImplementSoftStopSpaceObserver(null);
19527
19563
  if (tuiSeatAskTimer) clearInterval(tuiSeatAskTimer);
19528
19564
  }
19529
19565
  }
@@ -395,6 +395,8 @@ import { dispatchTerminalModalObserve } from '../../skills/tools/terminal-modal.
395
395
  import { SlashCommandRegistry } from './registry.js';
396
396
  import { cronSecondDueAt, filterLoopRows, formatLoopsTable, localLoopRows, type LoopsTableRow } from './loops-table.js';
397
397
  import { loopCronVerdict } from '../../loops/verdict.js';
398
+ import { checklistBoardSlash } from '../../release-loop/checklist-board.js';
399
+ import type { Checklist } from '../../release-loop/checklist.js';
398
400
  import { executeImmediateDashboardSlash } from '../input/slash-executor.js';
399
401
  import {
400
402
  buildContextSlashCommand,
@@ -1046,6 +1048,8 @@ export interface DashboardSlashContext {
1046
1048
 
1047
1049
  /** Test seam for the local read-only loop and cron registry. */
1048
1050
  loopsLocalRows?: (now: Date) => LoopsTableRow[];
1051
+ /** Test seam for the read-only release checklist. */
1052
+ checklistRead?: (version: string) => Checklist;
1049
1053
 
1050
1054
  sessionSlash: {
1051
1055
  /** opts.remote — when the dashboard is attached to a remote daemon. */
@@ -1467,6 +1471,11 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
1467
1471
  ctx.setChatScrollOffset(-1);
1468
1472
  });
1469
1473
 
1474
+ registry.register('board', (args, ctx) => {
1475
+ for (const line of checklistBoardSlash(args, ctx.checklistRead).split('\n')) ctx.pushChatLine(line);
1476
+ ctx.setChatScrollOffset(-1);
1477
+ });
1478
+
1470
1479
  registry.register('wish', (args, ctx) => {
1471
1480
  const text = args.join(' ').trim();
1472
1481
  if (!text) {
@@ -34,7 +34,9 @@ export function isIrreversible(entry: Pick<DecisionEntry, 'category'>): boolean
34
34
  return IRREVERSIBLE.has(entry.category);
35
35
  }
36
36
 
37
- const kst = (at: string) => new Intl.DateTimeFormat('ko-KR', { timeZone: 'Asia/Seoul', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(at));
37
+ const kst = (at: string) => Number.isFinite(Date.parse(at))
38
+ ? new Intl.DateTimeFormat('ko-KR', { timeZone: 'Asia/Seoul', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(at))
39
+ : '읽을 수 없음';
38
40
 
39
41
  /** The card opens with a short pitch; the full question and choice buttons remain below it. */
40
42
  export function renderCardText(e: DecisionEntry, extra: { note?: string; confirm?: string } = {}): string {
@@ -101,6 +103,7 @@ interface CardState {
101
103
  * deploy); they stay reachable through `/decisions`. */
102
104
  since?: string;
103
105
  cards: Record<string, { refs: CardRef[]; closed?: boolean; remindedAt?: string; note?: string; attempts?: number; noSubscribers?: boolean }>;
106
+ deferred?: Record<string, true>;
104
107
  testOriginQuestions?: Record<string, true>;
105
108
  }
106
109
 
@@ -113,6 +116,10 @@ export interface DecisionCardServiceOptions {
113
116
  /** Where this platform keeps which card it sent (one file per platform — the two bots may run in different processes). */
114
117
  statePath?: string;
115
118
  now?: () => Date;
119
+ /** Optional gate for new-card delivery. Omit to send every eligible open decision. */
120
+ sendFilter?: (entry: DecisionEntry, now: Date) => boolean;
121
+ /** Label recorded in the `push-deferred` observation when `sendFilter` holds a decision back. */
122
+ deferredReason?: (entry: DecisionEntry, now: Date) => string;
116
123
  /** Tell the seat that raised it. Default: none (observed only). */
117
124
  replyToRaiser?: (entry: DecisionEntry, via: CardPlatform) => Promise<void>;
118
125
  }
@@ -223,6 +230,18 @@ export class DecisionCardService {
223
230
  const card = state.cards[e.id];
224
231
  if (e.status === 'open' && (!card || (platform === 'webpush' && !card.refs.length && (card.attempts ?? 0) < WEBPUSH_MAX_SEND_ATTEMPTS))
225
232
  && e.options.length >= 2 && e.raisedAt !== undefined && e.raisedAt >= state.since) {
233
+ if (this.opts.sendFilter) {
234
+ const now = this.now();
235
+ if (!this.opts.sendFilter(e, now)) {
236
+ if (!state.deferred?.[e.id]) {
237
+ (state.deferred ??= {})[e.id] = true;
238
+ dirty = true;
239
+ debug.log(platform === 'webpush' ? 'decisions.webpush' : 'decisions.telegram', 'push-deferred',
240
+ { ...(platform === 'webpush' ? {} : { platform }), id: e.id, urgency: this.opts.deferredReason?.(e, now) ?? 'filtered' });
241
+ }
242
+ continue;
243
+ }
244
+ }
226
245
  if (platform === 'webpush' && !chats.length) {
227
246
  if (!card?.noSubscribers) {
228
247
  state.cards[e.id] = { ...(card ?? { refs: [] }), noSubscribers: true };
@@ -5,6 +5,8 @@ import { readPendingQuestionAnswer, readPendingQuestions, writePendingQuestionAn
5
5
  import { debug, redactSecretText } from '../debug/log.js';
6
6
  import { createVersionResolver, type VersionOptions, type Versions } from '../directives/version-at.js';
7
7
  import { getUserConfig } from '../user-config.js';
8
+ import { registeredSeats, resolveSeat } from '../seat-address/seat-address.js';
9
+ import { isSeatId } from '../seat-dispatch/seat-questions.js';
8
10
 
9
11
  export type DecisionCategory = 'secret' | 'publish' | 'money' | 'security' | 'scope' | 'irreversible' | 'other';
10
12
  /** Old track letters (S·T·F·O) stay readable; seat names (OP·MK·TC·UX) are the current identities. */
@@ -53,7 +55,8 @@ export class DecisionAnswerDeliveryError extends Error {
53
55
  }
54
56
  }
55
57
  const CATEGORIES: readonly string[] = ['secret', 'publish', 'money', 'security', 'scope', 'irreversible', 'other'];
56
- const TRACKS: readonly string[] = ['S', 'T', 'F', 'O', 'OP', 'MK', 'TC', 'UX'];
58
+ const isDecisionTrack = (value: string): boolean => registeredSeats().some(({ id, alias }) => value === id || value === alias);
59
+ const isRegisteredSeat = (value: string): boolean => isSeatId(value) && resolveSeat(value)?.id === value;
57
60
 
58
61
  function required(value: string, name: string): string {
59
62
  if (typeof value !== 'string' || !value.trim()) throw new Error(`${name} is required`);
@@ -88,7 +91,7 @@ function validate(input: RaiseInput, historical = false): RaiseInput {
88
91
  const title = safe(single(input.title, 'title'));
89
92
  if (!CATEGORIES.includes(input.category)) throw new Error('invalid category');
90
93
  if (!input.raisedBy?.agent) throw new Error('raisedBy.agent is required');
91
- if (input.raisedBy.track && !TRACKS.includes(input.raisedBy.track)) throw new Error('invalid track');
94
+ if (input.raisedBy.track && !isDecisionTrack(input.raisedBy.track)) throw new Error('invalid track');
92
95
  const s = scqaField(input.scqa.s, 's');
93
96
  const c = scqaField(input.scqa.c, 'c');
94
97
  const q = input.scqa.q?.trim() ? scqaField(input.scqa.q, 'q') : undefined;
@@ -117,7 +120,7 @@ function validate(input: RaiseInput, historical = false): RaiseInput {
117
120
  if (input.crossCheck !== undefined && !Array.isArray(input.crossCheck)) throw new Error('cross-check must be a list');
118
121
  const crossCheck = input.crossCheck?.map(check => {
119
122
  const seat = single(check.seat, 'cross-check seat');
120
- if (!['OP', 'MK', 'TC', 'UX'].includes(seat)) throw new Error('invalid cross-check seat');
123
+ if (!isRegisteredSeat(seat)) throw new Error('invalid cross-check seat');
121
124
  return { seat, at: utc(check.at), note: safe(single(check.note, 'cross-check note')) };
122
125
  });
123
126
  const crossCheckSkipped = input.crossCheckSkipped === undefined ? undefined : safe(single(input.crossCheckSkipped, 'cross-check skipped reason'));
@@ -242,7 +245,7 @@ export class DecisionLedger {
242
245
  /** Delegated decisions are already made: they share the append-only ledger, never the owner's open-card state machine. */
243
246
  recordSeatDecision(input: SeatDecisionInput): SeatDecisionRecord {
244
247
  const seat = input.seat;
245
- if (!['OP', 'MK', 'TC', 'UX'].includes(seat)) throw new Error('invalid seat');
248
+ if (!isRegisteredSeat(seat)) throw new Error('invalid seat');
246
249
  const title = safe(single(input.title, 'title'));
247
250
  const decision = safe(single(input.decision, 'decision'));
248
251
  const delegation = safe(single(input.delegation, 'delegation'));
@@ -263,7 +266,7 @@ export class DecisionLedger {
263
266
  }
264
267
  seatReport(filters: { since?: string; seat?: Seat } = {}): SeatDecisionRecord[] {
265
268
  const since = filters.since === undefined ? undefined : utc(filters.since);
266
- if (filters.seat && !['OP', 'MK', 'TC', 'UX'].includes(filters.seat)) throw new Error('invalid seat');
269
+ if (filters.seat && !isRegisteredSeat(filters.seat)) throw new Error('invalid seat');
267
270
  return this.events().filter((event): event is Extract<Event, { type: 'seat-recorded' }> => event.type === 'seat-recorded')
268
271
  .map(event => event.entry)
269
272
  .filter(entry => (!since || (entry.recordedAt ?? entry.decidedAt ?? '') >= since) && (!filters.seat || entry.seat === filters.seat))
@@ -307,7 +310,7 @@ export class DecisionLedger {
307
310
  if (!by || (by.kind !== 'human' && by.kind !== 'auto')) throw new Error('decidedBy is required');
308
311
  if (by.kind === 'auto') {
309
312
  single(by.delegation, 'delegation'); single(by.agent, 'agent');
310
- if (by.track && !TRACKS.includes(by.track)) throw new Error('invalid track');
313
+ if (by.track && !isDecisionTrack(by.track)) throw new Error('invalid track');
311
314
  by = { ...by, agent: safe(single(by.agent, 'agent')), delegation: safe(single(by.delegation, 'delegation')) };
312
315
  }
313
316
  return this.locked(() => {
@@ -424,7 +427,7 @@ export class DecisionLedger {
424
427
  if (choice ? !clean.options.some(o => o.key === choice) : clean.options.length !== 0) throw new Error(`option not found: ${choice}`);
425
428
  if (by.kind === 'auto') {
426
429
  single(by.agent, 'agent'); single(by.delegation, 'delegation');
427
- if (by.track && !TRACKS.includes(by.track)) throw new Error('invalid track');
430
+ if (by.track && !isDecisionTrack(by.track)) throw new Error('invalid track');
428
431
  by = { ...by, agent: safe(single(by.agent, 'agent')), delegation: safe(single(by.delegation, 'delegation')) };
429
432
  }
430
433
  const cleanNote = safe(single(note, 'note'));
@@ -449,7 +452,7 @@ export class DecisionLedger {
449
452
  completeRecorded(id: string, choice: string | undefined, by: DecisionActor, note: string, sourceOptions: DecisionOption[]): DecisionEntry {
450
453
  if (by.kind === 'auto') {
451
454
  single(by.agent, 'agent'); single(by.delegation, 'delegation');
452
- if (by.track && !TRACKS.includes(by.track)) throw new Error('invalid track');
455
+ if (by.track && !isDecisionTrack(by.track)) throw new Error('invalid track');
453
456
  by = { ...by, agent: safe(single(by.agent, 'agent')), delegation: safe(single(by.delegation, 'delegation')) };
454
457
  }
455
458
  const cleanNote = safe(single(note, 'note'));
@@ -1,8 +1,24 @@
1
1
  import { debug } from '../debug/log.js';
2
2
  import { listSubscriptions } from '../web-push/subscriptions.js';
3
3
  import { sendPushToAll } from '../web-push/sender.js';
4
- import { type CardTransport, type CardView } from './decision-cards.js';
5
- import { DecisionLedger } from './decision-ledger.js';
4
+ import { isIrreversible, type CardTransport, type CardView } from './decision-cards.js';
5
+ import { DecisionLedger, type DecisionEntry } from './decision-ledger.js';
6
+
7
+ /** How close a deadline must be for an otherwise reversible decision to ring the phone. */
8
+ export const WEB_PUSH_URGENT_WINDOW_MS = 24 * 3600_000;
9
+
10
+ export type WebPushUrgency = 'irreversible' | 'due-soon' | 'not-urgent' | 'due-unreadable';
11
+
12
+ /** Web push rings only for urgent decisions; an unreadable deadline is its own value (fail open, never folded into not-urgent). */
13
+ export function webPushUrgency(entry: DecisionEntry, now: Date): WebPushUrgency {
14
+ if (isIrreversible(entry)) return 'irreversible';
15
+ if (entry.dueAt !== undefined) {
16
+ const due = Date.parse(entry.dueAt);
17
+ if (!Number.isFinite(due)) return 'due-unreadable';
18
+ if (due - now.getTime() <= WEB_PUSH_URGENT_WINDOW_MS) return 'due-soon';
19
+ }
20
+ return 'not-urgent';
21
+ }
6
22
 
7
23
  const ID_IN_CARD = /^🗳 결정 요청 (D-\d{8}-\d+)(?: ·|\n)/;
8
24
  const ID_IN_REMINDER = /^⏰ 기한 2시간 전 — (D-\d{8}-\d+) /;
@@ -26,7 +42,7 @@ export function webPushDecisionTransport(
26
42
  const entry = ledger.show(id);
27
43
  if (entry.status !== 'open') return null;
28
44
  const recommendation = 'skipped' in entry.recommendation ? '추천안 없음' : `추천안: ${entry.recommendation.option.toUpperCase()}`;
29
- const body = `${recommendation}${entry.dueAt ? ` · 기한: ${new Intl.DateTimeFormat('ko-KR', { timeZone: 'Asia/Seoul', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(entry.dueAt))}` : ''}`;
45
+ const body = `${recommendation}${entry.dueAt ? ` · 기한: ${Number.isFinite(Date.parse(entry.dueAt)) ? new Intl.DateTimeFormat('ko-KR', { timeZone: 'Asia/Seoul', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(entry.dueAt)) : '읽을 수 없음'}` : ''}`;
30
46
  const result = await push({ title: title('대표 결정 · ', entry.title), body, url: url(id), tag: tag(id) });
31
47
  if (result.attempted) debug.log('decisions.webpush', 'card-sent', { id, delivered: result.delivered });
32
48
  return result.delivered ? { chat: 'webpush', message: id } : null;
@@ -64,7 +64,7 @@ import { getUserConfig } from './user-config.js';
64
64
  import { detectCard, runCardFollowup, NotACardError } from './card-followup/core.js';
65
65
  import { localOcrText } from './telegram-card-followup.js';
66
66
  import type { runGraph } from './graph-runner/runner.js';
67
- import { readSlashContextNow, renderTelegramNow } from './context-bus/context-now-surfaces.js';
67
+ import { readSlashContextNow, renderContextFirstNow, renderTelegramNow } from './context-bus/context-now-surfaces.js';
68
68
  import { contextNow, type ContextNowDeps } from './context-bus/context-now.js';
69
69
  import { createContextFirstGate, renderContextFirst } from './context-bus/context-first.js';
70
70
  import { telegramLoopsStatus, type LoopsSources } from './telegram-loops-command.js';
@@ -160,7 +160,7 @@ export function buildDiscordSelfOnMessage(deps: DiscordSelfMessageDeps): DcMessa
160
160
  const maybeSendContextFirst = async (channelId: string): Promise<void> => {
161
161
  if (!contextFirstGate.take(channelId) || cfg.discord?.contextFirst === false) return;
162
162
  try {
163
- await deps.getBot()?.sendMessage(channelId, renderContextFirst(contextNow, deps.nowDeps, renderTelegramNow));
163
+ await deps.getBot()?.sendMessage(channelId, renderContextFirst(contextNow, deps.nowDeps, renderContextFirstNow));
164
164
  } catch (err) {
165
165
  log(`discord context-first failed: ${err instanceof Error ? err.message : String(err)}`);
166
166
  }