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
@@ -4,20 +4,37 @@
4
4
  //
5
5
  // ⛔ Not under `bun test`: a real PTY of the real TUI is outside the test gate (NODE_ENV=test turns the PTY
6
6
  // manifest off, and the run takes ~1 minute). Each check gets a fresh temp config/state dir and its own PTY;
7
- // both are removed when the check ends, so the run leaves no process or folder behind.
7
+ // the temporary config/state directory is removed when the check ends. Failed checks preserve their screens and
8
+ // effective config under TUI_REGRESS_ARTIFACTS (or the default temp artifact root) for diagnosis.
8
9
  import { spawnSync } from 'node:child_process';
10
+ import { randomUUID } from 'node:crypto';
9
11
  import { mkdtempSync, rmSync } from 'node:fs';
10
12
  import { tmpdir } from 'node:os';
11
13
  import { join } from 'node:path';
12
14
  import { startPty } from '../src/pty-shell/registry.js';
13
- import { ERASE, TUI_REGRESS_CHECKS, type TuiCheck, type Verdict } from './lib/tui-regress-checks.js';
15
+ import { ERASE, inputRow, TUI_REGRESS_CHECKS, type TuiCheck, type Verdict } from './lib/tui-regress-checks.js';
16
+ import { preserveTuiRegressFailure } from './lib/tui-regress-evidence.js';
17
+ import { debug } from '../src/debug/log.js';
18
+ import { registerStandaloneLogSink } from '../src/domains/standalone-log-sink.js';
14
19
 
15
20
  const COLS = 160;
16
21
  const ROWS = 50;
17
- const BOOT_MS = 9_000;
22
+ const BOOT_TIMEOUT_MS = 60_000;
23
+ const BOOT_POLL_MS = 200;
24
+ const RUN_EVENT = 'tui-regress.completed';
18
25
  const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
26
+ type TuiRegressResult = Verdict & { bootMs: number };
19
27
 
20
- async function runCheck(check: TuiCheck): Promise<Verdict> {
28
+ async function waitForInputPrompt(handle: ReturnType<typeof startPty>): Promise<number> {
29
+ const startedAt = Date.now();
30
+ while (Date.now() - startedAt < BOOT_TIMEOUT_MS) {
31
+ if (inputRow(await handle.renderScreen())) return Date.now() - startedAt;
32
+ await sleep(BOOT_POLL_MS);
33
+ }
34
+ throw new Error(`TUI 입력 프롬프트 준비 시간 초과 (${BOOT_TIMEOUT_MS}ms)`);
35
+ }
36
+
37
+ async function runCheck(check: TuiCheck, runId: string, verificationCommand: string): Promise<TuiRegressResult> {
21
38
  const dir = mkdtempSync(join(tmpdir(), `tui-regress-${check.id}-`));
22
39
  const cli = join(import.meta.dir, '..', 'bin', 'elanous.mjs');
23
40
  if (check.role && check.role !== 'owner') {
@@ -32,8 +49,13 @@ async function runCheck(check: TuiCheck): Promise<Verdict> {
32
49
  env: { ...process.env, ELANOUS_DRIVE_TUI: '1', ELANOUS_STATE_DIR: dir },
33
50
  });
34
51
  const snaps: Record<string, string> = {};
52
+ let bootMs = 0;
53
+ let bootStartedAt = Date.now();
54
+ let bootComplete = false;
35
55
  try {
36
- await sleep(BOOT_MS);
56
+ bootStartedAt = Date.now();
57
+ bootMs = await waitForInputPrompt(handle);
58
+ bootComplete = true;
37
59
  for (const step of check.steps) {
38
60
  if (step.kind === 'type') handle.write(step.text);
39
61
  else if (step.kind === 'key') handle.write(step.data);
@@ -43,9 +65,52 @@ async function runCheck(check: TuiCheck): Promise<Verdict> {
43
65
  }
44
66
  // TUI_REGRESS_DUMP=<id> prints that check's screens (to see why a verdict failed).
45
67
  if (!json && process.env.TUI_REGRESS_DUMP === check.id) for (const [k, v] of Object.entries(snaps)) console.log(`--- ${check.id}:${k}\n${v.split('\n').filter((l) => l.trim()).join('\n')}`);
46
- return check.judge(snaps);
68
+ const verdict = check.judge(snaps);
69
+ if (!verdict.ok) {
70
+ const artifactDir = preserveTuiRegressFailure({
71
+ runId,
72
+ event: RUN_EVENT,
73
+ verificationCommand,
74
+ artifactRoot: process.env.TUI_REGRESS_ARTIFACTS || join(tmpdir(), 'elanous-tui-regress-failures'),
75
+ configDir: dir,
76
+ check: { id: check.id, title: check.title, role: check.role ?? 'owner' },
77
+ screens: snaps,
78
+ pty: { cols: COLS, rows: ROWS, bootMs },
79
+ environment: {
80
+ driveTui: '1',
81
+ nodeEnv: process.env.NODE_ENV ?? null,
82
+ credentialVariablesPresent: Object.keys(process.env).filter((key) => /API.?KEY|TOKEN|SECRET|CREDENTIAL/i.test(key)),
83
+ },
84
+ verdict,
85
+ });
86
+ return { ...verdict, bootMs, reason: `${verdict.reason} · 증거 보존: ${artifactDir}` };
87
+ }
88
+ return { ...verdict, bootMs };
47
89
  } catch (error) {
48
- return { ok: false, reason: `실행 오류: ${String(error).slice(0, 120)}` };
90
+ if (!bootComplete) bootMs = Date.now() - bootStartedAt;
91
+ const verdict: Verdict = { ok: false, reason: `실행 오류: ${String(error).slice(0, 120)}` };
92
+ try { snaps.failure = await handle.renderScreen(); } catch { /* PTY may already be gone */ }
93
+ try {
94
+ const artifactDir = preserveTuiRegressFailure({
95
+ runId,
96
+ event: RUN_EVENT,
97
+ verificationCommand,
98
+ artifactRoot: process.env.TUI_REGRESS_ARTIFACTS || join(tmpdir(), 'elanous-tui-regress-failures'),
99
+ configDir: dir,
100
+ check: { id: check.id, title: check.title, role: check.role ?? 'owner' },
101
+ screens: snaps,
102
+ pty: { cols: COLS, rows: ROWS, bootMs },
103
+ environment: {
104
+ driveTui: '1',
105
+ nodeEnv: process.env.NODE_ENV ?? null,
106
+ credentialVariablesPresent: Object.keys(process.env).filter((key) => /API.?KEY|TOKEN|SECRET|CREDENTIAL/i.test(key)),
107
+ },
108
+ verdict,
109
+ });
110
+ return { ...verdict, bootMs, reason: `${verdict.reason} · 증거 보존: ${artifactDir}` };
111
+ } catch (preserveError) {
112
+ return { ...verdict, bootMs, reason: `${verdict.reason} · 증거 보존 실패: ${String(preserveError).slice(0, 120)}` };
113
+ }
49
114
  } finally {
50
115
  try { handle.kill('SIGKILL'); } catch { /* already gone */ }
51
116
  rmSync(dir, { recursive: true, force: true });
@@ -58,14 +123,24 @@ const only = onlyArg >= 0 ? new Set((args[onlyArg + 1] ?? '').split(',').map((s)
58
123
  const json = args.includes('--json');
59
124
  const checks = TUI_REGRESS_CHECKS.filter((check) => !only || only.has(check.id));
60
125
  if (checks.length === 0) { console.error('tui-regress: 고른 칸이 없다 (--only 확인)'); process.exit(2); }
126
+ const runId = `run-${randomUUID()}`;
127
+ const verificationCommand = `bun scripts/tui-regress.ts${only ? ` --only ${[...only].join(',')}` : ''} --json`;
128
+ await registerStandaloneLogSink('tui-regress');
61
129
 
62
- const results: { id: string; title: string; ok: boolean; reason: string }[] = [];
130
+ const results: { id: string; title: string; ok: boolean; reason: string; bootMs: number }[] = [];
63
131
  for (const check of checks) {
64
- const verdict = await runCheck(check);
132
+ const verdict = await runCheck(check, runId, verificationCommand);
65
133
  results.push({ id: check.id, title: check.title, ...verdict });
66
134
  if (!json) console.log(`${check.id} ${verdict.ok ? '✅' : '❌'} ${check.title} — ${verdict.reason}`);
67
135
  }
68
136
  const fail = results.filter((r) => !r.ok).length;
69
- if (json) console.log(JSON.stringify({ results, pass: results.length - fail, fail }));
137
+ debug.log('tui-regress', RUN_EVENT, {
138
+ runId,
139
+ verificationCommand,
140
+ outcome: fail === 0 ? 'pass' : 'fail',
141
+ results: results.map(({ id, ok, bootMs }) => ({ id, ok, bootMs })),
142
+ });
143
+ debug.flush();
144
+ if (json) console.log(JSON.stringify({ runId, event: RUN_EVENT, verificationCommand, results, pass: results.length - fail, fail }));
70
145
  else console.log(`tui-regress: pass ${results.length - fail} · fail ${fail}`);
71
146
  process.exit(fail ? 1 : 0);
package/scripts/ux-sim.ts CHANGED
@@ -15,6 +15,7 @@
15
15
  // bun scripts/ux-sim.ts --list-trajectories # 저장한 궤적과 출처 목록
16
16
  // bun scripts/ux-sim.ts --fault cred-expiry # 결함 주입: grok 구독 만료 임박 × 갱신 결과 → 디스패처·발사 판정
17
17
  // bun scripts/ux-sim.ts --fault pod-death # 결함 주입: PARTIAL 줄을 남긴 Pod 가 SIGTERM 으로 지워짐 → 호스트 재방출 판정
18
+ // bun scripts/ux-sim.ts --fault pod-child-result # 결함 주입: Completed Pod 안의 report-deficit child 결과 보존
18
19
  // bun scripts/ux-sim.ts --fault pool-cap # 결함 주입: --pod-pool 에 :N 이 빠진 풀 → 승인 판정(limitedBy)
19
20
  // bun scripts/ux-sim.ts --fault sqlite-busy # 결함 주입: 실제 SQLite 잠금 → 로그 배치 버퍼·복구
20
21
  // bun scripts/ux-sim.ts emit child-error-long --json # 사건 주입(L0): 격리 우주 원장에 주입 줄 → 소비자 목록
@@ -128,7 +129,7 @@ if (argv[0] === 'seat-seq') {
128
129
  // ***영영 모른다*** — 오늘 이 저장소가 같은 함정을 다른 도구에서 이미 한 번 고쳤다.
129
130
  // ⛔ 그래서 「알려진 플래그」를 «한 곳»에 두고, 그 밖의 `--` 인자는 거부한다.
130
131
  const KNOWN_FLAGS = new Set([
131
- '--list', '--list-trajectories', '--computer-use', '--trajectory', '--from-run',
132
+ '--list', '--list-trajectories', '--computer-use', '--trajectory', '--from-run', '--seminar-rehearsal',
132
133
  '--save-trajectory', '--esc', '--queue', '--width', '--height', '--draft', '--fault',
133
134
  ]);
134
135
  {
@@ -142,6 +143,17 @@ const KNOWN_FLAGS = new Set([
142
143
  }
143
144
  if (argv.includes('--list')) { console.log([...PHASES, 'computer-use: normal | capture-stalls | capture-fails | target-missing'].join('\n')); process.exit(0); }
144
145
 
146
+ if (argv.includes('--seminar-rehearsal')) {
147
+ if (argv.length !== 1) {
148
+ console.error('⛔ --seminar-rehearsal 는 단독 모드다');
149
+ process.exit(2);
150
+ }
151
+ const { renderSeminarRehearsal, seminarRehearsalSweep } = await import('../src/ux-sim/seminar-rehearsal.js');
152
+ const result = seminarRehearsalSweep();
153
+ console.log(renderSeminarRehearsal(result).join('\n'));
154
+ process.exit(result.verdict === 'pass' ? 0 : 1);
155
+ }
156
+
145
157
  {
146
158
  // `--fault=<이름>` 꼴도 받는다 — KNOWN_FLAGS 는 등호 꼴을 통과시키므로 여기서 놓치면 조용히 기본 국면으로 빠진다.
147
159
  const eq = argv.find((a) => a.startsWith('--fault='));
@@ -159,6 +171,11 @@ if (argv.includes('--fault')) {
159
171
  console.log(renderPodDeath(simPodDeath()).join('\n'));
160
172
  process.exit(0);
161
173
  }
174
+ if (fault === 'pod-child-result') {
175
+ const { podChildResultScenario, renderPodChildResult } = await import('../src/ux-sim/fault-pod-child-result.js');
176
+ console.log(renderPodChildResult(podChildResultScenario()).join('\n'));
177
+ process.exit(0);
178
+ }
162
179
  if (fault === 'pool-cap') {
163
180
  const { poolCapSweep, renderPoolCap } = await import('../src/ux-sim/fault-pool-cap.js');
164
181
  console.log(renderPoolCap(poolCapSweep()).join('\n'));
@@ -169,7 +186,7 @@ if (argv.includes('--fault')) {
169
186
  console.log(renderSqliteBusy(simSqliteBusy()).join('\n'));
170
187
  process.exit(0);
171
188
  }
172
- console.error(`⛔ 모르는 결함이다: ${fault ?? '(없음)'} — 아는 것: cred-expiry · pod-death · pool-cap · sqlite-busy`);
189
+ console.error(`⛔ 모르는 결함이다: ${fault ?? '(없음)'} — 아는 것: cred-expiry · pod-death · pod-child-result · pool-cap · sqlite-busy`);
173
190
  process.exit(2);
174
191
  }
175
192
 
@@ -57,6 +57,13 @@ import { resolveSessionSurfaceProfile } from '../session-runtime/index.js';
57
57
  import { classifyTuiChatIntent, formatTuiRouteLine, isSeatOpsDirective, type TuiChatRoute } from '../core-turn/short-question.js';
58
58
  import { HARNESS_ROLE_ENV } from '../harness/harness-space.js';
59
59
  import { createReasoningThoughtBuffer } from './reasoning-thought-buffer.js';
60
+ import {
61
+ REQUEST_SIZE_MAX_CHARS,
62
+ createRequestSizeGuard,
63
+ estimateRequestChars,
64
+ formatRequestSizeStatus,
65
+ type RequestSizeGuard,
66
+ } from '../session/request-size-guard.js';
60
67
 
61
68
  const FACT_QUESTION_INSTRUCTION = '사실·최신 정보 질문이다. WebSearch 를 1~2회 쓰고 검색 결과(제목·스니펫·URL)로 답하라. 출처 링크를 붙여라. 셸·브라우저·파일 도구는 검색 결과로 부족할 때만. 도구 예산에 닿으면 지금까지 근거로 답하고 끝에 «더 찾아볼까요?»를 붙여라.';
62
69
 
@@ -143,6 +150,18 @@ export interface CoreTurnBridgeDeps {
143
150
  /** TUI-H1-SEAT-GOALLOOP — the seat this TUI works for (`detectSeatTui`), read per turn. null/absent = a human
144
151
  * conversation TUI (routing unchanged). A seat TUI sends operational directives to the goal loop. */
145
152
  resolveSeat?: () => string | null;
153
+ /** TUI-TOKEN-GUARD-WIRE — host write-back for the #32254 request-size cap.
154
+ * Compacts the host's own history store (the one `getMessages` reads) in place
155
+ * so the next prompt does not reload the original. The bridge re-reads
156
+ * `getMessages` after `fired:true`. Only consulted on `tuiRouting` turns. */
157
+ compactPersistedHistory?: (ctx: {
158
+ sessionId: string;
159
+ userText: string;
160
+ requestChars: number;
161
+ maxChars: number;
162
+ }) => Promise<{ fired: boolean; reason: string }>;
163
+ /** Override the request-size cap (tests). Defaults to `REQUEST_SIZE_MAX_CHARS`. */
164
+ requestSizeMaxChars?: number;
146
165
  }
147
166
 
148
167
  /** Default abort-poll cadence. 50ms = 20 Hz: responsive without
@@ -224,7 +243,7 @@ export function bridgeCoreTurnToAcp(
224
243
  (poll as unknown as { unref?: () => void }).unref?.();
225
244
 
226
245
  try {
227
- const messages = await Promise.resolve(
246
+ let messages = await Promise.resolve(
228
247
  deps.getMessages({
229
248
  sessionId: turnCtx.sessionId,
230
249
  userText: turnCtx.userText,
@@ -318,9 +337,71 @@ export function bridgeCoreTurnToAcp(
318
337
  }
319
338
  const explicitMaxToolTurns = deps.resolveMaxToolTurns?.({ sessionId: turnCtx.sessionId });
320
339
  const maxToolTurns = explicitMaxToolTurns ?? (factQuestion ? getUserConfig().chat.factQuestion.maxToolTurns : undefined);
321
- const turnMessages: LLMMessage[] = factQuestion
322
- ? [{ role: 'system', content: FACT_QUESTION_INSTRUCTION }, ...messages]
323
- : messages;
340
+ const withFactInstruction = (seed: LLMMessage[]): LLMMessage[] => factQuestion
341
+ ? [{ role: 'system', content: FACT_QUESTION_INSTRUCTION }, ...seed]
342
+ : seed;
343
+ let turnMessages: LLMMessage[] = withFactInstruction(messages);
344
+ // TUI-TOKEN-GUARD-WIRE — exact serialized provider measurement owns
345
+ // first-request compaction; the seed estimate is telemetry only. This
346
+ // keeps turn-0 history untouched until compactFirstRequest writes back.
347
+ let requestSizeGuard: RequestSizeGuard | undefined;
348
+ if (deps.tuiRouting === true) {
349
+ const maxChars = deps.requestSizeMaxChars ?? REQUEST_SIZE_MAX_CHARS;
350
+ let historyCompacted = false;
351
+ const compactHistory = async (requestChars: number, stage: 'first-request') => {
352
+ if (!deps.compactPersistedHistory || historyCompacted) return false;
353
+ let fired = false;
354
+ let reason = 'no-op';
355
+ try {
356
+ const result = await deps.compactPersistedHistory({
357
+ sessionId: turnCtx.sessionId, userText: turnCtx.userText, requestChars, maxChars,
358
+ });
359
+ fired = result.fired;
360
+ reason = result.reason;
361
+ historyCompacted = fired;
362
+ } catch (error) {
363
+ reason = 'compaction-error';
364
+ debug.log('llm.request', 'request-size-compact-error', {
365
+ stage, requestChars, maxChars, message: error instanceof Error ? error.message : String(error),
366
+ }, { level: 'warn' });
367
+ }
368
+ return { fired, reason };
369
+ };
370
+ const estimatedSeedChars = estimateRequestChars(turnMessages, tools);
371
+ debug.log('llm.request', 'request-size-compact', {
372
+ stage: 'estimate', sessionId: turnCtx.sessionId,
373
+ beforeChars: estimatedSeedChars, maxChars,
374
+ compacted: false, reason: 'awaiting-exact-wire-measurement',
375
+ });
376
+ requestSizeGuard = createRequestSizeGuard({
377
+ maxChars,
378
+ compactOptions: () => {
379
+ const guardModel = modelOverride ?? getUserConfig().llm?.model;
380
+ const guardConfig = getUserConfig().chat;
381
+ const preserveLastN = guardConfig?.autoCompact?.preserveLastN;
382
+ const archiveEnabled = guardConfig?.compact?.archiveEnabled;
383
+ return {
384
+ sessionId: turnCtx.sessionId,
385
+ ...(guardModel ? { activeModelId: guardModel } : {}),
386
+ ...(preserveLastN !== undefined ? { preserveLastN } : {}),
387
+ ...(archiveEnabled !== undefined ? { archiveEnabled } : {}),
388
+ };
389
+ },
390
+ // The preflight estimate missed (wire over cap, seed under): still write the
391
+ // compaction back so the next prompt starts small, then compact this request live.
392
+ compactFirstRequest: async (_current, info) => {
393
+ await compactHistory(info.requestChars, 'first-request');
394
+ return null;
395
+ },
396
+ onMeasured: (measurement) => {
397
+ if (!measurement.compacted) return;
398
+ void turnCtx.pushSessionUpdate(
399
+ { sessionUpdate: 'agent_thought_chunk', content: { type: 'text', text: formatRequestSizeStatus(measurement) } },
400
+ { status: true },
401
+ );
402
+ },
403
+ });
404
+ }
324
405
  let toolCallCount = 0;
325
406
  const toolKinds = new Set<string>();
326
407
  const observeToolBudget = () => {
@@ -369,6 +450,8 @@ export function bridgeCoreTurnToAcp(
369
450
  const runTurnDispatch = (c: CoreTurnContext): Promise<unknown> =>
370
451
  armGoalLoop
371
452
  ? runGoalLoop(c, {
453
+ // ACP owns an interactive provider loop: keep its post-completion response contract.
454
+ terminalCompletionShortcut: false,
372
455
  ...(goalLoopCfg?.maxIterations !== undefined ? { maxIterations: goalLoopCfg.maxIterations } : {}),
373
456
  // #29 처방 — 자리 판정으로 goal loop 에 «되돌아온» 턴만 빈 evidence 완료를 답으로 받는다.
374
457
  ...(route.reason.startsWith('seat-') ? { lenientCompletionEvidence: true } : {}),
@@ -432,8 +515,15 @@ export function bridgeCoreTurnToAcp(
432
515
  ...(modelOverride !== undefined ? { modelOverride } : {}),
433
516
  ...(autohealProvider ?? {}),
434
517
  ...(maxToolTurns !== undefined ? { maxToolTurns } : {}),
518
+ ...(requestSizeGuard ? { requestSizeGuard } : {}),
435
519
  ...((!factQuestion || explicitMaxToolTurns !== undefined) && deps.budgetGrant !== undefined ? { budgetGrant: deps.budgetGrant } : {}),
436
520
  callbacks: {
521
+ onStatus: (line) => {
522
+ void turnCtx.pushSessionUpdate(
523
+ { sessionUpdate: 'agent_thought_chunk', content: { type: 'text', text: line } },
524
+ { status: true },
525
+ );
526
+ },
437
527
  onGoalInterim: (text) => {
438
528
  void turnCtx.pushSessionUpdate(
439
529
  { sessionUpdate: 'agent_message_chunk', content: { type: 'text', text: '' } },
@@ -13,7 +13,7 @@
13
13
  // 콜백으로 위임(tgChat/dcChannel 정체성은 서피스가 소유).
14
14
 
15
15
  import { buildDelegateAgentTool, dispatchDelegateAgent } from '../boot/daemon-tools/delegate-agent.js';
16
- import { buildSelfImplementDaemonSpec, dispatchSelfImplement } from '../boot/daemon-tools/self-implement.js';
16
+ import { buildSelfImplementDaemonSpec, dispatchSelfImplement, dispatchSelfImplementManaged } from '../boot/daemon-tools/self-implement.js';
17
17
  // ⛔ 잎 모듈에서 받는다 — 순환 import TDZ 를 «구조적으로» 없앤 자리(`self-implement-names.ts` 머리말).
18
18
  import { SELF_IMPLEMENT_TOOL_NAMES } from '../boot/daemon-tools/self-implement-names.js';
19
19
  import { dispatchRelayShellPrompt } from '../skills/tools/relay-shell.js';
@@ -80,6 +80,9 @@ export function buildAutonomousToolSpecs(): LLMToolSpec[] {
80
80
  export interface AutonomousToolTurnCtx {
81
81
  cwd: string;
82
82
  signal: AbortSignal;
83
+ /** Core-turn identity used to make a managed SelfImplement admission retry-safe. */
84
+ sessionId?: string;
85
+ toolCallId?: string;
83
86
  surfaceHitlChannels?: ConfirmChannel[];
84
87
  surfaceQuestionChannels?: QuestionChannel[];
85
88
  surfaceFileSink?: FileSink;
@@ -139,18 +142,22 @@ export async function dispatchAutonomousTool(
139
142
  const hctx = {
140
143
  cwd: ctx.cwd,
141
144
  signal: ctx.signal,
145
+ ...(ctx.sessionId ? { sessionId: ctx.sessionId } : {}),
146
+ ...(ctx.toolCallId ? { toolCallId: ctx.toolCallId } : {}),
142
147
  ...(ctx.userText ? { userText: ctx.userText } : {}),
143
148
  ...(surfaceChannels ? { surfaceHitlChannels: surfaceChannels } : {}),
144
149
  ...(surfaceQuestionChannels ? { surfaceQuestionChannels } : {}),
145
150
  ...(surfaceFileSink ? { surfaceFileSink } : {}),
146
151
  ...(ctx.emitFeedback ? { emitFeedback: ctx.emitFeedback } : {}), // start-ack/진행 push
147
152
  };
148
- const dispatch = ctx.selfImplementDispatch ?? dispatchSelfImplement;
153
+ const dispatch = ctx.selfImplementDispatch;
149
154
  return wrapAutonomousTool(
150
155
  {
151
156
  toolNames: SELF_IMPLEMENT_TOOL_NAMES as readonly string[],
152
157
  label: 'SelfImplement',
153
- run: () => dispatch(args, hctx as Parameters<typeof dispatchSelfImplement>[1]),
158
+ run: () => dispatch
159
+ ? dispatch(args, hctx as Parameters<typeof dispatchSelfImplement>[1])
160
+ : dispatchSelfImplementManaged(args, hctx as Parameters<typeof dispatchSelfImplementManaged>[1]),
154
161
  },
155
162
  args,
156
163
  hctx,
@@ -18,6 +18,7 @@ import { existsSync } from 'node:fs';
18
18
  import type { UserConfig } from '../user-config.js';
19
19
  import { runTurn, type RunTurnOpts } from '../session/chat.js';
20
20
  import type { SessionSource } from '../session/index.js';
21
+ import type { CoreTurnDispatchTool } from '../core-turn/index.js';
21
22
  import { buildContinuationAgentTools } from '../dispatch/continuation-turn-runner.js';
22
23
  import { buildTerminalCapableTurn } from './terminal-surface.js';
23
24
  // ★ turn 조립기 통일 Phase 1(2026-07-22) — 자율tool 5종(delegate·SelfImplement·RelayShell·RunDevHarness·
@@ -202,7 +203,7 @@ export function makeElanousAgentRunTurn(cfg: UserConfig, surface: SessionSource,
202
203
  // Track whether the turn handed off to an ACP delegate — the footer then
203
204
  // reads acp-<backend> instead of self·<model>.
204
205
  let delegatedBackend: string | undefined;
205
- const dispatch = async (name: string, args: Record<string, unknown>): Promise<unknown> => {
206
+ const dispatch: CoreTurnDispatchTool = async (name, args, dispatchCtx) => {
206
207
  // ⭐ 소환기(F2 · 2026-07-26) — 이 서피스도 SelfImplement/RunDevHarness/
207
208
  // SolveMission 을 defer 하므로 tier-flip 이 ToolSearch 를 주입한다.
208
209
  // 라우팅이 없으면 모델이 소환을 시도하는 순간 "unknown tool" 이다.
@@ -217,6 +218,8 @@ export function makeElanousAgentRunTurn(cfg: UserConfig, surface: SessionSource,
217
218
  // Forward the turn's abort signal (from a /cancel-aware controller) so
218
219
  // an in-flight delegation can be cancelled; inert signal otherwise.
219
220
  signal: opts.signal ?? new AbortController().signal,
221
+ ...(dispatchCtx?.sessionId ? { sessionId: dispatchCtx.sessionId } : {}),
222
+ ...(dispatchCtx?.callId ? { toolCallId: dispatchCtx.callId } : {}),
220
223
  ...(surfaceChannels ? { surfaceHitlChannels: surfaceChannels } : {}),
221
224
  ...(surfaceQuestionChannels ? { surfaceQuestionChannels } : {}),
222
225
  ...(surfaceFileSink ? { surfaceFileSink } : {}),
@@ -159,9 +159,9 @@ export class AgentRegistry {
159
159
  * wants to register the task with the registry before deciding
160
160
  * whether to run it (e.g., confirmation gate). Always depth=0 —
161
161
  * manual register has no parent context. */
162
- register(definition: AgentDefinition, prompt: string): AgentTask {
162
+ register(definition: AgentDefinition, prompt: string, opts: { id?: string } = {}): AgentTask {
163
163
  const task: AgentTask = {
164
- id: randomUUID(),
164
+ id: opts.id ?? randomUUID(),
165
165
  definition,
166
166
  prompt,
167
167
  depth: 0,
@@ -176,6 +176,30 @@ export class AgentRegistry {
176
176
  return task;
177
177
  }
178
178
 
179
+ /** Run a registered non-LLM job under the same observable/cancellable task lifecycle. */
180
+ async runManaged<T>(id: string, runner: (signal: AbortSignal) => Promise<T>, renderResult: (value: T) => string = String): Promise<T> {
181
+ const task = this.tasks.get(id);
182
+ if (!task) throw new Error(`agent task not found: ${id}`);
183
+ if (task.state !== 'pending') throw new Error(`agent task is not pending: ${id} (${task.state})`);
184
+ task.state = 'running';
185
+ task.startedAt = Date.now();
186
+ try {
187
+ const value = await runner(task.controller.signal);
188
+ task.state = task.controller.signal.aborted ? 'aborted' : 'done';
189
+ task.result = renderResult(value);
190
+ return value;
191
+ } catch (error) {
192
+ const message = error instanceof Error ? error.message : String(error);
193
+ if (task.controller.signal.aborted) task.state = 'aborted';
194
+ else { task.state = 'error'; task.error = message; }
195
+ task.result = message;
196
+ throw error;
197
+ } finally {
198
+ task.finishedAt = Date.now();
199
+ this.notifyTaskDone(task);
200
+ }
201
+ }
202
+
179
203
  get(id: string): AgentTask | undefined {
180
204
  return this.tasks.get(id);
181
205
  }
@@ -39,7 +39,7 @@ export function buildSharedAppTools(cfg?: UserConfig): SharedAppTools {
39
39
  // context(B5) — 기억 조회 같은 긴 코어 도구가 진행 한 줄(emitFeedback)을 낼 수 있게 코어까지 넘긴다.
40
40
  const dispatch = async (name: string, args: Record<string, unknown>, context?: ToolRuntimeContext): Promise<unknown> =>
41
41
  name === skillsList.name ? dispatchElanousSkillsList(args as ElanousSkillsListArgs) :
42
- name === skill.id ? skill.run(args as unknown as SkillExecArgs, { surface: 'skill' }) :
42
+ name === skill.id ? skill.run(args as unknown as SkillExecArgs, { surface: context?.surface ?? 'skill', signal: context?.signal }) :
43
43
  fin && fin.names.has(name) ? fin.dispatch(name, args) : core.dispatch(name, args, undefined, context);
44
44
  return { specs, names, dispatch };
45
45
  }
@@ -75,7 +75,7 @@ function buildSurfaceUx(src: SurfaceUxSource): SurfaceUx {
75
75
  debug.log('surface-ux.confirm', 'answered', { surface, channel: res.channel, answer: res.answer });
76
76
  return res.answer === true;
77
77
  },
78
- async question(req) {
78
+ async question(req, opts) {
79
79
  if (!questionChannels || questionChannels.length === 0) {
80
80
  debug.log('surface-ux.confirm', 'question', {
81
81
  surface,
@@ -83,8 +83,17 @@ function buildSurfaceUx(src: SurfaceUxSource): SurfaceUx {
83
83
  });
84
84
  return null;
85
85
  }
86
- const res = await requestQuestion({ request: req, channels: questionChannels });
87
- if (res.channel === 'all-failed' || res.channel === 'timeout') {
86
+ const res = await requestQuestion({ request: req, channels: questionChannels, ...(opts?.timeoutMs === undefined ? {} : { timeoutMs: opts.timeoutMs }) });
87
+ if (res.channel === 'timeout') {
88
+ debug.log('surface-ux.confirm', 'question', {
89
+ surface,
90
+ mode: 'timeout',
91
+ elapsedMs: res.elapsedMs,
92
+ timeoutMs: opts?.timeoutMs,
93
+ });
94
+ return null;
95
+ }
96
+ if (res.channel === 'all-failed') {
88
97
  debug.log('surface-ux.confirm', 'question', {
89
98
  surface,
90
99
  mode: QUESTION_OBSERVATION_MODE.unanswered,
@@ -54,7 +54,7 @@ export interface SurfaceUx {
54
54
  /** HITL 승인(버튼). 채널 없으면 **fail-closed → false**(자동승인 금지·제1원칙). */
55
55
  confirm(req: ConfirmRequest): Promise<boolean>;
56
56
  /** 구조화 질문(N옵션). 채널 없으면 null(호출자가 default-and-note). */
57
- question(req: AskUserQuestionRequest): Promise<AskUserQuestionResult | null>;
57
+ question(req: AskUserQuestionRequest, opts?: { timeoutMs?: number }): Promise<AskUserQuestionResult | null>;
58
58
  /** 큰 출력 파일 첨부(fire-and-forget · 실패 삼킴). sink 없으면 no-op. */
59
59
  spillFile(f: SurfaceSpillFile): void;
60
60
  /** 진행 상태 push(비동기·best-effort). emitFeedback 없으면 no-op. */
@@ -28,11 +28,12 @@ import {
28
28
  type AgentRegistry,
29
29
  } from './registry.js';
30
30
  import type { AgentTask } from './types.js';
31
+ import type { RunStopRecord } from '../self-implement/run-stop.js';
31
32
  import { globalAgentFlash } from '../display/agent-flash.js';
32
33
  import { debug } from '../debug/log.js';
33
- import { DATA_DIR } from '../config.js';
34
- import { mkdirSync, writeFileSync } from 'node:fs';
35
- import { join } from 'node:path';
34
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
35
+ import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
36
+ import { dirname, join } from 'node:path';
36
37
  import { randomUUID } from 'node:crypto';
37
38
 
38
39
  /** Max chars of the child's final result we echo in the notification.
@@ -65,10 +66,15 @@ export interface PendingTaskNotification {
65
66
  }
66
67
 
67
68
  export class TaskNotificationQueue {
69
+ private readonly persistencePath: string;
68
70
  constructor(
69
- private readonly resultDir = join(DATA_DIR, 'agent-results'),
71
+ private readonly resultDir = join(effectiveInstanceRoot(), 'data', 'agent-results'),
70
72
  private readonly maxResultChars = 10_000_000,
71
- ) {}
73
+ persistencePath?: string,
74
+ ) {
75
+ this.persistencePath = persistencePath ?? '';
76
+ if (this.persistencePath) this.restore();
77
+ }
72
78
 
73
79
  private queue: PendingTaskNotification[] = [];
74
80
  /** De-dup guard — same task.finishedAt can fire twice if a caller
@@ -96,6 +102,13 @@ export class TaskNotificationQueue {
96
102
  return () => { this.wakeListeners.delete(listener); };
97
103
  }
98
104
 
105
+ /** Replay restored pending receipts to one newly installed wake consumer. */
106
+ replayPendingWakes(listener: (n: PendingTaskNotification) => void): void {
107
+ for (const pending of this.queue) {
108
+ try { listener(pending); } catch { /* replay listener isolation */ }
109
+ }
110
+ }
111
+
99
112
  enqueue(n: PendingTaskNotification): void {
100
113
  if (this.seen.has(n.taskId)) return;
101
114
  let pending = n;
@@ -119,6 +132,7 @@ export class TaskNotificationQueue {
119
132
  }
120
133
  this.seen.add(n.taskId);
121
134
  this.queue.push(pending);
135
+ this.persist();
122
136
  debug.log('agent.task-notification', 'wake', { taskId: n.taskId, size: this.queue.length });
123
137
  for (const listener of this.wakeListeners) {
124
138
  try {
@@ -141,6 +155,7 @@ export class TaskNotificationQueue {
141
155
  drain(): PendingTaskNotification[] {
142
156
  const out = this.queue;
143
157
  this.queue = [];
158
+ this.persist();
144
159
  // NOTE: we keep `seen` populated so a listener firing a second
145
160
  // time for the same task (rare but possible under races) still
146
161
  // can't double-inject. `seen` grows unbounded across a session;
@@ -172,10 +187,64 @@ export class TaskNotificationQueue {
172
187
  clear(): void {
173
188
  this.queue = [];
174
189
  this.seen.clear();
190
+ this.persist();
175
191
  }
192
+
193
+ private restore(): void {
194
+ try {
195
+ const value: unknown = JSON.parse(readFileSync(this.persistencePath, 'utf8'));
196
+ if (!value || typeof value !== 'object') throw new Error('invalid task notification snapshot');
197
+ const snapshot = value as { version?: number; queue?: PendingTaskNotification[]; seen?: string[] };
198
+ if (snapshot.version !== 1 || !Array.isArray(snapshot.queue) || !Array.isArray(snapshot.seen)) throw new Error('invalid task notification snapshot');
199
+ this.queue = snapshot.queue;
200
+ this.seen = new Set(snapshot.seen);
201
+ } catch (error) {
202
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;
203
+ debug.log('agent.task-notification', 'restore-failed', { path: this.persistencePath, reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' });
204
+ }
205
+ }
206
+
207
+ private persist(): void {
208
+ if (!this.persistencePath) return;
209
+ try {
210
+ mkdirSync(dirname(this.persistencePath), { recursive: true });
211
+ const temp = `${this.persistencePath}.${randomUUID()}.tmp`;
212
+ writeFileSync(temp, `${JSON.stringify({ version: 1, queue: this.queue, seen: [...this.seen] })}\n`, { encoding: 'utf8', flag: 'wx', mode: 0o600 });
213
+ renameSync(temp, this.persistencePath);
214
+ } catch (error) {
215
+ debug.log('agent.task-notification', 'persist-failed', { path: this.persistencePath, reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' });
216
+ }
217
+ }
218
+ }
219
+
220
+ export function resolveTaskNotificationPaths(instanceRoot = effectiveInstanceRoot()): { resultDir: string; persistencePath: string } {
221
+ const dataDir = process.env.ELANOUS_DATA_DIR?.trim() || join(instanceRoot, 'data');
222
+ return { resultDir: join(dataDir, 'agent-results'), persistencePath: join(dataDir, 'agent-task-notifications.json') };
176
223
  }
177
224
 
178
- export const globalTaskNotificationQueue = new TaskNotificationQueue();
225
+ const taskNotificationPaths = resolveTaskNotificationPaths();
226
+ export const globalTaskNotificationQueue = new TaskNotificationQueue(
227
+ taskNotificationPaths.resultDir, 10_000_000, taskNotificationPaths.persistencePath,
228
+ );
229
+
230
+ /** Wake a parent as soon as a SelfImplement run records its terminal stop, even if post-stop cleanup stalls. */
231
+ export function enqueueSelfImplementRunStopNotification(
232
+ input: { runId: string; taskId: string; feature: string; stop: RunStopRecord },
233
+ queue: TaskNotificationQueue = globalTaskNotificationQueue,
234
+ ): void {
235
+ const { runId, taskId, feature, stop } = input;
236
+ queue.enqueue({
237
+ taskId: `self-implement-stop:${runId}:${taskId}`,
238
+ agentName: 'SelfImplement',
239
+ label: feature.slice(0, 80),
240
+ state: 'error',
241
+ output: `SelfImplement run ${runId} stopped (${stop.class}${stop.site ? ` at ${stop.site}` : ''}): ${stop.cause} · next: ${stop.nextMove}`,
242
+ truncated: false,
243
+ errorMessage: stop.cause,
244
+ durationMs: 0,
245
+ finishedAt: Date.now(),
246
+ });
247
+ }
179
248
 
180
249
  // ── Auto-wire background task completion ─────────────────────────────
181
250
  //
@@ -72,6 +72,9 @@ export interface AgentDefinition {
72
72
  * other than by going through registry methods. */
73
73
  export interface AgentTask {
74
74
  id: string;
75
+ /** Optional identity links for managed non-LLM jobs hosted by the registry. */
76
+ runId?: string;
77
+ parentSessionId?: string;
75
78
  definition: AgentDefinition;
76
79
  /** Caller-supplied short label for this specific spawn — distinct
77
80
  * from `definition.description` which is the boilerplate stamp