elanous 0.2.22 → 0.2.24

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 (803) 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/{aBi6EyMtLsrl7J8eH4kF7 → Q-7iofoxOEv1WX18S35of}/_buildManifest.js +1 -1
  6. package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
  9. package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
  10. package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
  11. package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
  12. package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
  13. package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
  15. package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
  24. package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
  25. package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
  28. package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/272-0eed0fb0aab716b6.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
  31. package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
  36. package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3961-aaae04ed1d32622f.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
  40. package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
  49. package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
  53. package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
  54. package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
  57. package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
  65. package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
  70. package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
  72. package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
  74. package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
  75. package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
  79. package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
  84. package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
  85. package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
  86. package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
  88. package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
  91. package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
  98. package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
  100. package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
  102. package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
  103. package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
  106. package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
  111. package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
  112. package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
  113. package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
  115. package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
  117. package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
  118. package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
  121. package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
  124. package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
  125. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/approvals/page-3b9fc39362473ae7.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f2b62c19ca68fef8.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/board/page-d7602d489edf5f37.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/botlab/page-24282bf9f90031a5.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/bots/page-8b7c5ab6b5bc8d64.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/ceo/page-4eb84d454f8c3415.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/chat/page-b2e494bdad57fcb5.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/consult/{page-80ed511e02c81412.js → page-c0ab229673a8b0eb.js} +1 -1
  134. package/apps/pwa/out/_next/static/chunks/app/control/page-3e2b45f3c36dbac4.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c22aa511b28743ad.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/design-check/page-26345242e4049f55.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/editor/page-bf88c0f558d8ef54.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/exec/page-52fec523e5b5d3ad.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/field/page-67723dfdcde92b31.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/inside/page-22725e2570f1126b.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/intake/page-1891335950d68b70.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/layout-3267af1ebdc73cf5.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live/page-c314b75c11234998.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/live-run/page-9f9c85415f61782b.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/loops/page-c1d4276059085587.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/market/page-833aab587f26ad4c.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8526c17ae38e6a50.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/morning/page-f998637a8402115c.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/not-found-b7bb53828b17b335.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/observatory/page-1b1850de0257e46d.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6f23159fedb41f67.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1d809a87139dd024.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-da9e570234d481fd.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/outputs/page-b92caddb5c715f30.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/page-8ce3a38e210b810a.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/reflection/page-57ffeeb6019440fd.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-abbb417bf514630b.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2c2b3f29cec1efa4.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-9369279f72fc7b51.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/settings/page-64861f14039499c3.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ddc4c93efd8ab94b.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/page-901a1391b81053bc.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/share/page-68d9bbaac9841a58.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/showroom/page-b5c0c996f329371e.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/tasks/page-89881ccbcf728978.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/term/page-0e87a803b3d7165e.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/today/page-58d4e5cb30ef4871.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/trace/page-02ce4c3b5f39e4d2.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/vault/page-e620d1bb8eadcec2.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-acf868c64d77f950.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workflows/page-54fa605fa6dba457.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workspace/page-bc79f0833533fa84.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d5c4398eea03d8f3.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
  180. package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
  185. package/apps/pwa/out/_next/static/css/72becfd42807b50d.css +1 -0
  186. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
  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/catalog/models/openrouter/deepseek-v4-pro-0813.yaml +39 -0
  288. package/catalog/models/openrouter/deepseek-v4.1-flash.yaml +38 -0
  289. package/catalog/models/openrouter/glm-5.3-flash.yaml +35 -0
  290. package/catalog/providers/openrouter.yaml +2 -0
  291. package/graphs/implement-loop.yaml +31 -0
  292. package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
  293. package/graphs/log-horizon/recipes.yaml +3 -0
  294. package/graphs/ops/harness-gc.yaml +17 -0
  295. package/graphs/ops/recipes.yaml +3 -0
  296. package/graphs/overlays/README.md +1 -1
  297. package/graphs/overlays/stop-heal-ladder.yaml +105 -0
  298. package/graphs/release/recipes.yaml +1 -1
  299. package/graphs/release/release-loop.yaml +6 -2
  300. package/graphs/release-rehearsal/recipes.yaml +12 -0
  301. package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
  302. package/package.json +4 -1
  303. package/scripts/add-api-key.sh +1 -1
  304. package/scripts/bench-report.ts +82 -3
  305. package/scripts/ci-typecheck-changed.ts +80 -14
  306. package/scripts/fleet/bedrock-pod-secret.ts +122 -0
  307. package/scripts/fleet/node-setup-linux.sh +97 -0
  308. package/scripts/fleet/node-setup.sh +11 -0
  309. package/scripts/fleet/zai-pod-secret.ts +86 -0
  310. package/scripts/hq/hq-fence-wrapper.sh +148 -0
  311. package/scripts/land-global-checks.ts +3 -0
  312. package/scripts/lib/typecheck-ratchet.ts +51 -0
  313. package/scripts/measure-log-diet-2.ts +213 -0
  314. package/scripts/measure-tsc-affected-roots.ts +289 -0
  315. package/scripts/openai-relay-server.ts +5 -1
  316. package/scripts/release-loop/docs-node.ts +258 -43
  317. package/scripts/release-loop/gate-executor.ts +28 -0
  318. package/scripts/release-loop/gate-method.ts +59 -0
  319. package/scripts/release-loop/gate-node.ts +335 -33
  320. package/scripts/release-loop/gate-wall.ts +208 -0
  321. package/scripts/release-loop/known-issues-node.ts +53 -8
  322. package/scripts/release-loop/publish-at.ts +14 -0
  323. package/scripts/release-loop/publish-node.ts +17 -2
  324. package/scripts/release-loop/resume-release.ts +40 -4
  325. package/scripts/release-loop/resume.ts +94 -0
  326. package/scripts/release-loop/shard-plan.ts +3 -11
  327. package/scripts/release-loop/tui-node-checks.ts +22 -0
  328. package/scripts/release-loop/unattended-release.ts +29 -7
  329. package/scripts/rhythm/daily.ts +51 -2
  330. package/scripts/rhythm/weekly.ts +3 -2
  331. package/scripts/tsc-baseline-cache.ts +147 -0
  332. package/scripts/tsc-main-safety-net.ts +189 -0
  333. package/scripts/usage-rollup.ts +64 -8
  334. package/src/acp/codex-plugins.ts +48 -6
  335. package/src/agent/monad-agent-turn.ts +67 -5
  336. package/src/agent/run-context.ts +20 -0
  337. package/src/agent/tool-profile.ts +28 -2
  338. package/src/agent-mission/acp-judge.ts +8 -2
  339. package/src/agent-mission/capabilities-cli.ts +16 -1
  340. package/src/agent-mission/driver.ts +19 -4
  341. package/src/agent-mission/pr-review-watch.ts +6 -2
  342. package/src/agent-mission/resource-ladder.ts +8 -3
  343. package/src/agent-mission/review-loop.ts +41 -7
  344. package/src/agent-substrate/acp-implementer.ts +139 -0
  345. package/src/agent-substrate/acp-reviewer.ts +17 -8
  346. package/src/agent-substrate/pr-reviewer.ts +191 -28
  347. package/src/agent-substrate/review-intent.ts +6 -4
  348. package/src/agent-substrate/self-review-cli.ts +155 -21
  349. package/src/agent-substrate/shard-boundary-intent.ts +92 -26
  350. package/src/ask-user-question/pending-questions.ts +8 -2
  351. package/src/autopilot/build/llm-conflict-merge.ts +216 -12
  352. package/src/autopilot/codebase-grounding.ts +44 -0
  353. package/src/autopilot/llm-control-brain.ts +13 -1
  354. package/src/autopilot/mission-codebase-gate.ts +8 -77
  355. package/src/autopilot/mission-critique.ts +18 -5
  356. package/src/autopilot/mission-feasibility-negotiate.ts +11 -10
  357. package/src/autopilot/mission-trace.ts +12 -1
  358. package/src/autopilot/pr-manager.ts +12 -3
  359. package/src/autopilot/system-lookback-run.ts +16 -10
  360. package/src/bench/bench.ts +183 -0
  361. package/src/boot/acp-server.ts +4 -7
  362. package/src/boot/acp-socket-path.ts +7 -0
  363. package/src/briefing/brief-items.ts +21 -13
  364. package/src/budget/fetchers/grok.ts +15 -5
  365. package/src/budget/llm-cost.ts +37 -5
  366. package/src/budget/types.ts +8 -2
  367. package/src/budget/unified-usage.ts +88 -6
  368. package/src/chat/index.ts +12 -3
  369. package/src/cli/agent-cli.ts +20 -0
  370. package/src/cli/bench-cli.ts +34 -0
  371. package/src/cli/brief-cli.ts +27 -21
  372. package/src/cli/cli-user-error.ts +9 -2
  373. package/src/cli/guardian-cli.ts +26 -1
  374. package/src/cli/image-cli.ts +101 -0
  375. package/src/cli/log-event-names.ts +7 -0
  376. package/src/cli/logs-cli.ts +1 -0
  377. package/src/cli/mcp-login.ts +111 -37
  378. package/src/cli/plugin-cli.ts +21 -1
  379. package/src/cli/pod-cli.ts +26 -0
  380. package/src/cli/pr-cli.ts +90 -5
  381. package/src/cli/pr-land-overlap-evidence.ts +279 -0
  382. package/src/cli/release-cli.ts +63 -12
  383. package/src/cli/rfc-status.ts +52 -2
  384. package/src/cli/self-update.ts +277 -10
  385. package/src/cli/skills-cli.ts +12 -3
  386. package/src/cli/tasks-cli.ts +241 -30
  387. package/src/cli/usage-cli.ts +91 -8
  388. package/src/context-bus/context-first.ts +51 -2
  389. package/src/context-bus/context-now-surfaces.ts +13 -2
  390. package/src/context-bus/long-term-memory.ts +3 -1
  391. package/src/context-bus/nightly-condense.ts +3 -2
  392. package/src/core-turn/run-goal-loop.ts +87 -2
  393. package/src/dashboard/ad-run-setup-bindings.ts +279 -0
  394. package/src/dashboard/chat-fold.ts +20 -0
  395. package/src/dashboard/first-screen-band.ts +151 -1
  396. package/src/dashboard/index.ts +45 -281
  397. package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -3
  398. package/src/dashboard/stale-install-check.ts +24 -2
  399. package/src/dashboard/turn-stream-formatter.ts +25 -0
  400. package/src/debug/log-diet.ts +190 -0
  401. package/src/debug/log.ts +70 -17
  402. package/src/display/coordinator.ts +25 -2
  403. package/src/domains/coo-admin-tool.ts +27 -0
  404. package/src/domains/cron-match.ts +1 -0
  405. package/src/domains/outbound-alert.ts +17 -6
  406. package/src/domains/release-tool.ts +158 -10
  407. package/src/domains/schedule-registry.ts +10 -7
  408. package/src/domains/schedule-runner.ts +1 -0
  409. package/src/elanous-config-dir.ts +2 -2
  410. package/src/elanous-daemon.ts +3 -3
  411. package/src/error-report/report.ts +21 -4
  412. package/src/execution-loop/launch-gate.ts +1 -1
  413. package/src/expression/i18n/messages.en.ts +5 -0
  414. package/src/expression/i18n/messages.ja.ts +5 -0
  415. package/src/expression/i18n/messages.ko.ts +5 -0
  416. package/src/expression/i18n/messages.zh.ts +5 -0
  417. package/src/expression/i18n/types.ts +8 -0
  418. package/src/github/pr-labels.ts +2 -0
  419. package/src/graph-runner/graph-cli.ts +42 -1
  420. package/src/graph-runner/runner.ts +218 -8
  421. package/src/grok/usage.ts +23 -2
  422. package/src/grounding/ref-index.ts +253 -0
  423. package/src/harness/dispatch-backpressure.ts +267 -0
  424. package/src/harness/harness-clean.ts +199 -78
  425. package/src/harness/harness-cli-command.ts +229 -35
  426. package/src/harness/harness-gc.ts +331 -0
  427. package/src/harness/harness-seams.ts +2 -20
  428. package/src/harness/harness-stop.ts +4 -2
  429. package/src/harness/harness-substrate-default.ts +214 -8
  430. package/src/harness/launch-registry.ts +6 -0
  431. package/src/harness/nested-elanous-policy.ts +4 -2
  432. package/src/harness/worktree-branch-prefix.ts +9 -0
  433. package/src/hq/fence-wrapper.ts +7 -0
  434. package/src/hq/fence.ts +187 -0
  435. package/src/hq/hq.ts +33 -2
  436. package/src/hq/lease.ts +13 -0
  437. package/src/hq/seats.ts +133 -21
  438. package/src/images/image-ledger.ts +179 -0
  439. package/src/index.ts +250 -69
  440. package/src/instance/child-scope.ts +32 -1
  441. package/src/instance/dev-project.ts +133 -0
  442. package/src/instance/resolve.ts +24 -0
  443. package/src/instance/spawn-elanous.ts +45 -0
  444. package/src/intake-plane/collect-github.ts +19 -1
  445. package/src/intake-plane/digest.ts +45 -20
  446. package/src/intake-plane/lens.ts +36 -8
  447. package/src/intake-plane/ref-prefetch.ts +110 -0
  448. package/src/intelligence-map/model-alias.ts +6 -0
  449. package/src/intelligence-map/model-catalog.ts +113 -0
  450. package/src/knowledge/kgs/pack.ts +5 -2
  451. package/src/knowledge/kgs/sqlite-store.ts +15 -0
  452. package/src/knowledge/tools/knowledge-query.ts +20 -2
  453. package/src/knowledge/write.ts +234 -2
  454. package/src/llm/bedrock-eventstream.ts +215 -0
  455. package/src/llm/bedrock-provider.ts +248 -0
  456. package/src/llm/bedrock.ts +491 -0
  457. package/src/llm/openrouter-byok-cost.ts +96 -0
  458. package/src/llm/openrouter-deepseek.ts +151 -0
  459. package/src/llm/openrouter-upstream-pins.config.ts +25 -0
  460. package/src/llm/provider-credentials.ts +3 -1
  461. package/src/llm/zai-coding-plan.ts +700 -0
  462. package/src/llm.ts +383 -41
  463. package/src/loops/budget.ts +150 -0
  464. package/src/loops/checker.ts +148 -9
  465. package/src/loops/orchestrator/resync-shadow.ts +34 -7
  466. package/src/loops/orchestrator/seat-share.ts +6 -49
  467. package/src/loops/orchestrator/traffic.ts +5 -81
  468. package/src/market/signed-index.ts +42 -0
  469. package/src/maturity/feature-maturity.ts +2 -2
  470. package/src/mcp/mcp-oauth.ts +136 -17
  471. package/src/model-tier/llm-tier-map.ts +52 -4
  472. package/src/models/prompts.ts +23 -1
  473. package/src/mss/logging/horizon-watch.ts +168 -0
  474. package/src/mss/logging/log-store.ts +262 -26
  475. package/src/native-tool-catalog.ts +1 -1
  476. package/src/nexus/api/consult-requests.ts +7 -10
  477. package/src/nexus/api/discord-trigger-bot.ts +6 -3
  478. package/src/nexus/api/error-reports.ts +30 -8
  479. package/src/nexus/api/http-server.ts +8 -0
  480. package/src/nexus/api/loop-resources.ts +42 -0
  481. package/src/nexus/api/missions.ts +73 -2
  482. package/src/nexus/api/ops-api.ts +18 -0
  483. package/src/nexus/api/outbound-report.ts +8 -3
  484. package/src/nexus/api/telegram-trigger-bot.ts +6 -3
  485. package/src/nexus/index.ts +17 -75
  486. package/src/nexus/outbound/format.ts +2 -0
  487. package/src/nexus/outbound/router.ts +198 -13
  488. package/src/nexus/tools-kind.ts +78 -0
  489. package/src/oauth/codex-account-rotation.ts +55 -20
  490. package/src/oauth/codex-account-store.ts +451 -23
  491. package/src/oauth/fallback-chain.ts +75 -15
  492. package/src/onboarding/first-run.ts +37 -18
  493. package/src/onboarding/web-first.ts +20 -2
  494. package/src/onboarding.ts +2 -1
  495. package/src/ops/machine-heartbeat.ts +185 -0
  496. package/src/ops/overview-cache.ts +175 -0
  497. package/src/ops/overview.ts +8 -0
  498. package/src/plugins/adapters/claude-package.ts +4 -12
  499. package/src/plugins/core/capability-policy.ts +141 -0
  500. package/src/plugins/core/host.ts +21 -8
  501. package/src/plugins/core/manifest.ts +19 -2
  502. package/src/plugins/core/trust-store.ts +15 -0
  503. package/src/plugins/core/types.ts +12 -0
  504. package/src/plugins/install/market-fetch.ts +68 -16
  505. package/src/plugins/install/plugin-install.ts +187 -16
  506. package/src/plugins/maker/plugin-maker.ts +25 -20
  507. package/src/plugins/maker/wizard-generate.ts +16 -2
  508. package/src/policy/llm-policy.ts +14 -1
  509. package/src/process/pid-liveness.ts +1 -1
  510. package/src/prompt-cache/openai.ts +13 -6
  511. package/src/prompt-cache/openrouter.ts +94 -0
  512. package/src/prompt-cache/types.ts +5 -0
  513. package/src/prompt-enhance/enhance.ts +69 -5
  514. package/src/prompt-library/family-prompt-coverage.ts +1 -0
  515. package/src/prompt-library/universal-preamble.ts +2 -2
  516. package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
  517. package/src/registry/loader.ts +6 -1
  518. package/src/release-loop/checklist.ts +24 -9
  519. package/src/release-loop/feature-store.ts +3 -0
  520. package/src/release-loop/gate-shards.ts +48 -4
  521. package/src/release-loop/landed-to-green.ts +81 -0
  522. package/src/release-loop/light-rc.ts +11 -1
  523. package/src/release-loop/merged-pr-checklist.ts +10 -0
  524. package/src/release-loop/placement.ts +107 -23
  525. package/src/release-loop/rehearsal.ts +317 -0
  526. package/src/release-loop/release-schedule.ts +13 -1
  527. package/src/release-loop/rubric-types.ts +1 -0
  528. package/src/release-loop/rubric.ts +2 -2
  529. package/src/requirements/requirement-ledger.ts +536 -0
  530. package/src/retro/daily.ts +26 -12
  531. package/src/seat-loop/seat-loop.ts +66 -11
  532. package/src/seat-loop/traffic-signal.ts +44 -0
  533. package/src/self-dev/ask-launch-flow.ts +2 -2
  534. package/src/self-dev/dev-cli.ts +109 -11
  535. package/src/self-dev/dev-pipeline.ts +11 -8
  536. package/src/self-dev/draft-residue.ts +475 -0
  537. package/src/self-dev/draft-sweep.ts +254 -10
  538. package/src/self-dev/draft-triage-rules.ts +27 -1
  539. package/src/self-dev/graph-journey-route.ts +6 -0
  540. package/src/self-dev/launch-preflight-text.ts +549 -0
  541. package/src/self-dev/launch-preflight.ts +10 -545
  542. package/src/self-dev/orchestrate-cli.ts +82 -5
  543. package/src/self-dev/orchestrate-summary-line.ts +13 -0
  544. package/src/self-dev/orchestrate.ts +49 -141
  545. package/src/self-dev/review-provider-fallback.ts +115 -19
  546. package/src/self-dev/run-store.ts +1 -3
  547. package/src/self-dev/run-supervisor.ts +190 -36
  548. package/src/self-dev/run-types.ts +191 -0
  549. package/src/self-dev/shard-aggregate.ts +61 -13
  550. package/src/self-dev/shard-plan.ts +5 -1
  551. package/src/self-dev/shard-run.ts +23 -5
  552. package/src/self-dev/supervisor-verdict-edges.ts +3 -4
  553. package/src/self-implement/blocked-draft-policy.ts +3 -19
  554. package/src/self-implement/budget-gate.ts +53 -13
  555. package/src/self-implement/child-context-composition.ts +139 -0
  556. package/src/self-implement/child-llm-preference.ts +13 -5
  557. package/src/self-implement/claude-acp-implement.ts +67 -0
  558. package/src/self-implement/draft-on-stop-mode.ts +18 -0
  559. package/src/self-implement/flex-signals.ts +59 -0
  560. package/src/self-implement/follow-up-goals.ts +114 -38
  561. package/src/self-implement/frozen-merges.ts +8 -3
  562. package/src/self-implement/gate-baseline-reap.ts +157 -0
  563. package/src/self-implement/gate-baseline.ts +78 -16
  564. package/src/self-implement/gate-cli.ts +12 -2
  565. package/src/self-implement/gate-remote.ts +17 -6
  566. package/src/self-implement/goal-author-decompose.ts +10 -2
  567. package/src/self-implement/goal-author.ts +48 -13
  568. package/src/self-implement/goal-digest.ts +19 -0
  569. package/src/self-implement/graph-overlay-condition.ts +32 -0
  570. package/src/self-implement/graph-overlay-yaml.ts +41 -7
  571. package/src/self-implement/graph-templates.ts +33 -1
  572. package/src/self-implement/graph-yaml.ts +56 -0
  573. package/src/self-implement/headless-elanous-driver.ts +11 -9
  574. package/src/self-implement/heal-intake.ts +5 -1
  575. package/src/self-implement/host-regate.ts +120 -29
  576. package/src/self-implement/l8-merge-queue.ts +67 -5
  577. package/src/self-implement/merge-train.ts +131 -0
  578. package/src/self-implement/off-diff-evidence.ts +9 -0
  579. package/src/self-implement/orchestrator.ts +271 -25
  580. package/src/self-implement/review-finding-recurrence.ts +28 -0
  581. package/src/self-implement/rework-policy.ts +2 -1
  582. package/src/self-implement/round-summary-card.ts +63 -0
  583. package/src/self-implement/run-ledger.ts +4 -3
  584. package/src/self-implement/run-step-projection.ts +147 -0
  585. package/src/self-implement/run-stop.ts +1 -1
  586. package/src/self-implement/running-runs.ts +75 -5
  587. package/src/self-implement/seams.ts +83 -4
  588. package/src/self-implement/self-implement-cli.ts +12 -5
  589. package/src/self-implement/stop-autoheal.ts +69 -2
  590. package/src/self-implement/train-gate-remote.ts +158 -0
  591. package/src/session-runtime/index.ts +10 -1
  592. package/src/session-runtime/retry-api.ts +11 -1
  593. package/src/session-runtime/retry-policy.ts +2 -1
  594. package/src/skills/gift-install.ts +119 -0
  595. package/src/skills/runner.ts +59 -2
  596. package/src/skills/skill-feedback.ts +31 -1
  597. package/src/skills/skill-tier.ts +1 -0
  598. package/src/smart-wizard/capability-index.ts +231 -0
  599. package/src/smart-wizard/rung.ts +74 -0
  600. package/src/steward/launch.ts +22 -10
  601. package/src/steward/triage-budget.ts +62 -0
  602. package/src/steward/triage.ts +87 -24
  603. package/src/storage/file-lock.ts +8 -1
  604. package/src/task-agent/actions.ts +66 -5
  605. package/src/task-agent/card-evidence.ts +59 -13
  606. package/src/task-agent/completion-evidence.ts +5 -0
  607. package/src/task-agent/cover.ts +101 -3
  608. package/src/task-agent/judge.ts +20 -3
  609. package/src/task-agent/land-order-ledger.ts +95 -0
  610. package/src/task-agent/land-worktree.ts +201 -0
  611. package/src/task-agent/live-move-history.ts +219 -0
  612. package/src/task-agent/live-moves.ts +451 -34
  613. package/src/task-agent/parent-host.ts +117 -8
  614. package/src/task-agent/rejudge-on-head.ts +352 -0
  615. package/src/task-agent/review-prior-fix.ts +146 -0
  616. package/src/task-agent/review-result-capture.ts +218 -0
  617. package/src/task-agent/run-adopt.ts +136 -0
  618. package/src/task-agent/shadow.ts +154 -14
  619. package/src/task-agent/task-hand.ts +186 -14
  620. package/src/task-orchestrator/surfaces/pod-account-broker.ts +38 -5
  621. package/src/task-orchestrator/surfaces/pod-bedrock-child.ts +74 -0
  622. package/src/task-orchestrator/surfaces/pod-child-default.ts +50 -0
  623. package/src/task-orchestrator/surfaces/pod-child-providers.ts +42 -0
  624. package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
  625. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +94 -7
  626. package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
  627. package/src/task-orchestrator/surfaces/pod-lease.ts +110 -17
  628. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +32 -3
  629. package/src/task-orchestrator/surfaces/pod-pool.ts +86 -18
  630. package/src/task-orchestrator/surfaces/pod-zai-child.ts +101 -0
  631. package/src/task-orchestrator/surfaces/self-implement-pod.ts +463 -50
  632. package/src/task-orchestrator/surfaces/self-implement.ts +25 -3
  633. package/src/telegram-service.ts +5 -1
  634. package/src/telegram.ts +17 -4
  635. package/src/time/format.ts +13 -4
  636. package/src/tool-runtime/goal-author-runtime.ts +1 -0
  637. package/src/tool-runtime/self-cognition-catalog.ts +23 -0
  638. package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
  639. package/src/typecheck-ratchet.ts +1 -0
  640. package/src/user-config.ts +180 -32
  641. package/src/ux-sim/slash-menu-frames.ts +168 -0
  642. package/src/version/packed-revision.json +1 -1
  643. package/src/web-terminal/preview-tap-registry.ts +5 -2
  644. package/src/workflow-runtime/triggers/registry.ts +59 -0
  645. package/src/workflow-runtime/triggers/scheduler.ts +1 -0
  646. package/src/workflow-runtime/triggers/webhook-source.ts +35 -5
  647. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
  648. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
  649. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
  650. package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
  652. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
  653. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
  654. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
  656. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
  661. package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
  670. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
  671. package/apps/pwa/out/_next/static/chunks/2489-d238d3e2eb5b2bf5.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
  684. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
  692. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
  697. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
  699. package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
  703. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
  708. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
  713. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
  714. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
  716. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
  717. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
  725. package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
  728. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
  738. package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
  741. package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
  745. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
  746. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/approvals/page-88459e0903da2803.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d85c43f46f58716b.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/board/page-4e645600579ae952.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/botlab/page-87edbfd19117823b.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/chat/page-cbaf66b1e1804adf.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/control/page-9f5610caaa06178c.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/decisions/page-ec8f3575e339de74.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/exec/page-2a19c5cd3b562580.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/field/page-b6a09cde2e07521a.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/loops/page-abd86cd832aaa011.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8c3f168fc3f91939.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/morning/page-786fb4504d0f2fa9.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7ec8e289b4c14df6.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-8c8ac17d52be2a79.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d359ab048d63a9d9.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/settings/page-f151cc10ad026940.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/share/page-bf495a1e284f4e00.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/app/term/page-9abcfac07e02a542.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/app/workflows/page-69cb93d1a2e57e0e.js +0 -1
  794. package/apps/pwa/out/_next/static/chunks/app/workspace/page-72ec543928d67c3e.js +0 -1
  795. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +0 -1
  796. package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
  797. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
  798. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
  799. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
  800. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
  801. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
  802. package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +0 -1
  803. /package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → Q-7iofoxOEv1WX18S35of}/_ssgManifest.js +0 -0
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ import type { SelfDevRunParticipant, SelfDevRunState } from './self-dev/run-stor
7
7
  import { applyConfigDirFlagFromArgv } from './cli/config-dir-flag.js';
8
8
  import { LOGS_SINCE_OPTION, registerLogsCommands } from './cli/logs-cli.js';
9
9
  import { registerDocsCommands } from './cli/docs-cli.js';
10
+ import { registerBenchCommands } from './cli/bench-cli.js';
10
11
  import { registerRetroCommands } from './cli/retro-cli.js';
11
12
  import { registerA2ACommands } from './cli/a2a-cli.js';
12
13
  import { registerPluginCommands } from './cli/plugin-cli.js';
@@ -25,6 +26,7 @@ import { ensureRunIdentity, getHarnessSpace, normalizeSpaceId } from './harness/
25
26
  // 그 import 자체가 첫 비동기 작업이 되어, 그것이 거부되면 가드 없이 끝난다(무인 리뷰 must-fix).
26
27
  // ⇒ «정적» import 로 올린다. 이 모듈은 부작용이 없어 부팅 비용이 사실상 0 이다.
27
28
  import { installDevCompletionGuard } from './self-dev/dev-completion-guard.js';
29
+ import { formatOrchestrateResultLine } from './self-dev/orchestrate-summary-line.js';
28
30
  import { buildOrchestrateDecomposePrepareArgs, normalizeOrchestrateRequest, splitOrchestrateGoalTexts } from './self-dev/self-orchestrate-runtime.js';
29
31
  import { CLI_ENTRANCE_BASELINE, evaluateCommandEntranceBaseline } from './self-dev/entrance-baseline.js';
30
32
  import { CLI_HARNESS_DOGFOOD_ENTRANCE, CLI_HARNESS_ORCHESTRATE_ENTRANCE, describeEntranceCommand, listEntrancesWithModelExposure, renderLaunchEntrances, summarizeEntrances, type EntranceId } from './self-dev/entrance-registry.js';
@@ -50,6 +52,7 @@ import { registerPublishCommands } from './cli/publish-cli.js';
50
52
  import { registerAutopilotCommands } from './cli/autopilot-cli.js';
51
53
  import { registerRoleCommands } from './cli/role-cli.js';
52
54
  import { registerMachineCommands } from './cli/machine-cli.js';
55
+ import { recordImagePinFromConfigSet, registerImageCommands } from './cli/image-cli.js';
53
56
  import { registerAgentEnvCommands } from './cli/agent-env-cli.js';
54
57
  import { registerScheduleCommands } from './cli/schedule-cli.js';
55
58
  import { registerGuardianCommands } from './cli/guardian-cli.js';
@@ -898,9 +901,11 @@ registerPrCommands(program);
898
901
  registerRepoCommands(program);
899
902
  registerRoleCommands(program);
900
903
  registerMachineCommands(program);
904
+ registerImageCommands(program);
901
905
  registerAgentEnvCommands(program);
902
906
  // CLI entry: where action → resolveCurrentInstance → resolveInstance (instance universe).
903
907
  registerWhereCommand(program);
908
+ registerBenchCommands(program);
904
909
  registerShadowCommand(program);
905
910
  registerLlmDetectCommand(program);
906
911
  registerStorageDetectCommand(program);
@@ -1073,6 +1078,17 @@ fenceWrapperCmd.command('alert <reason>').description('HQ 울타리 실패를
1073
1078
  hqFenceAlert(reason, { root, outcomeDir: fenceOutcomeDir(_joinPath(root, 'hq', 'local.json')) });
1074
1079
  } catch (error) { console.error(`hq fence-wrapper alert: ${error instanceof Error ? error.message : String(error)}`); process.exitCode = 1; }
1075
1080
  });
1081
+ fenceWrapperCmd.command('record <role> <rc>').description('가벼운 울타리(FENCE-LIGHT)가 돌린 잡의 rc 를 역할별 연속 실패 기록에 남김')
1082
+ .action(async (role: string, rc: string) => {
1083
+ try {
1084
+ const { FENCE_ROLES } = await import('./hq/hq.js');
1085
+ if (!(FENCE_ROLES as readonly string[]).includes(role)) throw new Error(`unknown role: ${role}`);
1086
+ if (!/^\d{1,3}$/.test(rc)) throw new Error(`rc must be 0-255: ${rc}`);
1087
+ const { fenceOutcomeDir, recordFenceOutcome } = await import('./hq/fence-outcomes.js');
1088
+ const { getElanousConfigDir } = await import('./elanous-config-dir.js');
1089
+ recordFenceOutcome(fenceOutcomeDir(_joinPath(getElanousConfigDir(), 'hq', 'local.json')), role, Number(rc));
1090
+ } catch (error) { console.error(`hq fence-wrapper record: ${error instanceof Error ? error.message : String(error)}`); process.exitCode = 1; }
1091
+ });
1076
1092
  hqCmd.command('fence-audit').description('운영 crontab 의 HQ 울타리 밖 쓰기 잡 목록과 감싼 줄 제안(읽기 전용)')
1077
1093
  .option('--json', 'JSON 출력')
1078
1094
  .action(async (opts: { json?: boolean }) => {
@@ -1684,7 +1700,7 @@ telegramCmd
1684
1700
  const { spawnSync } = await import('node:child_process');
1685
1701
  const result = installTelegramService(file, getUserConfig().telegram.poller, process.getuid?.() ?? 0, {
1686
1702
  exists: fs.existsSync, readFile: (p) => fs.readFileSync(p, 'utf8'), writeFile: (p, t) => fs.writeFileSync(p, t),
1687
- mkdir: (p) => fs.mkdirSync(p, { recursive: true }), rename: fs.renameSync,
1703
+ mkdir: (p) => fs.mkdirSync(p, { recursive: true }), rename: fs.renameSync, chmod: fs.chmodSync,
1688
1704
  run: (c, a) => { const r = spawnSync(c, a, { encoding: 'utf8' }); return { status: r.status, stderr: r.stderr ?? String(r.error ?? '') }; },
1689
1705
  });
1690
1706
  debug.log('telegram.service', 'install', { ok: result.ok, path: result.path, backup: result.backup, steps: result.steps, reason: result.reason });
@@ -4701,7 +4717,7 @@ const selfOrchestrateCmd = selfCmd
4701
4717
  .option('--no-pod-rebuild', 'pod: 이미지 판(elanous.commit)이 HEAD 와 달라도 다시 굽지 않는다 — 측정은 «이미지 판»을 잰다')
4702
4718
  .option('--pod-pass-env <keys>', 'pod: 호스트 env 에서 Pod 로 넘길 키(쉼표) — 예 OPENROUTER_API_KEY,ANTHROPIC_API_KEY(벤치마크 과금 경로)')
4703
4719
  .option('--bench-arms <spec>', 'pod 벤치마크: 골 1개를 팔마다 «라벨 한 줄만 다르게» 복제해 동시에 — "id=provider[:model][@KEY+KEY];…" (예 codex=openai-codex;or-kimi=openrouter:openrouter/moonshotai/kimi-k3@OPENROUTER_API_KEY) · --auto-merge 거부 · RFC fleet 슈퍼바이저 §A3')
4704
- .addOption(new Option('--child-llm-provider <id>', 'pod: 구현 자식 LLM provider(openai-codex|grok) — 하니스 --child-llm-provider 가 이 자리로 온다(10-05)').hideHelp())
4720
+ .addOption(new Option('--child-llm-provider <id>', 'pod: 구현 자식 LLM provider(openai-codex|grok|openrouter|anthropic|bedrock|glm) — 하니스 --child-llm-provider 가 이 자리로 온다(10-05)').hideHelp())
4705
4721
  .addOption(new Option('--child-llm-model <id>', 'pod: 구현 자식 LLM model(--child-llm-provider 와 함께)').hideHelp())
4706
4722
  .addOption(new Option('--child-llm-effort <level>', 'pod: 구현 자식 추론 노력(--child-llm-provider 와 함께)').hideHelp())
4707
4723
  .option('--help-all', '모든 orchestrate 옵션 표시')
@@ -4879,7 +4895,9 @@ const selfOrchestrateCmd = selfCmd
4879
4895
  if (substrate === 'pod') {
4880
4896
  const { podSelfImplementSpawn, podSubstrateReady, defaultKubectl } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
4881
4897
  const poolMod = await import('./task-orchestrator/surfaces/pod-pool.js');
4882
- const poolSpec = poolMod.resolvePodPoolSpec((opts as { podPool?: string }).podPool);
4898
+ const { harnessLaunchPolicyConfig } = await import('./harness/harness-substrate-default.js');
4899
+ const launchPolicy = harnessLaunchPolicyConfig();
4900
+ const poolSpec = poolMod.resolvePodPoolSpec((opts as { podPool?: string }).podPool, process.env, () => launchPolicy.harness?.podPool ?? launchPolicy.pod?.pool);
4883
4901
  let pool: import('./task-orchestrator/surfaces/pod-pool.js').PodPoolScheduler | undefined;
4884
4902
  let poolMembers: import('./task-orchestrator/surfaces/pod-pool.js').PodPoolMember[] = [];
4885
4903
  let ready: { ok: boolean; reason: string };
@@ -4898,41 +4916,82 @@ const selfOrchestrateCmd = selfCmd
4898
4916
  }
4899
4917
  if (!ready.ok) { ui.error(`--substrate pod: ${ready.reason}`); process.exit(2); }
4900
4918
  // ⛔ Pod 의 elanous 는 이미지 판이다 — HEAD 와 다르면 다시 굽는다(BACKLOG E6 · 09-25 세 판이 옛 판을 쟀다).
4901
- const { podImageFreshness } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
4902
- // ☸️ 풀이 «원격 노드뿐»이면 이 기계의 이미지는 아무도 안 쓴다 — 로컬 판정·굽기를 건너뛰고 기준 판 = HEAD 로 노드 동기화만 한다.
4903
- // 🩸 2026-09-26 실측: 원격 전용 풀인데 로컬 이미지가 없다고 로컬에서 굽다가 로컬 클러스터(elanous-h1)가 없어 런이 시작도 전에 죽었다.
4904
- const remoteOnlyPool = poolMembers.length > 0 && poolMembers.every((m) => Boolean(m.sshHost));
4905
- const headCommit = remoteOnlyPool ? ((await import('./git-fs/runner.js')).runGitCommand(process.cwd(), ['rev-parse', 'HEAD'], { encoding: 'utf8' }).stdout.trim() || null) : null;
4906
- let image = remoteOnlyPool
4907
- ? { imageCommit: headCommit, headCommit, fresh: true, reason: 'remote-only pool — 노드 쪽에서 맞춘다' }
4908
- : podImageFreshness();
4909
- if (!image.fresh) {
4910
- if ((opts as { podRebuild?: boolean }).podRebuild === false) {
4911
- ui.warn(`--substrate pod: 이미지가 낡았다(${image.reason}) — --no-pod-rebuild 라 그대로 쓴다. 측정은 «이미지 판»을 잰다.`);
4912
- } else {
4913
- if (!opts.json) ui.info(`[pod] 이미지 다시 굽기 — ${image.reason} (~1분)`);
4914
- const { spawnSync } = await import('node:child_process');
4915
- const { runGitCommand } = await import('./git-fs/runner.js');
4916
- const top = runGitCommand(process.cwd(), ['rev-parse', '--show-toplevel'], { encoding: 'utf8' }).stdout.trim() || process.cwd();
4917
- // bun 1.4 applies the 1 MiB default maxBuffer: a docker build log past it kills the child (ENOBUFS · status null).
4918
- const b = spawnSync('bash', [`${top}/docker/harness/build.sh`], { encoding: 'utf8', timeout: 900_000, maxBuffer: 64 * 1024 * 1024 });
4919
- if (b.status !== 0) { ui.error(`--substrate pod: 이미지 굽기 실패 rc=${b.status}${b.error ? ` (${(b.error as NodeJS.ErrnoException).code ?? b.error.message})` : ''}: ${(b.stdout + b.stderr).slice(-400)}`); process.exit(2); }
4920
- image = podImageFreshness();
4919
+ const { podImageFreshness, rebuildLocalPodImageOnce } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
4920
+ type PodPoolMemberT = import('./task-orchestrator/surfaces/pod-pool.js').PodPoolMember;
4921
+ let remoteOnlyPool = false;
4922
+ // 종전 경로(HEAD 비교·굽기·노드 동기화). IMAGE-ONE-SOURCE: 기준값이 없으면 전 멤버로 «그대로» 부른다.
4923
+ const podHeadImagePath = async (members: readonly PodPoolMemberT[]) => {
4924
+ // ☸️ 풀이 «원격 노드뿐»이면 이 기계의 이미지는 아무도 안 쓴다 — 로컬 판정·굽기를 건너뛰고 기준 판 = HEAD 로 노드 동기화만 한다.
4925
+ // 🩸 2026-09-26 실측: 원격 전용 풀인데 로컬 이미지가 없다고 로컬에서 굽다가 로컬 클러스터(elanous-h1)가 없어 런이 시작도 전에 죽었다.
4926
+ remoteOnlyPool = members.length > 0 && members.every((m) => Boolean(m.sshHost));
4927
+ const headCommit = remoteOnlyPool ? ((await import('./git-fs/runner.js')).runGitCommand(process.cwd(), ['rev-parse', 'HEAD'], { encoding: 'utf8' }).stdout.trim() || null) : null;
4928
+ let image = remoteOnlyPool
4929
+ ? { imageCommit: headCommit, headCommit, fresh: true, reason: 'remote-only pool — 노드 쪽에서 맞춘다' }
4930
+ : podImageFreshness();
4931
+ if (!image.fresh) {
4932
+ if ((opts as { podRebuild?: boolean }).podRebuild === false) {
4933
+ ui.warn(`--substrate pod: 이미지가 낡았다(${image.reason}) — --no-pod-rebuild 라 그대로 쓴다. 측정은 «이미지 판»을 잰다.`);
4934
+ } else {
4935
+ const rebuilt = await rebuildLocalPodImageOnce({ initialImage: image,
4936
+ onBuild: (reason) => { if (!opts.json) ui.info(`[pod] 이미지 다시 굽기 — ${reason} (~1분)`); },
4937
+ onWait: () => { if (!opts.json) ui.info('[pod] 이미지 굽기 대기 — 같은 호스트의 다른 부모가 굽는 중'); },
4938
+ });
4939
+ if (rebuilt.action === 'failed') { ui.error(rebuilt.error ?? '--substrate pod: 이미지 굽기 실패'); process.exit(2); }
4940
+ image = rebuilt.image;
4941
+ }
4942
+ }
4943
+ debug.log('self-implement.pod', 'image-freshness', { ...image });
4944
+ // ☸️ 원격 노드도 «같은 판»이어야 한다 — 다르면 보내서 넣는다. 못 맞춘 노드는 풀에서 뺀다.
4945
+ const synced: PodPoolMemberT[] = [];
4946
+ if (pool) {
4947
+ // ⭐ 노드들을 «동시에» — 노드 쪽 빌드(바뀐 층만) 1순위 · 실패하면 통째 전송.
4948
+ const { podSkillsDigest, resolvePodSkills } = await import('./task-orchestrator/surfaces/pod-skills.js');
4949
+ const syncs = await poolMod.syncPoolImages(members, 'elanous-harness:local', image.imageCommit, { localSkillsDigest: podSkillsDigest(resolvePodSkills().skills).digest });
4950
+ for (const m of members) {
4951
+ const r = syncs.get(m.context)!;
4952
+ debug.log('self-implement.pod', 'pool-image-sync', { context: m.context, ...r });
4953
+ if (r.ok) synced.push(r.imageRef ? { ...m, imageRef: r.imageRef } : m); else ui.warn(`[pod-pool] ${m.context} 뺌 — 이미지 판을 못 맞췄다: ${r.detail}`);
4954
+ if (!opts.json && (r.action === 'shipped' || r.action === 'built')) ui.info(`[pod-pool] ${m.context} 이미지 ${r.action === 'built' ? '노드 쪽 빌드' : '보냄'} ${r.detail} · ${Math.round(r.ms / 1000)}초`);
4955
+ }
4921
4956
  }
4957
+ return { image, synced };
4958
+ };
4959
+ // 🧷 IMAGE-ONE-SOURCE: 운영 config `harness.imageCommit` 이 있으면 레지스트리를 가진 멤버는 굽지 않고 기준 이미지(커밋 태그)를 당긴다.
4960
+ const imageSourceMod = await import('./task-orchestrator/surfaces/pod-image-source.js');
4961
+ let podImageCfg: { harness?: { imageCommit?: unknown } } | undefined = undefined;
4962
+ // ⛔ 설정을 못 읽으면 «기준값 없음»으로 읽지 않는다 — 기준값이 있었을 수 있으니 굽지 않고 멈춘다.
4963
+ try { podImageCfg = (await import('./user-config.js')).getUserConfig(); } catch (e) {
4964
+ ui.error(`--substrate pod: 운영 config 를 못 읽어 기준 이미지(harness.imageCommit) 여부를 모른다 — 굽지 않고 멈춘다: ${(e as Error).message}`);
4965
+ debug.log('self-implement.pod', 'image-source', { kind: null, ref: null, headCommit: null, waitedMs: 0, outcome: 'config-unreadable', error: (e as Error).message });
4966
+ process.exit(2);
4967
+ }
4968
+ const pinWaitSec = process.env.ELANOUS_POD_IMAGE_PIN_WAIT_SEC?.trim() ? Number(process.env.ELANOUS_POD_IMAGE_PIN_WAIT_SEC) : Number.NaN;
4969
+ const preparedImage = await imageSourceMod.preparePodImage({
4970
+ cfg: podImageCfg,
4971
+ members: poolMembers,
4972
+ headPath: podHeadImagePath,
4973
+ ...imageSourceMod.podPoolImageLookup(),
4974
+ ...(Number.isFinite(pinWaitSec) && pinWaitSec >= 0 ? { maxWaitMs: pinWaitSec * 1000 } : {}),
4975
+ onWait: (pending, waitedMs) => { if (!opts.json) ui.info(`[pod] 기준 이미지 대기 — ${pending.map((m) => m.context).join(',')} 레지스트리에 아직 없다 (${Math.round(waitedMs / 1000)}초)`); },
4976
+ });
4977
+ // ref = 멤버가 «실제로» 당기는(또는 찾던) 이미지 ref 집합 — 기준 이미지 · 못 찾은 기준 이미지 · 종전 경로 멤버의 imageRef 또는 elanous-harness:local.
4978
+ const usedImageRefs = [...new Set([...preparedImage.pinned.map((m) => m.imageRef), ...preparedImage.missing.map((x) => x.ref), ...(preparedImage.head ? (pool ? preparedImage.head.synced.map((m) => m.imageRef ?? 'elanous-harness:local') : ['elanous-harness:local']) : [])])];
4979
+ if (preparedImage.source.kind === 'pinned') {
4980
+ const pinnedHead = (await import('./git-fs/runner.js')).runGitCommand(process.cwd(), ['rev-parse', 'HEAD'], { encoding: 'utf8' }).stdout.trim() || null;
4981
+ imageSourceMod.logPinnedImageSource(preparedImage, { ref: usedImageRefs.join(', '), headCommit: pinnedHead });
4982
+ if (preparedImage.outcome === 'pinned-missing') { ui.error(imageSourceMod.podImageMissingMessage([...new Set(preparedImage.missing.map((x) => x.ref))].join(', '))); process.exit(2); }
4983
+ for (const x of preparedImage.missing) ui.warn(`[pod-pool] ${x.member.context} 뺌 — ${imageSourceMod.podImageMissingMessage(x.ref)}`);
4984
+ } else {
4985
+ debug.log('self-implement.pod', 'image-source', { kind: 'head', ref: usedImageRefs.join(', ') || null, headCommit: preparedImage.head?.image.headCommit ?? null, waitedMs: 0, outcome: 'head' });
4922
4986
  }
4923
- debug.log('self-implement.pod', 'image-freshness', { ...image });
4924
- // ☸️ 원격 노드도 «같은 판»이어야 한다 — 다르면 보내서 넣는다. 못 맞춘 노드는 풀에서 뺀다.
4987
+ const pinnedOnly = preparedImage.head === null && preparedImage.source.kind === 'pinned';
4988
+ if (pinnedOnly) remoteOnlyPool = true;
4989
+ const image = preparedImage.head?.image
4990
+ ?? { imageCommit: preparedImage.source.kind === 'pinned' ? preparedImage.source.commit : null, headCommit: null, fresh: true, reason: 'pinned — 레지스트리 기준 이미지' };
4925
4991
  if (pool) {
4926
- const synced: typeof poolMembers = [];
4927
- // ⭐ 노드들을 «동시에» — 노드 쪽 빌드(바뀐 층만) 1순위 · 실패하면 통째 전송.
4928
- const { podSkillsDigest, resolvePodSkills } = await import('./task-orchestrator/surfaces/pod-skills.js');
4929
- const syncs = await poolMod.syncPoolImages(poolMembers, 'elanous-harness:local', image.imageCommit, { localSkillsDigest: podSkillsDigest(resolvePodSkills().skills).digest });
4930
- for (const m of poolMembers) {
4931
- const r = syncs.get(m.context)!;
4932
- debug.log('self-implement.pod', 'pool-image-sync', { context: m.context, ...r });
4933
- if (r.ok) synced.push(r.imageRef ? { ...m, imageRef: r.imageRef } : m); else ui.warn(`[pod-pool] ${m.context} 뺌 — 이미지 판을 못 맞췄다: ${r.detail}`);
4934
- if (!opts.json && (r.action === 'shipped' || r.action === 'built')) ui.info(`[pod-pool] ${m.context} 이미지 ${r.action === 'built' ? '노드 쪽 빌드' : '보냄'} ${r.detail} · ${Math.round(r.ms / 1000)}초`);
4935
- }
4992
+ const ok = new Set([...preparedImage.pinned.map((m) => m.context), ...(preparedImage.head?.synced ?? []).map((m) => m.context)]);
4993
+ const byContext = new Map<string, PodPoolMemberT>([...(preparedImage.head?.synced ?? []), ...preparedImage.pinned].map((m) => [m.context, m]));
4994
+ const synced = poolMembers.filter((m) => ok.has(m.context)).map((m) => byContext.get(m.context)!);
4936
4995
  if (synced.length === 0) { ui.error('--substrate pod: 이미지를 맞춘 풀 노드가 없다'); process.exit(2); }
4937
4996
  pool = new poolMod.PodPoolScheduler(synced);
4938
4997
  poolMembers = synced;
@@ -4943,8 +5002,35 @@ const selfOrchestrateCmd = selfCmd
4943
5002
  const explicitPodAccount = (opts as { podAccount?: string }).podAccount;
4944
5003
  let accountBroker: (() => string) | undefined;
4945
5004
  let rotationAccounts: readonly string[] | undefined;
4946
- let podProvider: 'openai-codex' | 'grok' = 'openai-codex';
5005
+ let podProvider: import('./task-orchestrator/surfaces/pod-child-providers.js').PodChildProvider = 'openai-codex';
4947
5006
  let grokApiKeyOptIn = false;
5007
+ {
5008
+ // SUBSCRIPTION-EXHAUST-REROUTE (0.2.24): a Pod launch with no child model gets the configured default
5009
+ // (tools.selfImplement.podChildDefault · default openrouter/z-ai/glm-5.3) instead of falling to codex.
5010
+ // It fills the same flags a named launch carries, so every check below runs unchanged.
5011
+ const child = opts as { childLlmProvider?: string; childLlmModel?: string; childLlmEffort?: string };
5012
+ const { resolvePodChildDefault } = await import('./task-orchestrator/surfaces/pod-child-default.js');
5013
+ const { homedir: defaultKeyHome } = await import('node:os');
5014
+ const childDefault = resolvePodChildDefault({
5015
+ flags: { provider: child.childLlmProvider, model: child.childLlmModel, effort: child.childLlmEffort },
5016
+ benchArms: Boolean(benchArms),
5017
+ explicitPodAccount: (opts as { podAccount?: string }).podAccount,
5018
+ config: (launchPolicy.tools?.selfImplement as { podChildDefault?: unknown } | undefined)?.podChildDefault,
5019
+ openrouterKeyPresent: () => {
5020
+ if (process.env.OPENROUTER_API_KEY?.trim()) return true;
5021
+ try { return Boolean(readFileSync(_joinPath(defaultKeyHome(), '.cache', 'openrouter_api_key'), 'utf8').trim()); } catch { return false; }
5022
+ },
5023
+ });
5024
+ if (childDefault.apply) {
5025
+ child.childLlmProvider = childDefault.provider;
5026
+ if (childDefault.model) child.childLlmModel = childDefault.model;
5027
+ debug.log('self-implement.pod', 'child-default-applied', { provider: childDefault.provider, model: childDefault.model ?? null, source: childDefault.source, ...(childDefault.invalidConfig !== undefined ? { invalidConfig: String(JSON.stringify(childDefault.invalidConfig)) } : {}) });
5028
+ if (!opts.json) ui.info(`[pod] child 기본 모델 = ${childDefault.provider}${childDefault.model ? `/${childDefault.model}` : ''} (${childDefault.source === 'config' ? 'tools.selfImplement.podChildDefault' : '기본값'}) — --child-llm-* 로 바꾼다`);
5029
+ } else if (childDefault.reason !== 'flag') {
5030
+ debug.log('self-implement.pod', 'child-default-skipped', { reason: childDefault.reason, provider: childDefault.provider ?? null, model: childDefault.model ?? null, ...(childDefault.invalidConfig !== undefined ? { invalidConfig: String(JSON.stringify(childDefault.invalidConfig)) } : {}) }, { level: childDefault.reason === 'no-openrouter-key' ? 'warn' : 'debug' });
5031
+ if (childDefault.reason === 'no-openrouter-key' && !opts.json) ui.warn('[pod] child 기본 모델(openrouter)을 못 쓴다 — 호스트에 OpenRouter 키 없음 · 종전 codex 경로로 간다');
5032
+ }
5033
+ }
4948
5034
  {
4949
5035
  // 10-05 PODPROVIDER: refuse child choices this Pod launch cannot honour instead of dropping them.
4950
5036
  const child = opts as { childLlmProvider?: string; childLlmModel?: string; childLlmEffort?: string };
@@ -4953,8 +5039,8 @@ const selfOrchestrateCmd = selfCmd
4953
5039
  ? 'pod: --child-llm-model/--child-llm-effort 는 --child-llm-provider 와 함께'
4954
5040
  : named && benchArms
4955
5041
  ? 'pod: --child-llm-provider 는 --bench-arms 와 함께 못 쓴다(팔마다 모델이 하나다)'
4956
- : named === 'grok' && explicitPodAccount
4957
- ? 'pod: --child-llm-provider grok 은 --pod-account 와 함께 못 쓴다(그것은 codex 계정을 고정한다)'
5042
+ : (named === 'grok' || named === 'openrouter' || named === 'anthropic' || named === 'bedrock' || named === 'glm') && explicitPodAccount
5043
+ ? `pod: --child-llm-provider ${named} 은 --pod-account 와 함께 못 쓴다(그것은 codex 계정을 고정한다)`
4958
5044
  : undefined;
4959
5045
  if (refuse) { ui.error(refuse); debug.log('self-implement.pod', 'child-provider-refused', { provider: named ?? null, reason: refuse }); process.exit(2); }
4960
5046
  }
@@ -4962,13 +5048,21 @@ const selfOrchestrateCmd = selfCmd
4962
5048
  const { inspectCodexRotation } = await import('./oauth/codex-account-store.js');
4963
5049
  const { planPodProvider, makePodAccountBroker } = await import('./task-orchestrator/surfaces/pod-account-broker.js');
4964
5050
  const { resolveGrokCredential } = await import('./grok/credential.js');
4965
- const { getUserConfig } = await import('./user-config.js');
4966
5051
  const { defaultGrokModel } = await import('./grok/models.js');
4967
- grokApiKeyOptIn = getUserConfig().harness?.pod?.grokApiKeyOptIn === true;
5052
+ grokApiKeyOptIn = launchPolicy.harness?.pod?.grokApiKeyOptIn === true;
4968
5053
  const credential = resolveGrokCredential();
4969
5054
  const { resolveCodexQuotaPolicy, codexPolicyAllowsCredits, codexPolicyAllowsFallback } = await import('./oauth/codex-quota-policy.js');
4970
- const resolvedQuota = resolveCodexQuotaPolicy(getUserConfig().llm);
5055
+ const resolvedQuota = resolveCodexQuotaPolicy(launchPolicy.llm);
4971
5056
  const quotaPolicy = resolvedQuota.policy;
5057
+ const { normalizeFallbackChain } = await import('./oauth/fallback-chain.js');
5058
+ const fallbackEnabled = codexPolicyAllowsFallback(quotaPolicy)
5059
+ && normalizeFallbackChain(launchPolicy.llm?.fallbackChain).chain.includes('grok');
5060
+ // CODEX-CREDITS-STEP — 체인 마지막 칸(크레딧). 켜져 있을 때만 grok 잔량을 잰다(발사 관문과 같은 80% 상한).
5061
+ // Pod 는 «grok 뒤» 순서(문서화된 배치)만 따른다 — grok 앞에 둔 체인은 Pod 계획에서 크레딧 칸을 쓰지 않는다.
5062
+ const launchChain = normalizeFallbackChain(launchPolicy.llm?.fallbackChain).chain;
5063
+ const codexCreditsStep = codexPolicyAllowsFallback(quotaPolicy)
5064
+ && launchChain.includes('codex-credits')
5065
+ && (!launchChain.includes('grok') || launchChain.indexOf('codex-credits') > launchChain.indexOf('grok'));
4972
5066
  // POL1 — say which policy this launch uses and where it came from; warn when a test universe disagrees with production.
4973
5067
  const { effectiveInstanceRoot, prodInstanceRoot } = await import('./instance/resolve.js');
4974
5068
  const root = effectiveInstanceRoot();
@@ -4988,7 +5082,7 @@ const selfOrchestrateCmd = selfCmd
4988
5082
  // GROK-OPTIONAL (10-05): an expiring grok subscription the host cannot refresh is dropped from the chain here,
4989
5083
  // so the launch goes on with codex instead of dying later in hostGrokCredentials.
4990
5084
  let grokSubscriptionUsable = credential?.kind === 'subscription';
4991
- if (grokSubscriptionUsable && codexPolicyAllowsFallback(quotaPolicy)) {
5085
+ if (grokSubscriptionUsable && fallbackEnabled) {
4992
5086
  const { podGrokSubscriptionUsable, podGrokSkippedLine } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
4993
5087
  const grokCheck = podGrokSubscriptionUsable();
4994
5088
  if (!grokCheck.usable) {
@@ -4999,41 +5093,82 @@ const selfOrchestrateCmd = selfCmd
4999
5093
  // 10-05 PODPROVIDER: a launch that named the child provider gets it, or is refused — never a silent codex.
5000
5094
  const namedChild = (opts as { childLlmProvider?: string }).childLlmProvider?.trim();
5001
5095
  const { podNamedChildProvider, podFallbackCredentials, podGrokSubscriptionUsable: namedGrokUsable } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
5096
+ const { readFileSync: readPodKeyFile } = await import('node:fs');
5097
+ const { homedir: podHome } = await import('node:os');
5098
+ const { join: podJoin } = await import('node:path');
5099
+ let openrouterKeyPresent = Boolean(process.env.OPENROUTER_API_KEY?.trim());
5100
+ if (namedChild === 'openrouter' && !openrouterKeyPresent) {
5101
+ try { openrouterKeyPresent = Boolean(readPodKeyFile(podJoin(podHome(), '.cache', 'openrouter_api_key'), 'utf8').trim()); } catch { /* missing host cache */ }
5102
+ }
5103
+ // POD-ANTHROPIC-PROVIDER — 제품 자격 해석(`getAnthropicApiKey` · 키 캐시 → env)으로 «있나»만 본다(값은 안 싣는다).
5104
+ const anthropicKeyPresent = namedChild === 'anthropic' && Boolean((await import('./config.js')).getAnthropicApiKey()?.trim());
5002
5105
  const namedChildDecision = podNamedChildProvider(namedChild, {
5003
5106
  grokSubscription: namedChild === 'grok' && credential?.kind === 'subscription' && (grokSubscriptionUsable || namedGrokUsable().usable),
5004
5107
  grokApiKey: credential?.kind === 'api_key' && grokApiKeyOptIn,
5005
- });
5108
+ openrouterKey: openrouterKeyPresent,
5109
+ anthropicKey: anthropicKeyPresent,
5110
+ }, (opts as { childLlmModel?: string }).childLlmModel);
5006
5111
  if (namedChildDecision.refuse) { ui.error(namedChildDecision.refuse); debug.log('self-implement.pod', 'child-provider-refused', { provider: namedChild, reason: namedChildDecision.refuse }); process.exit(2); }
5007
5112
  // A named codex child must stay codex — the plan may not fall back to grok (post-review must-fix).
5008
5113
  const namedCodex = namedChildDecision.provider === 'openai-codex';
5009
- const plan: import('./task-orchestrator/surfaces/pod-account-broker.js').PodProviderPlan = namedChildDecision.provider === 'grok'
5114
+ const plan: import('./task-orchestrator/surfaces/pod-account-broker.js').PodProviderPlan | null = namedChildDecision.provider === 'openrouter' || namedChildDecision.provider === 'anthropic' || namedChildDecision.provider === 'bedrock' || namedChildDecision.provider === 'glm' ? null : namedChildDecision.provider === 'grok'
5010
5115
  ? { provider: 'grok', excluded: [], grokSubscriptionEligible: credential?.kind === 'subscription' }
5011
5116
  : planPodProvider({
5012
5117
  codexCandidates: inspectCodexRotation().candidates,
5013
5118
  // Per-account caps (대표 default:97) override the Pod default cap — without them default was dropped at 60%.
5014
- thresholdPercentByAccount: getUserConfig().llm?.codexAccountRotationThresholdPercentByAccount,
5119
+ thresholdPercentByAccount: launchPolicy.llm?.codexAccountRotationThresholdPercentByAccount,
5015
5120
  // 대표 한도 정책 한 값(`llm.codexQuotaPolicy`) — 크레딧·폴백을 같이 정한다.
5016
5121
  creditsAllowed: codexPolicyAllowsCredits(quotaPolicy),
5122
+ // SUBSCRIPTION-EXHAUST-REROUTE — 예비분 이하 잔액(«알려진» 값)의 계정은 크레딧으로 쓰지 않는다.
5123
+ creditReserve: typeof launchPolicy.llm?.codexCreditReserve === 'number' && Number.isFinite(launchPolicy.llm.codexCreditReserve) && launchPolicy.llm.codexCreditReserve >= 0
5124
+ ? launchPolicy.llm.codexCreditReserve : (await import('./oauth/codex-account-store.js')).DEFAULT_CODEX_CREDIT_RESERVE,
5017
5125
  ...podFallbackCredentials(namedChildDecision.provider, {
5018
- grokSubscription: codexPolicyAllowsFallback(quotaPolicy) && grokSubscriptionUsable,
5019
- grokApiKey: codexPolicyAllowsFallback(quotaPolicy) && credential?.kind === 'api_key',
5126
+ grokSubscription: fallbackEnabled && grokSubscriptionUsable,
5127
+ grokApiKey: fallbackEnabled && credential?.kind === 'api_key',
5020
5128
  }),
5021
5129
  grokApiKeyOptIn,
5130
+ ...(codexCreditsStep ? { codexCreditsStep: true, grokQuota: await (async () => {
5131
+ const { readLiveGrokUsedPercent } = await import('./self-implement/budget-gate.js');
5132
+ const { LAUNCH_GROK_USED_PERCENT_CAP } = await import('./user-config.js');
5133
+ const used = await readLiveGrokUsedPercent();
5134
+ return used === undefined ? 'unknown' as const : used >= LAUNCH_GROK_USED_PERCENT_CAP ? 'exhausted' as const : 'usable' as const;
5135
+ })() } : {}),
5022
5136
  });
5023
- if (plan.provider === null) { ui.error(`pod: 쓸 codex 계정이 없다 — ${plan.reasons.join(' · ')}${namedCodex ? ' · child provider 를 openai-codex 로 지정해 grok 으로 넘기지 않는다' : ''} · 계정을 명시하려면 --pod-account <이름>`); process.exit(2); }
5024
- podProvider = plan.provider;
5025
- if (plan.provider === 'openai-codex') {
5137
+ if (plan?.provider === null) { ui.error(`pod: 쓸 codex 계정이 없다 — ${plan.reasons.join(' · ')}${namedCodex ? ' · child provider 를 openai-codex 로 지정해 grok 으로 넘기지 않는다' : ''} · 계정을 명시하려면 --pod-account <이름>`); process.exit(2); }
5138
+ podProvider = namedChildDecision.provider === 'openrouter' || namedChildDecision.provider === 'anthropic' || namedChildDecision.provider === 'bedrock' || namedChildDecision.provider === 'glm' ? namedChildDecision.provider : plan!.provider!;
5139
+ if (plan?.provider === 'openai-codex') {
5026
5140
  accountBroker = makePodAccountBroker({ usable: plan.accounts, excluded: plan.excluded });
5027
5141
  rotationAccounts = plan.accounts;
5028
5142
  debug.log('self-implement.pod', 'account-plan', { usable: plan.accounts, excluded: plan.excluded });
5143
+ if (plan.codexCreditsStep) debug.log('self-implement.pod', 'codex-credits-step', { outcome: 'credits', accounts: plan.accounts, skipped: plan.skipped ?? [] }, { level: 'warn' });
5029
5144
  { const { emitDecision } = await import('./live/detail-switch.js');
5030
5145
  emitDecision({ kind: 'ROUTE', what: `Pod 계정 배분 ${plan.accounts.join(' → ')}`, reason: plan.excluded.length ? `뺌 ${plan.excluded.map((x) => `${x.name}(${x.why})`).join(', ')}` : '모든 계정 여유', purpose: plan.creditAccounts ? '구독 잔량 0 — 정책상 크레딧으로 병렬 조각을 돌린다' : '병렬 조각이 한 계정에 몰리지 않게 잔량 순으로 돌려 준다', phase: 'dispatch', target: `Pod ${plan.accounts.length}계정`, paths: plan.accounts.length + plan.excluded.length }); }
5031
5146
  if (!opts.json) ui.info(`[pod] 계정 배분(잔량 순 · 돌려 가며): ${plan.accounts.join(' → ')}${plan.creditAccounts ? ' · 💳 크레딧(구독 잔량 0 · 허가됨)' : ''}${plan.excluded.length ? ` · 뺌 ${plan.excluded.map((x) => `${x.name}(${x.why})`).join(', ')}` : ''}`);
5147
+ } else if (namedChildDecision.provider === 'openrouter') {
5148
+ const model = (opts as { childLlmModel?: string }).childLlmModel!.trim();
5149
+ debug.log('self-implement.pod', 'provider-named', { provider: 'openrouter', model, openrouterKeyPresent: true });
5150
+ if (!opts.json) ui.info(`[pod] child provider = openrouter(모델 ${model}) — 발사 인자로 지정됨`);
5151
+ } else if (namedChildDecision.provider === 'anthropic') {
5152
+ const model = (opts as { childLlmModel?: string }).childLlmModel?.trim() || null;
5153
+ // ⓔ 과금 관측 — anthropic 은 API 키 과금(구독 아님). 새 예산 체계는 없다 · 관측 한 줄만.
5154
+ debug.log('self-implement.pod', 'provider-named', { provider: 'anthropic', model, anthropicKeyPresent: true, billing: 'api-key' });
5155
+ if (!opts.json) ui.info(`[pod] child provider = anthropic(모델 ${model ?? '기본'}) — 발사 인자로 지정됨 · 💳 API 키 과금(구독 아님)`);
5156
+ } else if (namedChildDecision.provider === 'bedrock') {
5157
+ const model = (opts as { childLlmModel?: string }).childLlmModel?.trim() || null;
5158
+ // BEDROCK-PROVIDER ② — 자격은 클러스터의 이름 있는 AWS Secret(발사 전 판정 · 없으면 apply 0 으로 거부). 과금 = AWS 계정.
5159
+ debug.log('self-implement.pod', 'provider-named', { provider: 'bedrock', model, billing: 'aws-account' });
5160
+ if (!opts.json) ui.info(`[pod] child provider = bedrock(모델 ${model ?? '기본'}) — 발사 인자로 지정됨 · 💳 AWS 계정 과금(구독 아님)`);
5161
+ } else if (namedChildDecision.provider === 'glm') {
5162
+ const model = (opts as { childLlmModel?: string }).childLlmModel?.trim() || null;
5163
+ // ZAI-POD-CHILD — 자격은 클러스터의 이름 있는 ZAI Secret(발사 전 판정 · 없으면 apply 0 으로 거부) · 과금 = GLM Coding Plan 정액.
5164
+ // 동시 상한(llm.zaiCodingPlan.maxConcurrent)을 넘는 Pod 는 정책(overage)대로 — openrouter·balance 면 OpenRouter GLM · stop 이면 거부.
5165
+ debug.log('self-implement.pod', 'provider-named', { provider: 'glm', model, billing: 'zai-coding-plan' });
5166
+ if (!opts.json) ui.info(`[pod] child provider = glm(모델 ${model ?? '기본'}) — 발사 인자로 지정됨 · GLM Coding Plan(정액) · 동시 상한을 넘는 Pod 는 llm.zaiCodingPlan.overage 대로`);
5032
5167
  } else if (namedChildDecision.provider === 'grok') {
5033
5168
  const model = (opts as { childLlmModel?: string }).childLlmModel?.trim() || defaultGrokModel().id;
5034
5169
  debug.log('self-implement.pod', 'provider-named', { provider: 'grok', model, credential: credential?.kind ?? null });
5035
5170
  if (!opts.json) ui.info(`[pod] child provider = grok(모델 ${model}) — 발사 인자로 지정됨`);
5036
- } else {
5171
+ } else if (plan) {
5037
5172
  const model = defaultGrokModel().id;
5038
5173
  debug.log('self-implement.pod', 'provider-fallback', { from: 'openai-codex', to: 'grok', excluded: plan.excluded, model });
5039
5174
  { const { emitDecision } = await import('./live/detail-switch.js');
@@ -5041,7 +5176,7 @@ const selfOrchestrateCmd = selfCmd
5041
5176
  if (!opts.json) ui.info(`[pod] 쓸 codex 계정 없음(${plan.excluded.map((x) => `${x.name}: ${x.why}`).join(' · ')}) → grok 으로(모델 ${model})`);
5042
5177
  }
5043
5178
  }
5044
- const passEnv = podProvider === 'grok' ? requestedPassEnv.filter((key) => !grokKeyNames.includes(key)) : requestedPassEnv;
5179
+ const passEnv = podProvider === 'grok' ? requestedPassEnv.filter((key) => !grokKeyNames.includes(key)) : podProvider === 'openrouter' ? [...new Set([...requestedPassEnv, 'OPENROUTER_API_KEY'])] : podProvider === 'anthropic' ? [...new Set([...requestedPassEnv, 'ANTHROPIC_API_KEY'])] : requestedPassEnv;
5045
5180
  const podSourceSpec = (opts as { podSource?: string }).podSource;
5046
5181
  let podSource: import('./task-orchestrator/surfaces/pod-source-receive.js').PodSource | undefined;
5047
5182
  if (podSourceSpec) {
@@ -5063,7 +5198,9 @@ const selfOrchestrateCmd = selfCmd
5063
5198
  const childFlags = opts as { childLlmProvider?: string; childLlmModel?: string; childLlmEffort?: string };
5064
5199
  const podChildLlm = childFlags.childLlmProvider?.trim() ? { childProviderExplicit: true, ...(childFlags.childLlmModel?.trim() ? { childModel: childFlags.childLlmModel.trim() } : {}), ...(childFlags.childLlmEffort?.trim() ? { childEffort: childFlags.childLlmEffort.trim() } : {}) } : {};
5065
5200
  if (childFlags.childLlmProvider?.trim()) debug.log('self-implement.pod', 'child-provider-named', { provider: childFlags.childLlmProvider.trim(), model: childFlags.childLlmModel ?? null, podProvider });
5066
- const podBase = { hostSupervised: opts.supervise === true, ...podChildLlm, ...(remoteOnlyPool ? { imageCommit: image.imageCommit } : {}), account: podProvider === 'grok' ? 'grok' : explicitPodAccount ?? 'team', ...(accountBroker ? { accountBroker, rotationAccounts } : {}), ...(podProvider === 'grok' ? { provider: 'grok' as const, grokApiKeyOptIn } : {}), passEnv, ...(pool ? { pool } : {}), ...((opts as { podSkillEnv?: boolean }).podSkillEnv ? { skillEnv: true } : {}), ...(podSource ? { source: podSource } : {}) };
5201
+ // BEDROCK-POD-PROVIDER-DROP — provider·account 는 한 곳(podLaunchProviderOptions)에서 — 손 나열이 bedrock 을 떨궈 codex(team)로 돌았다(10-11).
5202
+ const podProviderOptions = (await import('./task-orchestrator/surfaces/pod-child-providers.js')).podLaunchProviderOptions(podProvider, { explicitPodAccount, grokApiKeyOptIn });
5203
+ const podBase = { hostSupervised: opts.supervise === true, ...podChildLlm, ...(remoteOnlyPool ? { imageCommit: image.imageCommit } : {}), ...podProviderOptions, ...(accountBroker ? { accountBroker, rotationAccounts } : {}), passEnv, ...(pool ? { pool } : {}), ...((opts as { podSkillEnv?: boolean }).podSkillEnv ? { skillEnv: true } : {}), ...(podSource ? { source: podSource } : {}) };
5067
5204
  if (benchArms) {
5068
5205
  const { benchPodSpawn } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
5069
5206
  podSpawn = benchPodSpawn(benchArms, podBase);
@@ -5074,7 +5211,7 @@ const selfOrchestrateCmd = selfCmd
5074
5211
  ? poolMembers.map(({ context }) => ({ context, namespace: 'elanous-test' }))
5075
5212
  : [{ context: defaultKubectl(['config', 'current-context']).stdout.trim(), namespace: 'elanous-test' }];
5076
5213
  // ⭐ 팔 선언은 «runId 가 붙는» 이 줄에 싣는다 — 위의 `bench-arms` 줄은 runId 해석 «전»이라 비어 있다(09-25 실측) · 보고서(scripts/bench-report.ts)가 이 줄로 잇는다.
5077
- debug.log('self-dev.orchestrate', 'substrate', { substrate, account: podProvider === 'grok' ? 'grok' : (opts as { podAccount?: string }).podAccount ?? 'team', passEnv, context: ready.reason, imageCommit: image.imageCommit, imageFresh: image.fresh, ...(benchArms ? { benchArms: benchArms.map((a) => ({ id: a.id, provider: a.provider, model: a.model ?? null, modelSource: a.modelSource ?? null, passEnv: a.passEnv })) } : {}) });
5214
+ debug.log('self-dev.orchestrate', 'substrate', { substrate, account: podProviderOptions.account, passEnv, context: ready.reason, imageCommit: image.imageCommit, imageFresh: image.fresh, ...(benchArms ? { benchArms: benchArms.map((a) => ({ id: a.id, provider: a.provider, model: a.model ?? null, modelSource: a.modelSource ?? null, passEnv: a.passEnv })) } : {}) });
5078
5215
  } else if (substrate !== 'local') {
5079
5216
  ui.error(`--substrate: local | pod (받은 값: ${substrate})`); process.exit(2);
5080
5217
  }
@@ -5146,11 +5283,7 @@ const selfOrchestrateCmd = selfCmd
5146
5283
  const incomplete = results.length - done;
5147
5284
  console.log([
5148
5285
  `[self-dev] 완료 — ${done}/${results.length} done${promoted ? ` · ${promoted} PR 승격` : ''}${incomplete ? ` · 이어서: elanous self orchestrate <goals> --resume ${runId}` : ''}`,
5149
- ...results.map((r) => {
5150
- const icon = r.status === 'done' ? '✅' : r.status === 'cancelled' ? '⛔' : '❌';
5151
- const disp = r.merged ? ` → merged ${r.prUrl}` : r.prUrl ? ` → PR ${r.prUrl}` : r.stage ? ` [${r.stage}]` : '';
5152
- return ` ${icon} ${r.status} · ${r.feature.slice(0, 56)}${disp}${r.error ? ` — ${r.error.code}${r.error.code === 'pod-job-failed' ? `: ${r.error.message}` : ''}` : ''}`;
5153
- }),
5286
+ ...results.map(formatOrchestrateResultLine),
5154
5287
  ].join('\n'));
5155
5288
  await reportRun(results);
5156
5289
  if (outcome.exitCode !== 0) process.exit(outcome.exitCode); // seam 이 done<total→1 매핑(원 규약 보존)
@@ -5690,15 +5823,24 @@ selfCmd
5690
5823
  const { spawnSync } = await import('node:child_process');
5691
5824
  const { reviewPullRequest, renderReview } = await import('./agent-substrate/pr-reviewer.js');
5692
5825
  const { createRepositoryReferencedFileReader } = await import('./self-implement/goal-file-reader.js');
5693
- const { streamLLM } = await import('./llm.js');
5826
+ const { streamLLM, getProvider } = await import('./llm.js');
5694
5827
  const { registerStandaloneLogSink } = await import('./domains/standalone-log-sink.js');
5695
5828
  const { debug } = await import('./debug/log.js');
5696
- const { runSelfReviewCliCommand, reviewerContextArgs } = await import('./agent-substrate/self-review-cli.js');
5829
+ const { runSelfReviewCliCommand, reviewerContextArgs, selfReviewJsonLine } = await import('./agent-substrate/self-review-cli.js');
5830
+ const { subscriptionReviewerAvailability } = await import('./self-dev/review-provider-fallback.js');
5831
+ const { makeLazyAcpReviewLLM: makeRoleAcpReviewLLM } = await import('./agent-substrate/acp-reviewer.js');
5832
+ const { getOpenRouterApiKey: getOpenRouterApiKeyForReview } = await import('./config.js');
5833
+ const { ROLE_REVIEWER_FALLBACK_MODEL } = await import('./agent-substrate/self-review-cli.js');
5697
5834
  const contextOrder = reviewerContextArgs(process.argv.slice(2));
5698
5835
  const configuredAcpBackend = getUserConfig().acp.reviewBackend;
5699
- const { results } = await runSelfReviewCliCommand(prArgs, {
5836
+ // ⭐ Same reviewer row the harness reads (`dev-pipeline` → `resolveSubscriptionReviewer`).
5837
+ // The seam decides whether it applies (only without an explicit reviewer flag).
5838
+ const { loadLlmPolicy, resolveSubscriptionReviewer } = await import('./policy/llm-policy.js');
5839
+ const roleReviewerSelection = resolveSubscriptionReviewer(loadLlmPolicy(), getUserConfig().roleLlm);
5840
+ const { results, failed } = await runSelfReviewCliCommand(prArgs, {
5700
5841
  ...opts,
5701
5842
  ...(configuredAcpBackend ? { configuredAcpBackend } : {}),
5843
+ ...(roleReviewerSelection ? { roleReviewer: roleReviewerSelection.spec } : {}),
5702
5844
  ...(contextOrder.length > 0 ? { contextOrder } : {}),
5703
5845
  }, {
5704
5846
  gh: (args, timeoutMs) => {
@@ -5717,10 +5859,16 @@ selfCmd
5717
5859
  renderReview,
5718
5860
  // ⛔⭐ 하드코딩 금지(🩸 2026-09-23 실측: 여기 'medium' 이 박혀 있었다) — 무인 리뷰와 «같은» 규칙.
5719
5861
  // 대표 결정: 리뷰는 high. 역할 티어의 effort 를 쓰고, 티어가 없으면 high.
5720
- makeApiLlm: (model) => {
5862
+ // 명시 `--model` 이면 provider 를 그 모델의 것으로 «고정»한다 — 라우터 폴백(grok 등)으로 조용히 넘어가지 않고 오류로 낸다.
5863
+ makeApiLlm: (model, o) => {
5721
5864
  const effort = reviewReasoningEffort(resolveRoleLlm('review'));
5722
5865
  return (prompt: string) =>
5723
- streamLLM([{ role: 'user', content: prompt }], () => {}, { model, ...(effort ? { reasoningEffort: effort } : {}) });
5866
+ streamLLM([{ role: 'user', content: prompt }], () => {}, {
5867
+ model,
5868
+ ...(o?.pinProvider ? { provider: getProvider(model) } : {}),
5869
+ ...(o?.onResolved ? { onResolvedProvider: o.onResolved } : {}),
5870
+ ...(effort ? { reasoningEffort: effort } : {}),
5871
+ });
5724
5872
  },
5725
5873
  makeAcpLlm: (o) => {
5726
5874
  // ⚠️ 동기 팩토리라 여기서 동적 import 를 쓸 수 없다 — 지연 로드해 첫 호출에 붙인다.
@@ -5735,6 +5883,23 @@ selfCmd
5735
5883
  return made(prompt, images);
5736
5884
  };
5737
5885
  },
5886
+ // ⭐ Role-config ACP lane: the harness's subscription guard (subscription ⊕ usage cap ⊕ proxy URL),
5887
+ // then the claude ACP adapter with that scrubbed env. Unavailable = a reason code, never a throw.
5888
+ makeRoleReviewerLlm: (spec, o) => {
5889
+ // Defensive: the seam is only called with a resolved `roleReviewer`, so this is unreachable today.
5890
+ if (!roleReviewerSelection) return { reason: 'role-reviewer-unconfigured' };
5891
+ const availability = subscriptionReviewerAvailability(spec, roleReviewerSelection.cap, process.env);
5892
+ if (!availability.spawn) return { reason: availability.reason ?? 'subscription reviewer unavailable' };
5893
+ const spawn = availability.spawn;
5894
+ // handshakeTimeoutMs left to the adapter default (min(timeoutMs, 60s)) — the harness lane passes none either.
5895
+ return {
5896
+ backend: 'claude',
5897
+ llm: makeRoleAcpReviewLLM({ cwd: process.cwd(), backend: 'claude', backendSpec: spawn.backendSpec, env: spawn.env, timeoutMs: o.timeoutMs }),
5898
+ };
5899
+ },
5900
+ // SUBSCRIPTION-EXHAUST-REROUTE — role reviewer unavailable ⇒ GLM on OpenRouter (the review policy's first
5901
+ // fallback · same pin as POD_OPENROUTER_REVIEWER_PINS.glm), not the codex ladder. No key ⇒ today's default.
5902
+ roleFallbackModel: () => (getOpenRouterApiKeyForReview()?.trim() ? ROLE_REVIEWER_FALLBACK_MODEL : undefined),
5738
5903
  registerSink: async (surface) => { await registerStandaloneLogSink(surface); },
5739
5904
  log: (event, data, o) => debug.log('self-review', event, data, o ?? {}),
5740
5905
  info: (t) => ui.info(t),
@@ -5743,7 +5908,8 @@ selfCmd
5743
5908
  now: () => Date.now(),
5744
5909
  envModel: () => process.env.ELANOUS_PR_REVIEW_MODEL,
5745
5910
  });
5746
- if (opts.json) await writeStdoutJson(JSON.stringify(results.length === 1 ? results[0] : results) + '\n');
5911
+ if (opts.json) await writeStdoutJson(selfReviewJsonLine(results));
5912
+ if (failed >= 1) process.exitCode = 1;
5747
5913
  });
5748
5914
 
5749
5915
  selfCmd
@@ -6996,7 +7162,7 @@ const selfDevCmd = program
6996
7162
  .option('--no-commit', 'external+pty: 완료 시 자동 commit 생략')
6997
7163
  .option('--deliverable <hint>', 'external+pty: 산출물 유형 힌트')
6998
7164
  .option('--screens <dir>', 'external+pty: 스크린 캡처 디렉토리')
6999
- .option('--json', 'hold 결과를 한 줄 JSON으로 · --hold 전용')
7165
+ .option('--json', 'hold 결과 또는 self --ask/--say 전제 검사 중단을 한 줄 JSON으로 출력 (--target 경로도 유지)')
7000
7166
  // ⭐ 역할별 LLM — 「한 번 정하고 아래로는 인자로만」(RFC-role-scoped-llm-selection-2026-08-18 §4e).
7001
7167
  // ⛔ 모르는 역할·provider·tier 는 «거부»한다 — 110차에 `--acp-backend` 가 조용히 무시돼
7002
7168
  // API 로 새어 나간 것이 이 플래그가 fail-closed 인 이유다.
@@ -7049,8 +7215,8 @@ const selfDevCmd = program
7049
7215
 
7050
7216
  // ⭐ 여기부터가 「가드가 덮는 구간」이다 — 위로 올릴 것은 아무것도 없다.
7051
7217
  const invokedAsDrive = command.parent?.args[0] === 'drive';
7052
- if (opts.json === true && opts.hold !== true && (opts.target === undefined || opts.backend !== 'self' || opts.elanous === true || opts.implement === true || opts.goal !== undefined || opts.plan === true || opts.ask !== undefined || opts.say !== undefined || opts.attach !== undefined)) {
7053
- console.error('❌ --json은 --hold 전용입니다');
7218
+ if (opts.json === true && opts.hold !== true && (opts.backend !== 'self' || opts.elanous === true || opts.implement === true || opts.goal !== undefined || opts.plan === true || opts.attach !== undefined || (opts.target === undefined && opts.ask === undefined && opts.say === undefined))) {
7219
+ console.error('❌ --json은 --hold, self --target 또는 self --ask/--say 전제 검사 중단 전용입니다');
7054
7220
  completionGuard.conclude();
7055
7221
  process.exit(2);
7056
7222
  }
@@ -7232,6 +7398,10 @@ const selfDevCmd = program
7232
7398
  askAuthoredFile = flowResult.goalFile;
7233
7399
  if (flowResult.kind === 'stopped-by-preflight') {
7234
7400
  releaseAuthoringLease();
7401
+ if (opts.json) {
7402
+ const terminalResult = { kind: 'self', ok: false, stage: 'preflight-blocked', blockers: flowResult.blockers };
7403
+ await writeStdoutJson(`${JSON.stringify(terminalResult)}\n`);
7404
+ }
7235
7405
  completionGuard.conclude();
7236
7406
  process.exit(1);
7237
7407
  }
@@ -7325,6 +7495,7 @@ const selfDevCmd = program
7325
7495
  if (!opts.json && !invokedAsDrive && explicitOptions.includes('backend') && executor.kind === 'external') {
7326
7496
  console.error(`[dev] 외부 backend 미션의 자기 명령은 \`elanous agent-mission mission\` 입니다; 대응 명령: elanous agent-mission mission --backend ${executor.backend}`);
7327
7497
  }
7498
+ await devCli.ensureOpenRouterChildModelLive(devOpts.childLlmProvider, devOpts.childLlmModel);
7328
7499
  let spec = invokedAsDrive
7329
7500
  ? devCli.buildDriveAliasDevSpec(hasText ? textParts.join(' ') : undefined, devOpts, devCli.explicitDevOptionNames(command), devRunId)
7330
7501
  : buildDevCliSpec(input, executor, devOpts, devCli.explicitDevOptionNames(command), 'cli-dev-ask', undefined, undefined, devRunId);
@@ -7769,6 +7940,8 @@ configCmd
7769
7940
  } else if (credential?.source === 'none' && !isKeylessProvider(nextProvider)) {
7770
7941
  ui.warn(`provider credential unavailable: ${parsed}; keeping existing llm.apiKey (subscription or OAuth may be normal)`);
7771
7942
  }
7943
+ // IMAGE-LEDGER-TAGS: the baseline pin (the rail sets it through this command) goes into the image ledger.
7944
+ if (recordImagePinFromConfigSet(path, parsed) === 'recorded') ui.info(`image ledger: baseline ${String(parsed).slice(0, 12)} · keep=pin`);
7772
7945
  ui.info(`set ${path} = ${JSON.stringify(parsed)}`);
7773
7946
  });
7774
7947
 
@@ -11669,7 +11842,7 @@ async function main(): Promise<void> {
11669
11842
  if (needsFirstRun(cfg)) {
11670
11843
  if (cfg.onboarding.webFirst !== false) {
11671
11844
  const { runWebFirstSetup } = await import('./onboarding/web-first.js');
11672
- if (await runWebFirstSetup({ config: cfg, startedAt: firstRunStartedAt }) === 'link-shown') return;
11845
+ if (await runWebFirstSetup({ config: cfg, startedAt: firstRunStartedAt, startIfMissing: false }) === 'link-shown') return;
11673
11846
  }
11674
11847
  const { runFirstRun } = await import('./onboarding/first-run.js');
11675
11848
  if ((await runFirstRun({ config: cfg })).outcome !== 'ready') return;
@@ -11679,6 +11852,14 @@ async function main(): Promise<void> {
11679
11852
  // answer their first prompt. Printed above the dashboard altscreen
11680
11853
  // so it stays visible on quit (scrolls back into the terminal).
11681
11854
  console.log(`[elanous] ${oneLineProvider()}`);
11855
+ const noticeConfig = getUserConfig();
11856
+ // Only a run that will draw the dashboard (stdin TTY) counts as a person having seen the notice;
11857
+ // a piped/CI run that stops at the TTY gate must not mark it shown.
11858
+ const noticeSeen = (await import('./dashboard/tty-required.js')).dashboardCanUseTty();
11859
+ if (noticeSeen && noticeConfig.errorReports?.enabled !== false && noticeConfig.errorReports?.noticeShown !== true) {
11860
+ console.log((await import('./error-report/report.js')).errorReportNoticeLine(noticeConfig.errorReports));
11861
+ saveUserConfig({ ...noticeConfig, errorReports: { ...noticeConfig.errorReports, noticeShown: true } }, userConfigPath());
11862
+ }
11682
11863
  if (remote) {
11683
11864
  const authNote = remote.token ? 'token' : 'no-auth';
11684
11865
  console.log(`[elanous] remote daemon: ${remote.url} (${authNote})`);