elanous 0.2.38 → 0.2.41

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 (712) hide show
  1. package/README.md +7 -7
  2. package/apps/pwa/out/404/index.html +1 -1
  3. package/apps/pwa/out/404.html +1 -1
  4. package/apps/pwa/out/_next/static/{RrjXTwz-urRAbChP1bX02 → GiOLWmt4MqDZePubBjA4Q}/_buildManifest.js +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1115.434ae2ecb0ad986d.js +149 -0
  6. package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +36 -0
  7. package/apps/pwa/out/_next/static/chunks/1178.1aa9cad0e7695427.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/{5203.51e5d8b5f1dcfe53.js → 1219.7e17964e0e7cd8e5.js} +3 -3
  10. package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +287 -0
  11. package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1661.0dd330f3d89f73f3.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +90 -0
  16. package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/{7573.2376e13c9c21f1f8.js → 1765.679b29625c8e88d4.js} +2 -2
  18. package/apps/pwa/out/_next/static/chunks/{3528.e4b8ab70d339f965.js → 1800.f7ff51dc4978a958.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/1971-7efb628c471dc5a0.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2073.689dcb2680113d76.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{8879.ac06755bcf3e44a1.js → 2263.e09b6edea33bad2d.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2527-5c636a43c7cc5dde.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2743.5d3f76948be32b34.js +41 -0
  31. package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +32 -0
  32. package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/{9fe1b809.738da85c8b17e3fb.js → 2fdf2931.b431eee4fb468bc3.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/{eaad0cba.771200940c529df7.js → 2fe2c302.41b517f88d6fe502.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +79 -0
  36. package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3230-49298c3b73ef2268.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +74 -0
  41. package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{b7478fef.5917716286213fcc.js → 385e4574.e9886ab32759eda3.js} +3 -3
  46. package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4133.2056bb4d78f621af.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +148 -0
  53. package/apps/pwa/out/_next/static/chunks/{8911.bf5e712acb25fb6c.js → 4527.a69f2894d1bc9f4a.js} +1 -1
  54. package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +226 -0
  55. package/apps/pwa/out/_next/static/chunks/{5307.d7328020227880c2.js → 4667.97e31aa38c95c475.js} +4 -4
  56. package/apps/pwa/out/_next/static/chunks/{6142.913b44e260a3f925.js → 4702.4a4adc1f16d7c93b.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +94 -0
  64. package/apps/pwa/out/_next/static/chunks/{8487.291666583bebe640.js → 5159.115f1c2ca471386c.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/530.d26346e18089640a.js +115 -0
  67. package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +8 -0
  68. package/apps/pwa/out/_next/static/chunks/{89d6c04f-6b8ab341748e468a.js → 53aeb4ee-51c92f8d683f5220.js} +1 -1
  69. package/apps/pwa/out/_next/static/chunks/{3291.f6c1005387d514bd.js → 5471.1e611302ed3a7c53.js} +2 -2
  70. package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/{3086.fb14b60ce98b53d3.js → 5574.f35accf4f132b29d.js} +1 -1
  73. package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +24 -0
  74. package/apps/pwa/out/_next/static/chunks/{1632.7d87f998e714bede.js → 5744.b9415e18ad623100.js} +1 -1
  75. package/apps/pwa/out/_next/static/chunks/{5300.677c97e0393742e6.js → 5892.2526d962339662d8.js} +1 -1
  76. package/apps/pwa/out/_next/static/chunks/5937.c2df9e3447e1f667.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +286 -0
  78. package/apps/pwa/out/_next/static/chunks/{7161-8f22db3ec5ed005e.js → 5947-135e26537d80a6b9.js} +3 -3
  79. package/apps/pwa/out/_next/static/chunks/{3124-561f7f037943cde2.js → 5964-7e21164a8f2cf0ce.js} +1 -1
  80. package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +27 -0
  84. package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/6552.a3840aa7da35ad68.js +62 -0
  86. package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +24 -0
  87. package/apps/pwa/out/_next/static/chunks/6874.d5cf7eb8edb2cabe.js +2 -0
  88. package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +122 -0
  90. package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{2415.738b777642a02233.js → 7191.fdc955f7d96064a4.js} +1 -1
  93. package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{1026-44010f405704050c.js → 8050-9b364bdef8f71927.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/83184dcd-0ee6247ff41eb3f2.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +104 -0
  103. package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{5638.107314dc479e2f37.js → 9048.212083de42d25be3.js} +2 -2
  110. package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{8019.21ca554a821dad01.js → 9507.7026657a2f47eb64.js} +16 -16
  117. package/apps/pwa/out/_next/static/chunks/9541.eb8e2f8480c7feca.js +93 -0
  118. package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +34 -0
  123. package/apps/pwa/out/_next/static/chunks/{6493.27ad77de7aac7966.js → 9834.63ab2bbc3153172e.js} +1 -1
  124. package/apps/pwa/out/_next/static/chunks/{3389.012c70767a872f9b.js → 9869.81a1e24ca682d5a0.js} +1 -1
  125. package/apps/pwa/out/_next/static/chunks/{8994d93e.33ba491f95345fc2.js → a0a01613.6d1cca322238d7fe.js} +1 -1
  126. package/apps/pwa/out/_next/static/chunks/{de8b930d.d94c0f42acf807fc.js → addc2b32.8c4ff8f0aefe987d.js} +1 -1
  127. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-866aac5ff226a7f3.js → page-14949db884bfa672.js} +1 -1
  132. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-40f9e19149024298.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a142dfb0331a05f5.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/b2271e54.c1de3347976e90b0.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/{b7459770.6539b11860eb8a9c.js → c0c1a699.0ba79f97005965d4.js} +7 -7
  180. package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +1 -0
  185. package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +1 -0
  186. package/apps/pwa/out/approvals/index.html +1 -1
  187. package/apps/pwa/out/approvals/index.txt +22 -22
  188. package/apps/pwa/out/autopilot/index.html +1 -1
  189. package/apps/pwa/out/autopilot/index.txt +22 -22
  190. package/apps/pwa/out/board/index.html +1 -1
  191. package/apps/pwa/out/board/index.txt +22 -22
  192. package/apps/pwa/out/botlab/index.html +1 -1
  193. package/apps/pwa/out/botlab/index.txt +21 -21
  194. package/apps/pwa/out/bots/index.html +1 -1
  195. package/apps/pwa/out/bots/index.txt +21 -21
  196. package/apps/pwa/out/ceo/index.html +1 -1
  197. package/apps/pwa/out/ceo/index.txt +22 -22
  198. package/apps/pwa/out/chat/index.html +1 -1
  199. package/apps/pwa/out/chat/index.txt +21 -21
  200. package/apps/pwa/out/consult/index.html +1 -1
  201. package/apps/pwa/out/consult/index.txt +22 -22
  202. package/apps/pwa/out/control/index.html +1 -1
  203. package/apps/pwa/out/control/index.txt +22 -22
  204. package/apps/pwa/out/decisions/index.html +1 -1
  205. package/apps/pwa/out/decisions/index.txt +21 -21
  206. package/apps/pwa/out/design-check/index.html +1 -1
  207. package/apps/pwa/out/design-check/index.txt +22 -22
  208. package/apps/pwa/out/editor/index.html +1 -1
  209. package/apps/pwa/out/editor/index.txt +22 -22
  210. package/apps/pwa/out/exec/index.html +1 -1
  211. package/apps/pwa/out/exec/index.txt +22 -22
  212. package/apps/pwa/out/field/index.html +1 -1
  213. package/apps/pwa/out/field/index.txt +22 -22
  214. package/apps/pwa/out/healthz +1 -1
  215. package/apps/pwa/out/index.html +1 -1
  216. package/apps/pwa/out/index.txt +21 -21
  217. package/apps/pwa/out/inside/index.html +1 -1
  218. package/apps/pwa/out/inside/index.txt +21 -21
  219. package/apps/pwa/out/intake/index.html +1 -1
  220. package/apps/pwa/out/intake/index.txt +22 -22
  221. package/apps/pwa/out/live/index.html +1 -1
  222. package/apps/pwa/out/live/index.txt +22 -22
  223. package/apps/pwa/out/live-run/index.html +1 -1
  224. package/apps/pwa/out/live-run/index.txt +22 -22
  225. package/apps/pwa/out/loops/index.html +1 -1
  226. package/apps/pwa/out/loops/index.txt +21 -21
  227. package/apps/pwa/out/market/index.html +1 -1
  228. package/apps/pwa/out/market/index.txt +21 -21
  229. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  230. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  231. package/apps/pwa/out/morning/index.html +1 -1
  232. package/apps/pwa/out/morning/index.txt +22 -22
  233. package/apps/pwa/out/observatory/index.html +1 -1
  234. package/apps/pwa/out/observatory/index.txt +22 -22
  235. package/apps/pwa/out/ops/checklist/index.html +1 -1
  236. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  237. package/apps/pwa/out/ops/release/index.html +1 -1
  238. package/apps/pwa/out/ops/release/index.txt +21 -21
  239. package/apps/pwa/out/ops/seats/index.html +1 -1
  240. package/apps/pwa/out/ops/seats/index.txt +21 -21
  241. package/apps/pwa/out/outputs/index.html +1 -1
  242. package/apps/pwa/out/outputs/index.txt +21 -21
  243. package/apps/pwa/out/reflection/index.html +1 -1
  244. package/apps/pwa/out/reflection/index.txt +22 -22
  245. package/apps/pwa/out/scheduler/index.html +1 -1
  246. package/apps/pwa/out/scheduler/index.txt +22 -22
  247. package/apps/pwa/out/sessions/index.html +1 -1
  248. package/apps/pwa/out/sessions/index.txt +21 -21
  249. package/apps/pwa/out/settings/devices/index.html +1 -1
  250. package/apps/pwa/out/settings/devices/index.txt +22 -22
  251. package/apps/pwa/out/settings/index.html +1 -1
  252. package/apps/pwa/out/settings/index.txt +22 -22
  253. package/apps/pwa/out/setup/done/index.html +1 -1
  254. package/apps/pwa/out/setup/done/index.txt +22 -22
  255. package/apps/pwa/out/setup/index.html +1 -1
  256. package/apps/pwa/out/setup/index.txt +22 -22
  257. package/apps/pwa/out/share/index.html +1 -1
  258. package/apps/pwa/out/share/index.txt +22 -22
  259. package/apps/pwa/out/showroom/index.html +1 -1
  260. package/apps/pwa/out/showroom/index.txt +21 -21
  261. package/apps/pwa/out/tasks/index.html +1 -1
  262. package/apps/pwa/out/tasks/index.txt +22 -22
  263. package/apps/pwa/out/term/index.html +1 -1
  264. package/apps/pwa/out/term/index.txt +22 -22
  265. package/apps/pwa/out/today/index.html +1 -1
  266. package/apps/pwa/out/today/index.txt +22 -22
  267. package/apps/pwa/out/trace/index.html +1 -1
  268. package/apps/pwa/out/trace/index.txt +22 -22
  269. package/apps/pwa/out/vault/index.html +1 -1
  270. package/apps/pwa/out/vault/index.txt +22 -22
  271. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  272. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  273. package/apps/pwa/out/workflows/index.html +1 -1
  274. package/apps/pwa/out/workflows/index.txt +22 -22
  275. package/apps/pwa/out/workspace/index.html +1 -1
  276. package/apps/pwa/out/workspace/index.txt +22 -22
  277. package/apps/pwa/out/worktrees/index.html +1 -1
  278. package/apps/pwa/out/worktrees/index.txt +22 -22
  279. package/bin/elanous.mjs +6 -1
  280. package/catalog/models/openai/gpt-6.1-sol.yaml +16 -0
  281. package/catalog/models/openai/gpt-6.1-terra.yaml +16 -0
  282. package/graphs/demo/persona-marketer/fixtures/marketer-scenario.yaml +10 -0
  283. package/graphs/demo/persona-marketer/persona-marketer.yaml +25 -0
  284. package/graphs/demo/persona-marketer/recipes.yaml +19 -0
  285. package/graphs/demo/persona-teacher/lesson-pack.yaml +16 -0
  286. package/graphs/demo/persona-teacher/recipes.yaml +17 -0
  287. package/graphs/demo/persona-teacher/weekly-lesson.yaml +36 -0
  288. package/graphs/overlays/stop-heal-ladder.yaml +23 -2
  289. package/graphs/release/release-loop.yaml +3 -1
  290. package/graphs/units/gate/gate.yaml +20 -0
  291. package/graphs/units/git/git.yaml +26 -0
  292. package/graphs/units/implement/implement.yaml +19 -0
  293. package/graphs/units/landing/landing.yaml +18 -0
  294. package/graphs/units/review/review.yaml +20 -0
  295. package/graphs/units/verbs/recipes.yaml +3 -0
  296. package/graphs/units/verbs/research.yaml +20 -0
  297. package/graphs/video/explainer-line.yaml +4 -1
  298. package/graphs/work/research-report.yaml +11 -1
  299. package/package.json +1 -1
  300. package/scripts/dead-code/report.ts +169 -0
  301. package/scripts/disk-steward.ts +46 -0
  302. package/scripts/fleet/node-setup.sh +50 -0
  303. package/scripts/graph-units/verbs/research.ts +55 -0
  304. package/scripts/lib/morning-report-options.ts +3 -4
  305. package/scripts/lib/tui-regress-evidence.ts +56 -0
  306. package/scripts/llm-cost-ledger.ts +179 -8
  307. package/scripts/measure-nl-routing-corpus.ts +10 -2
  308. package/scripts/morning-report.ts +5 -1
  309. package/scripts/persona-teacher/weekly-lesson-node.ts +172 -0
  310. package/scripts/public-copy-lint.ts +163 -19
  311. package/scripts/public-export.ts +15 -7
  312. package/scripts/ratchets/train-side-invariants.sh +0 -1
  313. package/scripts/release-loop/export-check-node.ts +21 -3
  314. package/scripts/release-loop/gate-autoheal.ts +117 -0
  315. package/scripts/release-loop/gate-baseline-receipt.ts +8 -1
  316. package/scripts/release-loop/gate-diff.ts +22 -3
  317. package/scripts/release-loop/gate-node.ts +583 -64
  318. package/scripts/release-loop/gate-shard-dispatch.ts +128 -0
  319. package/scripts/release-loop/gate-shard-load-flaky.ts +256 -0
  320. package/scripts/release-loop/gate-shard-receipts.ts +89 -0
  321. package/scripts/release-loop/gate-triage-node.ts +70 -10
  322. package/scripts/release-loop/gate-wall.ts +5 -5
  323. package/scripts/release-loop/preflight.ts +6 -2
  324. package/scripts/release-loop/resume-release.ts +267 -20
  325. package/scripts/release-loop/resume.ts +48 -0
  326. package/scripts/release-loop/traffic-node.ts +6 -3
  327. package/scripts/release-loop/unattended-release.ts +4 -2
  328. package/scripts/release-loop/version-node.ts +7 -2
  329. package/scripts/release-story/draft.ts +1 -1
  330. package/scripts/research-bench/README.md +53 -0
  331. package/scripts/research-bench/questions.json +66 -0
  332. package/scripts/research-bench/rubric.md +33 -0
  333. package/scripts/research-bench/run.ts +523 -0
  334. package/scripts/shadow-authoring-probe.ts +20 -0
  335. package/scripts/tui-regress.ts +85 -10
  336. package/scripts/ux-sim.ts +19 -2
  337. package/src/acp/core-turn-bridge.ts +94 -4
  338. package/src/agent/autonomous-tools.ts +10 -3
  339. package/src/agent/monad-agent-turn.ts +4 -1
  340. package/src/agent/registry.ts +26 -2
  341. package/src/agent/shared-app-tools.ts +1 -1
  342. package/src/agent/surface-ux/build.ts +12 -3
  343. package/src/agent/surface-ux/types.ts +1 -1
  344. package/src/agent/task-notification.ts +75 -6
  345. package/src/agent/types.ts +3 -0
  346. package/src/agent-mission/driver.ts +29 -3
  347. package/src/agent-mission/mission-cli.ts +2 -1
  348. package/src/agent-substrate/review-context-pack.ts +365 -0
  349. package/src/agent-substrate/self-review-cli.ts +291 -20
  350. package/src/ask-user-question/index.ts +6 -0
  351. package/src/ask-user-question/inline-resolver.ts +49 -0
  352. package/src/auto-research/question-ladder-contract.ts +22 -3
  353. package/src/auto-research/research-turn.ts +359 -17
  354. package/src/autopilot/agent-loop.ts +1 -1
  355. package/src/autopilot/discovery/wiki-claim-proposer.ts +22 -1
  356. package/src/autopilot/pty-control-loop.ts +8 -1
  357. package/src/boot/daemon-tools/index.ts +4 -3
  358. package/src/boot/daemon-tools/self-implement.ts +312 -7
  359. package/src/boot/daemon-tools/types.ts +2 -0
  360. package/src/budget/llm-cost.ts +44 -5
  361. package/src/budget/shadow-arms.ts +52 -0
  362. package/src/budget/unified-usage.ts +17 -1
  363. package/src/capture/tui-self-report.ts +14 -0
  364. package/src/chat/index.ts +33 -7
  365. package/src/chat/pickers/state.ts +7 -1
  366. package/src/cli/agent-cli.ts +43 -8
  367. package/src/cli/intake-cli.ts +22 -1
  368. package/src/cli/lesson-cli.ts +19 -3
  369. package/src/cli/log-event-names.ts +6 -0
  370. package/src/cli/mcp-login.ts +8 -18
  371. package/src/cli/msg-cli.ts +57 -1
  372. package/src/cli/pod-cli.ts +17 -2
  373. package/src/cli/pr-land-heavy-remote.ts +15 -9
  374. package/src/cli/pty-takeover-cli.ts +67 -7
  375. package/src/cli/release-cli.ts +79 -7
  376. package/src/cli/repo-cli.ts +2 -1
  377. package/src/cli/sim-cli.ts +7 -1
  378. package/src/cli/tasks-cli.ts +41 -13
  379. package/src/codex/models.ts +30 -15
  380. package/src/control-plane/ledger.ts +21 -4
  381. package/src/core-turn/run-core-turn.ts +47 -3
  382. package/src/core-turn/run-goal-loop.ts +240 -10
  383. package/src/core-turn/types.ts +9 -0
  384. package/src/dashboard/acp-boot.ts +72 -3
  385. package/src/dashboard/chat/acp-chat.ts +2 -2
  386. package/src/dashboard/classic-sigquit.ts +16 -0
  387. package/src/dashboard/index.ts +327 -27
  388. package/src/dashboard/input/chat-main-interaction-opts.ts +3 -0
  389. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +7 -2
  390. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  391. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  392. package/src/dashboard/input/dashboard-priority-key-route.ts +21 -5
  393. package/src/dashboard/input/external-input-host.ts +2 -0
  394. package/src/dashboard/sidetab-runtime.ts +228 -0
  395. package/src/dashboard/slash-runtime/ask-clarification.ts +7 -1
  396. package/src/dashboard/slash-runtime/dashboard-handlers.ts +20 -8
  397. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -2
  398. package/src/dashboard/term-slash-runtime.ts +16 -18
  399. package/src/dashboard/turn-preamble.ts +14 -1
  400. package/src/disk-steward/judge.ts +73 -0
  401. package/src/disk-steward/ledger.ts +122 -0
  402. package/src/disk-steward/steward.ts +373 -0
  403. package/src/domains/guardian-tick.ts +191 -2
  404. package/src/domains/knowledge.ts +1 -1
  405. package/src/esc-abort-gate.ts +33 -1
  406. package/src/execution-loop/launch-gate.ts +206 -1
  407. package/src/graph-runner/graph-cli.ts +27 -4
  408. package/src/graph-runner/in-process-registry.ts +37 -0
  409. package/src/graph-runner/runner.ts +63 -11
  410. package/src/graph-wizard/generate.ts +16 -7
  411. package/src/graph-wizard/mission-compose.ts +201 -0
  412. package/src/grok/agent-search.ts +8 -2
  413. package/src/grok/credential.ts +5 -0
  414. package/src/grounding/ref-index.ts +30 -0
  415. package/src/grounding/ref-vector.ts +61 -0
  416. package/src/grounding/sources-cli.ts +11 -3
  417. package/src/grounding/sources.ts +15 -1
  418. package/src/harness/harness-cli-command.ts +305 -23
  419. package/src/harness/harness-incidents.ts +312 -7
  420. package/src/harness/harness-pod-dispatch.ts +7 -1
  421. package/src/harness/harness-space.ts +15 -1
  422. package/src/harness/progress-worker-entry.ts +59 -0
  423. package/src/harness/progress-worker-runtime.ts +11 -0
  424. package/src/index.ts +35 -5
  425. package/src/input/external-input-queue.ts +10 -0
  426. package/src/instance/dev-project.ts +25 -0
  427. package/src/intake-plane/collect-telegram-saved.ts +36 -1
  428. package/src/intake-plane/intake-to-tasks.ts +246 -3
  429. package/src/intelligence-map/model-alias.ts +6 -5
  430. package/src/intelligence-map/model-catalog.ts +59 -2
  431. package/src/lessons/friction-ledger.ts +154 -0
  432. package/src/live-supply/collector.ts +149 -0
  433. package/src/live-supply/probes.ts +52 -0
  434. package/src/live-supply/snapshot.ts +40 -0
  435. package/src/llm/model-defaults.ts +4 -4
  436. package/src/llm.ts +473 -87
  437. package/src/loops/orchestrator/tick.ts +56 -0
  438. package/src/mcp/mcp-oauth.ts +3 -1
  439. package/src/model-tier/llm-tier-map.ts +9 -9
  440. package/src/model-tier/turn-tier.ts +1 -1
  441. package/src/msg/msg-mirror-github.ts +80 -0
  442. package/src/msg/msg-mirror-policy.ts +61 -0
  443. package/src/msg/msg-mirror-runner.ts +219 -0
  444. package/src/msg/msg-mirror-state.ts +33 -0
  445. package/src/msg/msg-store.ts +11 -0
  446. package/src/nexus/api/harness-api.ts +2 -1
  447. package/src/output-truncation.ts +41 -12
  448. package/src/project/project-store.ts +48 -1
  449. package/src/pty/snapshot.py +132 -0
  450. package/src/pty-shell/pty-control-ipc.ts +29 -2
  451. package/src/pty-shell/pty-manifest.ts +59 -3
  452. package/src/pty-shell/registry.ts +2 -0
  453. package/src/pty-shell/tui-run-state.ts +80 -3
  454. package/src/release-loop/gate-host-reservation.ts +157 -4
  455. package/src/release-loop/gate-shard-ledger.ts +68 -0
  456. package/src/release-loop/merged-pr-checklist.ts +25 -2
  457. package/src/release-loop/rehearsal-shard-plan.ts +6 -1
  458. package/src/release-loop/rehearsal.ts +27 -0
  459. package/src/release-loop/release-schedule.ts +90 -1
  460. package/src/research/bloom-exemplars.ts +135 -0
  461. package/src/research/edge-decision.ts +124 -15
  462. package/src/research/gap-followup.ts +249 -0
  463. package/src/research/lenses/counter-evidence.ts +100 -0
  464. package/src/research/lenses/working-backwards.ts +89 -0
  465. package/src/research/plugin-discovery.ts +242 -0
  466. package/src/research-bridge/invoke.ts +4 -2
  467. package/src/research-bridge/types.ts +2 -0
  468. package/src/self-dev/ask-launch-flow.ts +73 -131
  469. package/src/self-dev/dev-cli.ts +19 -17
  470. package/src/self-dev/dev-pipeline.ts +8 -4
  471. package/src/self-dev/graph-front-nodes.ts +23 -0
  472. package/src/self-dev/graph-journey-route.ts +10 -2
  473. package/src/self-dev/launch-preflight-text.ts +2 -2
  474. package/src/self-dev/launch-preflight.ts +47 -11
  475. package/src/self-dev/orchestrate-cli.ts +1 -0
  476. package/src/self-dev/orchestrate.ts +15 -0
  477. package/src/self-dev/run-supervisor.ts +204 -3
  478. package/src/self-dev/run-types.ts +3 -0
  479. package/src/self-implement/device-first.ts +8 -2
  480. package/src/self-implement/doctor-visit.ts +76 -58
  481. package/src/self-implement/gate-artifacts.ts +16 -0
  482. package/src/self-implement/gate-baseline.ts +75 -4
  483. package/src/self-implement/gate-cli.ts +368 -30
  484. package/src/self-implement/gate-receipt-registry.ts +180 -0
  485. package/src/self-implement/gate-remote.ts +165 -24
  486. package/src/self-implement/goal-author-clarification.ts +205 -32
  487. package/src/self-implement/goal-author-decompose.ts +24 -15
  488. package/src/self-implement/goal-author.ts +86 -10
  489. package/src/self-implement/graph-stage-units.ts +172 -0
  490. package/src/self-implement/graph-templates.ts +162 -1
  491. package/src/self-implement/graph-variant.ts +37 -4
  492. package/src/self-implement/host-regate.ts +124 -49
  493. package/src/self-implement/impl-findings-feedback.ts +188 -0
  494. package/src/self-implement/knowhow-pack.ts +227 -10
  495. package/src/self-implement/off-diff-evidence.ts +124 -0
  496. package/src/self-implement/orchestrator.ts +320 -28
  497. package/src/self-implement/run-ledger.ts +110 -14
  498. package/src/self-implement/run-stop.ts +33 -2
  499. package/src/self-implement/running-runs.ts +35 -12
  500. package/src/self-implement/seams.ts +6 -3
  501. package/src/self-implement/self-implement-cli.ts +40 -6
  502. package/src/self-implement/stop-autoheal-operational.ts +43 -0
  503. package/src/self-implement/stop-autoheal.ts +15 -6
  504. package/src/session/chat.ts +66 -15
  505. package/src/session/request-size-guard.ts +123 -0
  506. package/src/session-runtime/provider-circuit.ts +140 -0
  507. package/src/shell-runner/file-engine.ts +1 -0
  508. package/src/shell-runner/types.ts +4 -0
  509. package/src/sidetab-core/model.ts +312 -0
  510. package/src/skills/tools/schedule-wakeup.ts +23 -1
  511. package/src/skills/tools/shell.ts +51 -5
  512. package/src/steward/directive-audit.ts +354 -0
  513. package/src/surface/child-process.ts +31 -0
  514. package/src/surface/tui-stderr-owner.ts +48 -0
  515. package/src/task-agent/cover.ts +30 -12
  516. package/src/task-agent/judge.ts +56 -0
  517. package/src/task-agent/parent-host.ts +14 -1
  518. package/src/task-agent/postland-card.ts +35 -2
  519. package/src/task-agent/rejudge-on-head.ts +46 -2
  520. package/src/task-agent/repair-cycle.ts +1 -1
  521. package/src/task-agent/task-hand.ts +133 -25
  522. package/src/task-agent/tier-split.ts +105 -21
  523. package/src/task-orchestrator/surfaces/pod-command-job.ts +330 -2
  524. package/src/task-orchestrator/surfaces/pod-config-snapshot.ts +123 -0
  525. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +70 -2
  526. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +29 -4
  527. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +11 -8
  528. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +1 -1
  529. package/src/task-orchestrator/surfaces/pod-source-receive.ts +74 -6
  530. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +2 -1
  531. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +56 -15
  532. package/src/task-orchestrator/surfaces/self-implement-pod.ts +298 -45
  533. package/src/task-orchestrator/surfaces/self-implement.ts +18 -0
  534. package/src/tool-runtime/skill-exec-runtime.ts +95 -5
  535. package/src/tui/entry.ts +25 -5
  536. package/src/tui/inline-choice.ts +188 -0
  537. package/src/tui/sidetab/list.ts +36 -165
  538. package/src/tui/sidetab/nl-tool.ts +2 -136
  539. package/src/tui/sidetab/peek.ts +52 -0
  540. package/src/tui/slash/term.ts +12 -1
  541. package/src/tui-client/dashboard-session.ts +10 -1
  542. package/src/user-config.ts +45 -9
  543. package/src/ux-sim/classic-tui-seat-scenarios.ts +1 -7
  544. package/src/ux-sim/fake-land-queue.ts +88 -0
  545. package/src/ux-sim/fault-needs-human-reason-repair.ts +107 -0
  546. package/src/ux-sim/fault-pod-child-result.ts +42 -0
  547. package/src/ux-sim/gate-shard-host-reroute.ts +82 -0
  548. package/src/ux-sim/goal-interim-trace.ts +24 -0
  549. package/src/ux-sim/next-tui-seat-scenarios.ts +8 -13
  550. package/src/ux-sim/release-sim-rig.ts +262 -0
  551. package/src/ux-sim/seminar-rehearsal.ts +109 -0
  552. package/src/ux-sim/subagent-tools-device.ts +2 -2
  553. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +4 -1
  554. package/src/version/packed-revision.json +1 -1
  555. package/src/video-pipeline/recipes/explainer.ts +54 -2
  556. package/src/web-search/grok.ts +32 -6
  557. package/src/web-search/index.ts +8 -7
  558. package/src/workflow-runtime/node-catalog.ts +53 -4
  559. package/apps/pwa/out/_next/static/chunks/1118.a8a74ea29aac3e46.js +0 -27
  560. package/apps/pwa/out/_next/static/chunks/1204-2aa830479adf80f4.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/1341-43b7d2dc77d45c9d.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/1440-c3ea8882badfd9bf.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/1698-9c11cbf97f13717e.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/1770-3b1fc92253ef9f2f.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/1923-5c1695332240246a.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/1938.0e6c60ee91c4d7f5.js +0 -148
  567. package/apps/pwa/out/_next/static/chunks/2104.70e086d5174a4736.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/213-20675f20673ba22a.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/214.186a430da28338f1.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/2277.3bd4c0ac7f1b5996.js +0 -93
  571. package/apps/pwa/out/_next/static/chunks/240.e09f433f71c78ff4.js +0 -104
  572. package/apps/pwa/out/_next/static/chunks/2417.02151393605a7cd0.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/2463.cd2641a76daaa9ff.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/2576.b9e9c629c4b84c52.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/265-c021de53f0865bd9.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/2998-b1cc13956cd6a6e7.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/2e4782d3.ba2f0ab2b63a53e7.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/3130.626b54382b4dc379.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/3221-1bb3f99a55088613.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/3280.24edb1ffd03a7f3f.js +0 -24
  581. package/apps/pwa/out/_next/static/chunks/3288-eb3c22a1cbf2ae68.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/33.ef99e8374f96c6c4.js +0 -36
  583. package/apps/pwa/out/_next/static/chunks/3341-f09b9efbd7a82f70.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/3410-d7c0f14b329d6fda.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/3421.c87d6313a7d670f7.js +0 -287
  586. package/apps/pwa/out/_next/static/chunks/3422-83a3953f9bd67e26.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/3587-002e24e368c515a9.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/3644.f12a7d821ab940af.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3660.d7516588e2d875c3.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3695.b82e2610f4cd4ea9.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/3858.ca1f5bc0f577eac9.js +0 -94
  592. package/apps/pwa/out/_next/static/chunks/3959-e6ac4a139d9d4bcc.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/3f0de3de-2340c532c00395db.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/4032.53f62176514ec0ea.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/4199-f7c6eb40cd0322f8.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4204-ef8484cbecd5d62f.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4259-163129ca79913c4b.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/428-eaa77df3d0c85969.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/4432-97e400ffa1e161f5.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/449-aa427cf2cbb75f50.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/4491-39a0fd32bbaf3840.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/4588.b7cf06d382953979.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/4690.70ec8060825366ab.js +0 -32
  604. package/apps/pwa/out/_next/static/chunks/4804.6012b5cd33c22792.js +0 -90
  605. package/apps/pwa/out/_next/static/chunks/4881.e4d22d730e3b9df5.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/4937.ce2e340dc29cad3e.js +0 -79
  607. package/apps/pwa/out/_next/static/chunks/5-bb1c08d84bd71df3.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/5005.de98df23b37cdf3c.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/5035.dc64a89cad5573cc.js +0 -74
  610. package/apps/pwa/out/_next/static/chunks/5041-5aada92ca215ffdd.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/5207.1a224035455790fd.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/5255-1b60d50eabe9f057.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/5269.d0436ee6d773382a.js +0 -286
  614. package/apps/pwa/out/_next/static/chunks/5309.3367c4d50f52b489.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/552-689827d49780fa00.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/5539.34cc9d60622cb69b.js +0 -8
  617. package/apps/pwa/out/_next/static/chunks/5568.218dea0c00ca2ec7.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/5645.b7e3b055455a04ea.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/5662.18cc0f30353cbd96.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/5671.da24fc9dc5e98325.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/5b141171.324c40fd49cb6821.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/6175-d4621f6a10b0cfab.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/6290.3eb53a20746b72ce.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/6415-9307f3eafa90837f.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/6579-3de35d00aacd71b5.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/680-2f324c4e039a5b67.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/6845-331b3c7481da3ba3.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/7000.28157393caaf5343.js +0 -62
  629. package/apps/pwa/out/_next/static/chunks/7311-60a7ea80d23c7521.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/7401.525d0a12f7d02c06.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/7438.c2cf72b66dca6aa4.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/7488.966b116789f3d41a.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7524.ce973525d30b3d52.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/7577.ea6e9ac72e035520.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/7628.6b16863ac3972333.js +0 -34
  636. package/apps/pwa/out/_next/static/chunks/7657.8d1fb3d2f7ebe273.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/7903-1435d5d2f0dd7807.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/7954.4f7a8832663ee979.js +0 -115
  639. package/apps/pwa/out/_next/static/chunks/7978-30a91192c5dbe3c2.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/8025-8795821525cf1a07.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8191.3674a00f0b565c23.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/8217-604955d8885c5ef2.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/8298-eed6f5f2585a63f4.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/8509.3a54d4e61893d7cb.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/8758.ac421f726a189125.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/891.d6c723a51a067b36.js +0 -149
  647. package/apps/pwa/out/_next/static/chunks/9223.cbcc88e0e9950426.js +0 -41
  648. package/apps/pwa/out/_next/static/chunks/9299.24e2a7d9b6d1f91b.js +0 -226
  649. package/apps/pwa/out/_next/static/chunks/9317.6a9869039c231bb3.js +0 -24
  650. package/apps/pwa/out/_next/static/chunks/9383.e4755f275b3c11ff.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/9581.da63ddf41acfad46.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/9715.8c5529a0a5c41a36.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/9817.3009d65f0889ef1f.js +0 -2
  654. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76873dd80da4f715.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed32b6ec5dea8f23.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-fdd40e15babf3d25.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/board/page-384efc78e85e400b.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/bots/page-d91809c5aeed319a.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/ceo/page-128f3522f89a81ab.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/chat/page-595961abf3b43ad1.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/consult/page-f41dccb76d8c0263.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/control/page-a3205c2e28b7d0d9.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c39a80277814a3f4.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/design-check/page-1ab3f98194513195.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/editor/page-a5246f7e254d77d0.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/exec/page-0f92287bdb81217d.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/field/page-5a37131ff63793ef.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76873dd80da4f715.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/inside/page-ac4bd14bb2348bfd.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/intake/page-c348a3959c5b5fc6.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/layout-2addd81c0d3e2906.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/live/page-da6b765f58a3eefb.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0661e40f8780c32c.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/loops/page-b89af1b1c8e4875b.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/market/page-da8aeb82ba751cdb.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-cc71317b239439db.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/morning/page-bde7fc1d64ffe369.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/not-found-e2797214f713fa58.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/observatory/page-2a35bcda70defaf6.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3af03deedde45032.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d1d1210f99f620ae.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-46d1b5500885861d.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/outputs/page-291ab19fe2acb173.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/page-7f569e533ddeecba.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/reflection/page-990129c9fee46d8f.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-7737f785ebb1cdaf.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f3c73a4f7ffd2f8.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-03be7fb347f01058.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/settings/page-96b0280625e4df2b.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-56855545049eb56d.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76873dd80da4f715.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/setup/page-79a909c9981f0338.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/share/page-a9d9a3e66459c1e0.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c383cbf2013f7069.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f57c6a2e54dbdca4.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/term/page-6b140f77593576eb.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/today/page-6b767ae2d9d0adfc.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/trace/page-116d6198d5da0e3d.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/vault/page-b9c9b778c7501370.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-a6c78392ab8f6335.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/workflows/page-455183deb4ed0cfe.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6a63e99526bd63d0.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-31c22caafe788c08.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/bb6987f9.3647e1a23b0e3217.js +0 -122
  705. package/apps/pwa/out/_next/static/chunks/framework-4b12a946f352cee2.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/main-941155250ed2644b.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/main-app-f8b6765abed6d149.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/pages/_app-78432194c85388f9.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/pages/_error-cdf7390829512b1b.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/webpack-d5f0964a9c2e92d2.js +0 -1
  711. package/scripts/ratchets/next-tui-entry-budget.ts +0 -124
  712. /package/apps/pwa/out/_next/static/{RrjXTwz-urRAbChP1bX02 → GiOLWmt4MqDZePubBjA4Q}/_ssgManifest.js +0 -0
@@ -13,7 +13,9 @@
13
13
  // - onProgress ← ux.progress (각 스테이지 진행을 서피스로).
14
14
  // - 큰 gate log → ux.spillFile (파일 첨부).
15
15
 
16
- import { basename } from 'node:path';
16
+ import { basename, isAbsolute, join, relative, resolve, sep } from 'node:path';
17
+ import { createHash, randomUUID } from 'node:crypto';
18
+ import { existsSync, linkSync, mkdirSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from 'node:fs';
17
19
  import type { LLMToolSpec } from '../../llm.js';
18
20
  import { childLifetimeSignal } from '../../turn-abort-scope.js';
19
21
  import { buildSelfImplementSpec } from '../../self-implement/self-implement-runtime.js';
@@ -25,7 +27,13 @@ import type { SurfaceUx } from '../../agent/surface-ux/types.js';
25
27
  import { resolveAutoOpenPrDecision } from '../../self-implement/auto-open-pr.js';
26
28
  import { resolveObserveOnlyDecision, _setObserveOnlyConfigReaderForTesting as _setSharedObserveOnlyReaderForTesting } from '../../self-implement/observe-only.js';
27
29
  import { debug } from '../../debug/log.js';
30
+ import { globalAgentRegistry, type AgentRegistry } from '../../agent/registry.js';
31
+ import type { TaskNotificationQueue } from '../../agent/task-notification.js';
32
+ import { effectiveInstanceRoot } from '../../instance/resolve.js';
28
33
  import { writeAuthoredGoal } from '../../self-implement/goal-author.js';
34
+ import { selfAnswerOrAssumeGoalDocumentClarifications, type GoalClarificationSelfResolver } from '../../self-implement/goal-author-clarification.js';
35
+ import { writeGoalDocumentAtomic } from '../../self-implement/goal-document-write.js';
36
+ import { DecisionLedger } from '../../decisions/decision-ledger.js';
29
37
  import { createGoalAuthorDecomposeSteps, readRecentStepCountsFailOpen, readRecentStepCountsFromLogStore, type RecentStepCountReader } from '../../self-implement/goal-author-decompose.js';
30
38
  import type { DaemonToolDispatchCtx } from './types.js';
31
39
 
@@ -40,7 +48,13 @@ export function resolveDispatchEntry(ctx: DaemonToolDispatchCtx): import('../../
40
48
 
41
49
  /** 데몬 서피스용 스펙 — 내부 툴과 단일 출처(buildSelfImplementSpec) 공유. */
42
50
  export function buildSelfImplementDaemonSpec(): LLMToolSpec {
43
- return buildSelfImplementSpec();
51
+ const spec = buildSelfImplementSpec();
52
+ const properties = spec.parameters.properties as Record<string, Record<string, unknown>>;
53
+ properties.goalFile = {
54
+ type: 'string',
55
+ description: '기존 SelfImplement 골 문서를 재개할 때만 지정한다. 문서에 결정을 반영한 뒤 같은 골을 다시 실행하며, 저장소 내부 GOAL-* 문서 경로만 허용된다.',
56
+ };
57
+ return spec;
44
58
  }
45
59
 
46
60
  // ⭐ 판정은 `../../self-implement/observe-only.js` **한 자리**가 한다 — 이 스위치를 타는 경로가
@@ -82,7 +96,7 @@ const END_STAGES: readonly SelfImplementProgressStage[] = ['pr-opened', 'aborted
82
96
  export type SelfImplementLaunchedToolResult = SelfImplementResult & { runId: string; kind: 'launched'; message: string; next: string; missing: string[] };
83
97
  export type SelfImplementPendingToolResult = Partial<SelfImplementResult> & { kind: 'pending'; message: string; next: string; missing: string[] };
84
98
  export type SelfImplementObservedOnlyToolResult = { kind: 'observed-only'; observed: true; message: string; next: string; missing: ['runId', 'node'] };
85
- export type SelfImplementFailedToolResult = Partial<SelfImplementResult> & { kind: 'failed'; reason: string; message: string; next: string; missing: string[] };
99
+ export type SelfImplementFailedToolResult = Partial<SelfImplementResult> & { kind: 'failed'; reason: string; message: string; next: string; missing: string[]; goalFile?: string };
86
100
  export type SelfImplementToolResult = SelfImplementLaunchedToolResult | SelfImplementPendingToolResult | SelfImplementObservedOnlyToolResult | SelfImplementFailedToolResult;
87
101
 
88
102
  /** 하니스가 런을 맡았다 — 파일 편집은 하니스 몫이므로 모델의 직접 Write/Edit 을 문면으로 막는다. */
@@ -188,6 +202,7 @@ type RunSelfImplementCliFn = (
188
202
  deps: SelfImplementCliDeps,
189
203
  ) => Promise<SelfImplementCliOutcome>;
190
204
  type SelfImplementSeamsFactory = (opts: import('../../self-implement/seams.js').DefaultSeamsOptions) => SelfImplementSeams | Promise<SelfImplementSeams>;
205
+ type DecisionLedgerFactory = () => DecisionLedger;
191
206
 
192
207
  async function runSelfImplementViaCli(
193
208
  command: RunSelfImplementCliFn,
@@ -211,6 +226,7 @@ const GOAL_ORIGINAL_TEXT_LIMIT = null;
211
226
 
212
227
  type GoalAuthorSummary = {
213
228
  authored: boolean;
229
+ reused: boolean;
214
230
  goalFile: string | null;
215
231
  userTextState: 'absent' | 'empty' | 'present';
216
232
  originalChars: number | null;
@@ -222,10 +238,23 @@ type GoalAuthorSummary = {
222
238
  function emitGoalAuthorSummary(ux: SurfaceUx, summary: GoalAuthorSummary): void {
223
239
  const message = summary.authored
224
240
  ? `goal-author authored ${basename(summary.goalFile!)} (${summary.userTextState}; ${summary.storedChars} chars; truncated=${summary.truncated})`
225
- : `goal-author not authored (${summary.userTextState}; no goal source)`;
241
+ : summary.reused
242
+ ? `goal-author resumed ${basename(summary.goalFile!)} (${summary.userTextState})`
243
+ : `goal-author not authored (${summary.userTextState}; no goal source)`;
226
244
  ux.progress(message, { phase: 'delta' });
227
245
  }
228
246
 
247
+ function resolveResumableGoalFile(requestedPath: string, cwd: string): string {
248
+ const root = realpathSync(cwd);
249
+ const candidate = realpathSync(isAbsolute(requestedPath) ? requestedPath : resolve(root, requestedPath));
250
+ const relativePath = relative(root, candidate);
251
+ if (!relativePath || relativePath === '..' || relativePath.startsWith(`..${sep}`) || isAbsolute(relativePath)
252
+ || !/^GOAL-[^/\\]+\.(?:md|txt)$/i.test(basename(candidate))) {
253
+ throw new Error('goalFile must point to an existing GOAL-*.md or GOAL-*.txt document inside the repository');
254
+ }
255
+ return candidate;
256
+ }
257
+
229
258
  /** Observability only; tool selection remains model-led. */
230
259
  function harnessMentionState(userText: string | undefined): 'absent' | 'matched' | 'not-matched' {
231
260
  if (userText === undefined) return 'absent';
@@ -240,9 +269,12 @@ export async function dispatchSelfImplement(
240
269
  authorGoal: SelfImplementGoalAuthor = writeAuthoredGoal,
241
270
  runCli: RunSelfImplementCliFn = runSelfImplementCliCommand,
242
271
  seamsFactory?: SelfImplementSeamsFactory,
272
+ clarificationResolver?: GoalClarificationSelfResolver,
273
+ decisionLedgerFactory?: DecisionLedgerFactory,
243
274
  ): Promise<SelfImplementToolResult> {
244
275
  const feature = typeof args.feature === 'string' ? args.feature.trim() : '';
245
276
  if (!feature) return buildFailedToolResult('SelfImplement: `feature` is required');
277
+ if (ctx.signal?.aborted) throw ctx.signal.reason ?? new Error('SelfImplement aborted');
246
278
  try {
247
279
  const base = typeof args.base === 'string' && args.base.trim() ? args.base.trim() : undefined;
248
280
  const draft = typeof args.draft === 'boolean' ? args.draft : true;
@@ -281,7 +313,18 @@ export async function dispatchSelfImplement(
281
313
  }
282
314
 
283
315
  let goalFile: string | undefined;
284
- if (goalSourceText !== undefined) {
316
+ let resumedGoal = false;
317
+ if (args.goalFile !== undefined) {
318
+ if (typeof args.goalFile !== 'string' || !args.goalFile.trim()) {
319
+ return buildFailedToolResult('goalFile must be a non-empty path to an existing authored goal document');
320
+ }
321
+ try {
322
+ goalFile = resolveResumableGoalFile(args.goalFile, ctx.cwd);
323
+ resumedGoal = true;
324
+ } catch (error) {
325
+ return buildFailedToolResult(error instanceof Error ? error.message : String(error));
326
+ }
327
+ } else if (goalSourceText !== undefined) {
285
328
  const recentStepCounts = readRecentStepCountsFailOpen(recentStepCountReader);
286
329
  goalFile = (await authorGoal(goalSourceText, ctx.cwd, {
287
330
  goalTitle: feature,
@@ -292,9 +335,81 @@ export async function dispatchSelfImplement(
292
335
  }),
293
336
  onProgress: (phase, event) => ux.progress(`goal-author ${phase} ${event === 'start' ? 'started' : 'ended'}`, { phase: 'delta' }),
294
337
  })).path;
338
+ if (ctx.signal?.aborted) throw ctx.signal.reason ?? new Error('SelfImplement aborted');
339
+ }
340
+ if (goalFile) {
341
+ let authoredDocument: string;
342
+ try {
343
+ authoredDocument = readFileSync(goalFile, 'utf8');
344
+ } catch (error) {
345
+ const errorCode = error && typeof error === 'object' && 'code' in error && typeof error.code === 'string'
346
+ ? error.code
347
+ : undefined;
348
+ const reason = errorCode === 'ENOENT'
349
+ ? 'goal file missing before clarification'
350
+ : 'goal file unreadable before clarification';
351
+ debug.log('daemon-tools.self-implement', 'goal-clarification-file-read-failed', {
352
+ goalFile,
353
+ errorCode: errorCode ?? null,
354
+ reason,
355
+ });
356
+ return buildFailedToolResult(reason);
357
+ }
358
+ const clarification = await selfAnswerOrAssumeGoalDocumentClarifications(authoredDocument, {
359
+ path: 'say-first',
360
+ ...(goalSourceText !== undefined ? { ask: goalSourceText } : {}),
361
+ ...(typeof args.runId === 'string' ? { runId: args.runId } : {}),
362
+ ...(clarificationResolver !== undefined ? { resolver: clarificationResolver } : {}),
363
+ });
364
+ if (clarification.document !== authoredDocument) writeGoalDocumentAtomic(goalFile, clarification.document);
365
+ if (clarification.decisionRequired.length > 0) {
366
+ const ledger = decisionLedgerFactory?.() ?? new DecisionLedger();
367
+ const decisions = clarification.decisionRequired.map((item) => {
368
+ const ref = `self-implement-clarification:${goalFile}:${item.questionId}`;
369
+ return ledger.raiseOnce({
370
+ title: `SelfImplement 확인 필요: ${item.header}`.slice(0, 120),
371
+ category: item.category,
372
+ scqa: {
373
+ s: 'SelfImplement 골 저작 중 자동 답변이 끝나지 않은 확인 질문이 남았다',
374
+ c: '금전·보안·되돌릴 수 없는 외부 효과는 정책 가정으로 승인하지 않는다',
375
+ q: item.question.slice(0, 240),
376
+ },
377
+ pendingQuestion: item.question,
378
+ options: [
379
+ { key: 'a', label: '답을 골 문서에 반영 후 재실행', consequence: '결정 내용을 골 문서에 명시하고 SelfImplement을 다시 호출한다' },
380
+ { key: 'b', label: '진행하지 않음', consequence: '이 범위는 실행하지 않는다' },
381
+ ],
382
+ recommendation: { skipped: true, reason: '금전·보안·되돌릴 수 없는 외부 효과는 자동으로 선택하지 않는다' },
383
+ crossCheckSkipped: '안전상 대표 판단 필요',
384
+ raisedBy: { agent: 'OPC', track: 'OP' },
385
+ refs: [ref],
386
+ }, ref);
387
+ });
388
+ debug.log('daemon-tools.self-implement', 'goal-clarification-no-launch', {
389
+ goalFile,
390
+ decisionIds: decisions.map((decision) => decision.id),
391
+ unanswered: clarification.decisionRequired.length,
392
+ reason: 'safety-critical-clarification-requires-recorded-decision',
393
+ });
394
+ const reason = `goal author clarification requires a recorded decision before launch (${decisions.map((decision) => decision.id).join(', ')})`;
395
+ const next = `Edit ${goalFile} with the explicit answer, then rerun SelfImplement using the same feature and goalFile=${goalFile}; the decision card alone does not launch or resume work`;
396
+ return {
397
+ kind: 'failed', reason, goalFile, next, missing: ['runId', 'node'],
398
+ message: `SelfImplement did not launch: ${reason}. Record the answer in ${goalFile}, then rerun the same feature with goalFile=${goalFile}. A decision-card choice alone does not resume the run.`,
399
+ };
400
+ }
401
+ if (clarification.unanswered > 0) {
402
+ debug.log('daemon-tools.self-implement', 'goal-clarification-assumption-incomplete', {
403
+ goalFile,
404
+ unanswered: clarification.unanswered,
405
+ reason: 'no-launch-unanswered-clarification',
406
+ });
407
+ return buildFailedToolResult(`goal author clarification remains unanswered; launch withheld to prevent a human popup (${clarification.unanswered})`);
408
+ }
295
409
  }
296
410
  const goalAuthorSummary: GoalAuthorSummary = {
297
- authored: goalFile !== undefined,
411
+ authored: goalFile !== undefined && !resumedGoal,
412
+ reused: resumedGoal,
298
413
  goalFile: goalFile ?? null,
299
414
  userTextState: originalUserText === undefined ? 'absent' : originalUserText === '' ? 'empty' : 'present',
300
415
  originalChars,
@@ -322,6 +437,7 @@ export async function dispatchSelfImplement(
322
437
  );
323
438
 
324
439
  const cliOpts: SelfImplementCliOpts = {
440
+ ...(ctx.runId ? { runId: ctx.runId } : {}),
325
441
  entry,
326
442
  ...(ctx.sessionId ? { parentSessionId: ctx.sessionId } : {}),
327
443
  ...(base ? { base } : {}),
@@ -336,10 +452,12 @@ export async function dispatchSelfImplement(
336
452
  };
337
453
  // 승인 통로는 surface seams.approvePr 하나다. opts/pipelineDeps.approver를 보강하면
338
454
  // 중앙 심이 seams를 다시 조립해 fail-closed 승인 게이트를 우회할 수 있다.
339
- const pipelineDeps: DevPipelineDeps = { buildSelfImplementSeams: () => seams };
455
+ const pipelineDeps: DevPipelineDeps = { buildSelfImplementSeams: () => seams, signal: ctx.signal };
340
456
  const result = run
341
457
  ? await run({
342
458
  feature,
459
+ ...(ctx.runId ? { runId: ctx.runId } : {}),
460
+ ...(ctx.signal ? { signal: ctx.signal } : {}),
343
461
  ...(ctx.sessionId ? { parentSessionId: ctx.sessionId } : {}),
344
462
  ...(base ? { base } : {}),
345
463
  draft,
@@ -369,3 +487,190 @@ export async function dispatchSelfImplement(
369
487
  return buildFailedToolResult(reason);
370
488
  }
371
489
  }
490
+
491
+ export type SelfImplementQueuedToolResult = {
492
+ kind: 'launched'; runId: string; taskId: string; state: 'queued' | 'running' | 'done' | 'error' | 'aborted'; ok: boolean;
493
+ message: string; next: string; missing: [];
494
+ };
495
+
496
+ type ManagedAdmissionState = 'queued' | 'running' | 'done' | 'error' | 'aborted';
497
+ export interface ManagedTaskAdmission {
498
+ version: 1;
499
+ requestKey: string;
500
+ runId: string;
501
+ taskId: string;
502
+ parentSessionId?: string;
503
+ feature: string;
504
+ state: ManagedAdmissionState;
505
+ createdAt: number;
506
+ updatedAt: number;
507
+ result?: string;
508
+ error?: string;
509
+ }
510
+
511
+ /** File-backed admission ledger. A hard-link claim makes duplicate tool-call admission atomic. */
512
+ export class ManagedTaskAdmissionStore {
513
+ constructor(private readonly root = resolveManagedAdmissionRoot()) {}
514
+
515
+ claim(input: Omit<ManagedTaskAdmission, 'version' | 'createdAt' | 'updatedAt'>): { record: ManagedTaskAdmission; created: boolean } {
516
+ mkdirSync(this.root, { recursive: true });
517
+ const path = this.pathFor(input.requestKey);
518
+ const now = Date.now();
519
+ const record: ManagedTaskAdmission = { ...input, version: 1, createdAt: now, updatedAt: now };
520
+ const temp = join(this.root, `.claim-${randomUUID()}.tmp`);
521
+ writeFileSync(temp, `${JSON.stringify(record)}\n`, { encoding: 'utf8', flag: 'wx', mode: 0o600 });
522
+ try {
523
+ linkSync(temp, path);
524
+ return { record, created: true };
525
+ } catch (error) {
526
+ if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;
527
+ return { record: this.read(path), created: false };
528
+ } finally { rmSync(temp, { force: true }); }
529
+ }
530
+
531
+ update(requestKey: string, patch: Partial<Pick<ManagedTaskAdmission, 'state' | 'result' | 'error'>>): ManagedTaskAdmission {
532
+ const path = this.pathFor(requestKey);
533
+ const record = { ...this.read(path), ...patch, updatedAt: Date.now() };
534
+ const temp = join(this.root, `.update-${randomUUID()}.tmp`);
535
+ writeFileSync(temp, `${JSON.stringify(record)}\n`, { encoding: 'utf8', flag: 'wx', mode: 0o600 });
536
+ renameSync(temp, path);
537
+ return record;
538
+ }
539
+
540
+ get(requestKey: string): ManagedTaskAdmission | undefined {
541
+ const path = this.pathFor(requestKey);
542
+ return existsSync(path) ? this.read(path) : undefined;
543
+ }
544
+
545
+ private pathFor(requestKey: string): string {
546
+ const digest = createHash('sha256').update(requestKey).digest('hex');
547
+ return join(this.root, `${digest}.json`);
548
+ }
549
+
550
+ private read(path: string): ManagedTaskAdmission {
551
+ const value: unknown = JSON.parse(readFileSync(path, 'utf8'));
552
+ if (!value || typeof value !== 'object' || (value as ManagedTaskAdmission).version !== 1) {
553
+ throw new Error(`invalid SelfImplement admission record: ${path}`);
554
+ }
555
+ return value as ManagedTaskAdmission;
556
+ }
557
+ }
558
+
559
+ export function resolveManagedAdmissionRoot(instanceRoot = effectiveInstanceRoot()): string {
560
+ const dataDir = process.env.ELANOUS_DATA_DIR?.trim() || join(instanceRoot, 'data');
561
+ return join(dataDir, 'self-implement-admissions');
562
+ }
563
+
564
+ /** Return a durable-addressable registry identity before doing any goal authoring or child setup. */
565
+ export function dispatchSelfImplementManaged(
566
+ args: Record<string, unknown>,
567
+ ctx: DaemonToolDispatchCtx & { autoMerge?: boolean },
568
+ run?: SelfImplementRunner,
569
+ authorGoal: SelfImplementGoalAuthor = writeAuthoredGoal,
570
+ runCli: RunSelfImplementCliFn = runSelfImplementCliCommand,
571
+ seamsFactory?: SelfImplementSeamsFactory,
572
+ admissionStore: ManagedTaskAdmissionStore = new ManagedTaskAdmissionStore(),
573
+ runtime: { taskNotifications?: TaskNotificationQueue; registry?: AgentRegistry } = {},
574
+ ): Promise<SelfImplementQueuedToolResult | SelfImplementToolResult> {
575
+ const feature = typeof args.feature === 'string' ? args.feature.trim() : '';
576
+ if (!feature) return Promise.resolve(buildFailedToolResult('SelfImplement: `feature` is required'));
577
+ const runId = randomUUID();
578
+ const taskId = randomUUID();
579
+ const requestKey = ctx.sessionId && ctx.toolCallId
580
+ ? `tool-call:${ctx.sessionId}:${ctx.toolCallId}`
581
+ : `request:${runId}`;
582
+ let claim: ReturnType<ManagedTaskAdmissionStore['claim']>;
583
+ try {
584
+ claim = admissionStore.claim({
585
+ requestKey, runId, taskId, feature,
586
+ ...(ctx.sessionId ? { parentSessionId: ctx.sessionId } : {}), state: 'queued',
587
+ });
588
+ } catch (error) {
589
+ return Promise.resolve(buildFailedToolResult(`SelfImplement admission could not be persisted: ${error instanceof Error ? error.message : String(error)}`));
590
+ }
591
+ const registry = runtime.registry ?? globalAgentRegistry;
592
+ if (!claim.created) {
593
+ let record = claim.record;
594
+ let existingTask = registry.get(record.taskId);
595
+ if (!existingTask) {
596
+ existingTask = registry.register(
597
+ { name: 'self-implement', systemPrompt: 'Managed SelfImplement execution; do not invoke an LLM agent.' },
598
+ record.feature, { id: record.taskId },
599
+ );
600
+ existingTask.runId = record.runId;
601
+ existingTask.parentSessionId = record.parentSessionId;
602
+ existingTask.label = `SelfImplement ${record.feature.slice(0, 80)}`;
603
+ existingTask.background = true;
604
+ if (record.state === 'queued' || record.state === 'running') {
605
+ record = admissionStore.update(requestKey, { state: 'error', error: 'SelfImplement worker was interrupted by process restart; submit a new request to retry.' });
606
+ existingTask.error = record.error;
607
+ existingTask.result = record.error;
608
+ existingTask.state = 'error';
609
+ existingTask.finishedAt = Date.now();
610
+ registry.notifyTaskDone(existingTask);
611
+ } else {
612
+ existingTask.state = record.state;
613
+ existingTask.result = record.result;
614
+ existingTask.error = record.error;
615
+ }
616
+ }
617
+ return Promise.resolve({
618
+ kind: 'launched', runId: record.runId, taskId: record.taskId, state: record.state,
619
+ ok: record.state !== 'error' && record.state !== 'aborted',
620
+ message: `SelfImplement prior admission · run ${record.runId} · task ${record.taskId}${record.error ? ` · ${record.error}` : ''}`,
621
+ next: `AgentOutput(${record.taskId})`, missing: [],
622
+ });
623
+ }
624
+ const task = registry.register(
625
+ { name: 'self-implement', systemPrompt: 'Managed SelfImplement execution; do not invoke an LLM agent.' },
626
+ feature, { id: taskId },
627
+ );
628
+ task.runId = runId;
629
+ task.parentSessionId = ctx.sessionId;
630
+ task.label = `SelfImplement ${feature.slice(0, 80)}`;
631
+ task.background = true;
632
+ const parentChildSignal = childLifetimeSignal(ctx.signal);
633
+ const signal = parentChildSignal
634
+ ? AbortSignal.any([task.controller.signal, parentChildSignal])
635
+ : task.controller.signal;
636
+ let unsubscribeRunStop = (): void => {};
637
+ const runStopListenerReady = import('../../self-implement/run-stop.js').then(({ onRunStop, readRunStopRecord }) => {
638
+ unsubscribeRunStop = onRunStop((entry) => {
639
+ if (entry.runId !== runId) return;
640
+ const stop = readRunStopRecord(entry);
641
+ if (!stop) return;
642
+ void import('../../agent/task-notification.js').then(({ enqueueSelfImplementRunStopNotification, globalTaskNotificationQueue }) => {
643
+ enqueueSelfImplementRunStopNotification(
644
+ { runId, taskId: task.id, feature, stop },
645
+ runtime.taskNotifications ?? globalTaskNotificationQueue,
646
+ );
647
+ debug.log('daemon-tools.self-implement', 'run-stop-wake-enqueued', { runId, taskId: task.id, stopClass: stop.class, site: stop.site ?? null });
648
+ });
649
+ unsubscribeRunStop();
650
+ });
651
+ });
652
+ // The task registry owns cancellation and terminal notification. All slow setup,
653
+ // including goal authoring and seam construction, happens after this receipt.
654
+ queueMicrotask(() => {
655
+ void runStopListenerReady.then(() => registry.runManaged(task.id, async () => {
656
+ admissionStore.update(requestKey, { state: 'running' });
657
+ if (signal.aborted) throw signal.reason ?? new Error('SelfImplement aborted');
658
+ const result = await dispatchSelfImplement(args, { ...ctx, runId, signal }, run, authorGoal, runCli, seamsFactory);
659
+ if (signal.aborted) throw signal.reason ?? new Error('SelfImplement aborted');
660
+ if (result.kind === 'failed') throw new Error(result.reason);
661
+ admissionStore.update(requestKey, { state: 'done', result: JSON.stringify(result) });
662
+ return result;
663
+ }, (result) => JSON.stringify(result)).catch((error) => {
664
+ try { admissionStore.update(requestKey, { state: task.controller.signal.aborted ? 'aborted' : 'error', error: error instanceof Error ? error.message : String(error) }); } catch { /* registry remains authoritative for this process */ }
665
+ debug.log('daemon-tools.self-implement', 'managed-task-failed', {
666
+ runId, taskId: task.id, reason: error instanceof Error ? error.message : String(error),
667
+ }, { level: 'warn' });
668
+ })).finally(unsubscribeRunStop);
669
+ });
670
+ debug.log('daemon-tools.self-implement', 'managed-admitted', { runId, taskId: task.id, parentSessionId: ctx.sessionId ?? null });
671
+ return Promise.resolve({
672
+ kind: 'launched', runId, taskId: task.id, state: claim.record.state, ok: true,
673
+ message: `SelfImplement accepted · run ${runId} · task ${task.id}`,
674
+ next: `AgentOutput(${task.id})`, missing: [],
675
+ });
676
+ }
@@ -59,6 +59,8 @@ export interface DaemonToolDispatchCtx {
59
59
  * the args. Optional for backward compat with tests / surfaces that
60
60
  * build the ctx by hand without a session in scope. */
61
61
  sessionId?: string;
62
+ /** Caller-minted SelfImplement identity, propagated by managed dispatch. */
63
+ runId?: string;
62
64
  /** Trusted server-side classification of the current turn, never supplied as a tool argument. */
63
65
  requestOrigin?: RequestOrigin;
64
66
  /** Owner principal verified at the server request boundary, not from input source metadata. */
@@ -25,16 +25,49 @@ export interface LlmPricingUsd {
25
25
  }
26
26
 
27
27
  /** AWS Bedrock Global Standard prices, USD per million tokens (AWS pricing API, ap-northeast-2).
28
- * ⛔ BEDROCK-COST-LEDGER(0.2.26) — mantle-openai 비-Anthropic Bedrock id(`openai.gpt-6-sol`·`zai.glm-5` 등
29
- * `src/llm/bedrock.ts` BEDROCK_MODELS 의 `route:'mantle-openai'` 행)는 여기에 행이 «없다»: 단가 수치 근거가
30
- * 하나도 확보되지 않았다. 근거 없는 id는 `isBedrockPricingModel` 게이트(`claude-` 시작)를 지나지 않아
31
- * `unknownCost()` 로 `kind:'unknown'` 에 머문다 — 0원으로 꾸미지 않는다. */
28
+ * Anthropic(Claude) 축만 담는다 — 이 표는 `isBedrockPricingModel` 게이트(`claude-` 시작) 뒤에 있다.
29
+ * ⛔ BEDROCK-COST-LEDGER(0.2.38) — mantle-openai 비-Anthropic id 는 «다른 표»
30
+ * (`BEDROCK_NON_ANTHROPIC_PRICING_USD`)로 분리했다. 이 객체는 Claude 5.5 착지분 그대로다(보존 계약). */
32
31
  export const BEDROCK_PRICING_USD: Readonly<Record<string, LlmPricingUsd>> = {
33
32
  'claude-haiku-5-5': { inputPerM: 0.1, outputPerM: 0.5, cacheWritePerM: 0.125, cacheReadPerM: 0.01 },
34
33
  'claude-sonnet-5-5': { inputPerM: 2, outputPerM: 10, cacheWritePerM: 2.5, cacheReadPerM: 0.1 },
35
34
  'claude-opus-5-5': { inputPerM: 4, outputPerM: 20, cacheWritePerM: 5, cacheReadPerM: 0.2 },
36
35
  };
37
36
 
37
+ /** Bedrock 비-Anthropic(mantle-openai) 단가의 근거 — AWS Price List API(`AmazonBedrock` offer,
38
+ * us-east-1 = mantle-openai 고정 리전) 조회 결과. 게시 시각 2026-10-16T21:08:06Z.
39
+ * 재현: `awscurl`/SDK 로 `GetProducts`(serviceCode=AmazonBedrock, regionCode=USE1) 후
40
+ * `USE1-<id>-mantle-{input,output}-tokens-standard` 키의 `pricePerUnit.USD` 를 읽는다(1K 토큰 단가 ×1000 = per-M).
41
+ * ⛔ 근거 없는 id 는 표에 «넣지 않는다» — `kind:'unknown'` 에 머문다(0원으로 꾸미지 않는다). */
42
+ export const BEDROCK_NON_ANTHROPIC_PRICING_USD: Readonly<Record<string, LlmPricingUsd>> = {
43
+ // AWS price list key: USE1-deepseek.v3.2-mantle-{input,output}-tokens-standard
44
+ 'deepseek.v3.2': { inputPerM: 0.62, outputPerM: 1.85 },
45
+ // AWS price list key: USE1-zai.glm-4.7-flash-mantle-{input,output}-tokens-standard
46
+ 'zai.glm-4.7-flash': { inputPerM: 0.07, outputPerM: 0.4 },
47
+ // AWS price list key: USE1-moonshotai.kimi-k2.5-mantle-{input,output}-tokens-standard
48
+ 'moonshotai.kimi-k2.5': { inputPerM: 0.6, outputPerM: 3 },
49
+ // AWS price list key: USE1-qwen.qwen3-coder-next-mantle-{input,output}-tokens-standard
50
+ 'qwen.qwen3-coder-next': { inputPerM: 0.5, outputPerM: 1.2 },
51
+ // AWS price list key: USE1-minimax.minimax-m2.5-mantle-{input,output}-tokens-standard
52
+ 'minimax.minimax-m2.5': { inputPerM: 0.3, outputPerM: 1.2 },
53
+ // AWS price list key: USE1-mistral.devstral-2-123b-mantle-{input,output}-tokens-standard
54
+ 'mistral.devstral-2-123b': { inputPerM: 0.4, outputPerM: 2 },
55
+ // ⛔ 근거 없음(AWS price list 조회 0행 → 표에 없음): openai.gpt-6-sol · openai.gpt-6-luna · zai.glm-5.
56
+ // 이 셋은 지금 mantle-openai 로 선택 가능하지만 단가 근거가 없으므로 `kind:'unknown'` 이 정직한 답이다.
57
+ };
58
+
59
+ /** Bedrock 비-Anthropic(mantle-openai) 단가 조회용 id 정규화 — invoke id 모양을 표의 키로 되돌린다.
60
+ * - `bedrock/` 접두(레지스트리 별칭) · `us.`/`global.` 같은 리전 스코프 접두
61
+ * - `-v1:0` 버전 꼬리 · `-20251001` 날짜 꼬리
62
+ * Anthropic id(`anthropic.claude-…`)는 이 축이 아니다 — `bedrockPricingModelId` 가 맡는다. */
63
+ export function bedrockNonAnthropicPricingModelId(model: string): string {
64
+ return model.trim()
65
+ .replace(/^bedrock\//, '')
66
+ .replace(/^(?:us|eu|apac|global)\./, '')
67
+ .replace(/-v1:\d+$/, '')
68
+ .replace(/-\d{8}$/, '');
69
+ }
70
+
38
71
  export interface LlmCostUsage {
39
72
  model: string;
40
73
  inputTokens?: number;
@@ -202,7 +235,7 @@ function resolvePricing(
202
235
  model: string,
203
236
  opts?: EstimateLlmCostOptions,
204
237
  ): { pricing: LlmPricingUsd; source: 'catalog' | 'bedrock-catalog' | 'config' | 'registry' } | undefined {
205
- // ⭐ 순서: 손 카탈로그(정확) → 정규화 id → config 오버레이 → Bedrock 표 → 저장소 정본 → 레지스트리. 앞이 이긴다.
238
+ // ⭐ 순서: 손 카탈로그(정확) → 정규화 id → config 오버레이 → Claude Bedrock 표 → 저장소 정본 → mantle Bedrock 표 → 레지스트리. 앞이 이긴다.
206
239
  const normalized = normalizePricingModelId(model);
207
240
  for (const id of normalized === model ? [model] : [model, normalized]) {
208
241
  const catalog = catalogPricing(id);
@@ -216,8 +249,14 @@ function resolvePricing(
216
249
  const bedrock = BEDROCK_PRICING_USD[bedrockPricingModelId(model)];
217
250
  if (validPricing(bedrock)) return { pricing: bedrock, source: 'bedrock-catalog' };
218
251
  }
252
+ // 저장소 정본이 mantle 표보다 우선한다. 같은 id 가 생기면 직접 모델 가격을 Bedrock 가격으로 덮지 않는다.
219
253
  const builtin = builtinCatalogPricing(normalized);
220
254
  if (validPricing(builtin)) return { pricing: builtin, source: 'catalog' };
255
+ // BEDROCK-COST-LEDGER(0.2.38) — mantle-openai 비-Anthropic 축: 근거 있는 행만 bedrock-catalog 로 값을 낸다.
256
+ // 표에 없는 id(openai.gpt-6-sol·zai.glm-5 등)는 여기서 결정되지 않아 아래 정본·레지스트리로 내려가고,
257
+ // 그것도 없으면 `unknownCost()` — 0원으로 꾸미지 않는다.
258
+ const mantle = BEDROCK_NON_ANTHROPIC_PRICING_USD[bedrockNonAnthropicPricingModelId(model)];
259
+ if (validPricing(mantle)) return { pricing: mantle, source: 'bedrock-catalog' };
221
260
  const registry = registryPricing(model);
222
261
  if (validPricing(registry)) return { pricing: registry, source: 'registry' };
223
262
  return undefined;
@@ -75,3 +75,55 @@ export function planShadowArms(input: PlanShadowArmsInput): ShadowArmsPlan {
75
75
 
76
76
  return { fire, skipped, remainingUsd };
77
77
  }
78
+
79
+ // ── SHADOW-MODEL-ARMS · 그림자 «1팔» probe(명시 실행 · 관측만) ─────────────────────
80
+ /**
81
+ * ⭐ 그림자 1팔 probe — `planShadowArms` 를 일일 상한 안에서 «실제 호출»해
82
+ * 난이도·모델·예상/실제 비용·결과를 기록한다.
83
+ * ⛔ 관측만 한다 — 라이브 LLM 호출 0 · 파일 원장 쓰기 0. 팔은 «계획»이고 실행은 후속 조각이다.
84
+ * ⛔ 후보가 여러 개여도 첫 후보 «1팔»만 계획한다(저작 단계 팔은 단일 팔이다).
85
+ */
86
+ export interface ShadowArmProbeRecord {
87
+ stage: ShadowStage;
88
+ difficulty: ShadowDifficulty;
89
+ model: string;
90
+ result: 'fire' | 'skipped';
91
+ skipReason: 'over-daily-cap' | 'unknown-price' | null;
92
+ expectedUsd: number | null;
93
+ actualUsd: number;
94
+ remainingUsd: number;
95
+ }
96
+
97
+ /** 그림자 1팔을 실제 호출해 기록을 낸다 — 실제 지출은 없다(계획만, actualUsd=0). */
98
+ export function probeShadowArm(input: PlanShadowArmsInput): ShadowArmProbeRecord {
99
+ const model = input.candidates[0] ?? '';
100
+ const plan = planShadowArms({ ...input, candidates: [model] });
101
+ const fired = plan.fire[0];
102
+ const skipped = plan.skipped[0];
103
+ return {
104
+ stage: input.stage,
105
+ difficulty: input.difficulty,
106
+ model,
107
+ result: fired ? 'fire' : 'skipped',
108
+ skipReason: skipped?.reason ?? null,
109
+ expectedUsd: fired?.estUsd ?? null,
110
+ actualUsd: 0,
111
+ remainingUsd: plan.remainingUsd,
112
+ };
113
+ }
114
+
115
+ /** 한 줄 원장 형식 — 예상 비용이 없으면 `expectedUsd=unknown`, fire 사유는 `under-daily-cap` 이다. */
116
+ export function formatShadowArmProbeRecord(record: ShadowArmProbeRecord): string {
117
+ const reason = record.skipReason ?? 'under-daily-cap';
118
+ const expectedUsd = record.expectedUsd === null ? 'unknown' : `${record.expectedUsd}`;
119
+ return [
120
+ `shadow-arm stage=${record.stage}`,
121
+ `difficulty=${record.difficulty}`,
122
+ `model=${record.model}`,
123
+ `result=${record.result}`,
124
+ `reason=${reason}`,
125
+ `expectedUsd=${expectedUsd}`,
126
+ `actualUsd=${record.actualUsd}`,
127
+ `remainingUsd=${record.remainingUsd}`,
128
+ ].join(' ');
129
+ }
@@ -459,6 +459,16 @@ function subscriptionFromCodexSnapshot(snap: UsageSnapshot): SubscriptionAxis {
459
459
  * 📏 응답 모양(실측 2026-09-23): `{data:{total_credits, total_usage}}` (USD). */
460
460
  export const OPENROUTER_CREDITS_ENDPOINT = 'https://openrouter.ai/api/v1/credits';
461
461
  export const OPENROUTER_KEY_ENDPOINT = 'https://openrouter.ai/api/v1/key';
462
+
463
+ /** 📏 CREDIT-READOUT 관측 — /key readout 이 «키 한도 note» 를 못 만든 이유를 남긴다.
464
+ * note 없는 openrouter 행만 보면 «/key 를 안 불렀나 · 404 인가 · 한도가 null(무제한) 인가» 가
465
+ * 안 갈리므로 판단 근거를 로그에 남긴다(행·문면·원장 형식은 불변 — 진단 전용). */
466
+ const OPENROUTER_KEY_UNAVAILABLE_EVENT = 'openrouter-key-unavailable';
467
+ type OpenRouterKeyUnavailableReason = 'http-error' | 'limit-not-finite' | 'throw';
468
+ function logOpenRouterKeyUnavailable(reason: OpenRouterKeyUnavailableReason, detail?: string): void {
469
+ debug.log('usage', OPENROUTER_KEY_UNAVAILABLE_EVENT, detail === undefined ? { reason } : { reason, detail });
470
+ }
471
+
462
472
  async function collectOpenRouterRows(deps: UnifiedUsageDeps): Promise<AccountUsageRow[]> {
463
473
  // ⛔ 시험 런타임은 seam 이 없으면 «키 없음»으로 본다 — 키 캐시는 «파일»이라 env 스크럽을 통과해
464
474
  // 기존 시험들이 실제 네트워크를 치게 된다(seam 을 모르는 옛 시험이 다수).
@@ -497,10 +507,16 @@ async function collectOpenRouterRows(deps: UnifiedUsageDeps): Promise<AccountUsa
497
507
  if (typeof limit === 'number' && Number.isFinite(limit)
498
508
  && typeof limitRemaining === 'number' && Number.isFinite(limitRemaining)) {
499
509
  note = `키 한도 남은 금액 $${limitRemaining.toFixed(2)}`;
510
+ } else {
511
+ logOpenRouterKeyUnavailable('limit-not-finite',
512
+ `limit=${JSON.stringify(limit) ?? 'absent'} limit_remaining=${JSON.stringify(limitRemaining) ?? 'absent'}`);
500
513
  }
514
+ } else {
515
+ logOpenRouterKeyUnavailable('http-error', `http-${keyRes.status}`);
501
516
  }
502
- } catch {
517
+ } catch (err) {
503
518
  // Key metadata is optional; preserve the successful credits row when unavailable.
519
+ logOpenRouterKeyUnavailable('throw', err instanceof Error ? err.message : String(err));
504
520
  }
505
521
  return [{
506
522
  ...base,
@@ -125,6 +125,8 @@ export interface TuiControlTargetDeps {
125
125
  dims?: () => { readonly cols: number; readonly rows: number } | undefined;
126
126
  /** 외부 주입 라우터 — 글 한 줄을 사용자 버퍼에 섞지 않고 별도 대기열로 돌린다(`input/external-input-queue`). */
127
127
  routeExternal?: (chars: string) => ExternalInputRoute;
128
+ /** Active TUI turn cancellation hook; absent means there is no force-stop capability. */
129
+ stopTurn?: () => boolean;
128
130
  }
129
131
 
130
132
  function stdoutDims(): { cols: number; rows: number } | undefined {
@@ -136,6 +138,16 @@ export interface TuiControlTarget extends PtyControlTarget {
136
138
  deactivate(): void;
137
139
  }
138
140
 
141
+ let activeTuiForceStop: (() => boolean) | null = null;
142
+
143
+ /** Dashboard turn owner hook used by the foreground TUI's control target. */
144
+ export function registerTuiForceStopHandler(handler: () => boolean): () => void {
145
+ activeTuiForceStop = handler;
146
+ return () => {
147
+ if (activeTuiForceStop === handler) activeTuiForceStop = null;
148
+ };
149
+ }
150
+
139
151
  /** Adapt the foreground TUI's own terminal to the existing PTY control
140
152
  * protocol without pretending it is a spawned child process. */
141
153
  export function createTuiControlTarget(surfaceId: string, deps: TuiControlTargetDeps = {}): TuiControlTarget {
@@ -143,6 +155,7 @@ export function createTuiControlTarget(surfaceId: string, deps: TuiControlTarget
143
155
  const parse = deps.splitKeys ?? splitKeys;
144
156
  const dims = deps.dims ?? stdoutDims;
145
157
  const routeExternal = deps.routeExternal ?? routeExternalInput;
158
+ const stopTurn = deps.stopTurn ?? (() => activeTuiForceStop?.() ?? false);
146
159
  let alive = true;
147
160
  let accessMode: PtyAccessMode = 'write';
148
161
  let transitionPolicy: PtyTransitionPolicy = 'open';
@@ -160,6 +173,7 @@ export function createTuiControlTarget(surfaceId: string, deps: TuiControlTarget
160
173
  return true;
161
174
  },
162
175
  isAlive: () => alive,
176
+ stopTurn: (force: true) => force && stopTurn(),
163
177
  canWrite: (actor: PtyWriteActor = 'human') => resolveWriteDecision(accessMode, actor).allow,
164
178
  write(chars: string): void {
165
179
  // ⭐ 이 write 는 «바깥»(제어 IPC)에서만 온다 — 키보드와 섞이기 전에 라우터가 먼저 가른다.