elanous 0.2.22 → 0.2.23

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 (705) hide show
  1. package/NOTICE +7 -0
  2. package/README.md +32 -22
  3. package/apps/pwa/out/404/index.html +1 -1
  4. package/apps/pwa/out/404.html +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
  9. package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
  11. package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
  12. package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
  21. package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
  23. package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
  24. package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
  27. package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/272-b23d2e92161d11fd.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
  35. package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3961-fbef064c213b2b18.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
  39. package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
  52. package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
  53. package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
  56. package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
  59. package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
  64. package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
  69. package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
  71. package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
  73. package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
  74. package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
  78. package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
  83. package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
  84. package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
  85. package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
  86. package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
  87. package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
  90. package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
  97. package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
  99. package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
  101. package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
  105. package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
  110. package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
  111. package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
  112. package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
  114. package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
  116. package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
  117. package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
  120. package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
  123. package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5341ac96203a983.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ad3bd8084048bee4.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/{page-80ed511e02c81412.js → page-6168a7c43e6ef8f5.js} +1 -1
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-a648bc464c9dc754.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-2bd9ce9c020d02d4.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-48fb31810693c357.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/page-cb154acadb025414.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-745d9b6c015076f8.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
  184. package/apps/pwa/out/_next/static/css/5619d59e87eddf66.css +1 -0
  185. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
  186. package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_buildManifest.js +1 -1
  187. package/apps/pwa/out/approvals/index.html +1 -1
  188. package/apps/pwa/out/approvals/index.txt +23 -23
  189. package/apps/pwa/out/autopilot/index.html +1 -1
  190. package/apps/pwa/out/autopilot/index.txt +23 -23
  191. package/apps/pwa/out/board/index.html +1 -1
  192. package/apps/pwa/out/board/index.txt +23 -23
  193. package/apps/pwa/out/botlab/index.html +1 -1
  194. package/apps/pwa/out/botlab/index.txt +22 -22
  195. package/apps/pwa/out/bots/index.html +1 -1
  196. package/apps/pwa/out/bots/index.txt +22 -22
  197. package/apps/pwa/out/ceo/index.html +1 -1
  198. package/apps/pwa/out/ceo/index.txt +23 -23
  199. package/apps/pwa/out/chat/index.html +1 -1
  200. package/apps/pwa/out/chat/index.txt +22 -22
  201. package/apps/pwa/out/consult/index.html +1 -1
  202. package/apps/pwa/out/consult/index.txt +23 -23
  203. package/apps/pwa/out/control/index.html +1 -1
  204. package/apps/pwa/out/control/index.txt +23 -23
  205. package/apps/pwa/out/decisions/index.html +1 -1
  206. package/apps/pwa/out/decisions/index.txt +22 -22
  207. package/apps/pwa/out/design-check/index.html +1 -1
  208. package/apps/pwa/out/design-check/index.txt +23 -23
  209. package/apps/pwa/out/editor/index.html +1 -1
  210. package/apps/pwa/out/editor/index.txt +24 -23
  211. package/apps/pwa/out/exec/index.html +1 -1
  212. package/apps/pwa/out/exec/index.txt +23 -23
  213. package/apps/pwa/out/field/index.html +1 -1
  214. package/apps/pwa/out/field/index.txt +23 -23
  215. package/apps/pwa/out/healthz +1 -1
  216. package/apps/pwa/out/index.html +1 -1
  217. package/apps/pwa/out/index.txt +22 -22
  218. package/apps/pwa/out/inside/index.html +1 -1
  219. package/apps/pwa/out/inside/index.txt +22 -22
  220. package/apps/pwa/out/intake/index.html +1 -1
  221. package/apps/pwa/out/intake/index.txt +23 -23
  222. package/apps/pwa/out/live/index.html +1 -1
  223. package/apps/pwa/out/live/index.txt +23 -23
  224. package/apps/pwa/out/live-run/index.html +1 -1
  225. package/apps/pwa/out/live-run/index.txt +24 -23
  226. package/apps/pwa/out/loops/index.html +1 -1
  227. package/apps/pwa/out/loops/index.txt +22 -22
  228. package/apps/pwa/out/market/index.html +1 -1
  229. package/apps/pwa/out/market/index.txt +22 -22
  230. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  231. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  232. package/apps/pwa/out/morning/index.html +1 -1
  233. package/apps/pwa/out/morning/index.txt +23 -23
  234. package/apps/pwa/out/observatory/index.html +1 -1
  235. package/apps/pwa/out/observatory/index.txt +23 -23
  236. package/apps/pwa/out/ops/checklist/index.html +1 -1
  237. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  238. package/apps/pwa/out/ops/release/index.html +1 -1
  239. package/apps/pwa/out/ops/release/index.txt +22 -22
  240. package/apps/pwa/out/ops/seats/index.html +1 -1
  241. package/apps/pwa/out/ops/seats/index.txt +22 -22
  242. package/apps/pwa/out/outputs/index.html +1 -1
  243. package/apps/pwa/out/outputs/index.txt +22 -22
  244. package/apps/pwa/out/reflection/index.html +1 -1
  245. package/apps/pwa/out/reflection/index.txt +23 -23
  246. package/apps/pwa/out/scheduler/index.html +1 -1
  247. package/apps/pwa/out/scheduler/index.txt +23 -23
  248. package/apps/pwa/out/sessions/index.html +1 -1
  249. package/apps/pwa/out/sessions/index.txt +22 -22
  250. package/apps/pwa/out/settings/devices/index.html +1 -1
  251. package/apps/pwa/out/settings/devices/index.txt +23 -23
  252. package/apps/pwa/out/settings/index.html +1 -1
  253. package/apps/pwa/out/settings/index.txt +23 -23
  254. package/apps/pwa/out/setup/done/index.html +1 -1
  255. package/apps/pwa/out/setup/done/index.txt +23 -23
  256. package/apps/pwa/out/setup/index.html +1 -1
  257. package/apps/pwa/out/setup/index.txt +23 -23
  258. package/apps/pwa/out/share/index.html +1 -1
  259. package/apps/pwa/out/share/index.txt +23 -23
  260. package/apps/pwa/out/showroom/index.html +1 -1
  261. package/apps/pwa/out/showroom/index.txt +22 -22
  262. package/apps/pwa/out/tasks/index.html +1 -1
  263. package/apps/pwa/out/tasks/index.txt +23 -23
  264. package/apps/pwa/out/term/index.html +1 -1
  265. package/apps/pwa/out/term/index.txt +23 -23
  266. package/apps/pwa/out/today/index.html +1 -1
  267. package/apps/pwa/out/today/index.txt +23 -23
  268. package/apps/pwa/out/trace/index.html +1 -1
  269. package/apps/pwa/out/trace/index.txt +23 -23
  270. package/apps/pwa/out/vault/index.html +1 -1
  271. package/apps/pwa/out/vault/index.txt +23 -23
  272. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  273. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  274. package/apps/pwa/out/workflows/index.html +1 -1
  275. package/apps/pwa/out/workflows/index.txt +23 -23
  276. package/apps/pwa/out/workspace/index.html +1 -1
  277. package/apps/pwa/out/workspace/index.txt +23 -23
  278. package/apps/pwa/out/worktrees/index.html +1 -1
  279. package/apps/pwa/out/worktrees/index.txt +23 -23
  280. package/catalog/models/anthropic/claude-haiku-5-5.yaml +32 -0
  281. package/catalog/models/anthropic/claude-opus-5-5.yaml +5 -0
  282. package/catalog/models/anthropic/claude-sonnet-5-5.yaml +31 -0
  283. package/catalog/models/anthropic/claude-sonnet-5.yaml +8 -2
  284. package/catalog/models/openai/gpt-6-astra.yaml +6 -0
  285. package/catalog/models/openai/gpt-6-luna.yaml +6 -0
  286. package/catalog/models/openai/gpt-6-sol.yaml +6 -0
  287. package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
  288. package/graphs/log-horizon/recipes.yaml +3 -0
  289. package/graphs/release/recipes.yaml +1 -1
  290. package/graphs/release/release-loop.yaml +6 -2
  291. package/graphs/release-rehearsal/recipes.yaml +12 -0
  292. package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
  293. package/package.json +4 -1
  294. package/scripts/bench-report.ts +82 -3
  295. package/scripts/ci-typecheck-changed.ts +10 -1
  296. package/scripts/hq/hq-fence-wrapper.sh +148 -0
  297. package/scripts/lib/typecheck-ratchet.ts +51 -0
  298. package/scripts/openai-relay-server.ts +5 -1
  299. package/scripts/release-loop/docs-node.ts +258 -43
  300. package/scripts/release-loop/gate-method.ts +59 -0
  301. package/scripts/release-loop/gate-node.ts +73 -7
  302. package/scripts/release-loop/gate-wall.ts +208 -0
  303. package/scripts/release-loop/known-issues-node.ts +53 -8
  304. package/scripts/release-loop/publish-at.ts +14 -0
  305. package/scripts/release-loop/publish-node.ts +17 -2
  306. package/scripts/release-loop/resume-release.ts +34 -4
  307. package/scripts/release-loop/resume.ts +53 -0
  308. package/scripts/release-loop/shard-plan.ts +3 -11
  309. package/scripts/release-loop/tui-node-checks.ts +22 -0
  310. package/scripts/release-loop/unattended-release.ts +8 -1
  311. package/scripts/rhythm/daily.ts +51 -2
  312. package/scripts/rhythm/weekly.ts +3 -2
  313. package/scripts/tsc-main-safety-net.ts +189 -0
  314. package/scripts/usage-rollup.ts +8 -4
  315. package/src/acp/codex-plugins.ts +48 -6
  316. package/src/agent/monad-agent-turn.ts +67 -5
  317. package/src/agent/run-context.ts +10 -0
  318. package/src/agent/tool-profile.ts +28 -2
  319. package/src/agent-mission/acp-judge.ts +8 -2
  320. package/src/agent-mission/capabilities-cli.ts +16 -1
  321. package/src/agent-mission/driver.ts +1 -1
  322. package/src/agent-mission/pr-review-watch.ts +6 -2
  323. package/src/agent-mission/review-loop.ts +33 -5
  324. package/src/agent-substrate/acp-reviewer.ts +17 -8
  325. package/src/agent-substrate/pr-reviewer.ts +164 -28
  326. package/src/agent-substrate/review-intent.ts +6 -4
  327. package/src/agent-substrate/self-review-cli.ts +111 -16
  328. package/src/agent-substrate/shard-boundary-intent.ts +92 -26
  329. package/src/ask-user-question/pending-questions.ts +8 -2
  330. package/src/autopilot/build/llm-conflict-merge.ts +216 -12
  331. package/src/autopilot/codebase-grounding.ts +44 -0
  332. package/src/autopilot/llm-control-brain.ts +13 -1
  333. package/src/autopilot/mission-codebase-gate.ts +8 -77
  334. package/src/autopilot/pr-manager.ts +12 -3
  335. package/src/boot/acp-server.ts +4 -7
  336. package/src/boot/acp-socket-path.ts +7 -0
  337. package/src/briefing/brief-items.ts +21 -13
  338. package/src/chat/index.ts +12 -3
  339. package/src/cli/agent-cli.ts +20 -0
  340. package/src/cli/brief-cli.ts +27 -21
  341. package/src/cli/cli-user-error.ts +9 -2
  342. package/src/cli/log-event-names.ts +3 -0
  343. package/src/cli/logs-cli.ts +1 -0
  344. package/src/cli/mcp-login.ts +111 -37
  345. package/src/cli/plugin-cli.ts +21 -1
  346. package/src/cli/pod-cli.ts +26 -0
  347. package/src/cli/pr-cli.ts +30 -2
  348. package/src/cli/pr-land-overlap-evidence.ts +131 -0
  349. package/src/cli/release-cli.ts +53 -11
  350. package/src/cli/self-update.ts +173 -10
  351. package/src/cli/skills-cli.ts +12 -3
  352. package/src/cli/tasks-cli.ts +133 -27
  353. package/src/context-bus/context-first.ts +51 -2
  354. package/src/context-bus/context-now-surfaces.ts +13 -2
  355. package/src/context-bus/long-term-memory.ts +3 -1
  356. package/src/context-bus/nightly-condense.ts +3 -2
  357. package/src/core-turn/run-goal-loop.ts +86 -2
  358. package/src/dashboard/chat-fold.ts +20 -0
  359. package/src/dashboard/first-screen-band.ts +151 -1
  360. package/src/dashboard/index.ts +27 -5
  361. package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -3
  362. package/src/dashboard/stale-install-check.ts +13 -2
  363. package/src/dashboard/turn-stream-formatter.ts +25 -0
  364. package/src/debug/log-diet.ts +159 -0
  365. package/src/debug/log.ts +52 -17
  366. package/src/display/coordinator.ts +25 -2
  367. package/src/domains/coo-admin-tool.ts +27 -0
  368. package/src/domains/cron-match.ts +1 -0
  369. package/src/domains/outbound-alert.ts +17 -6
  370. package/src/domains/release-tool.ts +119 -10
  371. package/src/domains/schedule-registry.ts +10 -7
  372. package/src/domains/schedule-runner.ts +1 -0
  373. package/src/elanous-config-dir.ts +2 -2
  374. package/src/elanous-daemon.ts +3 -3
  375. package/src/execution-loop/launch-gate.ts +1 -1
  376. package/src/expression/i18n/messages.en.ts +5 -0
  377. package/src/expression/i18n/messages.ja.ts +5 -0
  378. package/src/expression/i18n/messages.ko.ts +5 -0
  379. package/src/expression/i18n/messages.zh.ts +5 -0
  380. package/src/expression/i18n/types.ts +8 -0
  381. package/src/github/pr-labels.ts +1 -0
  382. package/src/graph-runner/runner.ts +54 -5
  383. package/src/harness/dispatch-backpressure.ts +259 -0
  384. package/src/harness/harness-cli-command.ts +107 -28
  385. package/src/harness/harness-seams.ts +2 -20
  386. package/src/harness/harness-substrate-default.ts +72 -1
  387. package/src/harness/nested-elanous-policy.ts +4 -2
  388. package/src/hq/fence-wrapper.ts +7 -0
  389. package/src/hq/hq.ts +33 -2
  390. package/src/hq/lease.ts +13 -0
  391. package/src/hq/seats.ts +114 -18
  392. package/src/index.ts +163 -64
  393. package/src/intake-plane/collect-github.ts +19 -1
  394. package/src/intake-plane/digest.ts +45 -20
  395. package/src/intake-plane/lens.ts +36 -8
  396. package/src/intelligence-map/model-alias.ts +6 -0
  397. package/src/intelligence-map/model-catalog.ts +41 -0
  398. package/src/knowledge/kgs/pack.ts +5 -2
  399. package/src/knowledge/kgs/sqlite-store.ts +15 -0
  400. package/src/knowledge/tools/knowledge-query.ts +20 -2
  401. package/src/knowledge/write.ts +234 -2
  402. package/src/llm/bedrock-provider.ts +175 -0
  403. package/src/llm/bedrock.ts +345 -0
  404. package/src/llm/provider-credentials.ts +3 -1
  405. package/src/llm.ts +306 -35
  406. package/src/loops/budget.ts +150 -0
  407. package/src/loops/orchestrator/seat-share.ts +6 -49
  408. package/src/loops/orchestrator/traffic.ts +5 -81
  409. package/src/market/signed-index.ts +42 -0
  410. package/src/mcp/mcp-oauth.ts +136 -17
  411. package/src/model-tier/llm-tier-map.ts +48 -4
  412. package/src/models/prompts.ts +22 -1
  413. package/src/mss/logging/horizon-watch.ts +168 -0
  414. package/src/mss/logging/log-store.ts +204 -15
  415. package/src/native-tool-catalog.ts +1 -1
  416. package/src/nexus/api/consult-requests.ts +7 -10
  417. package/src/nexus/api/discord-trigger-bot.ts +6 -3
  418. package/src/nexus/api/error-reports.ts +30 -8
  419. package/src/nexus/api/http-server.ts +8 -0
  420. package/src/nexus/api/loop-resources.ts +42 -0
  421. package/src/nexus/api/outbound-report.ts +8 -3
  422. package/src/nexus/api/telegram-trigger-bot.ts +6 -3
  423. package/src/nexus/index.ts +10 -0
  424. package/src/nexus/outbound/format.ts +2 -0
  425. package/src/nexus/outbound/router.ts +198 -13
  426. package/src/oauth/codex-account-rotation.ts +16 -18
  427. package/src/oauth/codex-account-store.ts +134 -5
  428. package/src/oauth/fallback-chain.ts +28 -6
  429. package/src/onboarding.ts +2 -1
  430. package/src/plugins/adapters/claude-package.ts +4 -12
  431. package/src/plugins/core/capability-policy.ts +141 -0
  432. package/src/plugins/core/host.ts +21 -8
  433. package/src/plugins/core/manifest.ts +19 -2
  434. package/src/plugins/core/trust-store.ts +15 -0
  435. package/src/plugins/core/types.ts +12 -0
  436. package/src/plugins/install/market-fetch.ts +68 -16
  437. package/src/plugins/install/plugin-install.ts +187 -16
  438. package/src/plugins/maker/plugin-maker.ts +25 -20
  439. package/src/plugins/maker/wizard-generate.ts +16 -2
  440. package/src/policy/llm-policy.ts +14 -1
  441. package/src/process/pid-liveness.ts +1 -1
  442. package/src/prompt-cache/openai.ts +10 -6
  443. package/src/prompt-cache/openrouter.ts +94 -0
  444. package/src/prompt-enhance/enhance.ts +46 -5
  445. package/src/prompt-library/family-prompt-coverage.ts +1 -0
  446. package/src/prompt-library/universal-preamble.ts +2 -2
  447. package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
  448. package/src/registry/loader.ts +6 -1
  449. package/src/release-loop/checklist.ts +24 -9
  450. package/src/release-loop/feature-store.ts +3 -0
  451. package/src/release-loop/gate-shards.ts +48 -4
  452. package/src/release-loop/landed-to-green.ts +81 -0
  453. package/src/release-loop/light-rc.ts +11 -1
  454. package/src/release-loop/merged-pr-checklist.ts +10 -0
  455. package/src/release-loop/placement.ts +91 -22
  456. package/src/release-loop/rehearsal.ts +317 -0
  457. package/src/release-loop/release-schedule.ts +13 -1
  458. package/src/release-loop/rubric-types.ts +1 -0
  459. package/src/release-loop/rubric.ts +2 -2
  460. package/src/retro/daily.ts +23 -9
  461. package/src/seat-loop/seat-loop.ts +34 -1
  462. package/src/seat-loop/traffic-signal.ts +44 -0
  463. package/src/self-dev/ask-launch-flow.ts +2 -2
  464. package/src/self-dev/dev-cli.ts +67 -3
  465. package/src/self-dev/dev-pipeline.ts +4 -6
  466. package/src/self-dev/draft-residue.ts +463 -0
  467. package/src/self-dev/draft-sweep.ts +151 -10
  468. package/src/self-dev/draft-triage-rules.ts +27 -1
  469. package/src/self-dev/launch-preflight-text.ts +549 -0
  470. package/src/self-dev/launch-preflight.ts +10 -545
  471. package/src/self-dev/orchestrate-cli.ts +57 -2
  472. package/src/self-dev/orchestrate-summary-line.ts +13 -0
  473. package/src/self-dev/orchestrate.ts +8 -135
  474. package/src/self-dev/review-provider-fallback.ts +115 -19
  475. package/src/self-dev/run-store.ts +1 -3
  476. package/src/self-dev/run-supervisor.ts +3 -22
  477. package/src/self-dev/run-types.ts +178 -0
  478. package/src/self-dev/shard-aggregate.ts +61 -13
  479. package/src/self-dev/shard-plan.ts +5 -1
  480. package/src/self-dev/shard-run.ts +23 -5
  481. package/src/self-dev/supervisor-verdict-edges.ts +2 -4
  482. package/src/self-implement/blocked-draft-policy.ts +3 -19
  483. package/src/self-implement/draft-on-stop-mode.ts +18 -0
  484. package/src/self-implement/follow-up-goals.ts +114 -38
  485. package/src/self-implement/gate-baseline-reap.ts +157 -0
  486. package/src/self-implement/gate-baseline.ts +78 -16
  487. package/src/self-implement/gate-cli.ts +12 -2
  488. package/src/self-implement/gate-remote.ts +17 -6
  489. package/src/self-implement/goal-author.ts +24 -4
  490. package/src/self-implement/goal-digest.ts +19 -0
  491. package/src/self-implement/graph-overlay-condition.ts +4 -0
  492. package/src/self-implement/headless-elanous-driver.ts +11 -9
  493. package/src/self-implement/host-regate.ts +120 -29
  494. package/src/self-implement/l8-merge-queue.ts +67 -5
  495. package/src/self-implement/merge-train.ts +131 -0
  496. package/src/self-implement/off-diff-evidence.ts +9 -0
  497. package/src/self-implement/orchestrator.ts +133 -16
  498. package/src/self-implement/review-finding-recurrence.ts +28 -0
  499. package/src/self-implement/rework-policy.ts +2 -1
  500. package/src/self-implement/round-summary-card.ts +63 -0
  501. package/src/self-implement/run-ledger.ts +4 -3
  502. package/src/self-implement/run-step-projection.ts +147 -0
  503. package/src/self-implement/run-stop.ts +1 -1
  504. package/src/self-implement/seams.ts +36 -3
  505. package/src/self-implement/self-implement-cli.ts +3 -1
  506. package/src/self-implement/train-gate-remote.ts +158 -0
  507. package/src/session-runtime/index.ts +10 -1
  508. package/src/session-runtime/retry-api.ts +11 -1
  509. package/src/skills/gift-install.ts +119 -0
  510. package/src/skills/runner.ts +59 -2
  511. package/src/skills/skill-feedback.ts +31 -1
  512. package/src/skills/skill-tier.ts +1 -0
  513. package/src/smart-wizard/capability-index.ts +231 -0
  514. package/src/smart-wizard/rung.ts +74 -0
  515. package/src/steward/launch.ts +20 -9
  516. package/src/steward/triage.ts +4 -2
  517. package/src/storage/file-lock.ts +8 -1
  518. package/src/task-agent/actions.ts +4 -0
  519. package/src/task-agent/card-evidence.ts +59 -13
  520. package/src/task-agent/judge.ts +4 -3
  521. package/src/task-agent/land-worktree.ts +201 -0
  522. package/src/task-agent/live-move-history.ts +133 -0
  523. package/src/task-agent/live-moves.ts +106 -19
  524. package/src/task-agent/parent-host.ts +117 -8
  525. package/src/task-agent/rejudge-on-head.ts +297 -0
  526. package/src/task-agent/review-result-capture.ts +218 -0
  527. package/src/task-agent/shadow.ts +103 -7
  528. package/src/task-agent/task-hand.ts +136 -11
  529. package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
  530. package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
  531. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
  532. package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
  533. package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
  534. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
  535. package/src/task-orchestrator/surfaces/pod-pool.ts +66 -14
  536. package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
  537. package/src/task-orchestrator/surfaces/self-implement.ts +6 -2
  538. package/src/telegram-service.ts +5 -1
  539. package/src/telegram.ts +17 -4
  540. package/src/time/format.ts +13 -4
  541. package/src/tool-runtime/goal-author-runtime.ts +1 -0
  542. package/src/tool-runtime/self-cognition-catalog.ts +23 -0
  543. package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
  544. package/src/user-config.ts +132 -24
  545. package/src/ux-sim/slash-menu-frames.ts +168 -0
  546. package/src/version/packed-revision.json +1 -1
  547. package/src/web-terminal/preview-tap-registry.ts +5 -2
  548. package/src/workflow-runtime/triggers/scheduler.ts +1 -0
  549. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
  550. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
  551. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
  552. package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
  554. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
  555. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
  556. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
  558. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
  563. package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
  572. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
  573. package/apps/pwa/out/_next/static/chunks/2489-d238d3e2eb5b2bf5.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
  586. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
  594. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
  599. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
  601. package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
  605. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
  610. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
  615. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
  616. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
  618. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
  619. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
  627. package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
  630. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
  640. package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
  643. package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
  647. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
  648. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/approvals/page-88459e0903da2803.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d85c43f46f58716b.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/board/page-4e645600579ae952.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/botlab/page-87edbfd19117823b.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/chat/page-cbaf66b1e1804adf.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/control/page-9f5610caaa06178c.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/decisions/page-ec8f3575e339de74.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/exec/page-2a19c5cd3b562580.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/field/page-b6a09cde2e07521a.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/loops/page-abd86cd832aaa011.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8c3f168fc3f91939.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/morning/page-786fb4504d0f2fa9.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7ec8e289b4c14df6.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-8c8ac17d52be2a79.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d359ab048d63a9d9.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/settings/page-f151cc10ad026940.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/share/page-bf495a1e284f4e00.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/term/page-9abcfac07e02a542.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/workflows/page-69cb93d1a2e57e0e.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/workspace/page-72ec543928d67c3e.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
  704. package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +0 -1
  705. /package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
@@ -75,15 +75,24 @@ export function registerConnectCommand(program: Command): void {
75
75
  export function registerSkillsCommands(program: Command): void {
76
76
  const skills = program.command('skills').description('Check, install and repair skills');
77
77
  skills.command('install <pack>')
78
- .description('Install a gift skill pack from a code')
78
+ .description('Install a gift skill pack from a code or a signed knowledge pack from a configured market')
79
79
  .option('--code <code>', 'Gift code')
80
80
  .option('--email <address>', 'Email for gift delivery')
81
81
  .option('--agree', 'Agree to email collection and retention')
82
82
  .option('--endpoint <url>', 'Gift API origin (overrides skills.giftEndpoint)')
83
+ .option('--market <name>', 'Install a signed knowledge pack from a configured market instead of redeeming a gift')
84
+ .option('--enterprise <id>', 'Authorized enterprise for an internal knowledge market')
83
85
  .option('--json', 'Print the install result as JSON')
84
- .action(async (pack: string, opts: { code?: string; email?: string; agree?: boolean; endpoint?: string; json?: boolean }) => {
86
+ .action(async (pack: string, opts: { code?: string; email?: string; agree?: boolean; endpoint?: string; market?: string; enterprise?: string; json?: boolean }) => {
85
87
  const { getUserConfig } = await import('../user-config.js');
86
- const { installGiftPack } = await import('../skills/gift-install.js');
88
+ const { installGiftPack, installMarketKnowledgePack } = await import('../skills/gift-install.js');
89
+ if (opts.market) {
90
+ const result = await installMarketKnowledgePack({ pack, market: opts.market, enterpriseId: opts.enterprise });
91
+ if (opts.json) console.log(JSON.stringify(result));
92
+ else console.log(result.ok ? `설치한 지식 팩: ${result.packId}` : `지식 팩 설치 실패: ${result.reason}`);
93
+ if (!result.ok) process.exitCode = 1;
94
+ return;
95
+ }
87
96
  const result = await installGiftPack({ pack, code: opts.code, email: opts.email, agree: opts.agree,
88
97
  endpoint: opts.endpoint ?? getUserConfig().skills.giftEndpoint });
89
98
  if (opts.json) console.log(JSON.stringify(result));
@@ -9,8 +9,9 @@ import { readNexusRuntime } from '../nexus/runtime.js';
9
9
  import { checklistDevVersion } from '../release-loop/checklist.js';
10
10
  import { cardsBoard, countBoardTasks, INTERNAL_PACK_PROJECT, mergeBoards, releasePackBoard, type BoardNode } from '../task-agent/board.js';
11
11
  import type { Task } from '../task-orchestrator/types.js';
12
- import { cardPrNumber, COMPLETION_KINDS, handTask, nextMoveFor, readTaskAgentState, readTaskCard, taskAgentStatePath as taskStatePathDefault, shellQuote, TASK_CARD_PREFIX, TASK_SEATS, type CompletionKind, type TaskCard, type TaskLaunchContext, type TaskLaunchReceipt, type TaskLauncher, type TaskSeat } from '../task-agent/task-hand.js';
12
+ import { cardPrNumber, COMPLETION_KINDS, handTask, LIVE_MOVE_HISTORY_EVENT, LIVE_MOVE_RESULT_EVENT, nextMoveFor, resolveHandText, readTaskAgentState, readTaskCard, taskAgentStatePath as taskStatePathDefault, shellQuote, TA_LAND_ENV, TASK_CARD_PREFIX, TASK_SEATS, type CompletionKind, type TaskCard, type TaskLaunchContext, type TaskLaunchReceipt, type TaskLauncher, type TaskSeat } from '../task-agent/task-hand.js';
13
13
  import { readCardSalvageBranch, refreshCardRunBinding, type CardRunEvidenceDeps } from '../task-agent/card-evidence.js';
14
+ import { captureReviewResults } from '../task-agent/review-result-capture.js';
14
15
  import { advanceMission, handMission, MissionAdvanceError, openMissionIds, recordPieceRef, type AdvanceMissionResult, type MissionDecompose, type PieceEvidenceReader } from '../task-agent/mission.js';
15
16
  import { formatTaskAgentCover, measureTaskAgentCover, type CoverRow, type TaskAgentCoverInput } from '../task-agent/cover.js';
16
17
  import { LogStore, STORE_SAFETY_MAX, type LogQuery, type LogStoreRow } from '../mss/logging/log-store.js';
@@ -25,6 +26,8 @@ export interface TasksCliDeps {
25
26
  output?: (line: string) => void;
26
27
  /** `task hand --live` 의 발사기(시험 주입). 기본은 운영 config-dir 로 `harness say` 를 떼어 띄운다. */
27
28
  taskLauncher?: TaskLauncher;
29
+ /** TA-REVIEW-RESULT-CAPTURE — `tasks show` 의 리뷰 결과 회수 시각(시험 주입 · 기본 지금). */
30
+ reviewResultNow?: () => Date;
28
31
  /** 과제 카드 상태 파일(시험 주입). 기본 = `effectiveInstanceRoot()/task-agent-actions.json`. */
29
32
  taskStatePath?: string;
30
33
  /** logs.db 싱크 등록(시험 주입). 기본 = `registerStandaloneLogSink`. `hand`·`show` 가 부른다. */
@@ -44,6 +47,10 @@ export interface TasksCliDeps {
44
47
  /** `tasks cover` logs 조회 seam. 기본은 등록된 모든 우주(운영 ⊕ test)의 logs.db 를 read-only 로 연다 —
45
48
  * pr land 는 작업 트리마다 파생 test 우주에 기록되므로 현재 우주만 읽으면 분모가 늘 0 이다. */
46
49
  coverLogs?: (query: LogQuery) => LogStoreRow[] | CoverLogRead;
50
+ /** TA-REJUDGE-ON-HEAD — `tasks rejudge` 의 판단 의존(시험 주입 · 기본 = 설정 liveMoves ⊕ 실물 gh·리뷰·재게이트·land). */
51
+ rejudge?: Partial<import('../task-agent/rejudge-on-head.js').RejudgeDeps>;
52
+ /** TA-REJUDGE-ON-HEAD — `tasks regate-run` 의 재게이트(시험 주입 · 기본 `runHostRegate`). */
53
+ hostRegate?: (input: import('../self-implement/host-regate.js').HostRegateInput) => Promise<import('../self-implement/host-regate.js').HostRegateResult>;
47
54
  }
48
55
 
49
56
  /** `<조각id>=<값>` 반복 인자. */
@@ -108,7 +115,7 @@ export interface DefaultTaskLauncherDeps {
108
115
  /** 이미 stop 이 있나(시험 주입). 기본 = 이 우주 런 원장 ⊕ 이 프로세스 기록. */
109
116
  hasStop?: (runId: string) => boolean;
110
117
  /** HARNESS-PARENT-ON-MSB1 — 원격 부모 대상(시험 주입). undefined = 설정·env 에서 푼다 · null = 끔. */
111
- parentHost?: import('../task-agent/parent-host.js').ParentHostConfig | null;
118
+ parentHost?: import('../task-agent/parent-host.js').ParentHostConfig | readonly import('../task-agent/parent-host.js').ParentHostConfig[] | null;
112
119
  /** 원격 ssh(시험 주입). */
113
120
  ssh?: import('../task-agent/parent-host.js').SshRunner;
114
121
  /** HQ 발사 동결(holdLaunches) 여부(시험 주입). */
@@ -125,21 +132,23 @@ export interface DefaultTaskLauncherDeps {
125
132
  */
126
133
  async function tryRemoteParent(args: string[], cwd: string | undefined, context: TaskLaunchContext, deps: DefaultTaskLauncherDeps): Promise<TaskLaunchReceipt | null> {
127
134
  const parentHostModule = await import('../task-agent/parent-host.js');
128
- let target = deps.parentHost;
129
- if (target === undefined) {
135
+ let configured: import('../task-agent/parent-host.js').ParentHostSetting | null | undefined = deps.parentHost;
136
+ if (configured === undefined) {
130
137
  const { getUserConfig } = await import('../user-config.js');
131
- let configured: Parameters<typeof parentHostModule.resolveParentHost>[0];
132
138
  try { configured = getUserConfig().taskAgent?.parentHost; } catch { configured = undefined; }
133
- target = parentHostModule.resolveParentHost(configured);
134
139
  }
135
- if (!target) return null;
140
+ const multi = Array.isArray(configured);
141
+ const targets = configured === null ? [] : parentHostModule.resolveParentHosts(configured, deps.parentHost === undefined ? process.env : { ...process.env, ELANOUS_TA_PARENT_HOST: undefined });
142
+ if (!targets.length) return null;
136
143
  const notice = deps.notice ?? ((line: string) => { try { process.stderr.write(`${line}\n`); } catch { /* ignore */ } });
137
- const fallback = (gaps: string[], facts: Record<string, string> = {}): null => {
138
- try { debug.log('task-agent', 'parent-host-fallback', { host: target!.host, runId: context.runId, gaps, facts }); } catch { /* fail-soft */ }
139
- notice(`[parent-host] ${target!.host} 로 못 띄움 — 로컬 발사로 간다: ${gaps.join(' · ')}`);
140
- return null;
144
+ const failed = (target: typeof targets[number], gaps: string[], facts: Record<string, string> = {}): void => {
145
+ try { debug.log('task-agent', 'parent-host-fallback', { host: target.host, runId: context.runId, gaps, facts }); } catch { /* fail-soft */ }
146
+ notice(`[parent-host] ${target.host} 로 못 띄움 — ${multi ? '다음 호스트 또는 로컬 발사로 간다' : '로컬 발사로 간다'}: ${gaps.join(' · ')}`);
141
147
  };
142
- if (cwd) return fallback(['project-target-is-local']);
148
+ if (cwd || context.env[TA_LAND_ENV] === '1') {
149
+ failed(targets[0]!, [cwd ? 'project-target-is-local' : 'ta-land-needs-local-parent']);
150
+ return null;
151
+ }
143
152
  let launchHoldActive = false;
144
153
  try {
145
154
  if (deps.launchHoldActive) launchHoldActive = deps.launchHoldActive();
@@ -149,18 +158,28 @@ async function tryRemoteParent(args: string[], cwd: string | undefined, context:
149
158
  launchHoldActive = readLandingFreeze(prodInstanceRoot())?.holdLaunches === true;
150
159
  }
151
160
  } catch { launchHoldActive = true; /* 못 읽으면 막힌 것으로(fail-closed) */ }
152
- const preflight = parentHostModule.preflightParentHost({ target, localVersion: deps.localVersion ?? parentHostModule.localElanousVersion(), launchHoldActive, ...(deps.ssh ? { ssh: deps.ssh } : {}) });
153
- if (!preflight.ok) return fallback(preflight.gaps, preflight.facts);
154
- try {
155
- const launched = parentHostModule.launchRemoteParent(target, args, context.env, deps.ssh);
156
- try { debug.log('task-agent', 'parent-host-launched', { host: target.host, runId: context.runId, pid: launched.pid, log: launched.log }); } catch { /* fail-soft */ }
157
- return { runId: context.runId, parentHost: { host: target.host, ...(target.configDir ? { configDir: target.configDir } : {}), pid: launched.pid, log: launched.log } };
158
- } catch (error) {
159
- // «확실히 안 떴다»일 때만 로컬로 — 불확실(ssh 끊김 등)은 던져 카드를 launch-failed 로 남긴다(중복 발사 방지).
160
- if (error instanceof parentHostModule.RemoteParentNotLaunchedError) return fallback([error.message]);
161
- try { debug.log('task-agent', 'parent-host-launch-uncertain', { host: target.host, runId: context.runId, error: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
162
- throw error;
161
+ const capacities = Object.fromEntries(multi ? targets.map((target) => [target.host, parentHostModule.readParentHostCapacity(target, deps.ssh)]) : []);
162
+ const ordered = multi ? parentHostModule.orderParentHosts(targets, context.runId, capacities) : targets;
163
+ for (const target of ordered) {
164
+ if (multi && (!capacities[target.host] || capacities[target.host]!.approvalHeadroom <= 0)) {
165
+ failed(target, ['capacity-unavailable']);
166
+ continue;
167
+ }
168
+ let preflight: ReturnType<typeof parentHostModule.preflightParentHost>;
169
+ try { preflight = parentHostModule.preflightParentHost({ target, localVersion: deps.localVersion ?? parentHostModule.localElanousVersion(), launchHoldActive, ...(deps.ssh ? { ssh: deps.ssh } : {}) }); }
170
+ catch (error) { failed(target, [`preflight-error: ${error instanceof Error ? error.message : String(error)}`]); continue; }
171
+ if (!preflight.ok) { failed(target, preflight.gaps, preflight.facts); continue; }
172
+ try {
173
+ const launched = parentHostModule.launchRemoteParent(target, args, context.env, deps.ssh);
174
+ try { debug.log('task-agent', 'parent-host-launched', { host: target.host, runId: context.runId, pid: launched.pid, log: launched.log }); } catch { /* fail-soft */ }
175
+ return { runId: context.runId, parentHost: { host: target.host, ...(target.configDir ? { configDir: target.configDir } : {}), pid: launched.pid, log: launched.log } };
176
+ } catch (error) {
177
+ if (error instanceof parentHostModule.RemoteParentNotLaunchedError) { failed(target, [error.message]); continue; }
178
+ try { debug.log('task-agent', 'parent-host-launch-uncertain', { host: target.host, runId: context.runId, error: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
179
+ throw error;
180
+ }
163
181
  }
182
+ return null;
164
183
  }
165
184
 
166
185
  /** stderr 파일의 첫 비어 있지 않은 줄(최대 4KB 만 읽는다 — 원 로그 꼬리를 싣지 않는다). */
@@ -315,10 +334,25 @@ function taskCardLines(card: TaskCard): string[] {
315
334
  [card.id, card.status, card.seat ?? '-', card.checklistId ?? '-', card.createdAt, card.text].join('\t'),
316
335
  ...(card.mission ? [`미션: ${card.mission} · after: ${card.after?.length ? card.after.join(', ') : '-'}`] : []),
317
336
  ...runLinkLine(card),
337
+ ...liveMoveLines(card),
318
338
  `다음 수: ${moveLine(card)}`,
319
339
  ];
320
340
  }
321
341
 
342
+ /** TA-LIVE-MOVE-CARD-HISTORY — 카드 history 의 live-move 줄(실행·그림자)을 한 줄씩. 없으면 없다(옛 카드 그대로). */
343
+ function liveMoveLines(card: TaskCard): string[] {
344
+ return (card.history ?? []).filter((item) => item.event === LIVE_MOVE_HISTORY_EVENT || item.event === LIVE_MOVE_RESULT_EVENT).map((item) => item.event === LIVE_MOVE_RESULT_EVENT ? [
345
+ // TA-REVIEW-RESULT-CAPTURE — 회수한 리뷰 결과(또는 «결과 없음») 줄.
346
+ `결과: ${item.at}`, `${item.kind ?? '?'}`, `PR ${item.pr !== undefined ? `#${item.pr}` : '-'}${item.head ? ` head ${item.head.slice(0, 12)}` : ''}`,
347
+ `verdict=${item.verdict ?? '—'} reviewed=${item.reviewed ?? '—'} must-fix=${item.mustFix ?? '—'} route=${item.reviewRoute ?? '—'}`,
348
+ `효과: ${item.effect ?? 'unknown'}`, (item.detail ?? '').replace(/\r\n|\r|\n/g, (match) => (match === '\r' ? '\\r' : '\\n')),
349
+ ].join(' · ') : [
350
+ `수: ${item.at}`, `${item.kind ?? '?'} ${item.executorResult ?? '?'}`, `executed=${item.executed === true} ok=${item.ok === undefined ? '—' : item.ok}`,
351
+ `PR ${item.pr !== undefined ? `#${item.pr}` : '-'}${item.head ? ` head ${item.head.slice(0, 12)}` : ''}`,
352
+ `효과: ${item.effect ?? 'unknown'}`, (item.detail ?? '').replace(/\r\n|\r|\n/g, (match) => (match === '\r' ? '\\r' : '\\n')),
353
+ ].join(' · '));
354
+ }
355
+
322
356
  /** 미션 카드 — 머리 한 줄 ⊕ 조각 한 줄씩(상태·다음 수·선행) ⊕ 간선 한 줄씩. */
323
357
  function missionLines(mission: TaskCard, pieces: TaskCard[]): string[] {
324
358
  const edges = pieces.flatMap((piece) => (piece.after ?? []).map((before) => `간선: ${before} -> ${piece.id}`));
@@ -553,8 +587,11 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
553
587
  .option('--milestone <id>', '보드 소속 이정표 id (task board)')
554
588
  .option('--target <dir>', '프로젝트 대상 디렉터리(있어야 한다 · 상대 경로는 절대로 · git 이 아니면 --completion 이 code-pr 밖이어야 한다) — 발사기를 이 디렉터리에서 띄운다')
555
589
  .option('--live', '실제로 발사한다(기본은 shadow — 명령만 출력)')
590
+ .option('--ta-land', 'TA-LIVE-LAND-2 — 호스트는 재게이트만 하고 병합은 TASK-AGENT 의 propose-land(`pr land --expected-head`)에 맡긴다 · 카드 taLand ⊕ 발사 env ELANOUS_TA_LAND=1 · taskAgent.liveMoves 에 propose-land 가 없으면 종전대로 호스트가 병합')
591
+ .option('--child-llm <provider/model>', 'TASKS-HAND-CHILD-LLM — 구현 자식 LLM(예: grok/grok-4.7) → 발사 인자 --child-llm-provider <provider> --child-llm-model <model> · «첫» `/` 에서만 가른다(모델 id 의 `/` 는 보존) · openrouter 는 모델 id 가 openrouter/ 접두를 포함하므로 전체를 모델로(openrouter/z-ai/glm-5.3 → --child-llm-model openrouter/z-ai/glm-5.3) · 카드 childLlm · 안 주면 명령·카드 무변경')
592
+ .option('--child-llm-effort <level>', '구현 자식 추론 노력 → 발사 인자 --child-llm-effort(검증은 하니스 · --child-llm 과 함께)')
556
593
  .option('--json', 'JSON 출력')
557
- .action(async (text: string | undefined, opts: { seat?: TaskSeat; checklist?: string; completion?: CompletionKind; mission?: string; project?: string; target?: string; goal?: string; milestone?: string; live?: boolean; json?: boolean }) => {
594
+ .action(async (text: string | undefined, opts: { seat?: TaskSeat; checklist?: string; completion?: CompletionKind; mission?: string; project?: string; target?: string; goal?: string; milestone?: string; live?: boolean; taLand?: boolean; childLlm?: string; childLlmEffort?: string; json?: boolean }) => {
558
595
  await registerTaskAgentSink(deps.registerSink);
559
596
  if ((text === undefined) === (opts.mission === undefined)) {
560
597
  out('과제 한 줄 «또는» --mission <문면> 중 하나만 준다');
@@ -566,8 +603,8 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
566
603
  process.exitCode = 1;
567
604
  return;
568
605
  }
569
- if (opts.mission !== undefined && (opts.completion !== undefined || opts.project !== undefined || opts.goal !== undefined || opts.milestone !== undefined)) {
570
- out('--completion/--project/--target/--goal/--milestone 은 과제 한 줄에만 준다 — --mission 조각은 종전처럼 code-pr 이다');
606
+ if (opts.mission !== undefined && (opts.completion !== undefined || opts.project !== undefined || opts.goal !== undefined || opts.milestone !== undefined || opts.taLand === true || opts.childLlm !== undefined || opts.childLlmEffort !== undefined)) {
607
+ out('--completion/--project/--target/--goal/--milestone/--ta-land/--child-llm 은 과제 한 줄에만 준다 — --mission 조각은 종전처럼 code-pr 이다');
571
608
  process.exitCode = 1;
572
609
  return;
573
610
  }
@@ -601,8 +638,18 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
601
638
  return;
602
639
  }
603
640
  try {
641
+ const resolved = resolveHandText(text!);
642
+ if (resolved.kind === 'rejected') {
643
+ try { debug.log('task-agent.hand', 'goal-file-rejected', { path: resolved.path, reason: resolved.reason }); } catch { /* fail-soft */ }
644
+ out(`골 파일 ${resolved.path}: ${resolved.reason}`);
645
+ process.exitCode = 1;
646
+ return;
647
+ }
648
+ if (resolved.kind === 'inlined') {
649
+ try { debug.log('task-agent.hand', 'goal-file-inlined', { path: resolved.path, chars: resolved.chars, sha256: resolved.sha256 }); } catch { /* fail-soft */ }
650
+ }
604
651
  const result = await handTask({
605
- text: text!,
652
+ text: resolved.text,
606
653
  ...(opts.project !== undefined && opts.target !== undefined ? { project: { id: opts.project, target: opts.target } } : {}),
607
654
  ...(opts.goal !== undefined ? { goal: opts.goal } : {}),
608
655
  ...(opts.milestone !== undefined ? { milestone: opts.milestone } : {}),
@@ -610,6 +657,9 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
610
657
  ...(opts.checklist ? { checklistId: opts.checklist } : {}),
611
658
  ...(opts.completion ? { completion: opts.completion } : {}),
612
659
  live: opts.live === true,
660
+ ...(opts.taLand === true ? { taLand: true } : {}),
661
+ ...(opts.childLlm !== undefined ? { childLlm: opts.childLlm } : {}),
662
+ ...(opts.childLlmEffort !== undefined ? { childLlmEffort: opts.childLlmEffort } : {}),
613
663
  ...(deps.taskStatePath ? { statePath: deps.taskStatePath } : {}),
614
664
  launcher: deps.taskLauncher ?? defaultTaskLauncher,
615
665
  });
@@ -618,6 +668,7 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
618
668
  out(`${result.card.id}\t${result.mode}\t${result.launched ? 'launched' : 'not launched'}`);
619
669
  out(`elanous ${result.move.command!.map(shellQuote).join(' ')}`);
620
670
  if (result.cwd) out(`(cwd: ${result.cwd})`);
671
+ if (result.card.taLand) out('(ta-land — 발사 env ELANOUS_TA_LAND=1 · 로컬 부모 · taskAgent.liveMoves 에 propose-land 가 있으면 병합은 TASK-AGENT 몫, 없으면 종전대로 호스트 병합)');
621
672
  if (!result.launched) out('(shadow — 띄우지 않았다 · 띄우려면 --live)');
622
673
  }
623
674
  } catch (error) {
@@ -785,6 +836,8 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
785
836
  // 근거 없음으로 보인다 — 원장 부재와 갈리게 실패는 남긴다.
786
837
  try { debug.log('task-agent', 'card-bind-failed', { card: cardId, via: 'show', error: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
787
838
  }
839
+ // TA-REVIEW-RESULT-CAPTURE — 떼어 띄운 live review 의 결과 파일을 이 카드 history 로 회수한다(대기 중인 요청이 있을 때만 쓴다 · 던지지 않는다).
840
+ captureReviewResults(deps.taskStatePath ?? taskStatePathDefault(), { cardIds: [cardId], ...(deps.reviewResultNow ? { now: deps.reviewResultNow } : {}) });
788
841
  }
789
842
  if (card) card = readTaskCard(id, deps.taskStatePath);
790
843
  } catch (error) {
@@ -841,6 +894,59 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
841
894
  } catch (error) { handleError(error, out); }
842
895
  });
843
896
 
897
+ tasks.command('rejudge [id]')
898
+ .description('TA-REJUDGE-ON-HEAD — 런 멈춤 뒤 카드 PR 머리가 바뀌었으면 재게이트(떼어 띄움)·리뷰 재요청·land(재게이트 통과 ⊕ 지금 머리 pass ⊕ must-fix 0 · 겹침 증거)를 다시 판단한다 · 허용은 설정 taskAgent.liveMoves 그대로')
899
+ .option('--all', '묶인 PR 로 TA 리뷰를 요청한 적이 있는 카드 전부')
900
+ .option('--json', 'JSON 출력')
901
+ .action(async (id: string | undefined, opts: { all?: boolean; json?: boolean }) => {
902
+ await registerTaskAgentSink(deps.registerSink);
903
+ if ((id === undefined) === (opts.all !== true)) { out('카드 id «또는» --all 중 하나만 준다'); process.exitCode = 1; return; }
904
+ const { rejudgeCandidates, rejudgeCardOnHead } = await import('../task-agent/rejudge-on-head.js');
905
+ const statePath = deps.taskStatePath ?? taskStatePathDefault();
906
+ let ids: string[];
907
+ try { ids = id ? [id] : rejudgeCandidates(readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(statePath).tasks ?? {}); } catch (error) {
908
+ out(error instanceof Error ? error.message : '과제 카드 읽기 실패'); process.exitCode = 1; return;
909
+ }
910
+ const { configuredTaskAgentLiveMoves } = await import('../task-agent/live-moves.js');
911
+ const liveMoves = deps.rejudge?.liveMoves ?? await configuredTaskAgentLiveMoves();
912
+ const all = [];
913
+ for (const cardId of ids) {
914
+ let outcomes: Awaited<ReturnType<typeof rejudgeCardOnHead>>;
915
+ try { outcomes = await rejudgeCardOnHead(cardId, { ...deps.rejudge, liveMoves, live: { ...deps.rejudge?.live, statePath } }); } catch (error) {
916
+ // 카드 하나의 예외가 --all 의 나머지 카드 판단을 멈추지 않게 — 사유를 남기고 다음 카드로.
917
+ const reason = (error instanceof Error ? error.message : String(error)).slice(-300);
918
+ try { debug.log('task-agent', 'rejudge-on-head', { card: cardId, pr: null, fromHead: null, toHead: null, step: 'target', decision: 'rejudge-threw', reason }, { level: 'warn' }); } catch { /* fail-soft */ }
919
+ outcomes = [{ card: cardId, pr: null, fromHead: null, toHead: null, step: 'target', decision: 'rejudge-threw', reason }];
920
+ process.exitCode = 1;
921
+ }
922
+ all.push(...outcomes);
923
+ if (!opts.json) for (const o of outcomes) out([o.card, `PR ${o.pr === null ? '-' : `#${o.pr}`}`, `${o.fromHead?.slice(0, 12) ?? '-'}→${o.toHead?.slice(0, 12) ?? '-'}`, o.step, o.decision, o.reason].join('\t'));
924
+ }
925
+ if (opts.json) out(JSON.stringify(all));
926
+ });
927
+
928
+ tasks.command('regate-run', { hidden: true })
929
+ .description('TA-REJUDGE-ON-HEAD 내부 — 카드 PR 머리 하나의 호스트 재게이트(병합 없음)를 돌리고 결과를 --out 파일로 쓴다(tasks rejudge 가 떼어 띄운다)')
930
+ .requiredOption('--card <id>').requiredOption('--pr <n>').requiredOption('--head <sha>').requiredOption('--repo <root>').requiredOption('--out <path>')
931
+ .action(async (opts: { card: string; pr: string; head: string; repo: string; out: string }) => {
932
+ await registerTaskAgentSink(deps.registerSink);
933
+ const pr = Number(opts.pr);
934
+ const { writeFileSync: write, mkdirSync: mkdir } = await import('node:fs');
935
+ const { dirname: dir } = await import('node:path');
936
+ let result: import('../self-implement/host-regate.js').HostRegateResult;
937
+ try {
938
+ const regate = deps.hostRegate ?? (await import('../self-implement/host-regate.js')).runHostRegate;
939
+ result = await regate({ prNumber: pr, headCommit: opts.head, repoRoot: opts.repo, noMerge: true });
940
+ } catch (error) {
941
+ result = { passed: false, failures: [{ step: 'host-regate', detail: (error instanceof Error ? error.message : String(error)).slice(-300) }], os: process.platform, status: 'unmeasured' };
942
+ }
943
+ const record = { pr, head: opts.head, passed: result.passed, ...(result.status ? { status: result.status } : {}), ...(result.baseCommit ? { baseCommit: result.baseCommit } : {}), failures: result.failures };
944
+ try { debug.log('task-agent', 'regate-run', { card: opts.card, ...record, failures: result.failures.slice(0, 3) }); } catch { /* fail-soft */ }
945
+ mkdir(dir(opts.out), { recursive: true });
946
+ write(opts.out, JSON.stringify(record));
947
+ if (!result.passed) process.exitCode = 1;
948
+ });
949
+
844
950
  tasks.command('approve <id...>')
845
951
  .description('외부 태스크 승인')
846
952
  .action(async (ids: string[]) => {
@@ -1,17 +1,59 @@
1
+ import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
2
+ import { dirname } from 'node:path';
3
+ import { debug } from '../debug/log.js';
1
4
  import type { ContextNowAnswer, ContextNowDeps } from './context-now.js';
2
5
 
3
6
  const CONTEXT_FIRST_GAP_MS = 6 * 60 * 60 * 1000;
4
7
  const CONTEXT_UNREADABLE = '맥락 못 읽음';
5
8
 
9
+ /** Where the last-utterance times survive a daemon restart, so a restart does not read as a first utterance. */
10
+ export interface ContextFirstStore {
11
+ load(): Record<string, number>;
12
+ save(lastUtteranceAt: Record<string, number>): void;
13
+ }
14
+
15
+ /** JSON-file store; unreadable or malformed content loads as empty, write failures never block the turn.
16
+ * Both are logged (`context-first.store`) so a gate that keeps re-arming after restarts can be traced. */
17
+ export function createContextFirstFileStore(path: string): ContextFirstStore {
18
+ return {
19
+ load() {
20
+ try {
21
+ const parsed: unknown = JSON.parse(readFileSync(path, 'utf8'));
22
+ if (!parsed || typeof parsed !== 'object') return {};
23
+ return Object.fromEntries(Object.entries(parsed).filter((entry): entry is [string, number] => Number.isFinite(entry[1])));
24
+ } catch (err) {
25
+ if ((err as NodeJS.ErrnoException)?.code !== 'ENOENT') {
26
+ debug.log('context-first.store', 'load-failed', { path, error: err instanceof Error ? err.message : String(err) });
27
+ }
28
+ return {};
29
+ }
30
+ },
31
+ save(lastUtteranceAt) {
32
+ try {
33
+ mkdirSync(dirname(path), { recursive: true });
34
+ // Write-then-rename so a daemon killed mid-write never leaves a torn file (which would re-arm every opening).
35
+ const tmp = `${path}.${process.pid}.tmp`;
36
+ writeFileSync(tmp, JSON.stringify(lastUtteranceAt));
37
+ renameSync(tmp, path);
38
+ } catch (err) {
39
+ // Persistence must not block the conversation, but a failure is observed.
40
+ debug.log('context-first.store', 'save-failed', { path, error: err instanceof Error ? err.message : String(err) });
41
+ }
42
+ },
43
+ };
44
+ }
45
+
6
46
  /** Track every allowed utterance, consuming a pending summary only on a normal turn. */
7
- export function createContextFirstGate({ now, gapMs = CONTEXT_FIRST_GAP_MS }: { now: () => number; gapMs?: number }) {
8
- const lastUtteranceAt = new Map<string, number>();
47
+ export function createContextFirstGate({ now, gapMs = CONTEXT_FIRST_GAP_MS, store }: { now: () => number; gapMs?: number; store?: ContextFirstStore }) {
48
+ const lastUtteranceAt = new Map<string, number>(Object.entries(store?.load() ?? {}));
9
49
  const pending = new Set<string>();
10
50
  return {
11
51
  note(key: string): void {
12
52
  const at = now();
13
53
  const previous = lastUtteranceAt.get(key);
14
54
  lastUtteranceAt.set(key, at);
55
+ // An entry older than the gap behaves like no entry, so it is dropped from the persisted state.
56
+ store?.save(Object.fromEntries([...lastUtteranceAt].filter(([, time]) => at - time < gapMs)));
15
57
  if (previous === undefined || at - previous >= gapMs) pending.add(key);
16
58
  },
17
59
  take(key: string): boolean {
@@ -20,6 +62,13 @@ export function createContextFirstGate({ now, gapMs = CONTEXT_FIRST_GAP_MS }: {
20
62
  };
21
63
  }
22
64
 
65
+ const OPERATIONAL_QUERY = /발행|릴리[스즈]|배포|버전|상태|현황|스케줄|체크리스트|도는\s*런|돌고\s*있|\brelease\b|\bversion\b|\bstatus\b|\/now\b/i;
66
+
67
+ /** A question about the operation or the release itself already asks for the ledger, so the opening would only push the answer down. */
68
+ export function isOperationalQuery(text: string | undefined): boolean {
69
+ return !!text && OPERATIONAL_QUERY.test(text);
70
+ }
71
+
23
72
  export function renderContextFirst(
24
73
  read: (options: {}, deps?: ContextNowDeps) => ContextNowAnswer,
25
74
  deps: ContextNowDeps | undefined,
@@ -57,6 +57,18 @@ export function renderTelegramNow(input: ContextNowAnswer, audience: ContextNowA
57
57
  * release run, late schedules) ahead of the same `/now` body. `/now` itself stays unchanged. */
58
58
  export function renderContextFirstNow(input: ContextNowAnswer, audience: ContextNowAudience = 'operator'): string {
59
59
  const answer = forAudience(input, audience);
60
+ const { lines, total } = operationalLines(answer);
61
+ if (total > lines.length) lines.push(`… 운영 항목 ${total - lines.length}개 더 (/now)`);
62
+ return [...lines, renderTelegramNow(answer, 'operator')].join('\n');
63
+ }
64
+
65
+ /** Telegram opening: at most three operational rows and nothing else — no `/now` body, no «최근:» row.
66
+ * Empty when nothing operational is running, so the caller sends no opening at all. */
67
+ export function renderContextFirstOpening(input: ContextNowAnswer, audience: ContextNowAudience = 'operator'): string {
68
+ return operationalLines(forAudience(input, audience)).lines.join('\n');
69
+ }
70
+
71
+ function operationalLines(answer: ContextNowAnswer): { lines: string[]; total: number } {
60
72
  const labels = { run: '도는 런', release: '발행 런', 'schedule-late': '지연 스케줄' } as const;
61
73
  const operational = answer.facts.filter(fact => fact.kind === 'run' ||
62
74
  (fact.kind === 'release' && (fact.unreadable || fact.status !== 'done')) ||
@@ -67,8 +79,7 @@ export function renderContextFirstNow(input: ContextNowAnswer, audience: Context
67
79
  const text = fact.kind === 'run' && !fact.unreadable ? `${short(fact.goal.replace(/\s+/g, ' ').trim())} · ${fact.phase} · ${fact.elapsed}` : factText(fact);
68
80
  return `${labels[fact.kind as keyof typeof labels]}: ${text} — ${fact.source}`.replace(/\s+/g, ' ').trim();
69
81
  });
70
- if (operational.length > lines.length) lines.push(`… 운영 항목 ${operational.length - lines.length}개 더 (/now)`);
71
- return [...lines, renderTelegramNow(answer, 'operator')].join('\n');
82
+ return { lines, total: operational.length };
72
83
  }
73
84
 
74
85
  export function renderTuiNow(input: ContextNowAnswer, audience: ContextNowAudience = 'operator'): string[] {
@@ -252,7 +252,9 @@ export async function condenseContextWindowWithReport(
252
252
  if (!/^(?:https?:\/\/|elanous:\/\/)[^\s]+$/.test(link)) { skip('bad-link', source); continue; }
253
253
  const claim = summary.claim && { key: safeLine(summary.claim.key), value: safeLine(summary.claim.value) };
254
254
  if (claim && (!claim.key || !claim.value)) { skip('bad-claim', source); continue; }
255
- if (source.kind === 'event' && !claim) { skip('no-claim', source); continue; }
255
+ // Sleep review can promote a sourced durable event without asserting a comparable fact.
256
+ // The ordinary condense command still requires a claim for event candidates.
257
+ if (source.kind === 'event' && !claim && policy.promotion !== 'sleep-review') { skip('no-claim', source); continue; }
256
258
  kept++;
257
259
  bump(funnel.summarized.accepted, source.seat);
258
260
  const key = keyFor({ project, seat, topic });
@@ -151,7 +151,7 @@ export function summaryInstruction(recipe: 'standard' | 'sleep-review' = 'standa
151
151
  const system = 'Summarize this one-line context event as a compact project/seat memory item. Return ONLY JSON: {"project":"...","topic":"...","summary":"...","claim":{"key":"...","value":"..."}}. Omit claim when the event makes no comparable factual assertion. Never invent a project, topic or claim.';
152
152
  if (recipe === 'standard') return system;
153
153
  // SLEEP1 builds on this librarian recipe; the guardian owns storage hygiene, not promotion judgments.
154
- return `${system.replace('"project":"..."', '"promote":false,"project":"..."')} You are the nightly task agent (librarian). Sleep review (librarian contract): apply the coordinator promotion policy. Return a boolean "promote" for every source. Set promote=true only for sourced, durable project/seat facts or decisions; set promote=false for chatter or speculative claims. A correction with a later timestamp wins; return a comparable claim only for an explicit factual assertion so opposing claims can become OP conflict candidates. Do not perform guardian hygiene (retention, compression, size, backup, integrity or rollback).`;
154
+ return `${system.replace('"project":"..."', '"promote":false,"project":"..."')} You are the nightly task agent (librarian). Sleep review (librarian contract): apply the coordinator promotion policy. Return a boolean "promote" for every source. Set promote=true only for sourced, durable project/seat facts or decisions, including durable updates without a comparable claim; set promote=false for chatter or speculative claims. A correction with a later timestamp wins; return a comparable claim only for an explicit factual assertion so opposing claims can become OP conflict candidates. Do not perform guardian hygiene (retention, compression, size, backup, integrity or rollback).`;
155
155
  }
156
156
 
157
157
  export async function summarize(source: MemorySource, injected?: Record<string, MemorySummary>, recipe: 'standard' | 'sleep-review' = 'standard'): Promise<MemorySummary> {
@@ -213,6 +213,7 @@ export async function runNightlyStage(stage: Stage, context: Context, root: stri
213
213
  if (!collected?.day || !collected.events || !collected.decisions) throw new Error('collect output missing');
214
214
  if (stage === 'condense') {
215
215
  const assignments: Array<{ owner: 'coordinator'; assignee: 'nightly-task-agent'; contract: 'librarian'; recipe: 'sleep-review'; workerPid: number }> = [];
216
+ const policy = { promotion: 'sleep-review', retention: 'guardian' } as const;
216
217
  const items = await condenseContextDay(collected.day, dryRun ? [] : storedItems(root).filter(item => Date.parse(item.updatedAt) < Date.parse(`${collected.day}T00:00:00Z`)), {
217
218
  events: () => collected.events!, decisions: () => collected.decisions!,
218
219
  summarize: async source => {
@@ -223,7 +224,7 @@ export async function runNightlyStage(stage: Stage, context: Context, root: stri
223
224
  assignments.push({ owner: 'coordinator', assignee: 'nightly-task-agent', contract: 'librarian', recipe: 'sleep-review', workerPid });
224
225
  return result;
225
226
  },
226
- }, now, { promotion: 'sleep-review', retention: 'guardian' });
227
+ }, now, policy);
227
228
  return { outcome: 'ok', items, assignments };
228
229
  }
229
230
  const items = context.outputs.condense?.items;
@@ -33,7 +33,7 @@ import { debug } from '../debug/log.js';
33
33
  import { publishGoalLifecycle } from '../goals/loop.js';
34
34
  import { boundReadableText } from '../self-implement/orchestrator.js';
35
35
  import { changedFiles } from '../self-implement/seams.js';
36
- import { getHarnessRunId, getHarnessSpace } from '../harness/harness-space.js';
36
+ import { getHarnessRole, getHarnessRunId, getHarnessSpace } from '../harness/harness-space.js';
37
37
  import { CONTROL_INBOX_DIR_ENV, drainControlInbox, drainSoftStopControlInbox, enqueueControlMemo, type ControlInboxDrain, type ControlMemoPayload } from '../harness/control-inbox.js';
38
38
  import { enqueuePendingUserInput } from '../session/pending-input.js';
39
39
  import { getCurrentPtyId } from '../agent/pty-identity.js';
@@ -200,6 +200,22 @@ export const GOAL_READBACK_PROMPT = [
200
200
  '이미 사용자에게 한 답을 다시 쓰지 마라 — 새 사실이 없으면 텍스트 없이 update_goal 만 호출하라.',
201
201
  ].join('\n');
202
202
 
203
+ /** GOAL-LOOP-INTENT-STALL (0.2.24 · OP or-audit-1010) — 구현 자식이 «도구를 한 번도 안 부르고 말만 한 턴»에
204
+ * 넣는 재촉. hermes-agent stall guard(`agent/turn_final_response.py` 172-205)를 본떴다.
205
+ * ⛔ 기존 프롬프트 상수는 건드리지 않는다 — 재촉 문면은 이 상수 하나뿐이다. */
206
+ export const GOAL_INTENT_STALL_PROMPT = [
207
+ '[act now]',
208
+ '말로 계획만 적고 도구를 하나도 호출하지 않았다. 지금 바로 실제로 도구를 호출해 첫 스텝을 실행하라(예: 대상 파일 읽기).',
209
+ '설명 문장만으로 이 턴을 끝내지 마라.',
210
+ ].join('\n');
211
+
212
+ /** 재촉 상한 — 이 횟수를 쓰고도 텍스트만이면 종전 ④(텍스트 수용)로 그대로 떨어진다. */
213
+ export const GOAL_INTENT_STALL_MAX_REPROMPTS = 2;
214
+
215
+ /** 재촉 가드가 켜지는 provider — ⭐ 이번 조각은 OpenRouter(오픈웨이트 모델) 구현 자식 «한정»이다
216
+ * (OP 10-10 결정 · 실측 GLM Flash 첫 턴 40토큰 말만 하고 abandoned). 다른 provider 는 종전 그대로. */
217
+ export const GOAL_INTENT_STALL_PROVIDERS: ReadonlySet<string> = new Set(['openrouter']);
218
+
203
219
  /** evidence 누락 complete 재주입 — update_goal(complete) 를 호출했으나 evidence 가 비었을 때. */
204
220
  export const GOAL_EVIDENCE_REQUIRED_PROMPT = [
205
221
  '[evidence required]',
@@ -264,6 +280,10 @@ export interface GoalLoopOptions {
264
280
  controlSpaceId?: string | null;
265
281
  /** Test seam — file-backed child liveness heartbeat. Default starts the workspace-file writer. */
266
282
  startLivenessHeartbeat?: typeof startChildLivenessHeartbeat;
283
+ /** GOAL-LOOP-INTENT-STALL — 구현 자식의 LLM provider. `openrouter` 일 때만 «도구 0회·텍스트만» 턴을
284
+ * 최대 2번 재촉한다. 생략하면 harness role 이 executor 인 프로세스에서만 활성 provider 로 푼다.
285
+ * null = 가드 꺼짐. 시험은 이 인자를 명시해 env 에 기대지 않는다. */
286
+ intentStallProvider?: string | null;
267
287
  }
268
288
 
269
289
  export type GoalLoopStopReason =
@@ -449,10 +469,17 @@ export async function runGoalLoop(
449
469
  // ※ 객체 홀더: onToolResult 클로저에서 변이하므로 let narrowing 대신 property 타입으로 읽는다.
450
470
  const runTests: { last: { ok: boolean; fail: number; unmatchedFilters: string[]; pass: number } | null } = { last: null };
451
471
  let lastResult: CoreTurnResult = { stopReason: 'end_turn', finalText: '' };
472
+ // GOAL-LOOP-INTENT-STALL — provider 는 루프 진입 시 «한 번» 정한다. 런 전체 도구 활동은 누적한다.
473
+ const intentStallProvider = await resolveIntentStallProvider(opts.intentStallProvider);
474
+ const intentStallGuard = intentStallProvider !== null && GOAL_INTENT_STALL_PROVIDERS.has(intentStallProvider);
475
+ let anyToolActivity = false;
476
+ let intentStallReprompts = 0;
477
+ // GOAL-LOOP-MIDRUN-STALL — 도구를 쓴 «뒤»의 말뿐인 턴 재촉은 런당 1회뿐이다.
478
+ let intentStallMidrunUsed = false;
452
479
 
453
480
  debug.log('goal.loop', 'start', {
454
481
  sessionId: ctx.sessionId, ...runAttribution, objective, maxIterations, noProgressLimit,
455
- contextTokenLimit, contextPressureRatio,
482
+ contextTokenLimit, contextPressureRatio, intentStallGuard, intentStallProvider,
456
483
  }, { level: 'info' });
457
484
  const bus = getChannelBus();
458
485
  ensureProcessLifecycleBridge(bus, opts.attachLifecycleBridge ?? attachLifecycleBridge);
@@ -702,6 +729,7 @@ export async function runGoalLoop(
702
729
  const goalUpdate = findGoalUpdate(turnNewMessages);
703
730
  const rejectedTools = findRejectedToolCalls(turnNewMessages);
704
731
  const toolActivity = hadToolActivity(turnNewMessages);
732
+ if (toolActivity) anyToolActivity = true;
705
733
  const markerComplete = hasCompletionMarker(lastResult.finalText);
706
734
  const markerBlocked = hasBlockedMarker(lastResult.finalText);
707
735
 
@@ -868,6 +896,43 @@ export async function runGoalLoop(
868
896
  }
869
897
  readbackStreak = 0;
870
898
 
899
+ // ④-0 GOAL-LOOP-INTENT-STALL — OpenRouter 구현 자식이 런 내내 도구를 한 번도 안 부르고 말만 했다
900
+ // (예: 「먼저 파일을 읽겠습니다」 후 멈춤). 일상 답변으로 수락하기 전에 «실제로 도구를 호출하라»를
901
+ // 최대 GOAL_INTENT_STALL_MAX_REPROMPTS 번 넣는다. 재촉 턴도 maxIterations 에 센다(하드캡이 이긴다).
902
+ // 상한을 쓰고도 텍스트만이면 포기 이벤트만 남기고 아래 ④ 로 «그대로» 떨어진다(포기 경로 불변).
903
+ // ⛔ 가드가 꺼졌거나(다른 provider·비-executor) 한 번이라도 도구를 불렀으면 이 블록은 아무것도 안 한다.
904
+ // ⭐ 빈 답(finalChars 0)도 «도구 0회»면 같은 정체로 본다 — 빈 답도 종전엔 text-only-accept 로 abandoned 됐다.
905
+ if (!toolActivity && intentStallGuard && !anyToolActivity) {
906
+ if (intentStallReprompts < GOAL_INTENT_STALL_MAX_REPROMPTS) {
907
+ intentStallReprompts += 1;
908
+ debug.log('goal.loop', 'intent-stall-reprompt', {
909
+ sessionId: ctx.sessionId, ...runAttribution, iterations, attempt: intentStallReprompts,
910
+ finalChars: lastResult.finalText.length, provider: intentStallProvider,
911
+ }, { level: 'info' });
912
+ messages.push({ role: 'user', content: GOAL_INTENT_STALL_PROMPT });
913
+ continue;
914
+ }
915
+ debug.log('goal.loop', 'intent-stall-exhausted', {
916
+ sessionId: ctx.sessionId, ...runAttribution, iterations, attempts: intentStallReprompts,
917
+ provider: intentStallProvider,
918
+ }, { level: 'warn' });
919
+ }
920
+
921
+ // ④-0b GOAL-LOOP-MIDRUN-STALL — 앞서 도구를 썼는데 이번 턴은 도구 없이 말로 끝났다
922
+ // (예: 파일을 읽은 뒤 「이제 수정하겠습니다」 후 멈춤 → 변경 0 abort · 10-10). 같은 가드에서
923
+ // 같은 GOAL_INTENT_STALL_PROMPT 를 «런당 1회»만 넣는다. 재촉 턴도 maxIterations 에 센다.
924
+ // 두 번째 중간 정체는 아래 ④ 로 «그대로» 떨어진다(text-only-accept 불변).
925
+ // ⛔ 가드가 꺼졌으면(다른 provider·비-executor) 이 블록은 아무것도 안 한다 · ④-0 과는 anyToolActivity 로 배타.
926
+ if (!toolActivity && intentStallGuard && anyToolActivity && !intentStallMidrunUsed) {
927
+ intentStallMidrunUsed = true;
928
+ debug.log('goal.loop', 'intent-stall-midrun', {
929
+ sessionId: ctx.sessionId, ...runAttribution, iterations,
930
+ finalChars: lastResult.finalText.length, provider: intentStallProvider,
931
+ }, { level: 'info' });
932
+ messages.push({ role: 'user', content: GOAL_INTENT_STALL_PROMPT });
933
+ continue;
934
+ }
935
+
871
936
  // ④ 순수 텍스트(도구 없음)로 끝났고 종결 신호도 없음 = 일상 답변(목표성 작업 아님).
872
937
  // 재주입하지 않고 그대로 수용해 trivial chat 을 이중 루프하지 않는다.
873
938
  if (!toolActivity) {
@@ -908,3 +973,22 @@ export async function runGoalLoop(
908
973
  stopLivenessHeartbeat();
909
974
  }
910
975
  }
976
+
977
+ /** 가드 provider 를 정한다. 명시 인자가 이긴다(시험·호출부). 생략하면 «구현 자식»(harness role executor)
978
+ * 프로세스에서만 활성 provider(`resolveActiveProvider` — `ELANOUS_LLM_PROVIDER` 릴레이 포함)를 읽는다.
979
+ * ⛔ executor 가 아닌 프로세스(ACP 대시보드·`chat --goal-loop`)는 읽지도 않는다 ⇒ null = 가드 꺼짐.
980
+ * 읽기 실패도 null(fail-open = 종전 동작). */
981
+ async function resolveIntentStallProvider(explicit: string | null | undefined): Promise<string | null> {
982
+ if (explicit !== undefined) return explicit?.trim().toLowerCase() || null;
983
+ if (getHarnessRole() !== 'executor') return null;
984
+ try {
985
+ const { getUserConfig, resolveActiveProvider } = await import('../user-config.js');
986
+ return resolveActiveProvider(getUserConfig());
987
+ } catch (error) {
988
+ // fail-open(가드 꺼짐 = 종전 동작)이지만 «왜 꺼졌나»는 남긴다 — 조용한 꺼짐은 관측 안 한 것이다.
989
+ debug.log('goal.loop', 'intent-stall-provider-unresolved', {
990
+ error: error instanceof Error ? error.message : String(error),
991
+ }, { level: 'warn' });
992
+ return null;
993
+ }
994
+ }
@@ -0,0 +1,20 @@
1
+ import { format, getMessages } from '../expression/i18n/index.js';
2
+
3
+ type Locale = NonNullable<Parameters<typeof getMessages>[0]>;
4
+
5
+ export function splitNoSynthesisTail(text: string): { head: string; tail: string } | null {
6
+ const index = text.indexOf('[NO FINAL SYNTHESIS]');
7
+ if (index === -1) return null;
8
+ return {
9
+ head: text.slice(0, index).trimEnd(),
10
+ tail: text.slice(index),
11
+ };
12
+ }
13
+
14
+ /** English fallback for locale bundles that do not carry the optional key. */
15
+ const FOLDED_TAIL_FALLBACK = '● Internal notes folded · {n} lines · press f to expand';
16
+
17
+ export function buildFoldedTailLine(lineCount: number, locale?: Locale): string {
18
+ const template = getMessages(locale).chatFoldedInternalTail ?? FOLDED_TAIL_FALLBACK;
19
+ return format(template, { n: lineCount });
20
+ }