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
@@ -4,7 +4,7 @@ import { isScalar, parseDocument } from 'yaml';
4
4
  import { getElanousConfigDir } from '../elanous-config-dir.js';
5
5
  import { DEFAULT_FALLBACK_CHAIN, isFallbackStep, type FallbackStep } from '../oauth/fallback-chain.js';
6
6
  import { isCodexQuotaPolicy } from '../oauth/codex-quota-policy.js';
7
- import { DEFAULT_BUDGET_GATE_MAX_USED_PERCENT, MODEL_ROLES, RUNTIME_LLM_PROVIDER_NAMES, parseRoleLlmEntry, parseSubscriptionReviewerSpec, type RoleLlmConfig } from '../user-config.js';
7
+ import { DEFAULT_BUDGET_GATE_MAX_USED_PERCENT, MODEL_ROLES, RUNTIME_LLM_PROVIDER_NAMES, parseRoleLlmEntry, parseSubscriptionReviewerSpec, type RoleLlmConfig, type SubscriptionReviewerSpec } from '../user-config.js';
8
8
 
9
9
  export interface LlmPolicy {
10
10
  version: 1;
@@ -164,6 +164,19 @@ function removeExpired(input: Obj, now: Date, warnings: string[], prefix = ''):
164
164
  }
165
165
  }
166
166
 
167
+ /**
168
+ * The reviewer ACP lane (`roleLlm.reviewer`) and its usage cap, resolved once for every caller.
169
+ * The harness (`dev-pipeline`) and `elanous self review` read the same policy row, so the two
170
+ * reviewers cannot drift apart on which config selects the subscription reviewer.
171
+ */
172
+ export function resolveSubscriptionReviewer(
173
+ loaded: LoadedLlmPolicy,
174
+ userRoleLlm?: RoleLlmConfig,
175
+ ): { spec: SubscriptionReviewerSpec; cap: number } | undefined {
176
+ const spec = loaded.policy.roles.reviewer ?? userRoleLlm?.reviewer;
177
+ return spec ? { spec, cap: loaded.policy.caps.claude.harness } : undefined;
178
+ }
179
+
167
180
  export function loadLlmPolicy(opts: LoadLlmPolicyOptions = {}): LoadedLlmPolicy {
168
181
  const configDir = opts.configDir ?? getElanousConfigDir();
169
182
  const path = opts.path ?? join(configDir, 'policy', 'llm.yaml');
@@ -14,7 +14,6 @@
14
14
  * ⚠️ 이 판정은 «같은 호스트»에서만 뜻이 있다 — pid 는 호스트 지역 값이다.
15
15
  * 락처럼 호스트가 섞이는 소비자는 호스트를 «먼저» 가른 뒤 이걸 부른다.
16
16
  */
17
- import { debug } from '../debug/log.js';
18
17
 
19
18
  /** ⛔ 두 값이 아니라 «셋»이다 — 「살아 있는데 내가 못 건드린다」는 별도의 사실이다.
20
19
  * 그것을 `alive` 나 `dead` 어느 쪽으로도 접지 않는 것이 이 타입의 존재 이유다. */
@@ -58,6 +57,7 @@ export function pidLiveness(pid: number): PidLiveness {
58
57
  if (verdict === 'alive-not-mine') {
59
58
  // ⛔ 「살아 있는데 남의 것」은 조용히 지나가면 안 된다 — 🅢 요청(2026-09-20):
60
59
  // 원장에 «대상 pid 와 소유자 축»이 남아야 A 구간(남의 트리에서 도는 자식)과 닿는다.
60
+ const { debug } = require('../debug/log.js') as { debug: { log: (category: string, event: string, data: Record<string, unknown>) => void } };
61
61
  debug.log('process.liveness', 'kill-refused', { pid, myUid: myUid(), errno });
62
62
  observer?.({ pid, liveness: verdict, myUid: myUid(), errno });
63
63
  }
@@ -23,6 +23,7 @@
23
23
  // event with cacheReadInputTokens absent (treated as 0 downstream).
24
24
 
25
25
  import type { LLMUsage } from './types.js';
26
+ import { readOpenRouterByokUsage } from '../llm/openrouter-byok-cost.js';
26
27
 
27
28
  /** Extract LLMUsage from an OpenAI streaming chunk. Returns null when
28
29
  * the chunk has no usage object (every chunk except the final one
@@ -35,7 +36,8 @@ export function parseOpenAIUsage(event: unknown): LLMUsage | null {
35
36
  const r = raw as {
36
37
  prompt_tokens?: number;
37
38
  completion_tokens?: number;
38
- prompt_tokens_details?: { cached_tokens?: number };
39
+ /** OpenRouter 는 캐시 쓰기를 `cache_write_tokens` 로 싣는다(Anthropic 상류 · OR-ANTHROPIC-CACHE). */
40
+ prompt_tokens_details?: { cached_tokens?: number; cache_write_tokens?: number };
39
41
  completion_tokens_details?: { reasoning_tokens?: number };
40
42
  /** Kimi(Moonshot) — 최상위에 싣는다. */
41
43
  cached_tokens?: number;
@@ -50,14 +52,17 @@ export function parseOpenAIUsage(event: unknown): LLMUsage | null {
50
52
  // 캐시 단가로 또 한 번 매겨진다(BACKLOG C4 · opencode openai-chat.ts · hermes normalize_usage 와 같은 처리).
51
53
  const cached = [r.prompt_tokens_details?.cached_tokens, r.cached_tokens, r.prompt_cache_hit_tokens]
52
54
  .find((v): v is number => typeof v === 'number');
53
- if (typeof r.prompt_tokens === 'number') out.inputTokens = Math.max(0, r.prompt_tokens - (cached ?? 0));
55
+ // OR-ANTHROPIC-CACHE — OpenRouter(Anthropic 상류)의 캐시 «쓰기»도 prompt_tokens 에 포함돼 온다 → 새 입력에서 빼고
56
+ // cacheCreationInputTokens 로 옮긴다(Anthropic 규약). 칸이 없으면(OpenAI·Grok·DeepSeek …) 종전과 같다.
57
+ const written = typeof r.prompt_tokens_details?.cache_write_tokens === 'number' ? r.prompt_tokens_details.cache_write_tokens : undefined;
58
+ if (typeof r.prompt_tokens === 'number') out.inputTokens = Math.max(0, r.prompt_tokens - (cached ?? 0) - (written ?? 0));
54
59
  if (typeof r.completion_tokens === 'number') out.outputTokens = r.completion_tokens;
55
- if (cached !== undefined) {
56
- out.cacheReadInputTokens = cached;
60
+ if (cached !== undefined || written !== undefined) {
61
+ out.cacheReadInputTokens = cached ?? 0;
57
62
  // OpenAI caches are free-on-hit and rolled into prompt_tokens for
58
63
  // creation — we set creation to 0 so metrics math (hit-rate) works
59
- // uniformly across providers.
60
- out.cacheCreationInputTokens = 0;
64
+ // uniformly across providers. OpenRouter→Anthropic reports writes.
65
+ out.cacheCreationInputTokens = written ?? 0;
61
66
  }
62
67
  // Reasoning tokens — OpenAI o1/o3, qwen 3.6 (LM Studio surfaces this
63
68
  // even though qwen calls it `reasoning_content` rather than the
@@ -67,6 +72,8 @@ export function parseOpenAIUsage(event: unknown): LLMUsage | null {
67
72
  out.reasoningOutputTokens = r.completion_tokens_details.reasoning_tokens;
68
73
  }
69
74
  if (typeof r.cost === 'number' && Number.isFinite(r.cost) && r.cost >= 0) out.reportedCostUsd = r.cost;
75
+ // OR-BYOK-COST — BYOK 호출이면 `byok` ⊕ `upstreamCostUsd`(비-BYOK 이면 아무 칸도 안 더한다 · 종전 바이트).
76
+ Object.assign(out, readOpenRouterByokUsage(event));
70
77
  const keys = Object.keys(out).filter(k => k !== 'provider');
71
78
  return keys.length === 0 ? null : out;
72
79
  }
@@ -0,0 +1,94 @@
1
+ // OR-ANTHROPIC-CACHE (2026-10-10) — OpenRouter 경유 Anthropic·Moonshot(Kimi) 호출의 프롬프트 캐시 중단점.
2
+ //
3
+ // OpenRouter 는 OpenAI 꼴 본문을 받아 상류(Anthropic·Moonshot)로 옮긴다. 이 두 계열은 «요청이 청해야»
4
+ // 캐시를 쓴다 — 본문에 `cache_control` 이 없으면 적중 0 이다(10-10 벤치: Haiku·Sonnet 5.5 팔 cachedInput 0).
5
+ //
6
+ // 배치(참고 구현 대조):
7
+ // - opencode `provider/transform.ts` applyCaching — system 앞 2 ⊕ 비-system 끝 2 (상한 4).
8
+ // - hermes `agent/prompt_caching.py` envelope layout — OpenRouter 는 «content 파트»의 cache_control 만 따른다.
9
+ // · role:tool 의 «최상위» cache_control 은 OpenRouter 에서 조용히 멎는다 → 파트에만 단다(OpenRouter 가
10
+ // tool_result 블록으로 옮긴다).
11
+ // · content 가 비거나 null 인 assistant(순수 tool_calls)는 중단점을 낭비하므로 건너뛴다.
12
+ // · Kimi(moonshotai/*) 도 같은 envelope 꼴로 적중 1% → 97% (hermes #25970).
13
+ // - tools: 따로 표시하지 않는다. Anthropic 접두 순서가 tools → system → messages 라 system 끝 중단점이
14
+ // 도구 정의까지 덮는다. hermes 도 tools 배열 표시는 «직접 Anthropic» 경로에만 쓴다.
15
+ //
16
+ // ⛔ 순수 함수 — 입력 배열·메시지를 고치지 않고 바뀐 메시지만 새로 만든다.
17
+
18
+ /** Anthropic 상한. */
19
+ export const OPENROUTER_MAX_CACHE_BREAKPOINTS = 4;
20
+
21
+ export type OpenRouterCacheFamily = 'anthropic' | 'moonshotai';
22
+
23
+ /** wire 모델(`anthropic/claude-haiku-5.5`)이 캐시 중단점 대상인가. 대상이 아니면 null. */
24
+ export function openRouterPromptCacheFamily(wireModel: string): OpenRouterCacheFamily | null {
25
+ if (wireModel.startsWith('anthropic/')) return 'anthropic';
26
+ if (wireModel.startsWith('moonshotai/')) return 'moonshotai';
27
+ return null;
28
+ }
29
+
30
+ type WireMessage = Record<string, unknown>;
31
+ type CacheMarker = { type: 'ephemeral'; ttl?: '1h' };
32
+
33
+ function isMarkablePart(part: unknown): boolean {
34
+ // 텍스트 파트에만 단다 — image_url 파트 위 cache_control 의 OpenRouter 전달은 확인하지 않았다(보수).
35
+ return !!part && typeof part === 'object' && (part as { type?: unknown }).type === 'text';
36
+ }
37
+
38
+ function canCarryMarker(msg: WireMessage): boolean {
39
+ const content = msg.content;
40
+ if (typeof content === 'string') return content.length > 0;
41
+ if (Array.isArray(content) && content.length > 0) return isMarkablePart(content[content.length - 1]);
42
+ return false;
43
+ }
44
+
45
+ function withMarker(msg: WireMessage, marker: CacheMarker): WireMessage {
46
+ const content = msg.content;
47
+ if (typeof content === 'string') {
48
+ return { ...msg, content: [{ type: 'text', text: content, cache_control: { ...marker } }] };
49
+ }
50
+ const parts = (content as Array<Record<string, unknown>>).slice();
51
+ parts[parts.length - 1] = { ...parts[parts.length - 1], cache_control: { ...marker } };
52
+ return { ...msg, content: parts };
53
+ }
54
+
55
+ export interface OpenRouterCachePlan {
56
+ messages: WireMessage[];
57
+ /** 실제로 단 중단점 수(0~4). */
58
+ breakpoints: number;
59
+ systemBreakpoints: number;
60
+ tailBreakpoints: number;
61
+ }
62
+
63
+ /** system 앞 2 ⊕ 비-system 끝 2 (합 ≤ 4) 의 마지막 텍스트 파트에 `cache_control` 을 단다.
64
+ * `ttl:'1h'` 은 anthropic 계열에만 싣는다(Moonshot 의 1h 계층은 확인하지 않았다 → 기본 5m). */
65
+ export function applyOpenRouterCacheControl(
66
+ messages: readonly WireMessage[],
67
+ opts: { family: OpenRouterCacheFamily; ttl?: '5m' | '1h' },
68
+ ): OpenRouterCachePlan {
69
+ const marker: CacheMarker = opts.family === 'anthropic' && opts.ttl === '1h'
70
+ ? { type: 'ephemeral', ttl: '1h' }
71
+ : { type: 'ephemeral' };
72
+ const out = messages.slice();
73
+ let systemBreakpoints = 0;
74
+ for (let i = 0; i < out.length && systemBreakpoints < 2; i++) {
75
+ if (out[i]!.role !== 'system') continue;
76
+ if (!canCarryMarker(out[i]!)) continue;
77
+ out[i] = withMarker(out[i]!, marker);
78
+ systemBreakpoints++;
79
+ }
80
+ const remaining = Math.min(2, OPENROUTER_MAX_CACHE_BREAKPOINTS - systemBreakpoints);
81
+ const tail: number[] = [];
82
+ for (let i = out.length - 1; i >= 0 && tail.length < remaining; i--) {
83
+ const m = out[i]!;
84
+ if (m.role === 'system') continue;
85
+ if (canCarryMarker(m)) tail.push(i);
86
+ }
87
+ for (const i of tail) out[i] = withMarker(out[i]!, marker);
88
+ return {
89
+ messages: out,
90
+ breakpoints: systemBreakpoints + tail.length,
91
+ systemBreakpoints,
92
+ tailBreakpoints: tail.length,
93
+ };
94
+ }
@@ -32,6 +32,11 @@ export interface LLMUsage {
32
32
  /** provider 가 «응답에 실어 보낸» 실제 청구액(USD) — OpenRouter `usage.cost`(요청에 `usage:{include:true}`).
33
33
  * ⭐ 추정(카탈로그 단가)이 아니라 청구 사실이다 — 비용 판정이 이것을 먼저 쓴다(BACKLOG C7). */
34
34
  reportedCostUsd?: number;
35
+ /** OR-BYOK-COST — OpenRouter `usage.is_byok === true`(상류 키로 청구된 호출 · OR `cost` 는 0). */
36
+ byok?: true;
37
+ /** OR-BYOK-COST — OpenRouter `usage.cost_details.upstream_inference_cost`(상류 키로 실제 청구된 USD).
38
+ * ⛔ 칸이 없거나 숫자가 아니면 «없다»(=미상) — 0 으로 꾸미지 않는다. */
39
+ upstreamCostUsd?: number;
35
40
  }
36
41
 
37
42
  /** Back-compat alias for callers that imported `AnthropicUsage` from
@@ -16,6 +16,7 @@ import { streamLLM, type LLMMessage } from '../llm.js';
16
16
  import { debug } from '../debug/log.js';
17
17
  import type { LLMUsage } from '../prompt-cache/types.js';
18
18
  import { llmUsageCostFields } from '../budget/llm-cost.js';
19
+ import { getUserConfig, resolveRoleLlm, type UserConfig } from '../user-config.js';
19
20
 
20
21
  function logLlmUsage(model: string, usage: LLMUsage): void {
21
22
  try {
@@ -97,6 +98,8 @@ export interface EnhanceOpts {
97
98
  */
98
99
  checklistUse?: ChecklistUse;
99
100
  reasoningEffort?: 'low' | 'medium' | 'high';
101
+ /** 호출자의 저작 시점 config. 생략 시 현재 사용자 설정을 읽는다. */
102
+ config?: UserConfig;
100
103
  /** 산출물 유형 힌트(선택) — 예: 'PPT 발표덱', 'PLAN 문서'. 제약 문구 조정. */
101
104
  deliverableHint?: string;
102
105
  /** Optional usage observer for the caller's authoring phase; missing usage stays unknown. */
@@ -115,6 +118,8 @@ export interface EnhanceOpts {
115
118
  * ⭐ 새 LLM 경로를 만들지 않는다 — 이 모듈이 이미 그 자리의 유일한 LLM 단계다.
116
119
  */
117
120
  groundedFacts?: readonly string[];
121
+ /** Clock seam for the first-token observation (ms epoch); defaults to `Date.now`. */
122
+ now?: () => number;
118
123
  }
119
124
 
120
125
  const FENCE = '```';
@@ -129,8 +134,52 @@ function askMarkerCount(ask: string): number {
129
134
  return (ask.match(/(?:^|\s)(?:불변식|경계|판정\s*신호|invariant|boundary|decision\s+signal)\s*:/gi) ?? []).length;
130
135
  }
131
136
 
132
- const defaultModel = (): string =>
133
- process.env.ELANOUS_PROMPT_ENHANCE_MODEL || process.env.ELANOUS_PR_REVIEW_MODEL || tierModel('better');
137
+ type EnhanceSelectionSource = 'opts' | 'env' | 'config-role' | 'default';
138
+
139
+ /** Select the authoring knobs independently; a planning effort alone cannot change the model. */
140
+ export function selectEnhanceLlm(
141
+ opts: Pick<EnhanceOpts, 'model' | 'reasoningEffort' | 'config'> = {},
142
+ env: NodeJS.ProcessEnv = process.env,
143
+ ): { model: string; effort: 'low' | 'medium' | 'high'; modelSource: EnhanceSelectionSource; effortSource: EnhanceSelectionSource } {
144
+ const config = opts.config ?? getUserConfig();
145
+ const planning = config.roleLlm?.planning;
146
+ const configuredModel = opts.model === undefined && !env.ELANOUS_PROMPT_ENHANCE_MODEL
147
+ && planning && (planning.model || planning.tier || planning.provider)
148
+ ? resolveRoleLlm('planning', { config, overrides: {} }).model : undefined;
149
+ const modelSource: EnhanceSelectionSource = opts.model !== undefined ? 'opts'
150
+ : env.ELANOUS_PROMPT_ENHANCE_MODEL ? 'env'
151
+ : configuredModel !== undefined ? 'config-role' : 'default';
152
+ const model = opts.model ?? (env.ELANOUS_PROMPT_ENHANCE_MODEL || configuredModel || env.ELANOUS_PR_REVIEW_MODEL || tierModel('better'));
153
+ const envEffort = env.ELANOUS_PROMPT_ENHANCE_EFFORT;
154
+ const validEnvEffort = envEffort === 'low' || envEffort === 'medium' || envEffort === 'high' ? envEffort : undefined;
155
+ const effortSource: EnhanceSelectionSource = opts.reasoningEffort !== undefined ? 'opts'
156
+ : validEnvEffort !== undefined ? 'env'
157
+ : planning?.effort !== undefined ? 'config-role' : 'default';
158
+ return { model, effort: opts.reasoningEffort ?? validEnvEffort ?? planning?.effort ?? 'high', modelSource, effortSource };
159
+ }
160
+
161
+ /**
162
+ * ⭐ AUTHOR-DECOMPOSE-KNOB(0.2.24 · G7 #25848) — 골 쪼개기·적대 비평의 `streamLLM` 두 호출이 따를 노브.
163
+ * `selectEnhanceLlm` 과 «같은 규칙»으로 planning 역할을 푼다: ELANOUS_PROMPT_ENHANCE_MODEL/EFFORT →
164
+ * `roleLlm.planning`(`resolveRoleLlm('planning', …)`). 규칙의 «유일한» 차이는 model 폴백이다 —
165
+ * 인핸서는 자기 기본(`tierModel('better')`)으로 떨어지지만, 이 길은 아무것도 설정되지 않으면
166
+ * `undefined` 를 돌려 호출자가 `model` 을 아예 전달하지 않게 한다(프로바이더 기본 모델 = 종전 동작).
167
+ * effort 는 `selectEnhanceLlm` 과 같은 `high` 폴백이며, 두 노브는 따로 풀린다 —
168
+ * effort 만 세팅돼도 모델은 종전 기본 그대로다.
169
+ */
170
+ export function selectPlanningLlm(
171
+ env: NodeJS.ProcessEnv = process.env,
172
+ config: UserConfig = getUserConfig(),
173
+ ): { model: string | undefined; effort: 'low' | 'medium' | 'high' } {
174
+ const planning = config.roleLlm?.planning;
175
+ const model = env.ELANOUS_PROMPT_ENHANCE_MODEL
176
+ || (planning && (planning.model || planning.tier || planning.provider)
177
+ ? resolveRoleLlm('planning', { config, overrides: {} }).model
178
+ : undefined);
179
+ const envEffort = env.ELANOUS_PROMPT_ENHANCE_EFFORT;
180
+ const validEnvEffort = envEffort === 'low' || envEffort === 'medium' || envEffort === 'high' ? envEffort : undefined;
181
+ return { model, effort: validEnvEffort ?? planning?.effort ?? 'high' };
182
+ }
134
183
 
135
184
  /** 스캐폴드 생성 LLM 시스템 프롬프트 — 가산·원문불가침 규율. */
136
185
  const enhanceSystem = (deliverableHint?: string, wantsScqa = false, checklistUse: ChecklistUse = 'coverage-gate'): string =>
@@ -332,7 +381,10 @@ export async function enhancePrompt(raw: string, opts: EnhanceOpts = {}): Promis
332
381
  return { original, enhanced, checklist: [], verbatimPreserved: true, enhancedBy: 'fallback', model: null };
333
382
  }
334
383
 
335
- const model = opts.model ?? defaultModel();
384
+ // Selected only when an LLM call will actually be attempted — the disabled path never records a selection.
385
+ const { model, effort, modelSource, effortSource } = selectEnhanceLlm(opts);
386
+ debug.log('prompt-enhance.model', 'selected', { model, effort, modelSource, effortSource });
387
+
336
388
  let goal = '';
337
389
  let constraints: string[] = [];
338
390
  let checklist: string[] = [];
@@ -367,9 +419,21 @@ export async function enhancePrompt(raw: string, opts: EnhanceOpts = {}): Promis
367
419
  ].join('\n'),
368
420
  },
369
421
  ];
370
- const rawOut = await streamLLM(messages, () => {}, {
422
+ // ⭐ OPENROUTER-OPTIMIZE G13 — 첫 토큰까지 걸린 시간(TTFT)을 호출마다 «한 번» 남긴다.
423
+ // 총 소요만으로는 「대기(큐·라우팅)」와 「생성」을 못 가른다. 본문은 싣지 않는다(길이도 안 싣는다).
424
+ // ⚠️ 첫 «텍스트» 델타까지다 — 추론(reasoning) 토큰을 먼저 내는 모델은 그 생성 시간도 여기 들어간다
425
+ // (순수 대기·라우팅 시간으로 읽지 않는다).
426
+ const now = opts.now ?? Date.now;
427
+ const requestStartedAt = now();
428
+ let firstTokenLogged = false;
429
+ const onChunk = (delta: string): void => {
430
+ if (firstTokenLogged || delta.length === 0) return;
431
+ firstTokenLogged = true;
432
+ debug.log('prompt-enhance.stream', 'first-token', { model, ttftMs: Math.max(0, now() - requestStartedAt) });
433
+ };
434
+ const rawOut = await streamLLM(messages, onChunk, {
371
435
  model,
372
- reasoningEffort: opts.reasoningEffort ?? 'high',
436
+ reasoningEffort: effort,
373
437
  onUsage: (usage) => {
374
438
  logLlmUsage(model, usage);
375
439
  try { opts.onUsage?.(usage); } catch { /* usage observation must not change enhancement */ }
@@ -31,6 +31,7 @@ export const FAMILY_PROBE_MODEL_IDS: Readonly<Record<Exclude<ModelFamily, 'other
31
31
  grok: 'grok-4.7',
32
32
  gemini: 'gemini-3-pro',
33
33
  local: 'local:qwen',
34
+ 'open-weight': 'openrouter/z-ai/glm-5.3',
34
35
  };
35
36
 
36
37
  export interface FamilyPromptCoverage {
@@ -32,11 +32,11 @@ import { buildGrokFamilyAddendum } from './grok-family-addendum.js';
32
32
  import { buildSessionGuidanceAddendum } from './session-guidance.js';
33
33
  import { getHarnessSpace } from '../harness/harness-space.js';
34
34
 
35
- export const PROJECT_ANCHOR_MAX_CHARS = 32 * 1024;
35
+ export const PROJECT_ANCHOR_MAX_CHARS = 36 * 1024; // 10-10 증액(32K→36K) — 줄이기는 AGENTS-CLAUDE-DIET(0.2.24)
36
36
  /** «lean» 예산(BACKLOG L2 · 2026-09-25) — 로컬 모델 구현 자식은 매 턴 이것을 prefill 한다.
37
37
  * 📏 09-25 node-b 기록 프록시: 시스템 50,068자 중 AGENTS.md 앵커 ~32K · 트리 ~8K 가 상위 둘이었다.
38
38
  * ⭐ 켜는 법: env `ELANOUS_PROMPT_BUDGET=lean` — 하니스 구현 자식 spawn 이 child provider 가 local 일 때 준다.
39
- * ⛔ API 모델 경로의 기본(32K·8K)은 그대로다 — 잘 도는 것을 바꾸지 않는다. */
39
+ * ⛔ API 모델 경로의 기본(36K·8K)은 그대로다 — 잘 도는 것을 바꾸지 않는다. */
40
40
  export const PROJECT_ANCHOR_LEAN_MAX_CHARS = 8 * 1024;
41
41
  export const PROJECT_TREE_LEAN_MAX_CHARS = 2 * 1024;
42
42
  function promptBudgetLean(): boolean { return process.env.ELANOUS_PROMPT_BUDGET?.trim() === 'lean'; }
@@ -0,0 +1,122 @@
1
+ // OR-MODEL-NAMESPACE (대표 2026-10-10 «OpenRouter 로 Claude 계열이 안 도는 이유를 먼저 고쳐라»).
2
+ //
3
+ // S: 구현 자식 모델 해석(`resolveImplementationChildModel`)은 `openrouter/<vendor>/<model>` 을 호스트의
4
+ // `discovery-snapshot.json` 에 «있는 id» 로만 받는다.
5
+ // C: 스냅숏은 갱신이 멎으면 늙는다(09-23 판) — 그 뒤 OpenRouter 에 올라온 모델(claude-haiku-5.5 등)은
6
+ // «있는데도» 거부된다. 거부 사유는 「없다」지만 사실은 「우리 스냅숏이 모른다」다.
7
+ // A: 스냅숏에 없을 때만 공개 `/api/v1/models` 를 «한 번» 묻는다(기존 `openrouterSource` 재사용 · 키 불요).
8
+ // 있으면 그 항목을 스냅숏에 합치고 카탈로그를 다시 읽는다. 없으면 지금처럼 거부.
9
+ // ⛔ 네트워크 실패·시간 초과는 «거부»(fail-closed) — 「확인 못 함」을 「있다」로 접지 않는다.
10
+
11
+ import { mkdirSync, renameSync, writeFileSync } from 'node:fs';
12
+ import { dirname } from 'node:path';
13
+ import { debug } from '../../debug/log.js';
14
+ import { isolatedCatalogTestUniverse, reloadCatalog } from '../loader.js';
15
+ import { defaultDiscoveryCachePath, readDiscoveryCache, type DiscoverySnapshot } from './cache.js';
16
+ import { openrouterSource } from './sources/openrouter.js';
17
+ import type { DiscoveredModel } from './types.js';
18
+
19
+ export const OPENROUTER_LIVE_RESOLVE_TIMEOUT_MS = 10_000;
20
+ export const OPENROUTER_SNAPSHOT_STALE_DAYS = 7;
21
+ const NAMESPACED_OPENROUTER_ID = /^openrouter\/([^/\s]+\/[^/\s]+)$/;
22
+ const DAY_MS = 24 * 60 * 60 * 1000;
23
+
24
+ /** 이 프로세스에서 라이브로 확인한 id — 스냅숏 쓰기가 실패해도 같은 프로세스의 재해석은 통과시킨다. */
25
+ const liveVerified = new Set<string>();
26
+
27
+ export function isLiveVerifiedOpenRouterModel(id: string): boolean {
28
+ return liveVerified.has(id);
29
+ }
30
+
31
+ export function __resetOpenRouterLiveResolveForTests(): void {
32
+ liveVerified.clear();
33
+ }
34
+
35
+ /** `openrouter/<vendor>/<model>` → `<vendor>/<model>`(스냅숏·OpenRouter 의 id). 형식이 아니면 undefined. */
36
+ export function upstreamOpenRouterId(id: string): string | undefined {
37
+ return NAMESPACED_OPENROUTER_ID.exec(id)?.[1];
38
+ }
39
+
40
+ /** 카탈로그 로더가 «접는» 스냅숏 경로. 시험 런타임에서 명시 경로가 없으면 undefined(실 `~/.elanous` 를 안 건드린다). */
41
+ export function foldSnapshotPath(): string | undefined {
42
+ const explicit = process.env.ELANOUS_CATALOG_DISCOVERY_SNAPSHOT?.trim();
43
+ if (explicit) return explicit;
44
+ if (isolatedCatalogTestUniverse()) return undefined;
45
+ return defaultDiscoveryCachePath();
46
+ }
47
+
48
+ export function snapshotAgeDays(snapshot: DiscoverySnapshot | null, now: number = Date.now()): number | undefined {
49
+ if (!snapshot?.generatedAt) return undefined;
50
+ const t = Date.parse(snapshot.generatedAt);
51
+ if (!Number.isFinite(t)) return undefined;
52
+ return Math.max(0, Math.floor((now - t) / DAY_MS));
53
+ }
54
+
55
+ export function readFoldSnapshotAgeDays(now: number = Date.now()): number | undefined {
56
+ const path = foldSnapshotPath();
57
+ return path ? snapshotAgeDays(readDiscoveryCache({ cachePath: path }), now) : undefined;
58
+ }
59
+
60
+ function persistMergedModel(path: string, model: DiscoveredModel, now: number): boolean {
61
+ try {
62
+ const existing = readDiscoveryCache({ cachePath: path });
63
+ const snapshot: DiscoverySnapshot = existing ?? {
64
+ version: 1,
65
+ generatedAt: new Date(now).toISOString(),
66
+ sources: [],
67
+ models: [],
68
+ };
69
+ if (!snapshot.models.some((m) => m.provider === 'openrouter' && m.id === model.id)) {
70
+ snapshot.models.push(model);
71
+ }
72
+ mkdirSync(dirname(path), { recursive: true });
73
+ const tmp = `${path}.${process.pid}.tmp`;
74
+ writeFileSync(tmp, JSON.stringify(snapshot, null, 2), 'utf-8');
75
+ renameSync(tmp, path);
76
+ return true;
77
+ } catch {
78
+ return false;
79
+ }
80
+ }
81
+
82
+ export type OpenRouterLiveLookup =
83
+ | { found: true; id: string; merged: DiscoveredModel; persisted: boolean; snapshotAgeDays?: number }
84
+ | { found: false; id: string; error?: string; snapshotAgeDays?: number };
85
+
86
+ /** 스냅숏에 없는 `openrouter/<vendor>/<model>` 을 공개 `/models` 에 «한 번» 묻는다.
87
+ * found → 스냅숏에 합치고(가능하면) 카탈로그를 다시 읽는다. error → 확인 못 함(호출자가 거부). */
88
+ export async function liveLookupOpenRouterModel(
89
+ id: string,
90
+ opts: { fetchImpl?: typeof fetch; timeoutMs?: number; now?: () => number; persist?: boolean } = {},
91
+ ): Promise<OpenRouterLiveLookup> {
92
+ const now = opts.now ?? Date.now;
93
+ const path = foldSnapshotPath();
94
+ const ageDays = path ? snapshotAgeDays(readDiscoveryCache({ cachePath: path }), now()) : undefined;
95
+ const age = ageDays !== undefined ? { snapshotAgeDays: ageDays } : {};
96
+ const upstream = upstreamOpenRouterId(id);
97
+ if (!upstream) {
98
+ debug.log('registry.discovery', 'child-model-live-resolve', { id, found: false, ...age, error: 'not-namespaced' });
99
+ return { found: false, id, error: 'not-namespaced', ...age };
100
+ }
101
+ const result = await openrouterSource.run({
102
+ timeoutMs: opts.timeoutMs ?? OPENROUTER_LIVE_RESOLVE_TIMEOUT_MS,
103
+ ...(opts.fetchImpl ? { fetchImpl: opts.fetchImpl } : {}),
104
+ now,
105
+ });
106
+ if (!result.ok) {
107
+ const error = result.error ?? 'unknown';
108
+ debug.log('registry.discovery', 'child-model-live-resolve', { id, found: false, ...age, error });
109
+ return { found: false, id, error, ...age };
110
+ }
111
+ const merged = result.models.find((m) => m.id === upstream);
112
+ if (!merged) {
113
+ debug.log('registry.discovery', 'child-model-live-resolve', { id, found: false, ...age });
114
+ return { found: false, id, ...age };
115
+ }
116
+ liveVerified.add(id);
117
+ // ⚠️ 잠금 없는 read-modify-write — discovery 크론과 같은 순간이면 한쪽 쓰기가 사라질 수 있다(감시 항목 · 다음 조회가 다시 합친다).
118
+ const persisted = path && opts.persist !== false ? persistMergedModel(path, merged, now()) : false;
119
+ if (persisted) reloadCatalog();
120
+ debug.log('registry.discovery', 'child-model-live-resolve', { id, found: true, ...age, persisted });
121
+ return { found: true, id, merged, persisted, ...age };
122
+ }
@@ -385,13 +385,18 @@ function buildCatalog(): Catalog {
385
385
  };
386
386
  }
387
387
 
388
+ /** 시험 런타임(NODE_ENV=test)은 카탈로그 스냅숏을 기본 경로에서 접지 않는다 — 이 판정을 쓰는 쪽(자식 모델 형식 검사)과 공유한다. */
389
+ export function isolatedCatalogTestUniverse(): boolean {
390
+ return process.env.NODE_ENV === 'test';
391
+ }
392
+
388
393
  /** 폴드할 스냅숏을 고른다. ⛔ 시험 런타임은 preload 가 config-dir 를 격리하지 않아 실제
389
394
  * `~/.elanous/discovery-snapshot.json` 을 읽게 되므로(=기계마다 다른 카탈로그), 경로를 «명시»했을
390
395
  * 때만 접는다. 운영은 기본 경로를 읽고, 없으면 «모른다»(null) — 접을 것이 없을 뿐 오류가 아니다. */
391
396
  function loadFoldSnapshot(): DiscoverySnapshot | null {
392
397
  const explicit = process.env.ELANOUS_CATALOG_DISCOVERY_SNAPSHOT?.trim();
393
398
  if (explicit) return readDiscoveryCache({ cachePath: explicit });
394
- if (process.env.NODE_ENV === 'test') return null;
399
+ if (isolatedCatalogTestUniverse()) return null;
395
400
  return readDiscoveryCache();
396
401
  }
397
402
 
@@ -7,8 +7,9 @@ import { CliUserError } from '../cli/cli-user-error.js';
7
7
 
8
8
  export type ChecklistStatus = 'green' | 'yellow' | 'red' | 'done';
9
9
  export type ChecklistDisposition = 'move' | 'known-issue' | 'block';
10
- /** `screen` = a five-surface feature cell — its evidence carries a `짝:` line (MANUAL-five-surface-parity §A). */
11
- export type ChecklistKind = 'screen';
10
+ /** `screen` = a five-surface feature cell — its evidence carries a `짝:` line (MANUAL-five-surface-parity §A). `postpub` = measured after publication, outside the pre-publication gate. */
11
+ export type ChecklistKind = 'screen' | 'postpub';
12
+ const CHECKLIST_KINDS: readonly ChecklistKind[] = ['screen', 'postpub'];
12
13
  export interface ChecklistItem {
13
14
  id: string;
14
15
  title: string;
@@ -227,7 +228,7 @@ export function validateCeoLoad(input: { ceoMinutes?: number; ceoDate?: string }
227
228
  export function addItem(v: string, input: { id: string; title: string; refs?: string[]; owner?: string; kind?: ChecklistKind; priority?: ChecklistItem['priority']; predecessors?: string[]; deadlineVersion?: string; ceoMinutes?: number; ceoDate?: string; accelerator?: boolean }, options: { allowDuplicateId?: boolean } = {}): Checklist {
228
229
  if (!input.id.trim()) throw new CliUserError('칸 id 가 비었다');
229
230
  if (!input.title.trim()) throw new CliUserError('칸 제목이 비었다');
230
- if (input.kind !== undefined && input.kind !== 'screen') throw new CliUserError(`잘못된 종류: ${input.kind}`, 'screen');
231
+ if (input.kind !== undefined && !CHECKLIST_KINDS.includes(input.kind)) throw new CliUserError(`잘못된 종류: ${input.kind}`, 'screen|postpub');
231
232
  if (input.owner !== undefined) parseOwner(input.owner);
232
233
  if (input.priority !== undefined && !['P0', 'P1', 'P2'].includes(input.priority)) throw new CliUserError(`잘못된 우선순위: ${input.priority}`);
233
234
  if (input.predecessors !== undefined && (!Array.isArray(input.predecessors) || input.predecessors.some((p) => typeof p !== 'string' || !p.trim() || p === input.id))) throw new CliUserError('잘못된 선행 칸');
@@ -258,7 +259,7 @@ export function setItem(v: string, id: string, patch: { status?: ChecklistStatus
258
259
  if (!item) throw new CliUserError(`없는 칸: ${id}`, 'list 로 칸 목록을 본다');
259
260
  if (patch.status !== undefined && !['green', 'yellow', 'red', 'done'].includes(patch.status)) throw new CliUserError(`잘못된 상태: ${patch.status}`);
260
261
  if (patch.disposition !== undefined && !['move', 'known-issue', 'block'].includes(patch.disposition)) throw new CliUserError(`잘못된 처분: ${patch.disposition}`);
261
- if (patch.kind !== undefined && patch.kind !== 'screen') throw new CliUserError(`잘못된 종류: ${patch.kind}`, 'screen');
262
+ if (patch.kind !== undefined && !CHECKLIST_KINDS.includes(patch.kind)) throw new CliUserError(`잘못된 종류: ${patch.kind}`, 'screen|postpub');
262
263
  if (patch.priority !== undefined && !['P0', 'P1', 'P2'].includes(patch.priority)) throw new CliUserError(`잘못된 우선순위: ${patch.priority}`);
263
264
  if (patch.predecessors !== undefined && (!Array.isArray(patch.predecessors) || patch.predecessors.some((p) => typeof p !== 'string' || !p.trim() || p === id))) throw new CliUserError('잘못된 선행 칸');
264
265
  if (patch.deadlineVersion !== undefined) store.validateVersion(patch.deadlineVersion);
@@ -357,6 +358,8 @@ export interface ChecklistGate {
357
358
  blocked: string[];
358
359
  moved: string[];
359
360
  knownIssues: Array<{ id: string; title: string; evidence: string }>;
361
+ /** Post-publication cells excluded from the pre-publication judgement. */
362
+ postpub?: string[];
360
363
  /** Screen cells whose `짝:` line is missing or has an untracked ⏳ — a warning; it never changes `ok`. */
361
364
  parity?: Array<{ id: string; why: string }>;
362
365
  }
@@ -374,8 +377,9 @@ export function parityGap(evidence: string | undefined): string | null {
374
377
  }
375
378
 
376
379
  export function checklistGate(v: string): ChecklistGate {
377
- const result: ChecklistGate = { ok: true, red: [], undecided: [], blocked: [], moved: [], knownIssues: [], parity: [] };
380
+ const result: ChecklistGate = { ok: true, red: [], undecided: [], blocked: [], moved: [], knownIssues: [], postpub: [], parity: [] };
378
381
  for (const item of listChecklist(v).items) {
382
+ if (item.kind === 'postpub') { result.postpub!.push(item.id); continue; }
379
383
  if (item.kind === 'screen') {
380
384
  const why = parityGap(item.evidence);
381
385
  if (why) result.parity!.push({ id: item.id, why });
@@ -388,16 +392,27 @@ export function checklistGate(v: string): ChecklistGate {
388
392
  else result.undecided.push(item.id);
389
393
  }
390
394
  result.ok = result.red.length === 0 && result.undecided.length === 0 && result.blocked.length === 0;
395
+ if (result.postpub!.length) debug.log('release-loop.checklist', 'gate-postpub-excluded', { version: v, ids: result.postpub });
391
396
  return result;
392
397
  }
393
398
 
394
399
  /** GATE-ENTRY-ALIGN: the cut-time judgement shared by `release run`'s entry check and the checklist-gate node —
395
- * past the landing deadline a non-P0 yellow without a disposition is carried (moved), and a P0 yellow always blocks. */
400
+ * past the landing deadline a non-P0 yellow without a disposition is carried (moved); P0 yellow blocks unless OP recorded known-issue. */
396
401
  export function cutChecklistGate(v: string, landBy: string | null | undefined, now: Date = new Date()): ChecklistGate & { autoMoved: string[] } {
397
- const items = listChecklist(v).items;
402
+ const { items, history } = listChecklist(v);
398
403
  const overdue = landBy !== null && landBy !== undefined && now.getTime() > Date.parse(landBy);
399
- const autoMoved = overdue ? items.filter((item) => item.status === 'yellow' && item.priority !== 'P0' && item.disposition === undefined).map((item) => item.id) : [];
400
- const p0 = items.filter((item) => item.status === 'yellow' && item.priority === 'P0').map((item) => item.id);
404
+ const autoMoved = overdue ? items.filter((item) => item.kind !== 'postpub' && item.status === 'yellow' && item.priority !== 'P0' && item.disposition === undefined).map((item) => item.id) : [];
405
+ const p0 = items.filter((item) => {
406
+ if (item.kind === 'postpub' || item.status !== 'yellow' || item.priority !== 'P0') return false;
407
+ if (item.disposition === 'known-issue') {
408
+ const decision = [...history].reverse().find((entry) => entry.id === item.id && entry.field === 'disposition' && entry.to === 'known-issue');
409
+ if (decision?.by === 'OP') {
410
+ debug.log('release-loop.checklist', 'p0-known-issue-allowed', { version: v, id: item.id, by: decision.by, at: decision.at });
411
+ return false;
412
+ }
413
+ }
414
+ return true;
415
+ }).map((item) => item.id);
401
416
  const gate = checklistGate(v);
402
417
  gate.undecided = gate.undecided.filter((id) => !autoMoved.includes(id) && !p0.includes(id));
403
418
  gate.moved = gate.moved.filter((id) => !p0.includes(id)).concat(autoMoved);
@@ -3,6 +3,7 @@ import { createHash, randomUUID } from 'node:crypto';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { Database } from 'bun:sqlite';
5
5
  import { releaseLedgerRoot } from '../instance/resolve.js';
6
+ import { assertNotTestWritingOps } from '../instance/test-write-guard.js';
6
7
  import { CliUserError } from '../cli/cli-user-error.js';
7
8
  import { debug } from '../debug/log.js';
8
9
  import { getUserConfig } from '../user-config.js';
@@ -46,6 +47,7 @@ function schemaCurrent(db: Database): boolean {
46
47
  }
47
48
  function open(root = releaseLedgerRoot()): Database {
48
49
  const path = join(root, 'release', 'features.sqlite');
50
+ assertNotTestWritingOps(path, 'open the checklist ledger');
49
51
  mkdirSync(dirname(path), { recursive: true });
50
52
  const db = new Database(path, { create: true, strict: true });
51
53
  try {
@@ -546,6 +548,7 @@ export function details(id: string): { id: string; title: string; owner: string
546
548
  export function exportJson(version: string, released = releasedVersion(), dev = devVersion()): Checklist {
547
549
  const data = list(version, released, dev);
548
550
  const path = jsonPath(version);
551
+ assertNotTestWritingOps(path, 'export the checklist ledger');
549
552
  mkdirSync(dirname(path), { recursive: true });
550
553
  const temp = `${path}.${process.pid}.${randomUUID()}.tmp`;
551
554
  const contents = `${JSON.stringify(data, null, 2)}\n`;