elanous 0.2.22 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (705) hide show
  1. package/NOTICE +7 -0
  2. package/README.md +32 -22
  3. package/apps/pwa/out/404/index.html +1 -1
  4. package/apps/pwa/out/404.html +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
  9. package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
  11. package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
  12. package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
  21. package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
  23. package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
  24. package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
  27. package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/272-b23d2e92161d11fd.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
  35. package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3961-fbef064c213b2b18.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
  39. package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
  52. package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
  53. package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
  56. package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
  59. package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
  64. package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
  69. package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
  71. package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
  73. package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
  74. package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
  78. package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
  83. package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
  84. package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
  85. package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
  86. package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
  87. package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
  90. package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
  97. package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
  99. package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
  101. package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
  105. package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
  110. package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
  111. package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
  112. package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
  114. package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
  116. package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
  117. package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
  120. package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
  123. package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5341ac96203a983.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ad3bd8084048bee4.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/{page-80ed511e02c81412.js → page-6168a7c43e6ef8f5.js} +1 -1
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-a648bc464c9dc754.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-2bd9ce9c020d02d4.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-48fb31810693c357.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/page-cb154acadb025414.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-745d9b6c015076f8.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
  184. package/apps/pwa/out/_next/static/css/5619d59e87eddf66.css +1 -0
  185. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
  186. package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_buildManifest.js +1 -1
  187. package/apps/pwa/out/approvals/index.html +1 -1
  188. package/apps/pwa/out/approvals/index.txt +23 -23
  189. package/apps/pwa/out/autopilot/index.html +1 -1
  190. package/apps/pwa/out/autopilot/index.txt +23 -23
  191. package/apps/pwa/out/board/index.html +1 -1
  192. package/apps/pwa/out/board/index.txt +23 -23
  193. package/apps/pwa/out/botlab/index.html +1 -1
  194. package/apps/pwa/out/botlab/index.txt +22 -22
  195. package/apps/pwa/out/bots/index.html +1 -1
  196. package/apps/pwa/out/bots/index.txt +22 -22
  197. package/apps/pwa/out/ceo/index.html +1 -1
  198. package/apps/pwa/out/ceo/index.txt +23 -23
  199. package/apps/pwa/out/chat/index.html +1 -1
  200. package/apps/pwa/out/chat/index.txt +22 -22
  201. package/apps/pwa/out/consult/index.html +1 -1
  202. package/apps/pwa/out/consult/index.txt +23 -23
  203. package/apps/pwa/out/control/index.html +1 -1
  204. package/apps/pwa/out/control/index.txt +23 -23
  205. package/apps/pwa/out/decisions/index.html +1 -1
  206. package/apps/pwa/out/decisions/index.txt +22 -22
  207. package/apps/pwa/out/design-check/index.html +1 -1
  208. package/apps/pwa/out/design-check/index.txt +23 -23
  209. package/apps/pwa/out/editor/index.html +1 -1
  210. package/apps/pwa/out/editor/index.txt +24 -23
  211. package/apps/pwa/out/exec/index.html +1 -1
  212. package/apps/pwa/out/exec/index.txt +23 -23
  213. package/apps/pwa/out/field/index.html +1 -1
  214. package/apps/pwa/out/field/index.txt +23 -23
  215. package/apps/pwa/out/healthz +1 -1
  216. package/apps/pwa/out/index.html +1 -1
  217. package/apps/pwa/out/index.txt +22 -22
  218. package/apps/pwa/out/inside/index.html +1 -1
  219. package/apps/pwa/out/inside/index.txt +22 -22
  220. package/apps/pwa/out/intake/index.html +1 -1
  221. package/apps/pwa/out/intake/index.txt +23 -23
  222. package/apps/pwa/out/live/index.html +1 -1
  223. package/apps/pwa/out/live/index.txt +23 -23
  224. package/apps/pwa/out/live-run/index.html +1 -1
  225. package/apps/pwa/out/live-run/index.txt +24 -23
  226. package/apps/pwa/out/loops/index.html +1 -1
  227. package/apps/pwa/out/loops/index.txt +22 -22
  228. package/apps/pwa/out/market/index.html +1 -1
  229. package/apps/pwa/out/market/index.txt +22 -22
  230. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  231. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  232. package/apps/pwa/out/morning/index.html +1 -1
  233. package/apps/pwa/out/morning/index.txt +23 -23
  234. package/apps/pwa/out/observatory/index.html +1 -1
  235. package/apps/pwa/out/observatory/index.txt +23 -23
  236. package/apps/pwa/out/ops/checklist/index.html +1 -1
  237. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  238. package/apps/pwa/out/ops/release/index.html +1 -1
  239. package/apps/pwa/out/ops/release/index.txt +22 -22
  240. package/apps/pwa/out/ops/seats/index.html +1 -1
  241. package/apps/pwa/out/ops/seats/index.txt +22 -22
  242. package/apps/pwa/out/outputs/index.html +1 -1
  243. package/apps/pwa/out/outputs/index.txt +22 -22
  244. package/apps/pwa/out/reflection/index.html +1 -1
  245. package/apps/pwa/out/reflection/index.txt +23 -23
  246. package/apps/pwa/out/scheduler/index.html +1 -1
  247. package/apps/pwa/out/scheduler/index.txt +23 -23
  248. package/apps/pwa/out/sessions/index.html +1 -1
  249. package/apps/pwa/out/sessions/index.txt +22 -22
  250. package/apps/pwa/out/settings/devices/index.html +1 -1
  251. package/apps/pwa/out/settings/devices/index.txt +23 -23
  252. package/apps/pwa/out/settings/index.html +1 -1
  253. package/apps/pwa/out/settings/index.txt +23 -23
  254. package/apps/pwa/out/setup/done/index.html +1 -1
  255. package/apps/pwa/out/setup/done/index.txt +23 -23
  256. package/apps/pwa/out/setup/index.html +1 -1
  257. package/apps/pwa/out/setup/index.txt +23 -23
  258. package/apps/pwa/out/share/index.html +1 -1
  259. package/apps/pwa/out/share/index.txt +23 -23
  260. package/apps/pwa/out/showroom/index.html +1 -1
  261. package/apps/pwa/out/showroom/index.txt +22 -22
  262. package/apps/pwa/out/tasks/index.html +1 -1
  263. package/apps/pwa/out/tasks/index.txt +23 -23
  264. package/apps/pwa/out/term/index.html +1 -1
  265. package/apps/pwa/out/term/index.txt +23 -23
  266. package/apps/pwa/out/today/index.html +1 -1
  267. package/apps/pwa/out/today/index.txt +23 -23
  268. package/apps/pwa/out/trace/index.html +1 -1
  269. package/apps/pwa/out/trace/index.txt +23 -23
  270. package/apps/pwa/out/vault/index.html +1 -1
  271. package/apps/pwa/out/vault/index.txt +23 -23
  272. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  273. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  274. package/apps/pwa/out/workflows/index.html +1 -1
  275. package/apps/pwa/out/workflows/index.txt +23 -23
  276. package/apps/pwa/out/workspace/index.html +1 -1
  277. package/apps/pwa/out/workspace/index.txt +23 -23
  278. package/apps/pwa/out/worktrees/index.html +1 -1
  279. package/apps/pwa/out/worktrees/index.txt +23 -23
  280. package/catalog/models/anthropic/claude-haiku-5-5.yaml +32 -0
  281. package/catalog/models/anthropic/claude-opus-5-5.yaml +5 -0
  282. package/catalog/models/anthropic/claude-sonnet-5-5.yaml +31 -0
  283. package/catalog/models/anthropic/claude-sonnet-5.yaml +8 -2
  284. package/catalog/models/openai/gpt-6-astra.yaml +6 -0
  285. package/catalog/models/openai/gpt-6-luna.yaml +6 -0
  286. package/catalog/models/openai/gpt-6-sol.yaml +6 -0
  287. package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
  288. package/graphs/log-horizon/recipes.yaml +3 -0
  289. package/graphs/release/recipes.yaml +1 -1
  290. package/graphs/release/release-loop.yaml +6 -2
  291. package/graphs/release-rehearsal/recipes.yaml +12 -0
  292. package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
  293. package/package.json +4 -1
  294. package/scripts/bench-report.ts +82 -3
  295. package/scripts/ci-typecheck-changed.ts +10 -1
  296. package/scripts/hq/hq-fence-wrapper.sh +148 -0
  297. package/scripts/lib/typecheck-ratchet.ts +51 -0
  298. package/scripts/openai-relay-server.ts +5 -1
  299. package/scripts/release-loop/docs-node.ts +258 -43
  300. package/scripts/release-loop/gate-method.ts +59 -0
  301. package/scripts/release-loop/gate-node.ts +73 -7
  302. package/scripts/release-loop/gate-wall.ts +208 -0
  303. package/scripts/release-loop/known-issues-node.ts +53 -8
  304. package/scripts/release-loop/publish-at.ts +14 -0
  305. package/scripts/release-loop/publish-node.ts +17 -2
  306. package/scripts/release-loop/resume-release.ts +34 -4
  307. package/scripts/release-loop/resume.ts +53 -0
  308. package/scripts/release-loop/shard-plan.ts +3 -11
  309. package/scripts/release-loop/tui-node-checks.ts +22 -0
  310. package/scripts/release-loop/unattended-release.ts +8 -1
  311. package/scripts/rhythm/daily.ts +51 -2
  312. package/scripts/rhythm/weekly.ts +3 -2
  313. package/scripts/tsc-main-safety-net.ts +189 -0
  314. package/scripts/usage-rollup.ts +8 -4
  315. package/src/acp/codex-plugins.ts +48 -6
  316. package/src/agent/monad-agent-turn.ts +67 -5
  317. package/src/agent/run-context.ts +10 -0
  318. package/src/agent/tool-profile.ts +28 -2
  319. package/src/agent-mission/acp-judge.ts +8 -2
  320. package/src/agent-mission/capabilities-cli.ts +16 -1
  321. package/src/agent-mission/driver.ts +1 -1
  322. package/src/agent-mission/pr-review-watch.ts +6 -2
  323. package/src/agent-mission/review-loop.ts +33 -5
  324. package/src/agent-substrate/acp-reviewer.ts +17 -8
  325. package/src/agent-substrate/pr-reviewer.ts +164 -28
  326. package/src/agent-substrate/review-intent.ts +6 -4
  327. package/src/agent-substrate/self-review-cli.ts +111 -16
  328. package/src/agent-substrate/shard-boundary-intent.ts +92 -26
  329. package/src/ask-user-question/pending-questions.ts +8 -2
  330. package/src/autopilot/build/llm-conflict-merge.ts +216 -12
  331. package/src/autopilot/codebase-grounding.ts +44 -0
  332. package/src/autopilot/llm-control-brain.ts +13 -1
  333. package/src/autopilot/mission-codebase-gate.ts +8 -77
  334. package/src/autopilot/pr-manager.ts +12 -3
  335. package/src/boot/acp-server.ts +4 -7
  336. package/src/boot/acp-socket-path.ts +7 -0
  337. package/src/briefing/brief-items.ts +21 -13
  338. package/src/chat/index.ts +12 -3
  339. package/src/cli/agent-cli.ts +20 -0
  340. package/src/cli/brief-cli.ts +27 -21
  341. package/src/cli/cli-user-error.ts +9 -2
  342. package/src/cli/log-event-names.ts +3 -0
  343. package/src/cli/logs-cli.ts +1 -0
  344. package/src/cli/mcp-login.ts +111 -37
  345. package/src/cli/plugin-cli.ts +21 -1
  346. package/src/cli/pod-cli.ts +26 -0
  347. package/src/cli/pr-cli.ts +30 -2
  348. package/src/cli/pr-land-overlap-evidence.ts +131 -0
  349. package/src/cli/release-cli.ts +53 -11
  350. package/src/cli/self-update.ts +173 -10
  351. package/src/cli/skills-cli.ts +12 -3
  352. package/src/cli/tasks-cli.ts +133 -27
  353. package/src/context-bus/context-first.ts +51 -2
  354. package/src/context-bus/context-now-surfaces.ts +13 -2
  355. package/src/context-bus/long-term-memory.ts +3 -1
  356. package/src/context-bus/nightly-condense.ts +3 -2
  357. package/src/core-turn/run-goal-loop.ts +86 -2
  358. package/src/dashboard/chat-fold.ts +20 -0
  359. package/src/dashboard/first-screen-band.ts +151 -1
  360. package/src/dashboard/index.ts +27 -5
  361. package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -3
  362. package/src/dashboard/stale-install-check.ts +13 -2
  363. package/src/dashboard/turn-stream-formatter.ts +25 -0
  364. package/src/debug/log-diet.ts +159 -0
  365. package/src/debug/log.ts +52 -17
  366. package/src/display/coordinator.ts +25 -2
  367. package/src/domains/coo-admin-tool.ts +27 -0
  368. package/src/domains/cron-match.ts +1 -0
  369. package/src/domains/outbound-alert.ts +17 -6
  370. package/src/domains/release-tool.ts +119 -10
  371. package/src/domains/schedule-registry.ts +10 -7
  372. package/src/domains/schedule-runner.ts +1 -0
  373. package/src/elanous-config-dir.ts +2 -2
  374. package/src/elanous-daemon.ts +3 -3
  375. package/src/execution-loop/launch-gate.ts +1 -1
  376. package/src/expression/i18n/messages.en.ts +5 -0
  377. package/src/expression/i18n/messages.ja.ts +5 -0
  378. package/src/expression/i18n/messages.ko.ts +5 -0
  379. package/src/expression/i18n/messages.zh.ts +5 -0
  380. package/src/expression/i18n/types.ts +8 -0
  381. package/src/github/pr-labels.ts +1 -0
  382. package/src/graph-runner/runner.ts +54 -5
  383. package/src/harness/dispatch-backpressure.ts +259 -0
  384. package/src/harness/harness-cli-command.ts +107 -28
  385. package/src/harness/harness-seams.ts +2 -20
  386. package/src/harness/harness-substrate-default.ts +72 -1
  387. package/src/harness/nested-elanous-policy.ts +4 -2
  388. package/src/hq/fence-wrapper.ts +7 -0
  389. package/src/hq/hq.ts +33 -2
  390. package/src/hq/lease.ts +13 -0
  391. package/src/hq/seats.ts +114 -18
  392. package/src/index.ts +163 -64
  393. package/src/intake-plane/collect-github.ts +19 -1
  394. package/src/intake-plane/digest.ts +45 -20
  395. package/src/intake-plane/lens.ts +36 -8
  396. package/src/intelligence-map/model-alias.ts +6 -0
  397. package/src/intelligence-map/model-catalog.ts +41 -0
  398. package/src/knowledge/kgs/pack.ts +5 -2
  399. package/src/knowledge/kgs/sqlite-store.ts +15 -0
  400. package/src/knowledge/tools/knowledge-query.ts +20 -2
  401. package/src/knowledge/write.ts +234 -2
  402. package/src/llm/bedrock-provider.ts +175 -0
  403. package/src/llm/bedrock.ts +345 -0
  404. package/src/llm/provider-credentials.ts +3 -1
  405. package/src/llm.ts +306 -35
  406. package/src/loops/budget.ts +150 -0
  407. package/src/loops/orchestrator/seat-share.ts +6 -49
  408. package/src/loops/orchestrator/traffic.ts +5 -81
  409. package/src/market/signed-index.ts +42 -0
  410. package/src/mcp/mcp-oauth.ts +136 -17
  411. package/src/model-tier/llm-tier-map.ts +48 -4
  412. package/src/models/prompts.ts +22 -1
  413. package/src/mss/logging/horizon-watch.ts +168 -0
  414. package/src/mss/logging/log-store.ts +204 -15
  415. package/src/native-tool-catalog.ts +1 -1
  416. package/src/nexus/api/consult-requests.ts +7 -10
  417. package/src/nexus/api/discord-trigger-bot.ts +6 -3
  418. package/src/nexus/api/error-reports.ts +30 -8
  419. package/src/nexus/api/http-server.ts +8 -0
  420. package/src/nexus/api/loop-resources.ts +42 -0
  421. package/src/nexus/api/outbound-report.ts +8 -3
  422. package/src/nexus/api/telegram-trigger-bot.ts +6 -3
  423. package/src/nexus/index.ts +10 -0
  424. package/src/nexus/outbound/format.ts +2 -0
  425. package/src/nexus/outbound/router.ts +198 -13
  426. package/src/oauth/codex-account-rotation.ts +16 -18
  427. package/src/oauth/codex-account-store.ts +134 -5
  428. package/src/oauth/fallback-chain.ts +28 -6
  429. package/src/onboarding.ts +2 -1
  430. package/src/plugins/adapters/claude-package.ts +4 -12
  431. package/src/plugins/core/capability-policy.ts +141 -0
  432. package/src/plugins/core/host.ts +21 -8
  433. package/src/plugins/core/manifest.ts +19 -2
  434. package/src/plugins/core/trust-store.ts +15 -0
  435. package/src/plugins/core/types.ts +12 -0
  436. package/src/plugins/install/market-fetch.ts +68 -16
  437. package/src/plugins/install/plugin-install.ts +187 -16
  438. package/src/plugins/maker/plugin-maker.ts +25 -20
  439. package/src/plugins/maker/wizard-generate.ts +16 -2
  440. package/src/policy/llm-policy.ts +14 -1
  441. package/src/process/pid-liveness.ts +1 -1
  442. package/src/prompt-cache/openai.ts +10 -6
  443. package/src/prompt-cache/openrouter.ts +94 -0
  444. package/src/prompt-enhance/enhance.ts +46 -5
  445. package/src/prompt-library/family-prompt-coverage.ts +1 -0
  446. package/src/prompt-library/universal-preamble.ts +2 -2
  447. package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
  448. package/src/registry/loader.ts +6 -1
  449. package/src/release-loop/checklist.ts +24 -9
  450. package/src/release-loop/feature-store.ts +3 -0
  451. package/src/release-loop/gate-shards.ts +48 -4
  452. package/src/release-loop/landed-to-green.ts +81 -0
  453. package/src/release-loop/light-rc.ts +11 -1
  454. package/src/release-loop/merged-pr-checklist.ts +10 -0
  455. package/src/release-loop/placement.ts +91 -22
  456. package/src/release-loop/rehearsal.ts +317 -0
  457. package/src/release-loop/release-schedule.ts +13 -1
  458. package/src/release-loop/rubric-types.ts +1 -0
  459. package/src/release-loop/rubric.ts +2 -2
  460. package/src/retro/daily.ts +23 -9
  461. package/src/seat-loop/seat-loop.ts +34 -1
  462. package/src/seat-loop/traffic-signal.ts +44 -0
  463. package/src/self-dev/ask-launch-flow.ts +2 -2
  464. package/src/self-dev/dev-cli.ts +67 -3
  465. package/src/self-dev/dev-pipeline.ts +4 -6
  466. package/src/self-dev/draft-residue.ts +463 -0
  467. package/src/self-dev/draft-sweep.ts +151 -10
  468. package/src/self-dev/draft-triage-rules.ts +27 -1
  469. package/src/self-dev/launch-preflight-text.ts +549 -0
  470. package/src/self-dev/launch-preflight.ts +10 -545
  471. package/src/self-dev/orchestrate-cli.ts +57 -2
  472. package/src/self-dev/orchestrate-summary-line.ts +13 -0
  473. package/src/self-dev/orchestrate.ts +8 -135
  474. package/src/self-dev/review-provider-fallback.ts +115 -19
  475. package/src/self-dev/run-store.ts +1 -3
  476. package/src/self-dev/run-supervisor.ts +3 -22
  477. package/src/self-dev/run-types.ts +178 -0
  478. package/src/self-dev/shard-aggregate.ts +61 -13
  479. package/src/self-dev/shard-plan.ts +5 -1
  480. package/src/self-dev/shard-run.ts +23 -5
  481. package/src/self-dev/supervisor-verdict-edges.ts +2 -4
  482. package/src/self-implement/blocked-draft-policy.ts +3 -19
  483. package/src/self-implement/draft-on-stop-mode.ts +18 -0
  484. package/src/self-implement/follow-up-goals.ts +114 -38
  485. package/src/self-implement/gate-baseline-reap.ts +157 -0
  486. package/src/self-implement/gate-baseline.ts +78 -16
  487. package/src/self-implement/gate-cli.ts +12 -2
  488. package/src/self-implement/gate-remote.ts +17 -6
  489. package/src/self-implement/goal-author.ts +24 -4
  490. package/src/self-implement/goal-digest.ts +19 -0
  491. package/src/self-implement/graph-overlay-condition.ts +4 -0
  492. package/src/self-implement/headless-elanous-driver.ts +11 -9
  493. package/src/self-implement/host-regate.ts +120 -29
  494. package/src/self-implement/l8-merge-queue.ts +67 -5
  495. package/src/self-implement/merge-train.ts +131 -0
  496. package/src/self-implement/off-diff-evidence.ts +9 -0
  497. package/src/self-implement/orchestrator.ts +133 -16
  498. package/src/self-implement/review-finding-recurrence.ts +28 -0
  499. package/src/self-implement/rework-policy.ts +2 -1
  500. package/src/self-implement/round-summary-card.ts +63 -0
  501. package/src/self-implement/run-ledger.ts +4 -3
  502. package/src/self-implement/run-step-projection.ts +147 -0
  503. package/src/self-implement/run-stop.ts +1 -1
  504. package/src/self-implement/seams.ts +36 -3
  505. package/src/self-implement/self-implement-cli.ts +3 -1
  506. package/src/self-implement/train-gate-remote.ts +158 -0
  507. package/src/session-runtime/index.ts +10 -1
  508. package/src/session-runtime/retry-api.ts +11 -1
  509. package/src/skills/gift-install.ts +119 -0
  510. package/src/skills/runner.ts +59 -2
  511. package/src/skills/skill-feedback.ts +31 -1
  512. package/src/skills/skill-tier.ts +1 -0
  513. package/src/smart-wizard/capability-index.ts +231 -0
  514. package/src/smart-wizard/rung.ts +74 -0
  515. package/src/steward/launch.ts +20 -9
  516. package/src/steward/triage.ts +4 -2
  517. package/src/storage/file-lock.ts +8 -1
  518. package/src/task-agent/actions.ts +4 -0
  519. package/src/task-agent/card-evidence.ts +59 -13
  520. package/src/task-agent/judge.ts +4 -3
  521. package/src/task-agent/land-worktree.ts +201 -0
  522. package/src/task-agent/live-move-history.ts +133 -0
  523. package/src/task-agent/live-moves.ts +106 -19
  524. package/src/task-agent/parent-host.ts +117 -8
  525. package/src/task-agent/rejudge-on-head.ts +297 -0
  526. package/src/task-agent/review-result-capture.ts +218 -0
  527. package/src/task-agent/shadow.ts +103 -7
  528. package/src/task-agent/task-hand.ts +136 -11
  529. package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
  530. package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
  531. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
  532. package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
  533. package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
  534. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
  535. package/src/task-orchestrator/surfaces/pod-pool.ts +66 -14
  536. package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
  537. package/src/task-orchestrator/surfaces/self-implement.ts +6 -2
  538. package/src/telegram-service.ts +5 -1
  539. package/src/telegram.ts +17 -4
  540. package/src/time/format.ts +13 -4
  541. package/src/tool-runtime/goal-author-runtime.ts +1 -0
  542. package/src/tool-runtime/self-cognition-catalog.ts +23 -0
  543. package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
  544. package/src/user-config.ts +132 -24
  545. package/src/ux-sim/slash-menu-frames.ts +168 -0
  546. package/src/version/packed-revision.json +1 -1
  547. package/src/web-terminal/preview-tap-registry.ts +5 -2
  548. package/src/workflow-runtime/triggers/scheduler.ts +1 -0
  549. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
  550. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
  551. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
  552. package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
  554. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
  555. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
  556. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
  558. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
  563. package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
  572. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
  573. package/apps/pwa/out/_next/static/chunks/2489-d238d3e2eb5b2bf5.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
  586. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
  594. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
  599. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
  601. package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
  605. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
  610. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
  615. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
  616. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
  618. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
  619. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
  627. package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
  630. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
  640. package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
  643. package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
  647. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
  648. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/approvals/page-88459e0903da2803.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d85c43f46f58716b.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/board/page-4e645600579ae952.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/botlab/page-87edbfd19117823b.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/chat/page-cbaf66b1e1804adf.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/control/page-9f5610caaa06178c.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/decisions/page-ec8f3575e339de74.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/exec/page-2a19c5cd3b562580.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/field/page-b6a09cde2e07521a.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/loops/page-abd86cd832aaa011.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8c3f168fc3f91939.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/morning/page-786fb4504d0f2fa9.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7ec8e289b4c14df6.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-8c8ac17d52be2a79.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d359ab048d63a9d9.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/settings/page-f151cc10ad026940.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/share/page-bf495a1e284f4e00.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/term/page-9abcfac07e02a542.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/workflows/page-69cb93d1a2e57e0e.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/workspace/page-72ec543928d67c3e.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
  704. package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +0 -1
  705. /package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
package/src/telegram.ts CHANGED
@@ -81,8 +81,8 @@ import { maybeHandleCardPhoto, type CardPhotoDeps } from './telegram-card-follow
81
81
  import { attachTelegramProjectButtons } from './telegram-project-command.js';
82
82
  import { attachTelegramFabricPlan } from './telegram-fabric-plan.js';
83
83
  import { contextNow as readContextNow, type ContextNowDeps } from './context-bus/context-now.js';
84
- import { renderContextFirstNow } from './context-bus/context-now-surfaces.js';
85
- import { createContextFirstGate, renderContextFirst } from './context-bus/context-first.js';
84
+ import { renderContextFirstOpening } from './context-bus/context-now-surfaces.js';
85
+ import { createContextFirstFileStore, createContextFirstGate, isOperationalQuery, renderContextFirst, type ContextFirstStore } from './context-bus/context-first.js';
86
86
 
87
87
  export type TgAttachmentKind = 'photo' | 'voice' | 'audio' | 'document';
88
88
 
@@ -239,6 +239,8 @@ export interface TelegramBotOpts {
239
239
  /** 시험 seam — `/v1/context/now` 와 같은 `contextNow` 읽기. 던지면 «맥락 못 읽음». */
240
240
  readContextNow?: typeof readContextNow;
241
241
  contextNowDeps?: ContextNowDeps;
242
+ /** Keeps last-utterance times across a daemon restart so a restart does not re-send the context-first opening. */
243
+ contextFirstStore?: ContextFirstStore;
242
244
  }
243
245
 
244
246
  /** Surface-unification v2 (FU-2) — Telegram trigger event passed to
@@ -363,7 +365,7 @@ export class TelegramBot {
363
365
  private readonly handleFabricPlan: (ctx: TgIncoming) => Promise<boolean>;
364
366
  private readonly readContextNow: typeof readContextNow;
365
367
  private readonly contextNowDeps?: ContextNowDeps;
366
- private readonly contextFirstGate = createContextFirstGate({ now: () => this.nowImpl() });
368
+ private readonly contextFirstGate: ReturnType<typeof createContextFirstGate>;
367
369
  private seatAskTimer: ReturnType<typeof setInterval> | null = null;
368
370
  /** 앨범 id → `#현장` 행사 · 답장 디바운스. 태그된 앨범만 들어온다. */
369
371
  private readonly fieldGroups = new Map<string, {
@@ -390,6 +392,10 @@ export class TelegramBot {
390
392
  this.log = opts.log ?? ((m: string) => debug.log('telegram.core', m));
391
393
  this.sleepImpl = opts.sleepImpl ?? sleep;
392
394
  this.nowImpl = opts.nowImpl ?? (() => Date.now());
395
+ this.contextFirstGate = createContextFirstGate({
396
+ now: () => this.nowImpl(),
397
+ ...(opts.contextFirstStore ? { store: opts.contextFirstStore } : {}),
398
+ });
393
399
  this.perChatGapMs = opts.perChatGapMs ?? DEFAULT_PER_CHAT_GAP_MS;
394
400
  this.globalMaxPerSec = opts.globalMaxPerSec ?? DEFAULT_GLOBAL_MAX_PER_SEC;
395
401
  this.streamEditGapMs = opts.streamEditGapMs ?? DEFAULT_STREAM_EDIT_GAP_MS;
@@ -436,8 +442,11 @@ export class TelegramBot {
436
442
  if (!this.contextFirstGate.take(key)) return;
437
443
  const cfg = this.slashContext?.userConfig.telegram;
438
444
  if (cfg?.contextFirst === false) return;
445
+ if (isOperationalQuery(ctx.text)) return;
439
446
  try {
440
- await this.sendMessage(ctx.chatId, renderContextFirst(this.readContextNow, this.contextNowDeps, renderContextFirstNow), { replyTo: ctx.messageId, threadId: ctx.threadId });
447
+ const opening = renderContextFirst(this.readContextNow, this.contextNowDeps, renderContextFirstOpening);
448
+ if (!opening) return;
449
+ await this.sendMessage(ctx.chatId, opening, { replyTo: ctx.messageId, threadId: ctx.threadId });
441
450
  } catch (err) {
442
451
  this.log(`telegram context-first failed: ${err instanceof Error ? err.message : String(err)}`);
443
452
  }
@@ -2988,6 +2997,10 @@ export function botFromConfig(opts: BotFromConfigOpts): TelegramBot {
2988
2997
  ...(opts.daemonBridge !== undefined ? { daemonBridge: opts.daemonBridge } : {}),
2989
2998
  },
2990
2999
  ...(voiceAdapter ? { voiceAdapter } : {}),
3000
+ // An injected clock marks a test/replay harness: it must not read or write the live daemon's state file.
3001
+ ...(opts.telegramBotOpts?.nowImpl === undefined
3002
+ ? { contextFirstStore: createContextFirstFileStore(joinPath(getElanousConfigDir(), 'telegram-context-first.json')) }
3003
+ : {}),
2991
3004
  ...opts.telegramBotOpts,
2992
3005
  });
2993
3006
  // Register the surface-HITL callback subscription up front so the
@@ -47,7 +47,7 @@ function isValidTimeZone(tz: string): boolean {
47
47
  * 뒤이어 도는 모든 테스트 파일이 오염된다(실제로 이 세션에서 catch-up 테스트 4건이
48
48
  * 그렇게 깨졌고, 파일 순서를 뒤집으면 통과했다). 그래서 env/OS 를 주입으로 뺀다. */
49
49
  export interface ResolveTimeZoneDeps {
50
- /** config 의 timezone 값. 생략 시 user-config 에서 lazy 로드. */
50
+ /** config 의 timezone 값. 생략 시 등록된 config 소스에서 읽는다. */
51
51
  configTimeZone?: string | undefined;
52
52
  /** env 의 TZ 값. 생략 시 `process.env.TZ`. */
53
53
  envTimeZone?: string | undefined;
@@ -60,12 +60,21 @@ export interface ResolveTimeZoneDeps {
60
60
  * `process.env.TZ` 를 단독으로 믿지 않는 이유: launchd 로 뜬 데몬은 TZ 를 물려받지
61
61
  * 못한다(실측 확인). 반면 `Intl` 은 OS 설정을 직접 읽어 그 경우에도 올바른 지역을
62
62
  * 돌려준다. 그래서 env 보다 OS 를 **뒤**에 두되 fallback 으로 반드시 둔다. */
63
+ let configTimeZoneSource: (() => string | undefined) | undefined;
64
+
65
+ /** Config 소유자가 로드될 때 등록한다. 이 바닥 모듈은 config 를 로드하지 않는다.
66
+ * 반환된 함수는 이전 소스를 복원한다(격리 테스트에서만 사용). */
67
+ export function setConfigTimeZoneSource(fn: () => string | undefined): () => void {
68
+ const previous = configTimeZoneSource;
69
+ configTimeZoneSource = fn;
70
+ return () => { configTimeZoneSource = previous; };
71
+ }
72
+
63
73
  export function resolveTimeZone(deps: ResolveTimeZoneDeps = {}): ResolvedTimeZone {
64
74
  let cfg = deps.configTimeZone;
65
- if (cfg === undefined && !('configTimeZone' in deps)) {
75
+ if (!('configTimeZone' in deps)) {
66
76
  try {
67
- const mod = require('../user-config.js') as typeof import('../user-config.js');
68
- cfg = (mod.getUserConfig() as { timezone?: string }).timezone;
77
+ cfg = configTimeZoneSource?.();
69
78
  } catch { /* config 미가용(부팅 초기·격리 테스트) — 아래로 */ }
70
79
  }
71
80
  if (typeof cfg === 'string' && isValidTimeZone(cfg.trim())) {
@@ -1,3 +1,4 @@
1
+ import '../autopilot/mission-codebase-gate.js';
1
2
  import { readFileSync } from 'node:fs';
2
3
  import { resolve, relative, isAbsolute } from 'node:path';
3
4
  import type { LLMToolSpec } from '../llm.js';
@@ -0,0 +1,23 @@
1
+ /** Canonical names for the read-only self-cognition surface. */
2
+ export const SELF_COGNITION_TOOL_NAMES = [
3
+ 'self_recall',
4
+ 'logs_query',
5
+ 'ops_status',
6
+ 'memory_recall',
7
+ 'context_now',
8
+ ] as const;
9
+
10
+ /** MCP catalog metadata derived from the same name ledger as the runtimes. */
11
+ export const SELF_COGNITION_MCP_CATALOG_ENTRIES = SELF_COGNITION_TOOL_NAMES.map(name => ({
12
+ id: name,
13
+ kind: 'other',
14
+ aliases: [name] as [typeof name],
15
+ displayName: name,
16
+ description: 'Read-only self-cognition query over elanous history, memory, operations, or logs.',
17
+ promptSummary: `\`${name}\` (read-only self-cognition query)`,
18
+ host: ['mcp'] as ['mcp'],
19
+ safety: ['read-only'] as ['read-only'],
20
+ supportsParallel: true,
21
+ defaultEnabled: true,
22
+ intentScope: 'ops-ui',
23
+ } as const));
@@ -2,17 +2,10 @@ import { createRequire } from 'node:module';
2
2
  import { isMainThread, parentPort, Worker } from 'node:worker_threads';
3
3
  import { debug } from '../debug/log.js';
4
4
  import type { LLMToolSpec } from '../llm.js';
5
- import type { NativeToolCatalogEntry } from '../native-tool-catalog.js';
6
5
  import type { ToolRunResult, ToolRuntime, ToolRuntimeContext } from './types.js';
6
+ import { SELF_COGNITION_TOOL_NAMES } from './self-cognition-catalog.js';
7
7
 
8
- /** Canonical names for the read-only self-cognition surface. */
9
- export const SELF_COGNITION_TOOL_NAMES = [
10
- 'self_recall',
11
- 'logs_query',
12
- 'ops_status',
13
- 'memory_recall',
14
- 'context_now',
15
- ] as const;
8
+ export { SELF_COGNITION_TOOL_NAMES, SELF_COGNITION_MCP_CATALOG_ENTRIES } from './self-cognition-catalog.js';
16
9
 
17
10
  type SelfCognitionToolName = (typeof SELF_COGNITION_TOOL_NAMES)[number];
18
11
  type RecallToolName = 'memory_recall' | 'self_recall';
@@ -207,18 +200,3 @@ export const SELF_COGNITION_RUNTIMES: readonly ToolRuntime[] = SELF_COGNITION_TO
207
200
  ? runRecall(name, args, ctx)
208
201
  : toToolRunResult(await coreTools().buildCoreTools().dispatch(name, args)),
209
202
  }));
210
-
211
- /** MCP catalog metadata derived from the same name ledger as the runtimes. */
212
- export const SELF_COGNITION_MCP_CATALOG_ENTRIES: readonly NativeToolCatalogEntry[] = SELF_COGNITION_TOOL_NAMES.map(name => ({
213
- id: name,
214
- kind: 'other',
215
- aliases: [name],
216
- displayName: name,
217
- description: 'Read-only self-cognition query over elanous history, memory, operations, or logs.',
218
- promptSummary: `\`${name}\` (read-only self-cognition query)`,
219
- host: ['mcp'],
220
- safety: ['read-only'],
221
- supportsParallel: true,
222
- defaultEnabled: true,
223
- intentScope: 'ops-ui',
224
- }));
@@ -27,7 +27,7 @@
27
27
  // crashed wizard cannot corrupt an existing file. Mode 0600 when the
28
28
  // telegram bot token is present.
29
29
 
30
- import { DRAFT_ON_STOP_MODES, parseDraftOnStopMode, type DraftOnStopMode } from './self-implement/blocked-draft-policy.js';
30
+ import { DRAFT_ON_STOP_MODES, parseDraftOnStopMode, type DraftOnStopMode } from './self-implement/draft-on-stop-mode.js';
31
31
  import { isCodexQuotaPolicy } from './oauth/codex-quota-policy.js';
32
32
  import { defaultObsidianVault } from './obsidian/default-vault.js';
33
33
  import {
@@ -47,7 +47,8 @@ import {
47
47
  QWEN_MODEL,
48
48
  GLM_MODEL,
49
49
  } from './config.js';
50
- import type { SkillTier } from './skills/runner.js';
50
+ import type { SkillTier } from './skills/skill-tier.js';
51
+ import type { RubricAxis } from './release-loop/rubric-types.js';
51
52
  import { sharedAgentSkillRoots } from './skills/shared-agent-skill-roots.js';
52
53
  import {
53
54
  isModelTier,
@@ -58,6 +59,7 @@ import {
58
59
  type SmartDefaultsUserConfig,
59
60
  } from './model-tier/types.js';
60
61
  import { lookupLlmTierSpec } from './model-tier/llm-tier-map.js';
62
+ import { BEDROCK_DEFAULT_MODEL } from './llm/bedrock.js';
61
63
  import { userConfigPath as nexusUserConfigPath } from './nexus/config/paths.js';
62
64
  import { type StreamingMode, isStreamingMode } from './session/streaming/stream-compositor.js';
63
65
  import type { DevRequestRoutingConfig } from './skills/dev-request-router.js';
@@ -65,6 +67,7 @@ import type { UrlRoutingConfig } from './skills/url-router.js';
65
67
  import { migrateLegacyXdgUserConfig } from './storage/legacy-elanous-config-migrate.js';
66
68
  import { withFileLockSync } from './storage/file-lock.js';
67
69
  import { debug } from './debug/log.js';
70
+ import { setConfigTimeZoneSource } from './time/format.js';
68
71
  import type { FoldMode } from './log-entry.js';
69
72
  import {
70
73
  CLAUDE_PACKAGE_MISSING,
@@ -138,18 +141,20 @@ export type LLMProviderName =
138
141
  // entries name the *cloud* surface only.
139
142
  | 'kimi' | 'qwen' | 'glm'
140
143
  // 대표 2026-09-23 — OpenAI 호환 게이트웨이. kimi·qwen·glm 의 «첫 실제 경로»(모델 id `openrouter/<vendor>/<model>`).
141
- | 'openrouter';
144
+ | 'openrouter'
145
+ // 대표 2026-10-10 (BEDROCK-PROVIDER) — AWS Bedrock 의 Claude. 자격 = AWS 기본 자격 체인 · 명시 선택 전용(auto·폴백 후보 아님).
146
+ | 'bedrock';
142
147
 
143
148
  /** Stored config retains its established provider normalization contract. */
144
149
  // ⛔ 2026-09-23 — 손으로 적은 목록이라 새 provider 를 «조용히» 거른다: `openrouter` 를 배선(#19900)했는데
145
150
  // 여기 없어서 config 로 고르면 정규화가 `auto` 로 떨궜다(「직렬화 드롭」). 자 = `test/llm-provider-name-lists.test.ts`.
146
151
  export const CONFIG_LLM_PROVIDER_NAMES: readonly LLMProviderName[] = [
147
- 'auto', 'grok', 'openai', 'anthropic', 'local', 'openai-codex', 'gemini', 'openrouter',
152
+ 'auto', 'grok', 'openai', 'anthropic', 'local', 'openai-codex', 'gemini', 'openrouter', 'bedrock',
148
153
  ];
149
154
 
150
155
  /** `ELANOUS_LLM_PROVIDER` additionally permits every declared runtime provider. */
151
156
  export const RUNTIME_LLM_PROVIDER_NAMES: readonly LLMProviderName[] = [
152
- 'auto', 'grok', 'openai', 'anthropic', 'local', 'openai-codex', 'gemini', 'kimi', 'qwen', 'glm', 'openrouter',
157
+ 'auto', 'grok', 'openai', 'anthropic', 'local', 'openai-codex', 'gemini', 'kimi', 'qwen', 'glm', 'openrouter', 'bedrock',
153
158
  ];
154
159
 
155
160
  /** Provider-agnostic reasoning intensity. The HUD click cycle and the
@@ -173,6 +178,10 @@ export interface LLMConfig {
173
178
  apiKey?: string;
174
179
  model?: string;
175
180
  baseUrl?: string;
181
+ /** OpenRouter 설정 한 곳(두 골이 같은 키를 쓴다):
182
+ * - `providerPreferences` — 상류 라우팅 선호; 도구 가능 기본값(require_parameters·allow_fallbacks)을 얕게 덮는다(OR-LLM-ROUTING-1).
183
+ * - `fallbackModel` — 유료 OpenRouter 폴백 모델; 체인에 openrouter 를 명시하고 모델·키를 모두 줄 때만 선택된다(OR-FALLBACK-TIER-1). */
184
+ openrouter?: { providerPreferences?: Record<string, unknown>; fallbackModel?: string };
176
185
  /** Ordered rotation of providers the user can cycle through with
177
186
  * `elanous provider:rotate` / `/provider next`. Each entry is a
178
187
  * full (provider, model, apiKey, baseUrl) tuple that gets
@@ -186,7 +195,7 @@ export interface LLMConfig {
186
195
  * ⛔ **기본 ON** (대표 결정 2026-08-05) — `false` 일 때만 꺼진다.
187
196
  * ⛔ 이것은 provider 회전(`rotation`)과 «다른 축»이다: 저 축은 provider·모델을 바꾸고,
188
197
  * 이 축은 «같은 provider 안에서 어느 계정의 토큰을 쓸지»를 바꾼다.
189
- * ⛔ 리셋 크레딧 «소비»는 여기에 «없다» — 되돌릴 수 없어 사람이 명시적으로 한다. */
198
+ * 리셋 크레딧 자동 소비는 별도 일일 상한으로 제한한다. */
190
199
  codexAccountRotation?: boolean;
191
200
  /** ⭐⭐ codex 계정 «알림» — 회전·리셋크레딧 소비를 텔레그램 등 outbound 로 보낼지.
192
201
  * ⛔ **기본 ON** — `false` 일 때만 조용해진다.
@@ -206,6 +215,8 @@ export interface LLMConfig {
206
215
  * 🩸 2026-09-24(대표): 「third 부터 소진하고 그다음 team」 — 이름순(default<new<third)으론 못 만든다.
207
216
  * ⛔ 여기 없는 계정은 버리지 않는다 — 뒤로 가서 이름순으로 붙는다. */
208
217
  codexAccountOrder?: string[];
218
+ /** Automatic reset-credit uses across all Codex accounts per UTC day; default 1, 0 disables. */
219
+ codexResetAutoConsumePerDay?: number;
209
220
  /** 대표 2026-09-28 «크레딧 사용 허가» — 주간 한도가 찬 codex 계정도 «선불 크레딧으로 계속» 쓴다(서버가 한도 소진 시 크레딧으로 넘긴다).
210
221
  * 켜면 회전이 «후보 없음»(→ grok 폴백) 대신 지금 계정에 머물고, Pod 배분도 찬 계정을 사용률 낮은 순으로 쓴다.
211
222
  * 순서는 여전히 «구독 잔량이 남은 계정 먼저». 기본 꺼짐(크레딧은 돈이다). */
@@ -218,7 +229,8 @@ export interface LLMConfig {
218
229
  grokWeeklyCapPct?: number;
219
230
  /** ⭐⭐ codex 가 «소진된 뒤» 갈 곳을 «순서»로 정한다 (대표 2026-08-13).
220
231
  *
221
- * 값: `['codex-rotate', 'grok']` — 아는 칸은 그 둘뿐이고, 모르는 이름은 버린다(관측에 남는다).
232
+ * 값: `['codex-rotate', 'grok']` 등 — 아는 칸은 `FALLBACK_STEPS`, 모르는 이름은 버린다(관측에 남는다).
233
+ * `openrouter` 는 명시적 체인·`llm.openrouter.fallbackModel`·API 키가 모두 있어야 한다(유료).
222
234
  * ⛔ **미설정이면 `DEFAULT_FALLBACK_CHAIN`(`src/oauth/fallback-chain.ts`) = `['codex-rotate','grok']`** — 설정이 없어도 grok 으로 샌다(#10575).
223
235
  * 막으려면 `['codex-rotate']` 를 «명시»한다. 이 인스턴스의 값은 `elanous config get llm.fallbackChain` 으로 잰다.
224
236
  *
@@ -1306,13 +1318,15 @@ export interface LogsConfig {
1306
1318
  maxAgeDays: number;
1307
1319
  /** DB 크기 상한 MB(기본 500). 초과 시 오래된 행부터 삭제. 0 = 무제한. */
1308
1320
  maxDbMb: number;
1321
+ /** 크기 정리 보존 하한 시간(기본 24). 이 시간 안의 행은 크기 정리로 지우지 않는다. 0 = 하한 없음(옛 동작). */
1322
+ minRetainHours: number;
1309
1323
  };
1310
1324
  /** 로그 출처 이름 오버라이드 (LF7-a). 미설정 시 자동 유도 —
1311
1325
  * prod(기본) 또는 `test:<repo폴더명>` (ELANOUS_STATE_DIR 기준). */
1312
1326
  instanceName?: string;
1313
1327
  }
1314
1328
 
1315
- const LOGS_DEFAULTS: LogsConfig = { retention: { maxAgeDays: 7, maxDbMb: 500 } };
1329
+ const LOGS_DEFAULTS: LogsConfig = { retention: { maxAgeDays: 7, maxDbMb: 500, minRetainHours: 24 } };
1316
1330
 
1317
1331
  // ── Shell / PTY ──────────────────────────────────────────────────────
1318
1332
  // Gate for exposing PtyShell* native tools to the dashboard chat loop.
@@ -3315,6 +3329,7 @@ export interface RoleLlmSpec {
3315
3329
  provider?: LLMProviderName;
3316
3330
  tier?: ModelTier;
3317
3331
  model?: string;
3332
+ effort?: 'low' | 'medium' | 'high';
3318
3333
  }
3319
3334
 
3320
3335
  /** Reviewer-only ACP subscription selection; it is not a streaming LLM provider. */
@@ -3396,7 +3411,10 @@ export const ROLE_MODEL_DEFAULTS: Record<ModelRole, { environment: string; tier:
3396
3411
  export function resolveActiveProvider(config: UserConfig): LLMProviderName {
3397
3412
  if (config.llm.provider !== 'auto') return config.llm.provider;
3398
3413
  // eslint-disable-next-line @typescript-eslint/no-require-imports
3399
- const { decideProviderForConfig, getProvider } = require('./llm.js') as typeof import('./llm.js');
3414
+ const { decideProviderForConfig, getProvider } = require('./llm.js') as {
3415
+ decideProviderForConfig: (config: UserConfig) => { provider: LLMProviderName | `auto:${string}` };
3416
+ getProvider: () => { name: string };
3417
+ };
3400
3418
  // ⭐ 2026-09-24 — 런타임이 실제로 보내는 곳과 같은 결정을 쓴다(종전 `getProvider()` 는 auto 에서 codex 를 건너뛰었다).
3401
3419
  const decided = decideProviderForConfig(config).provider;
3402
3420
  if (typeof decided === 'string' && decided.startsWith('auto:')) return decided.slice('auto:'.length) as LLMProviderName;
@@ -3499,10 +3517,12 @@ export interface RoleLlmResolveOptions {
3499
3517
  config?: UserConfig;
3500
3518
  /** 발사 시점에 «한 번» 정해 아래로 내리는 인자 — 사다리 최상층(source='flag'). */
3501
3519
  overrides?: RoleLlmConfig;
3520
+ /** Test seam — 기본 process.env. `ELANOUS_ROLE_LLM_<ROLE>` 을 읽는다(source='environment'). */
3521
+ env?: NodeJS.ProcessEnv;
3502
3522
  }
3503
3523
 
3504
3524
  /** ★ 역할별 LLM 해석 SSOT — RFC-role-scoped-llm-selection-2026-08-18 §4c.
3505
- * 사다리: ① overrides(flag) → ② config.roleLlm → ③~⑥ 기존(resolveRoleLlmBaseline).
3525
+ * 사다리: ① overrides(flag) → ①b env 고정 `ELANOUS_ROLE_LLM_<ROLE>`(POD-ROLE-LLM) → ② config.roleLlm → ③~⑥ 기존(resolveRoleLlmBaseline).
3506
3526
  * ⛔ 아무 override 도 없으면 ③~⑥ 만 타므로 산출이 종전과 «같다»(§4f 불변식 · NL 진입 무변경). */
3507
3527
  export function resolveRoleLlm(role: ModelRole, opts: RoleLlmResolveOptions = {}): RoleLlmResolution {
3508
3528
  const config = opts.config ?? getUserConfig();
@@ -3511,8 +3531,10 @@ export function resolveRoleLlm(role: ModelRole, opts: RoleLlmResolveOptions = {}
3511
3531
  const globalProvider = (): LLMProviderName => (activeProvider ??= resolveActiveProvider(config));
3512
3532
  // 명시 인자가 있으면 그것이 진실 — 없을 때만 발사 시점에 정해진 값을 읽는다(둘 다 source='flag').
3513
3533
  const flagSpec = (opts.overrides ?? launchRoleLlmOverrides)?.[role];
3534
+ const envSpec = roleLlmEnvPin(role, opts.env ?? process.env);
3514
3535
  const layers: ReadonlyArray<readonly [RoleLlmSpec | undefined, RoleLlmSource]> = [
3515
3536
  [flagSpec, 'flag'],
3537
+ [envSpec, 'environment'],
3516
3538
  [config.roleLlm?.[role], 'config-role'],
3517
3539
  ];
3518
3540
  for (const [spec, source] of layers) {
@@ -3527,10 +3549,35 @@ export function resolveRoleLlm(role: ModelRole, opts: RoleLlmResolveOptions = {}
3527
3549
  // 세 칸이 «다 비었으면» 아래 층으로 흘린다 — 빈 칸은 선언이 아니다.
3528
3550
  }
3529
3551
  const baseline = resolveRoleLlmBaseline(role, config, globalProvider());
3530
- if (opts.overrides || launchRoleLlmOverrides || config.roleLlm?.[role]) observeRoleLlm(role, baseline, flagSpec);
3552
+ if (opts.overrides || launchRoleLlmOverrides || envSpec || config.roleLlm?.[role]) observeRoleLlm(role, baseline, flagSpec);
3531
3553
  return baseline;
3532
3554
  }
3533
3555
 
3556
+ /** POD-ROLE-LLM — 역할 고정을 «프로세스 env» 로 받는 칸. `ELANOUS_ROLE_LLM_<ROLE>` = RoleLlmSpec JSON
3557
+ * (예 `{"provider":"openai-codex","tier":"best","model":"gpt-6-sol"}`).
3558
+ * ⭐ 왜 env 인가: `--role-llm` 은 부모 프로세스 메모리 값이고 Pod 안엔 운영 config 가 없다 —
3559
+ * Pod Job 이 실을 수 있는 «비밀 아닌» 길은 armEnv 하나뿐이다(self-implement-pod.ts).
3560
+ * ⛔ 못 읽는 값은 삼키지 않고 관측을 남긴 뒤 «무시»한다(아래 층으로 흘린다 · 고정 실패가 런을 죽이지 않는다). */
3561
+ export function roleLlmEnvName(role: ModelRole): string {
3562
+ return `ELANOUS_ROLE_LLM_${role.toUpperCase().replace(/-/g, '_')}`;
3563
+ }
3564
+
3565
+ function roleLlmEnvPin(role: ModelRole, env: NodeJS.ProcessEnv): RoleLlmSpec | undefined {
3566
+ const name = roleLlmEnvName(role);
3567
+ const raw = env[name]?.trim();
3568
+ if (!raw) return undefined;
3569
+ let parsed: unknown;
3570
+ try { parsed = JSON.parse(raw); } catch { parsed = undefined; }
3571
+ const entry = parseRoleLlmEntry(parsed);
3572
+ if (entry.ok) return entry.spec;
3573
+ try {
3574
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
3575
+ const { debug } = require('./debug/log.js') as typeof import('./debug/log.js');
3576
+ debug.log('harness.role-llm', 'env-pin-rejected', { role, env: name, reason: parsed === undefined ? 'not-json' : 'invalid-spec' }); // ⛔ 값 원문은 싣지 않는다
3577
+ } catch { /* fail-open */ }
3578
+ return undefined;
3579
+ }
3580
+
3534
3581
  /** Resolves a model role without forcing a sparse user setting when it is empty.
3535
3582
  * ⭐ 이제 resolveRoleLlm 위의 «얇은 래퍼»다 — 그래야 기존 소비자 «전부»가 새 사다리를 자동으로 탄다
3536
3583
  * (옆에 새 함수를 두면 「형태만 있고 실행 경로엔 없다」가 된다). */
@@ -3710,7 +3757,7 @@ export function parseGateRemoteConfig(raw: unknown): GateRemoteConfig | undefine
3710
3757
 
3711
3758
  export interface ProjectConfig {
3712
3759
  /** `axes` is absent when the configured axes are invalid; `error` then carries the config error text. */
3713
- rubric?: { axes?: import('./release-loop/rubric.js').RubricAxis[]; error?: string };
3760
+ rubric?: { axes?: RubricAxis[]; error?: string };
3714
3761
  }
3715
3762
 
3716
3763
  /** Validate one project's `rubric.axes` — throws the config error text (key duplicate · non-numeric weight). */
@@ -3765,7 +3812,7 @@ export interface UserConfig {
3765
3812
  guardian?: { mode?: 'shadow' | 'live' };
3766
3813
  /** TA-JUDGE-LIVE-SAFE: task-agent judge moves executed for real. Only `review` · `propose-green` are honoured
3767
3814
  * (`src/task-agent/live-moves.ts` drops anything else with a warning). Absent = env ELANOUS_TASK_AGENT_LIVE_MOVES, else none (pure shadow). */
3768
- taskAgent?: { liveMoves?: string[]; parentHost?: { host?: string; cwd?: string; elanous?: string; configDir?: string; podPool?: string } };
3815
+ taskAgent?: { liveMoves?: string[]; parentHost?: { host?: string; cwd?: string; elanous?: string; configDir?: string; podPool?: string; approvalCapacity?: number } | Array<{ host?: string; cwd?: string; elanous?: string; configDir?: string; podPool?: string; approvalCapacity?: number }> };
3769
3816
  events?: EventsConfig;
3770
3817
  /** GATE-REMOTE — see GateRemoteConfig. Absent = defaults (auto on · node-b · load 20 · cap 2). */
3771
3818
  gateRemote?: GateRemoteConfig;
@@ -3790,7 +3837,7 @@ export interface UserConfig {
3790
3837
  loops?: { owners?: Record<string, EventSeat>; defaultOwner?: EventSeat; orchestrator?: OrchestratorLoopConfig; steward?: { mode?: StewardLoopMode; linearTeam?: string; roles?: Record<string, { maxConcurrent?: number }>; budget?: number; tracks?: Record<string, string>; alertAfterFailures?: number; launch?: 'off' | 'shadow' | 'live'; maxParallel?: number; podPool?: string }; seat?: SeatLoopConfig; persona?: PersonaLoopConfig };
3791
3838
  /** 🔐 Pod 의 Grok API 키 과금은 명시 opt-in 만. 생략·잘못된 값은 false.
3792
3839
  * budgetGate 와 같은 `harness` 객체다 — 중복 선언이면 뒤 타입이 앞을 지운다. */
3793
- harness?: { edgeRail?: { canaryOkRuns?: number; failureMultiplier?: number; minSamples?: number }; /** Goal authoring grade; absent or invalid config resolves to full. */ authorGrade?: 'full' | 'lite'; revertGuard?: { depth: number }; pod?: { grokApiKeyOptIn: boolean }; budgetGate?: HarnessBudgetGateConfig; exposeGate?: 'warn' | 'strict'; difficultyPlacement?: boolean; defaultRepo?: string; /** Optional GitHub repository name (owner/repo), distinct from the local defaultRepo path. */ repo?: string; substrate?: 'local' | 'pod'; podPool?: string; worktreeAddTimeoutSec?: number; queue?: { seatCap?: Partial<Record<'OP' | 'TC' | 'MK' | 'UX', number>>; /** Direct `harness say|ask` goes through the seat queue first (ONEDOOR-2). Absent = env ELANOUS_HARNESS_QUEUE_DIRECT_SAY, else off. */ directSay?: boolean; /** SEAT-CAP-STALE: a run whose last ledger progress is older than this stops holding its seat. Absent = env ELANOUS_HARNESS_QUEUE_STALE_RUN_MINUTES, else 30. */ staleRunMinutes?: number; /** Seat-less runs count in one bucket with this cap instead of every seat. Absent = env ELANOUS_HARNESS_QUEUE_UNKNOWN_SEAT_CAP, else 2. */ unknownSeatCap?: number; /** QUEUE-BURST: most launches one scheduled tick may make (30 s apart, each within seat cap and Pod pool headroom). Absent or invalid = 5; 1 = one launch per tick. */ burstMax?: number }; /** `harness say` 문장을 Pod 안에서 저작부터 돌릴지. 생략·false = 끔(호스트가 저작). */ authorOnPod?: boolean; /** SIBLING-RESYNC-ON-MERGE: most open sibling PR file inventories fetched per merge. Absent or invalid = 40. */ siblingResync?: { maxFetch?: number }; /** Stopped-PR repair goals: shadow records only (default); live enqueues them. */ helper?: { repair?: 'shadow' | 'live'; /** Live launches allowed per UTC day. Absent or invalid means 3. */ repairPerDay?: number };
3840
+ harness?: { edgeRail?: { canaryOkRuns?: number; failureMultiplier?: number; minSamples?: number }; /** Goal authoring grade; absent or invalid config resolves to full. */ authorGrade?: 'full' | 'lite'; revertGuard?: { depth: number }; pod?: { grokApiKeyOptIn: boolean }; budgetGate?: HarnessBudgetGateConfig; exposeGate?: 'warn' | 'strict'; difficultyPlacement?: boolean; defaultRepo?: string; /** Optional GitHub repository name (owner/repo), distinct from the local defaultRepo path. */ repo?: string; substrate?: 'local' | 'pod'; podPool?: string; /** IMAGE-ONE-SOURCE: Pod 발사가 당길 기준 이미지 커밋(hex 12~40 · 레지스트리 태그 = 앞 12자리). 없으면 종전대로 HEAD 비교·굽기. */ imageCommit?: string; worktreeAddTimeoutSec?: number; queue?: { seatCap?: Partial<Record<'OP' | 'TC' | 'MK' | 'UX', number>>; /** Direct `harness say|ask` goes through the seat queue first (ONEDOOR-2). Absent = env ELANOUS_HARNESS_QUEUE_DIRECT_SAY, else off. */ directSay?: boolean; /** SEAT-CAP-STALE: a run whose last ledger progress is older than this stops holding its seat. Absent = env ELANOUS_HARNESS_QUEUE_STALE_RUN_MINUTES, else 30. */ staleRunMinutes?: number; /** Seat-less runs count in one bucket with this cap instead of every seat. Absent = env ELANOUS_HARNESS_QUEUE_UNKNOWN_SEAT_CAP, else 2. */ unknownSeatCap?: number; /** QUEUE-BURST: most launches one scheduled tick may make (30 s apart, each within seat cap and Pod pool headroom). Absent or invalid = 5; 1 = one launch per tick. */ burstMax?: number }; /** `harness say` 문장을 Pod 안에서 저작부터 돌릴지. 생략·false = 끔(호스트가 저작). */ authorOnPod?: boolean; /** SIBLING-RESYNC-ON-MERGE: most open sibling PR file inventories fetched per merge. Absent or invalid = 40. */ siblingResync?: { maxFetch?: number }; /** Stopped-PR repair goals: shadow records only (default); live enqueues them. */ helper?: { repair?: 'shadow' | 'live'; /** Live launches allowed per UTC day. Absent or invalid means 3. */ repairPerDay?: number };
3794
3841
  /** Nested elanous launches. Only depth 0 may set `allow`. Absent or any other value refuses. A depth >= 1 `--nested-elanous allow` is ignored. */
3795
3842
  nestedElanous?: 'allow' | 'refuse';
3796
3843
  /** Maximum nested elanous depth; safe positive integer, default 2. */
@@ -4043,22 +4090,32 @@ function parseAutoReviewConfig(raw: unknown): AutoReviewConfig | undefined {
4043
4090
  return Object.keys(out).length > 0 ? out : undefined;
4044
4091
  }
4045
4092
 
4046
- /** Keeps `taskAgent.liveMoves` as raw strings — the allow-list (and the unknown-entry warning) lives in the task agent. */
4047
- /** HARNESS-PARENT-ON-MSB1 — `taskAgent.parentHost` (기본 없음 = 끔). 문자열 칸만 받는다. */
4093
+ /** HARNESS-PARENT-ON-MSB1 — `taskAgent.parentHost` (기본 없음 = 끔). 객체 또는 검증된 객체 목록. */
4048
4094
  function parseTaskAgentParentHost(raw: unknown): NonNullable<UserConfig['taskAgent']>['parentHost'] {
4049
4095
  if (raw === undefined) return undefined;
4050
- if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
4051
- warnUserConfigDrop('taskAgent.parentHost', '객체가 아니다 — 버림(로컬 발사)');
4052
- return undefined;
4096
+ if (Array.isArray(raw)) {
4097
+ const hosts = raw.map((entry) => parseParentHostEntry(entry)).filter((entry): entry is NonNullable<ReturnType<typeof parseParentHostEntry>> => entry !== undefined);
4098
+ return hosts.length ? hosts : undefined;
4053
4099
  }
4054
- const out: Record<string, string> = {};
4100
+ const host = parseParentHostEntry(raw);
4101
+ if (!host) warnUserConfigDrop('taskAgent.parentHost', '객체가 아니다 — 버림(로컬 발사)');
4102
+ return host;
4103
+ }
4104
+
4105
+ function parseParentHostEntry(raw: unknown): { host?: string; cwd?: string; elanous?: string; configDir?: string; podPool?: string; approvalCapacity?: number } | undefined {
4106
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return undefined;
4107
+ const out: NonNullable<ReturnType<typeof parseParentHostEntry>> = {};
4055
4108
  for (const key of ['host', 'cwd', 'elanous', 'configDir', 'podPool'] as const) {
4056
4109
  const value = (raw as Record<string, unknown>)[key];
4057
4110
  if (typeof value === 'string' && value.trim()) out[key] = value.trim();
4058
4111
  }
4112
+ const capacity = (raw as Record<string, unknown>).approvalCapacity;
4113
+ if (Number.isSafeInteger(capacity) && (capacity as number) > 0) out.approvalCapacity = capacity as number;
4114
+ else if (capacity !== undefined) return undefined;
4059
4115
  return out;
4060
4116
  }
4061
4117
 
4118
+ /** Keeps `taskAgent.liveMoves` as raw strings — the allow-list (and the unknown-entry warning) lives in the task agent. */
4062
4119
  function parseTaskAgentConfig(raw: unknown): UserConfig['taskAgent'] {
4063
4120
  if (raw === undefined) return undefined;
4064
4121
  if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
@@ -4152,9 +4209,21 @@ function parseRoleLlmConfig(raw: unknown): RoleLlmConfig | undefined {
4152
4209
  const dropped: Array<{ role: ModelRole; reason: string }> = [];
4153
4210
  for (const role of MODEL_ROLES) {
4154
4211
  if (values[role] === undefined) continue;
4155
- const entry = parseRoleLlmEntry(values[role]);
4156
- if (entry.ok) parsed[role] = entry.spec;
4157
- else dropped.push({ role, reason: entry.reason });
4212
+ const rawEntry = values[role];
4213
+ if (rawEntry && typeof rawEntry === 'object' && !Array.isArray(rawEntry)) {
4214
+ const { effort, ...modelFields } = rawEntry as Record<string, unknown>;
4215
+ const entry = effort !== undefined && Object.keys(modelFields).length === 0 ? undefined : parseRoleLlmEntry(modelFields);
4216
+ if (entry && !entry.ok) { dropped.push({ role, reason: entry.reason }); continue; }
4217
+ const spec: RoleLlmSpec = entry?.ok ? entry.spec : {};
4218
+ if (effort !== undefined) {
4219
+ if (effort === 'low' || effort === 'medium' || effort === 'high') spec.effort = effort;
4220
+ else warnUserConfigDrop(`roleLlm.${role}.effort`, `low|medium|high 가 아니다(${JSON.stringify(effort)}) — 버림`);
4221
+ }
4222
+ if (Object.keys(spec).length > 0) parsed[role] = spec;
4223
+ } else {
4224
+ const entry = parseRoleLlmEntry(rawEntry);
4225
+ if (!entry.ok) dropped.push({ role, reason: entry.reason });
4226
+ }
4158
4227
  }
4159
4228
  if (values.reviewer !== undefined) {
4160
4229
  parsed.reviewer = parseSubscriptionReviewerSpec(values.reviewer);
@@ -4433,7 +4502,7 @@ function runtimeLlmProviderOverride(): LLMProviderName | undefined {
4433
4502
  * `src/llm/model-defaults.ts` (that module imports this file). */
4434
4503
  export type RuntimeLlmModelFamily =
4435
4504
  | 'grok' | 'anthropic' | 'openai' | 'openai-codex' | 'gemini' | 'local'
4436
- | 'kimi' | 'qwen' | 'glm' | 'openrouter' | 'unknown';
4505
+ | 'kimi' | 'qwen' | 'glm' | 'openrouter' | 'bedrock' | 'unknown';
4437
4506
 
4438
4507
  export function inferRuntimeLlmModelFamily(model: string | undefined): RuntimeLlmModelFamily {
4439
4508
  if (!model) return 'unknown';
@@ -4442,6 +4511,9 @@ export function inferRuntimeLlmModelFamily(model: string | undefined): RuntimeLl
4442
4511
  // ⛔ 2026-09-23 — 게이트웨이 접두가 «먼저»다. 안 그러면 `openrouter/anthropic/claude-…` 가 `anthropic` 으로
4443
4512
  // 읽혀 openrouter 와 «비호환»이 되고, `openrouter/z-ai/…` 는 `unknown` 이라 아무 provider 와도 «호환»이 됐다.
4444
4513
  if (m.startsWith('openrouter/')) return 'openrouter';
4514
+ // ⭐ BEDROCK-PROVIDER — Bedrock 전용 꼴(`anthropic.claude-…`·지역 접두·`bedrock/…`)이 `includes('claude')` 보다 «먼저».
4515
+ // 1st-party id(`claude-…`)는 그대로 anthropic 이다(불변).
4516
+ if (m.startsWith('bedrock/') || /^(?:[a-z]{2,6}\.)?anthropic\.claude-/.test(m)) return 'bedrock';
4445
4517
  if (m.includes('grok')) return 'grok';
4446
4518
  if (m.includes('claude')) return 'anthropic';
4447
4519
  if (m.startsWith('gemini-') || m.includes('gemini')) return 'gemini';
@@ -4480,6 +4552,8 @@ export function isRuntimeLlmModelCompatibleWithProvider(
4480
4552
  const family = inferRuntimeLlmModelFamily(model);
4481
4553
  if (family === 'unknown') return true;
4482
4554
  if (provider === 'local') return family === 'local';
4555
+ // bedrock 은 1st-party claude id 도 받는다(공급자가 `anthropic.` 접두로 바꿔 보낸다).
4556
+ if (provider === 'bedrock') return family === 'bedrock' || family === 'anthropic';
4483
4557
  return provider === family;
4484
4558
  }
4485
4559
 
@@ -4506,6 +4580,7 @@ function defaultModelForProvider(provider: LLMProviderName): string | undefined
4506
4580
  case 'kimi': return KIMI_MODEL;
4507
4581
  case 'qwen': return QWEN_MODEL;
4508
4582
  case 'glm': return GLM_MODEL;
4583
+ case 'bedrock': return BEDROCK_DEFAULT_MODEL;
4509
4584
  case 'auto': return undefined;
4510
4585
  }
4511
4586
  }
@@ -5022,6 +5097,13 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
5022
5097
  })() },
5023
5098
  ...(harness.substrate === 'local' || harness.substrate === 'pod' ? { substrate: harness.substrate } : {}),
5024
5099
  ...(typeof harness.podPool === 'string' && harness.podPool.trim() ? { podPool: harness.podPool.trim() } : {}),
5100
+ ...(() => {
5101
+ if (harness.imageCommit === undefined) return {};
5102
+ const v = typeof harness.imageCommit === 'string' ? harness.imageCommit.trim().toLowerCase() : '';
5103
+ if (/^[0-9a-f]{12,40}$/u.test(v)) return { imageCommit: v };
5104
+ warnUserConfigDrop('harness.imageCommit', `커밋 hex 12~40자리가 아니다(${JSON.stringify(harness.imageCommit)}) — 무시하고 HEAD 비교·굽기로 진행`);
5105
+ return {};
5106
+ })(),
5025
5107
  ...(typeof harness.worktreeAddTimeoutSec === 'number' && Number.isSafeInteger(harness.worktreeAddTimeoutSec)
5026
5108
  && harness.worktreeAddTimeoutSec > 0 && harness.worktreeAddTimeoutSec <= 2_147_483
5027
5109
  ? { worktreeAddTimeoutSec: harness.worktreeAddTimeoutSec } : {}),
@@ -5111,6 +5193,18 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
5111
5193
  };
5112
5194
  })(),
5113
5195
  model: resolveRuntimeLlmModel(baseProvider, selectedProvider, str(llm.model), escalationProvider || undefined),
5196
+ openrouter: (() => {
5197
+ const router = llm.openrouter;
5198
+ if (!router || typeof router !== 'object' || Array.isArray(router)) return undefined;
5199
+ const preferences = (router as Record<string, unknown>).providerPreferences;
5200
+ const fallbackModel = (router as Record<string, unknown>).fallbackModel;
5201
+ const out = {
5202
+ ...(preferences && typeof preferences === 'object' && !Array.isArray(preferences)
5203
+ ? { providerPreferences: { ...preferences } as Record<string, unknown> } : {}),
5204
+ ...(typeof fallbackModel === 'string' ? { fallbackModel } : {}),
5205
+ };
5206
+ return Object.keys(out).length > 0 ? out : undefined;
5207
+ })(),
5114
5208
  // ★ escalate effort override(#2·2026-07-22 대표) — ELANOUS_ESCALATE_EFFORT 있으면 reasoning effort 를 그 값으로
5115
5209
  // (sol high 등 강한 시도). reasoningLevel(anthropic/일반)+codexReasoning(openai-codex/sol) 둘 다 커버. 미설정=종전.
5116
5210
  reasoningLevel: parseReasoningLevel(process.env.ELANOUS_ESCALATE_EFFORT?.trim() || llm.reasoningLevel),
@@ -5146,6 +5240,9 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
5146
5240
  codexAccountOrder: Array.isArray(llm.codexAccountOrder)
5147
5241
  ? llm.codexAccountOrder.filter((v: unknown): v is string => typeof v === 'string' && v.length > 0)
5148
5242
  : undefined,
5243
+ codexResetAutoConsumePerDay: typeof llm.codexResetAutoConsumePerDay === 'number'
5244
+ && Number.isSafeInteger(llm.codexResetAutoConsumePerDay) && llm.codexResetAutoConsumePerDay >= 0
5245
+ ? llm.codexResetAutoConsumePerDay : undefined,
5149
5246
  // ⛔ 여기선 «배열이고 문자열 원소만» 통과시킨다 — 아는 이름인지의 판정은
5150
5247
  // `normalizeFallbackChain()` 이 «한 자»로 한다(두 곳에서 정규화하면 자가 갈린다).
5151
5248
  fallbackChain: Array.isArray(llm.fallbackChain)
@@ -5281,6 +5378,7 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
5281
5378
  return {
5282
5379
  maxAgeDays: num(r.maxAgeDays, LOGS_DEFAULTS.retention.maxAgeDays),
5283
5380
  maxDbMb: num(r.maxDbMb, LOGS_DEFAULTS.retention.maxDbMb),
5381
+ minRetainHours: num(r.minRetainHours, LOGS_DEFAULTS.retention.minRetainHours),
5284
5382
  };
5285
5383
  })(),
5286
5384
  ...(typeof logsRaw.instanceName === 'string' && logsRaw.instanceName.trim().length > 0
@@ -5996,6 +6094,13 @@ export function getUserConfig(path: string = defaultPath()): UserConfig {
5996
6094
  return cache;
5997
6095
  }
5998
6096
 
6097
+ // Read at call time, not registration time, so reload/reset and on-disk edits keep their semantics.
6098
+ // Stored timezone is kept in raw by buildUserConfig; do not change getUserConfig's returned shape.
6099
+ setConfigTimeZoneSource(() => {
6100
+ const config = getUserConfig();
6101
+ return config.timezone ?? (typeof config.raw.timezone === 'string' ? config.raw.timezone : undefined);
6102
+ });
6103
+
5999
6104
  export function reloadUserConfig(path: string = defaultPath()): UserConfig {
6000
6105
  cache = applyOverlay(buildUserConfig(path));
6001
6106
  cachedPath = path;
@@ -6101,6 +6206,8 @@ export const PROVIDER_DEFAULT_MODEL: Record<LLMProviderName, string> = {
6101
6206
  kimi: 'kimi-k2.6',
6102
6207
  qwen: 'qwen3.6-flash',
6103
6208
  glm: 'glm-5.1',
6209
+ // BEDROCK-PROVIDER (2026-10-10) — Bedrock 의 Claude(`anthropic.` 접두 · 공식 «Supported models» 표).
6210
+ bedrock: BEDROCK_DEFAULT_MODEL,
6104
6211
  };
6105
6212
 
6106
6213
  /** Resolve the display model for a rotation entry — falls back to the
@@ -6415,6 +6522,7 @@ export function saveUserConfig(
6415
6522
  codexQuotaPolicy: cfg.llm.codexQuotaPolicy,
6416
6523
  grokWeeklyCapPct: cfg.llm.grokWeeklyCapPct,
6417
6524
  fallbackChain: cfg.llm.fallbackChain,
6525
+ openrouter: cfg.llm.openrouter,
6418
6526
  reviewFallbackModels: cfg.llm.reviewFallbackModels,
6419
6527
  codexStore: cfg.llm.codexStore,
6420
6528
  geminiSafety: cfg.llm.geminiSafety,