elanous 0.2.21 → 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 (780) 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-111cabe4d1fd69ae.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/{MObU8ujkMciAKr6ljAV05 → 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/catalog/catalog.yaml +1 -1
  288. package/graphs/drafts/recipes.yaml +2 -2
  289. package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
  290. package/graphs/log-horizon/recipes.yaml +3 -0
  291. package/graphs/release/recipes.yaml +1 -1
  292. package/graphs/release/release-loop.yaml +6 -2
  293. package/graphs/release-rehearsal/recipes.yaml +12 -0
  294. package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
  295. package/graphs/test-diet/recipes.yaml +3 -0
  296. package/graphs/test-diet/test-diet.yaml +3 -1
  297. package/package.json +4 -1
  298. package/scripts/bench-report.ts +82 -3
  299. package/scripts/ci-typecheck-changed.ts +10 -1
  300. package/scripts/f-session-monitor.ts +69 -0
  301. package/scripts/hq/hq-fence-wrapper.sh +148 -0
  302. package/scripts/hq/standby-snapshot.ts +7 -3
  303. package/scripts/knowledge-compress.ts +11 -0
  304. package/scripts/lib/typecheck-ratchet.ts +51 -0
  305. package/scripts/nightly-docops.ts +90 -3
  306. package/scripts/openai-relay-server.ts +5 -1
  307. package/scripts/release-loop/docs-node.ts +258 -43
  308. package/scripts/release-loop/gate-method.ts +59 -0
  309. package/scripts/release-loop/gate-node.ts +73 -7
  310. package/scripts/release-loop/gate-wall.ts +208 -0
  311. package/scripts/release-loop/known-issues-node.ts +53 -8
  312. package/scripts/release-loop/publish-at.ts +14 -0
  313. package/scripts/release-loop/publish-node.ts +17 -2
  314. package/scripts/release-loop/resume-release.ts +34 -4
  315. package/scripts/release-loop/resume.ts +53 -0
  316. package/scripts/release-loop/shard-plan.ts +3 -11
  317. package/scripts/release-loop/tui-node-checks.ts +22 -0
  318. package/scripts/release-loop/unattended-release.ts +8 -1
  319. package/scripts/research-coo-admin-dates.ts +39 -0
  320. package/scripts/rhythm/daily.ts +51 -2
  321. package/scripts/rhythm/weekly.ts +3 -2
  322. package/scripts/skills/public-check.ts +7 -2
  323. package/scripts/smart-merge/resync-shadow.ts +5 -3
  324. package/scripts/test-diet/lib.ts +81 -1
  325. package/scripts/test-diet/node.ts +48 -2
  326. package/scripts/tsc-main-safety-net.ts +189 -0
  327. package/scripts/usage-rollup.ts +8 -4
  328. package/scripts/verify-coo-admin-evidence.ts +83 -0
  329. package/src/acp/client.ts +4 -2
  330. package/src/acp/codex-plugins.ts +48 -6
  331. package/src/agent/monad-agent-turn.ts +67 -5
  332. package/src/agent/run-context.ts +14 -0
  333. package/src/agent/tool-profile.ts +28 -2
  334. package/src/agent-env/profile.ts +25 -5
  335. package/src/agent-mission/acp-judge.ts +8 -2
  336. package/src/agent-mission/capabilities-cli.ts +16 -1
  337. package/src/agent-mission/driver.ts +27 -13
  338. package/src/agent-mission/pr-review-watch.ts +6 -2
  339. package/src/agent-mission/review-loop.ts +33 -5
  340. package/src/agent-mission/supervisor-metrics.ts +17 -2
  341. package/src/agent-substrate/acp-reviewer.ts +25 -9
  342. package/src/agent-substrate/pr-reviewer.ts +175 -32
  343. package/src/agent-substrate/review-intent.ts +106 -5
  344. package/src/agent-substrate/self-review-cli.ts +111 -16
  345. package/src/agent-substrate/shard-boundary-intent.ts +92 -26
  346. package/src/ask-user-question/pending-questions.ts +8 -2
  347. package/src/autopilot/build/llm-conflict-merge.ts +238 -20
  348. package/src/autopilot/codebase-grounding.ts +44 -0
  349. package/src/autopilot/llm-control-brain.ts +13 -1
  350. package/src/autopilot/mission-codebase-gate.ts +8 -77
  351. package/src/autopilot/pr-manager.ts +30 -11
  352. package/src/away/release-watch.ts +47 -8
  353. package/src/boot/acp-server.ts +4 -7
  354. package/src/boot/acp-socket-path.ts +7 -0
  355. package/src/briefing/brief-items.ts +123 -22
  356. package/src/chat/index.ts +13 -3
  357. package/src/cli/agent-cli.ts +20 -0
  358. package/src/cli/brief-cli.ts +46 -22
  359. package/src/cli/cli-user-error.ts +9 -2
  360. package/src/cli/config-classify.ts +83 -0
  361. package/src/cli/control-cli.ts +14 -0
  362. package/src/cli/decisions-cli.ts +26 -16
  363. package/src/cli/log-event-names.ts +3 -0
  364. package/src/cli/logs-cli.ts +1 -0
  365. package/src/cli/logs-model-input.ts +1 -1
  366. package/src/cli/mcp-login.ts +111 -37
  367. package/src/cli/plugin-cli.ts +21 -1
  368. package/src/cli/pod-cli.ts +26 -0
  369. package/src/cli/pr-cli.ts +94 -9
  370. package/src/cli/pr-land-overlap-evidence.ts +131 -0
  371. package/src/cli/release-cli.ts +74 -15
  372. package/src/cli/self-update.ts +173 -10
  373. package/src/cli/skills-cli.ts +12 -3
  374. package/src/cli/tasks-cli.ts +241 -28
  375. package/src/connectors/types.ts +6 -6
  376. package/src/context-bus/context-first.ts +51 -2
  377. package/src/context-bus/context-now-surfaces.ts +29 -0
  378. package/src/context-bus/coord-events.ts +32 -4
  379. package/src/context-bus/long-term-memory.ts +26 -7
  380. package/src/context-bus/nightly-condense.ts +170 -21
  381. package/src/control/control-status.ts +87 -0
  382. package/src/control-plane/light-member.ts +5 -3
  383. package/src/control-plane/member.ts +172 -7
  384. package/src/core-turn/run-goal-loop.ts +108 -3
  385. package/src/dashboard/chat-fold.ts +20 -0
  386. package/src/dashboard/first-screen-band.ts +151 -1
  387. package/src/dashboard/index.ts +27 -5
  388. package/src/dashboard/slash-runtime/dashboard-handlers.ts +14 -3
  389. package/src/dashboard/stale-install-check.ts +13 -2
  390. package/src/dashboard/turn-stream-formatter.ts +25 -0
  391. package/src/debug/log-diet.ts +159 -0
  392. package/src/debug/log.ts +52 -17
  393. package/src/decisions/decision-cards.ts +20 -1
  394. package/src/decisions/decision-ledger.ts +11 -8
  395. package/src/decisions/web-push-decision-cards.ts +19 -3
  396. package/src/discord-self-message.ts +2 -2
  397. package/src/display/coordinator.ts +25 -2
  398. package/src/domains/coo-admin-dates.evidence.json +876 -0
  399. package/src/domains/coo-admin-tool.ts +75 -14
  400. package/src/domains/cron-match.ts +1 -0
  401. package/src/domains/ops-status.ts +53 -0
  402. package/src/domains/outbound-alert.ts +41 -7
  403. package/src/domains/release-tool.ts +119 -10
  404. package/src/domains/schedule-registry.ts +10 -7
  405. package/src/domains/schedule-runner.ts +1 -0
  406. package/src/elanous-config-dir.ts +2 -2
  407. package/src/elanous-daemon.ts +3 -3
  408. package/src/exec-requests/planner.ts +6 -0
  409. package/src/execution-loop/launch-gate.ts +1 -1
  410. package/src/expression/i18n/messages.en.ts +5 -0
  411. package/src/expression/i18n/messages.ja.ts +5 -0
  412. package/src/expression/i18n/messages.ko.ts +5 -0
  413. package/src/expression/i18n/messages.zh.ts +5 -0
  414. package/src/expression/i18n/types.ts +8 -0
  415. package/src/github/pr-labels.ts +1 -0
  416. package/src/graph-kinds/registry.ts +6 -6
  417. package/src/graph-runner/graph-cli.ts +34 -2
  418. package/src/graph-runner/graph-run-api.ts +7 -0
  419. package/src/graph-runner/graph-tick.ts +73 -12
  420. package/src/graph-runner/runner.ts +94 -13
  421. package/src/graph-unify/wf-to-graph.ts +79 -0
  422. package/src/graph-wizard/generate.ts +34 -2
  423. package/src/graph-wizard/steps.ts +13 -0
  424. package/src/harness/dispatch-backpressure.ts +259 -0
  425. package/src/harness/harness-cli-command.ts +227 -50
  426. package/src/harness/harness-queue.ts +58 -14
  427. package/src/harness/harness-seams.ts +2 -20
  428. package/src/harness/harness-substrate-default.ts +72 -1
  429. package/src/harness/launch-advice.ts +23 -0
  430. package/src/harness/nested-elanous-policy.ts +4 -2
  431. package/src/hq/fence-wrapper.ts +7 -0
  432. package/src/hq/hq.ts +33 -2
  433. package/src/hq/lease.ts +13 -0
  434. package/src/hq/seats.ts +114 -18
  435. package/src/index.ts +199 -71
  436. package/src/intake-plane/collect-github.ts +19 -1
  437. package/src/intake-plane/digest.ts +45 -20
  438. package/src/intake-plane/lens.ts +36 -8
  439. package/src/intelligence-map/model-alias.ts +6 -0
  440. package/src/intelligence-map/model-catalog.ts +41 -0
  441. package/src/knowledge/conclusion-compress.ts +93 -0
  442. package/src/knowledge/kgs/pack.ts +5 -2
  443. package/src/knowledge/kgs/sqlite-store.ts +15 -0
  444. package/src/knowledge/know-find.ts +9 -2
  445. package/src/knowledge/query.ts +20 -0
  446. package/src/knowledge/tools/knowledge-query.ts +20 -2
  447. package/src/knowledge/write.ts +234 -2
  448. package/src/llm/bedrock-provider.ts +175 -0
  449. package/src/llm/bedrock.ts +345 -0
  450. package/src/llm/provider-credentials.ts +3 -1
  451. package/src/llm.ts +332 -51
  452. package/src/loops/budget.ts +150 -0
  453. package/src/loops/neighbor-runtime.ts +88 -0
  454. package/src/loops/orchestrator/author-depth.ts +29 -11
  455. package/src/loops/orchestrator/overlap.ts +7 -1
  456. package/src/loops/orchestrator/resync-shadow.ts +1 -1
  457. package/src/loops/orchestrator/seat-share.ts +6 -49
  458. package/src/loops/orchestrator/tick.ts +35 -2
  459. package/src/loops/orchestrator/traffic.ts +6 -80
  460. package/src/loops/registry.ts +5 -0
  461. package/src/market/publish.ts +17 -1
  462. package/src/market/signed-index.ts +42 -0
  463. package/src/maturity/feature-maturity.ts +2 -1
  464. package/src/mcp/mcp-oauth.ts +136 -17
  465. package/src/model-tier/llm-tier-map.ts +48 -4
  466. package/src/models/prompts.ts +22 -1
  467. package/src/mss/logging/horizon-watch.ts +168 -0
  468. package/src/mss/logging/log-store.ts +204 -15
  469. package/src/mss/logging/redaction.ts +17 -0
  470. package/src/native-tool-catalog.ts +1 -1
  471. package/src/nexus/api/consult-requests.ts +7 -10
  472. package/src/nexus/api/discord-trigger-bot.ts +6 -3
  473. package/src/nexus/api/draft-metrics.ts +22 -8
  474. package/src/nexus/api/error-reports.ts +30 -8
  475. package/src/nexus/api/graph-peer-edit.ts +77 -0
  476. package/src/nexus/api/graph-wizard-api.ts +9 -1
  477. package/src/nexus/api/graphs-api.ts +145 -7
  478. package/src/nexus/api/http-server.ts +101 -8
  479. package/src/nexus/api/loop-resources.ts +42 -0
  480. package/src/nexus/api/outbound-report.ts +8 -3
  481. package/src/nexus/api/plugins-market.ts +24 -0
  482. package/src/nexus/api/telegram-trigger-bot.ts +6 -3
  483. package/src/nexus/index.ts +13 -2
  484. package/src/nexus/outbound/format.ts +2 -0
  485. package/src/nexus/outbound/router.ts +198 -13
  486. package/src/oauth/claude-pty-maturity.ts +24 -0
  487. package/src/oauth/codex-account-rotation.ts +16 -18
  488. package/src/oauth/codex-account-store.ts +134 -5
  489. package/src/oauth/fallback-chain.ts +50 -15
  490. package/src/onboarding.ts +2 -1
  491. package/src/plugins/adapters/claude-package.ts +4 -12
  492. package/src/plugins/core/capability-policy.ts +141 -0
  493. package/src/plugins/core/host.ts +21 -8
  494. package/src/plugins/core/manifest.ts +19 -2
  495. package/src/plugins/core/trust-store.ts +15 -0
  496. package/src/plugins/core/types.ts +12 -0
  497. package/src/plugins/install/market-fetch.ts +68 -16
  498. package/src/plugins/install/plugin-install.ts +187 -16
  499. package/src/plugins/maker/market-bundle.ts +9 -0
  500. package/src/plugins/maker/plugin-maker.ts +32 -21
  501. package/src/plugins/maker/wizard-generate.ts +87 -9
  502. package/src/policy/llm-policy.ts +24 -6
  503. package/src/process/pid-liveness.ts +1 -1
  504. package/src/prompt-cache/openai.ts +10 -6
  505. package/src/prompt-cache/openrouter.ts +94 -0
  506. package/src/prompt-enhance/enhance.ts +46 -5
  507. package/src/prompt-library/family-prompt-coverage.ts +1 -0
  508. package/src/prompt-library/universal-preamble.ts +2 -2
  509. package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
  510. package/src/registry/loader.ts +6 -1
  511. package/src/release-loop/checklist-board.ts +27 -0
  512. package/src/release-loop/checklist.ts +62 -9
  513. package/src/release-loop/feature-store.ts +3 -0
  514. package/src/release-loop/gate-shards.ts +48 -4
  515. package/src/release-loop/landed-to-green.ts +81 -0
  516. package/src/release-loop/light-rc.ts +11 -1
  517. package/src/release-loop/merged-pr-checklist.ts +10 -0
  518. package/src/release-loop/placement.ts +91 -22
  519. package/src/release-loop/rehearsal.ts +317 -0
  520. package/src/release-loop/release-schedule.ts +13 -1
  521. package/src/release-loop/rubric-types.ts +1 -0
  522. package/src/release-loop/rubric.ts +2 -2
  523. package/src/retro/daily.ts +23 -9
  524. package/src/seat-address/seat-address.ts +1 -0
  525. package/src/seat-loop/seat-loop.ts +208 -21
  526. package/src/seat-loop/seat-report.ts +29 -1
  527. package/src/seat-loop/traffic-signal.ts +44 -0
  528. package/src/self-dev/ask-launch-flow.ts +2 -2
  529. package/src/self-dev/dev-cli.ts +157 -11
  530. package/src/self-dev/dev-pipeline.ts +18 -1
  531. package/src/self-dev/draft-residue.ts +463 -0
  532. package/src/self-dev/draft-sweep.ts +195 -17
  533. package/src/self-dev/draft-triage-rules.ts +27 -1
  534. package/src/self-dev/launch-preflight-text.ts +549 -0
  535. package/src/self-dev/launch-preflight.ts +10 -545
  536. package/src/self-dev/orchestrate-cli.ts +57 -2
  537. package/src/self-dev/orchestrate-summary-line.ts +13 -0
  538. package/src/self-dev/orchestrate.ts +9 -133
  539. package/src/self-dev/review-provider-fallback.ts +179 -0
  540. package/src/self-dev/run-store.ts +1 -3
  541. package/src/self-dev/run-supervisor.ts +8 -23
  542. package/src/self-dev/run-types.ts +178 -0
  543. package/src/self-dev/shard-aggregate.ts +61 -13
  544. package/src/self-dev/shard-plan.ts +5 -1
  545. package/src/self-dev/shard-run.ts +23 -5
  546. package/src/self-dev/supervisor-verdict-edges.ts +2 -4
  547. package/src/self-implement/blocked-draft-policy.ts +3 -19
  548. package/src/self-implement/draft-on-stop-mode.ts +18 -0
  549. package/src/self-implement/follow-up-goals.ts +114 -38
  550. package/src/self-implement/gate-baseline-reap.ts +157 -0
  551. package/src/self-implement/gate-baseline.ts +78 -16
  552. package/src/self-implement/gate-cli.ts +12 -2
  553. package/src/self-implement/gate-remote.ts +17 -6
  554. package/src/self-implement/goal-author.ts +24 -4
  555. package/src/self-implement/goal-digest.ts +19 -0
  556. package/src/self-implement/graph-overlay-condition.ts +4 -0
  557. package/src/self-implement/harness-policy-gates.ts +7 -5
  558. package/src/self-implement/headless-elanous-driver.ts +11 -9
  559. package/src/self-implement/host-regate.ts +148 -43
  560. package/src/self-implement/l8-merge-queue.ts +147 -13
  561. package/src/self-implement/merge-train.ts +131 -0
  562. package/src/self-implement/off-diff-evidence.ts +9 -0
  563. package/src/self-implement/orchestrator.ts +201 -43
  564. package/src/self-implement/review-finding-recurrence.ts +28 -0
  565. package/src/self-implement/rework-policy.ts +2 -1
  566. package/src/self-implement/round-summary-card.ts +63 -0
  567. package/src/self-implement/run-ledger.ts +4 -3
  568. package/src/self-implement/run-step-projection.ts +147 -0
  569. package/src/self-implement/run-stop.ts +1 -1
  570. package/src/self-implement/seams.ts +41 -6
  571. package/src/self-implement/self-implement-cli.ts +6 -0
  572. package/src/self-implement/train-gate-remote.ts +158 -0
  573. package/src/session-runtime/index.ts +10 -1
  574. package/src/session-runtime/retry-api.ts +11 -1
  575. package/src/shell-env-bootstrap.ts +19 -4
  576. package/src/skills/gift-install.ts +119 -0
  577. package/src/skills/runner.ts +59 -2
  578. package/src/skills/skill-feedback.ts +31 -1
  579. package/src/skills/skill-tier.ts +1 -0
  580. package/src/smart-wizard/capability-index.ts +231 -0
  581. package/src/smart-wizard/rung.ts +74 -0
  582. package/src/steward/launch.ts +20 -9
  583. package/src/steward/triage.ts +29 -10
  584. package/src/storage/file-lock.ts +40 -4
  585. package/src/task-agent/actions.ts +4 -0
  586. package/src/task-agent/card-evidence.ts +59 -13
  587. package/src/task-agent/completion-evidence.ts +31 -3
  588. package/src/task-agent/cover.ts +61 -0
  589. package/src/task-agent/judge.ts +4 -3
  590. package/src/task-agent/land-worktree.ts +201 -0
  591. package/src/task-agent/live-move-history.ts +133 -0
  592. package/src/task-agent/live-moves.ts +222 -12
  593. package/src/task-agent/parent-host.ts +117 -8
  594. package/src/task-agent/rejudge-on-head.ts +297 -0
  595. package/src/task-agent/review-result-capture.ts +218 -0
  596. package/src/task-agent/shadow.ts +118 -7
  597. package/src/task-agent/task-hand.ts +138 -11
  598. package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
  599. package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
  600. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
  601. package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
  602. package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
  603. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
  604. package/src/task-orchestrator/surfaces/pod-pool.ts +203 -28
  605. package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
  606. package/src/task-orchestrator/surfaces/self-implement.ts +11 -0
  607. package/src/telegram-commands.ts +8 -0
  608. package/src/telegram-project-command.ts +6 -0
  609. package/src/telegram-service.ts +5 -1
  610. package/src/telegram.ts +17 -4
  611. package/src/time/format.ts +13 -4
  612. package/src/tool-runtime/goal-author-runtime.ts +1 -0
  613. package/src/tool-runtime/self-cognition-catalog.ts +23 -0
  614. package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
  615. package/src/typecheck-ratchet.ts +2 -1
  616. package/src/user-config.ts +167 -28
  617. package/src/ux-sim/slash-menu-frames.ts +168 -0
  618. package/src/version/packed-revision.json +1 -1
  619. package/src/web-terminal/preview-tap-registry.ts +5 -2
  620. package/src/workflow-runtime/executor.ts +24 -2
  621. package/src/workflow-runtime/triggers/registry.ts +27 -0
  622. package/src/workflow-runtime/triggers/schedule-source.ts +30 -3
  623. package/src/workflow-runtime/triggers/scheduler.ts +1 -0
  624. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
  625. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
  626. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
  627. package/apps/pwa/out/_next/static/chunks/1307-c97eba9fb72a9a5e.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
  629. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
  630. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
  631. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
  633. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
  638. package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
  647. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
  648. package/apps/pwa/out/_next/static/chunks/2489-ff55a35b202c0f94.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
  661. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
  669. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
  674. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
  676. package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
  680. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
  684. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/5977-59fedea50d13c762.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
  689. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
  690. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
  692. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
  693. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
  701. package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
  704. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
  714. package/apps/pwa/out/_next/static/chunks/8857-f1762140ef9a96b1.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
  717. package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/9247-7581825d511a64c0.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
  721. package/apps/pwa/out/_next/static/chunks/9497-b0e758d1cd4ae8d7.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
  723. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/approvals/page-937c92292a4ab4f0.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d781be3e3a9cfd74.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/board/page-b0a80997903852d8.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/botlab/page-2b1263165630d9c8.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea998f7f5d156bea.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/ceo/page-33c328b64ca508f8.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/chat/page-e2d6bed48ac20120.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/control/page-544dd4bd4847eeb7.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/decisions/page-3ee191319bf97d87.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e4bcb2c503dab04b.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/editor/page-300897dcbbd5ed76.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/exec/page-a449f1ed472b81c2.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/field/page-9045094d6d3b5cd0.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/inside/page-c06673596849ef45.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/intake/page-103fa3191c1b2e08.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/layout-9f81233f29dcd409.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/live/page-be8b4615c919e36c.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/live-run/page-c685b104e0dfa609.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/loops/page-8d693331cfbb6add.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/market/page-cef4f30a4c22fae1.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66ea1b54fc83fa15.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/morning/page-7a12f61be4a579d1.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/not-found-c85b0589591a99c9.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/observatory/page-725a4da02dd129eb.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-8cc707bd09a497d9.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-90b55be1f15ce0e8.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cb16606e08be65db.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/outputs/page-16dc64b74ed6a40a.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/page-21bec4afeb2f0917.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/reflection/page-dc39ee7a36d26385.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-84ae759f76053672.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/sessions/page-3db58ddb61fe2be9.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c5315e30f3528dc4.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/settings/page-2fe368efb6de3b6a.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8d04132dd0ac5e10.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/setup/page-f23484de467c9ea3.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/share/page-c69762987b751174.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/showroom/page-5456692bda39aafb.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d75f7cd65845ce98.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/term/page-5603f5e568b25ce3.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/today/page-d2cc0f4e89f42028.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/trace/page-a6eb73b8a4840f1c.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/vault/page-c0a3f4d10edb83fa.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6c0b88068c143f15.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/workflows/page-7f8d7fcdf058a845.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/workspace/page-22163556cd38bc88.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-141436fd26dd56fc.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
  779. package/apps/pwa/out/_next/static/css/e81df11490b4413b.css +0 -1
  780. /package/apps/pwa/out/_next/static/{MObU8ujkMciAKr6ljAV05 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
@@ -41,6 +41,34 @@ export interface RecurrenceFinding {
41
41
  readonly item: string;
42
42
  }
43
43
 
44
+ /** Pod 리뷰 예산 소진 잔여 분류(FLEX-POD-ACCEPT-1).
45
+ * `repeatedIds` = 앞 라운드와 id(내용 해시) 또는 비지 않은 `reviewFindingKey` 가 같은 지적.
46
+ * `keyOnlyRepeatedIds` = 그중 «키로만» 반복된 것(문면이 달라 내용 해시는 다르다).
47
+ * ⛔ 사양 v2(OP 18:1x (a)): Pod 수락은 «전부 내용 해시 반복»일 때만 — 키로만 반복된 지적은 관측만 하고 수락 근거로 쓰지 않는다. */
48
+ export function classifyPodReviewBudgetResidue(
49
+ current: readonly RecurrenceFinding[] | undefined,
50
+ previous: readonly RecurrenceFinding[] | undefined,
51
+ ): { status: 'all-repeated' | 'has-new' | 'unmeasured'; repeatedIds: string[]; newIds: string[]; keyOnlyRepeatedIds: string[] } {
52
+ if (!previous?.length || !current?.length) return { status: 'unmeasured', repeatedIds: [], newIds: [], keyOnlyRepeatedIds: [] };
53
+ const previousIds = new Set(previous.map(({ id }) => id));
54
+ const previousKeys = new Set(previous.map(({ item }) => reviewFindingKey(item).key).filter(Boolean));
55
+ const repeatedIds: string[] = [];
56
+ const newIds: string[] = [];
57
+ const keyOnlyRepeatedIds: string[] = [];
58
+ for (const { id, item } of current) {
59
+ if (previousIds.has(id)) {
60
+ repeatedIds.push(id);
61
+ continue;
62
+ }
63
+ const key = reviewFindingKey(item).key;
64
+ if (key !== '' && previousKeys.has(key)) {
65
+ repeatedIds.push(id);
66
+ keyOnlyRepeatedIds.push(id);
67
+ } else newIds.push(id);
68
+ }
69
+ return { status: newIds.length ? 'has-new' : 'all-repeated', repeatedIds, newIds, keyOnlyRepeatedIds };
70
+ }
71
+
44
72
  export interface AcceptedRefutationHistory {
45
73
  /** 반박이 수용되어 앞 라운드에 기각된 stable must-fix ID. */
46
74
  readonly acceptedRefutationFindingIds?: readonly string[];
@@ -459,6 +459,7 @@ export function applyReworkBudgetDecision(
459
459
  priorRounds = Number.POSITIVE_INFINITY,
460
460
  shadowStop = false,
461
461
  previousVerdict?: ReworkBudgetVerdict,
462
+ gateBaselineOnly?: boolean,
462
463
  ): { effectiveMax: number; stop: boolean; exit: 'continue' | 'proceed' | 'blocked'; applied: boolean; shadowed?: boolean; wouldExit?: 'proceed' | 'blocked'; contractConflictDisposition?: ContractConflictDisposition } {
463
464
  const cap = Math.max(0, hardCap);
464
465
  const normalizedMax = Math.min(cap, Math.max(0, effectiveMax));
@@ -482,7 +483,7 @@ export function applyReworkBudgetDecision(
482
483
  return { effectiveMax: extendedMax, stop: false, exit: 'continue', applied: extendedMax > normalizedMax };
483
484
  }
484
485
  if (decision.verdict === 'SUFFICIENT') {
485
- if (kind !== 'review') return { effectiveMax: normalizedMax, stop: false, exit: 'continue', applied: false };
486
+ if (kind !== 'review' && !(kind === 'gate' && gateBaselineOnly === true)) return { effectiveMax: normalizedMax, stop: false, exit: 'continue', applied: false };
486
487
  return shadowStop
487
488
  ? { effectiveMax: normalizedMax, stop: false, exit: 'continue', applied: false, shadowed: true, wouldExit: 'proceed' }
488
489
  : { effectiveMax: normalizedMax, stop: true, exit: 'proceed', applied: true };
@@ -0,0 +1,63 @@
1
+ export interface RoundSummaryEntry {
2
+ /** The round whose result this entry records; zero is the first implementation. */
3
+ round: number;
4
+ kind: 'gate' | 'review';
5
+ tried?: string;
6
+ failedIds?: readonly string[];
7
+ filesTouched?: readonly string[];
8
+ rung?: string;
9
+ premiseFindings?: readonly string[];
10
+ }
11
+
12
+ const HEADER = '[라운드 요약 카드 — 이미 해 본 수와 결과]';
13
+
14
+ function singleLine(value: string): string {
15
+ return value.replace(/\s+/g, ' ').trim();
16
+ }
17
+
18
+ function list(items: readonly string[] | undefined): string {
19
+ return items === undefined ? '못 쟀다' : items.length === 0 ? '0건' : items.map(singleLine).join(', ');
20
+ }
21
+
22
+ function failureKey(entry: RoundSummaryEntry): string | undefined {
23
+ return entry.failedIds?.length ? JSON.stringify([...new Set(entry.failedIds)].sort()) : undefined;
24
+ }
25
+
26
+ /** Only recorded results are rendered; no filesystem or runtime state is consulted. */
27
+ export function renderRoundSummaryCard(entries: readonly RoundSummaryEntry[], { maxChars = 1500 }: { maxChars?: number } = {}): string {
28
+ if (!entries.length) return '';
29
+ const lines = entries.map((entry) => `라운드 ${entry.round} · ${entry.kind} · 해 본 수: ${entry.tried === undefined ? '못 쟀다' : singleLine(entry.tried)} · 실패 id: ${list(entry.failedIds)} · 손댄 파일: ${list(entry.filesTouched)}`
30
+ + (entry.rung === undefined ? '' : ` · rung: ${singleLine(entry.rung)}`)
31
+ + (entry.premiseFindings === undefined ? '' : ` · premiseFindings: ${list(entry.premiseFindings)}`));
32
+ const lastKey = failureKey(entries[entries.length - 1]!);
33
+ const prior = lastKey === undefined ? undefined : entries.slice(0, -1).find((entry) => failureKey(entry) === lastKey);
34
+ const guidance = prior === undefined ? '' : [
35
+ `이 실패 집합은 라운드 ${prior.round} 에서도 같았다 — 같은 수 대신 다른 칸을 열 수 있다.`,
36
+ '이렇게 하라: (F1) base(origin/main)에서 같은 시험을 돌려 원래 깨진 것인지 보고, 호출자와 `git log -S <심볼>`로 선례를 보라.',
37
+ '(F2) docs/의 매뉴얼·FINDING에서 같은 증상을 찾아라. 원인이 이 골의 범위 밖이라면 근거(파일:줄·명령 출력)를 PR 본문 «남은 것»에 적어라.',
38
+ ].join('\n');
39
+ const render = (omitted: number) => [HEADER, ...(omitted ? [`…(앞 라운드 ${omitted}개 생략)`] : []), ...lines.slice(omitted), ...(guidance ? [guidance] : [])].join('\n');
40
+ let omitted = 0;
41
+ while (omitted < lines.length - 1 && render(omitted).length > maxChars) omitted++;
42
+ const card = render(omitted);
43
+ if (card.length <= maxChars) return card;
44
+ // Reserve the repeated-failure actions before truncating the latest round's details.
45
+ const latestEntry = entries[entries.length - 1]!;
46
+ const latest = lines[lines.length - 1]!;
47
+ const identity = `라운드 ${latestEntry.round} · ${latestEntry.kind}`;
48
+ const marker = omitted ? `…(앞 라운드 ${omitted}개 생략)\n` : '';
49
+ const heading = `${HEADER}\n`;
50
+ const prefix = heading.length + marker.length + identity.length <= maxChars ? heading + marker
51
+ : heading.length + identity.length <= maxChars ? heading
52
+ : '';
53
+ const available = Math.max(0, maxChars - prefix.length);
54
+ if (available < identity.length) return identity.slice(0, available);
55
+ const fullAdvice = guidance ? `\n${guidance}` : '';
56
+ const shortAdvice = prior ? `\n라운드 ${prior.round} 실패 반복 — base 시험을 확인하고 다른 칸을 열어라.` : '';
57
+ const advice = identity.length + fullAdvice.length <= available ? fullAdvice
58
+ : identity.length + shortAdvice.length <= available ? shortAdvice : '';
59
+ const resultBudget = available - advice.length;
60
+ const visible = latest.length <= resultBudget ? latest
61
+ : resultBudget > identity.length ? `${latest.slice(0, resultBudget - 1)}…` : identity;
62
+ return prefix + visible + advice;
63
+ }
@@ -2,14 +2,14 @@ import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, statS
2
2
  import { dirname, isAbsolute, join, resolve } from 'node:path';
3
3
  import { refuseProductionLedgerWriteInTest } from '../harness/ledger-write-guard.js';
4
4
  import { tracedPathReferences, verbatimOriginalAsk } from './goal-author.js';
5
- import { parseAskTargetPathHintsResult } from '../self-dev/launch-preflight.js';
5
+ import { parseAskTargetPathHintsResult } from '../self-dev/launch-preflight-text.js';
6
6
  import { isRunStatus } from './run-status-mapping.js';
7
7
  import { elanousStateRoot } from '../autopilot/state-paths.js';
8
8
  import { normalizeRunId } from '../harness/harness-space.js';
9
9
  import { resolveLogTargets, type LogTarget } from '../cli/logs-cli.js';
10
10
  import { LogStore, logsDbPath, type LogStoreRow } from '../mss/logging/log-store.js';
11
11
  import { loadSelfDevRun, selfDevRunsDir } from '../self-dev/run-store.js';
12
- import { extractHarnessReviewAcceptance } from '../harness/harness-seams.js';
12
+ import { extractHarnessReviewAcceptance } from './goal-digest.js';
13
13
  import { resolveGoalDocumentsDir } from './goal-documents-dir.js';
14
14
  import { debug } from '../debug/log.js';
15
15
  import { withRunLedgerLock, restoreArchivedRunLedger } from './run-ledger-compact.js';
@@ -1561,7 +1561,8 @@ interface UnfinishedLedgerFacts {
1561
1561
  fixedLifecycle: UnfinishedRunLifecycle;
1562
1562
  }
1563
1563
 
1564
- const UNFINISHED_LEDGER_CACHE_LIMIT = 5_000;
1564
+ // A full federated scan can exceed 5,000 files; keep the previous scan resident for mtime-checked reuse.
1565
+ const UNFINISHED_LEDGER_CACHE_LIMIT = 32_768;
1565
1566
  const unfinishedLedgerCache = new Map<string, { size: number; mtimeMs: number; facts: UnfinishedLedgerFacts }>();
1566
1567
  const unfinishedReaderIds = new WeakMap<RunLedgerReader, number>();
1567
1568
  let nextUnfinishedReaderId = 1;
@@ -0,0 +1,147 @@
1
+ import type { RunLedgerEntry } from './run-ledger.js';
2
+
3
+ export type RunStep =
4
+ | { seq: number; ts: string; type: 'node-enter'; node: string; visit: number }
5
+ | { seq: number; ts: string; type: 'node-exit'; node: string; outcome: string }
6
+ | { seq: number; ts: string; type: 'edge-taken'; from: string; to: string; via: string; condition?: string }
7
+ | { seq: number; ts: string; type: 'node-skipped'; node: string; reason: string; condition?: string }
8
+ | { seq: number; ts: string; type: 'node-added'; node: string; kind: string; decider: string; reason: string; trigger?: unknown; undo?: unknown }
9
+ | { seq: number; ts: string; type: 'edge-rerouted'; from: string; outcome: string; to: string; was: string; decider: string; reason: string }
10
+ | { seq: number; ts: string; type: 'unit-expanded'; node: string; unit: string; childRunId: string; resolution: number; decider: string; reason: string }
11
+ | { seq: number; ts: string; type: 'unit-collapsed'; node: string; resolution: number; decider: string; reason: string };
12
+
13
+ export interface RunStepProjection {
14
+ runId: string;
15
+ graph: { graphId: string | null; version: string | null; variantHash: string | null };
16
+ steps: readonly RunStep[];
17
+ complete: boolean;
18
+ /** Number of recognized steps whose source record could not be projected. */
19
+ unreadable: number;
20
+ /** Source sequence and reason for every rejected or duplicate step. */
21
+ violations: readonly { seq: number | null; reason: string }[];
22
+ }
23
+
24
+ const STEP_EVENTS = new Set([
25
+ 'node-enter', 'node-exit', 'edge-taken', 'node-skipped',
26
+ 'node-added', 'edge-rerouted', 'unit-expanded', 'unit-collapsed',
27
+ 'pipeline-node-entry', 'pipeline-node-exit', 'graph-edge-taken',
28
+ ]);
29
+ const STRUCTURAL_EVENTS = new Set(['node-added', 'edge-rerouted', 'unit-expanded', 'unit-collapsed']);
30
+
31
+ function text(data: Record<string, unknown>, key: string): string | null {
32
+ const value = data[key];
33
+ return typeof value === 'string' && value.trim().length > 0 ? value : null;
34
+ }
35
+
36
+ function validSeq(value: unknown): value is number {
37
+ return typeof value === 'number' && Number.isSafeInteger(value) && value > 0;
38
+ }
39
+
40
+ function stepType(entry: RunLedgerEntry): string | null {
41
+ if (STEP_EVENTS.has(entry.event)) {
42
+ if (entry.event === 'pipeline-node-entry') return 'node-enter';
43
+ if (entry.event === 'pipeline-node-exit') return 'node-exit';
44
+ if (entry.event === 'graph-edge-taken') return 'edge-taken';
45
+ return entry.event;
46
+ }
47
+ if (entry.event === 'applied' && entry.data.op === 'add-node') return 'node-added';
48
+ if (entry.event === 'applied' && entry.data.op === 'reroute') return 'edge-rerouted';
49
+ if (entry.event === 'applied' && entry.data.op === 'zoom-in') return 'unit-expanded';
50
+ if (entry.event === 'applied' && entry.data.op === 'collapse') return 'unit-collapsed';
51
+ return null;
52
+ }
53
+
54
+ function projectStep(entry: RunLedgerEntry, type: string, seq: number): RunStep | string {
55
+ const data = entry.data;
56
+ const ts = entry.timestamp;
57
+ if (typeof ts !== 'string' || !Number.isFinite(Date.parse(ts))) return 'timestamp missing or invalid';
58
+ const node = text(data, 'node');
59
+ const condition = text(data, 'condition');
60
+ if (STRUCTURAL_EVENTS.has(type) && (!text(data, 'decider') || !text(data, 'reason'))) {
61
+ return 'structural change requires decider and reason';
62
+ }
63
+ switch (type) {
64
+ case 'node-enter': {
65
+ const visit = data.visit;
66
+ return node && validSeq(visit) ? { seq, ts, type, node, visit } : 'node-enter requires node and positive visit';
67
+ }
68
+ case 'node-exit': {
69
+ const outcome = text(data, 'outcome');
70
+ return node && outcome ? { seq, ts, type, node, outcome } : 'node-exit requires node and outcome';
71
+ }
72
+ case 'edge-taken': {
73
+ const from = text(data, 'from');
74
+ const to = text(data, 'taken') ?? text(data, 'to');
75
+ const via = text(data, 'via') ?? (entry.event === 'graph-edge-taken' ? data.source === 'graph' ? 'outcome' : 'fallback' : null);
76
+ return from && to && via ? { seq, ts, type, from, to, via, ...(condition ? { condition } : {}) } : 'edge-taken requires from, to and via';
77
+ }
78
+ case 'node-skipped': {
79
+ const reason = text(data, 'reason');
80
+ return node && reason ? { seq, ts, type, node, reason, ...(condition ? { condition } : {}) } : 'node-skipped requires node and reason';
81
+ }
82
+ case 'node-added': {
83
+ const kind = text(data, 'kind');
84
+ return node && kind ? { seq, ts, type, node, kind, decider: text(data, 'decider')!, reason: text(data, 'reason')!, ...(data.trigger === undefined ? {} : { trigger: data.trigger }), ...(data.undo === undefined ? {} : { undo: data.undo }) } : 'node-added requires node and kind';
85
+ }
86
+ case 'edge-rerouted': {
87
+ const from = text(data, 'from');
88
+ const outcome = text(data, 'outcome');
89
+ const to = text(data, 'to');
90
+ const was = text(data, 'was');
91
+ return from && outcome && to && was ? { seq, ts, type, from, outcome, to, was, decider: text(data, 'decider')!, reason: text(data, 'reason')! } : 'edge-rerouted requires from, outcome, to and was';
92
+ }
93
+ case 'unit-expanded': {
94
+ const unit = text(data, 'unit') ?? text(data, 'into');
95
+ const childRunId = text(data, 'childRunId');
96
+ const resolution = data.resolution;
97
+ return node && unit && childRunId && typeof resolution === 'number' && Number.isSafeInteger(resolution) && resolution >= 0
98
+ ? { seq, ts, type, node, unit, childRunId, resolution, decider: text(data, 'decider')!, reason: text(data, 'reason')! }
99
+ : 'unit-expanded requires node, unit, childRunId and resolution';
100
+ }
101
+ case 'unit-collapsed': {
102
+ const resolution = data.resolution;
103
+ return node && typeof resolution === 'number' && Number.isSafeInteger(resolution) && resolution >= 0
104
+ ? { seq, ts, type, node, resolution, decider: text(data, 'decider')!, reason: text(data, 'reason')! }
105
+ : 'unit-collapsed requires node and resolution';
106
+ }
107
+ default: return 'unrecognized step';
108
+ }
109
+ }
110
+
111
+ /** Pure projection of already-read JSONL records; never guesses a sequence from timestamps or line positions. */
112
+ export function projectRunLedgerSteps(runId: string, entries: readonly RunLedgerEntry[]): RunStepProjection {
113
+ const steps: RunStep[] = [];
114
+ const violations: { seq: number | null; reason: string }[] = [];
115
+ const seen = new Set<number>();
116
+ let graphId: string | null = null;
117
+ let version: string | null = null;
118
+ let variantHash: string | null = null;
119
+ for (const entry of entries) {
120
+ if (entry.runId !== runId) continue;
121
+ graphId = text(entry.data, 'graphId') ?? graphId;
122
+ version = text(entry.data, 'graphVersion') ?? version;
123
+ variantHash = text(entry.data, 'variantHash') ?? variantHash;
124
+ const type = stepType(entry);
125
+ if (!type) continue;
126
+ const topLevelSeq = (entry as RunLedgerEntry & { seq?: unknown }).seq;
127
+ const seq = topLevelSeq ?? entry.data.seq;
128
+ if (topLevelSeq !== undefined && entry.data.seq !== undefined && topLevelSeq !== entry.data.seq) {
129
+ violations.push({ seq: validSeq(topLevelSeq) ? topLevelSeq : null, reason: 'conflicting step seq' });
130
+ continue;
131
+ }
132
+ if (!validSeq(seq)) {
133
+ violations.push({ seq: null, reason: 'step requires positive safe-integer seq' });
134
+ continue;
135
+ }
136
+ if (seen.has(seq)) {
137
+ violations.push({ seq, reason: 'duplicate step seq' });
138
+ continue;
139
+ }
140
+ seen.add(seq);
141
+ const step = projectStep(entry, type, seq);
142
+ if (typeof step === 'string') violations.push({ seq, reason: step });
143
+ else steps.push(step);
144
+ }
145
+ steps.sort((a, b) => a.seq - b.seq);
146
+ return { runId, graph: { graphId, version, variantHash }, steps, complete: violations.length === 0, unreadable: violations.length, violations };
147
+ }
@@ -63,7 +63,7 @@ export function classifyMergeHoldStop(mergeReason: string | undefined): RunStopC
63
63
  const reason = mergeReason ?? '';
64
64
  if (reason.startsWith('main-sync') || reason === 'default-branch-unresolved') return 'main-sync';
65
65
  if (reason === 'required-evidence-uncovered') return 'evidence-uncovered';
66
- if (reason === 'review-must-fix' || reason.startsWith('review-budget')) return 'review-repeat';
66
+ if (reason === 'review-must-fix' || reason === 'review-warn-with-must-fix' || reason.startsWith('review-budget')) return 'review-repeat';
67
67
  if (reason.startsWith('review-diff') || reason === 'no-real-review') return 'review-out-of-scope';
68
68
  return 'unclassified';
69
69
  }
@@ -23,11 +23,12 @@ import { tmpdir } from 'node:os';
23
23
  import { isAbsolute, join, relative, resolve, sep } from 'node:path';
24
24
  import { promisify } from 'node:util';
25
25
  import { forkSessionById, HARNESS_SESSION_ORIGIN, isHarnessSessionOrigin } from '../session/index.js';
26
- import { configuredWorktreeRoot, getUserConfig, resolveRoleLlm } from '../user-config.js';
26
+ import { configuredWorktreeRoot, getUserConfig, resolveActiveProvider, resolveRoleLlm } from '../user-config.js';
27
27
  import { elanousStateRoot } from '../autopilot/state-paths.js';
28
28
  import { addHarnessQueue } from '../harness/harness-queue.js';
29
29
  import { readFollowUpMode } from './follow-up-goals.js';
30
- import { getProviderForConfig } from '../llm.js';
30
+ import { getProviderForConfig, NoLlmProviderAvailableError } from '../llm.js';
31
+ import { lookupLlmTierSpec } from '../model-tier/llm-tier-map.js';
31
32
  import { createWorktree, DEFAULT_BRANCH_WORKTREE_BASE, linkWorktreeDependencies, removeWorktree, resolveDefaultBranchBase, resolveMainRepoRoot } from '../git-fs/worktree.js';
32
33
  import { isWorktreeInUse, listActiveTerminalDirectories } from '../harness/harness-clean.js';
33
34
  import { readWorktreePorcelain } from './abandoned-classification.js';
@@ -198,7 +199,39 @@ export const SELF_IMPLEMENT_COMPLETION_REPORT_HINT = '자식이 최종 요약
198
199
 
199
200
  /** self-implement 실행 경계가 범용 brain에 전용 종료-보고 규칙을 주입한다. */
200
201
  export function createSelfImplementControlBrain(opts: Omit<LlmControlBrainOpts, 'systemHint'>) {
201
- return createLlmControlBrain({ ...opts, systemHint: SELF_IMPLEMENT_COMPLETION_REPORT_HINT });
202
+ // ⭐ 이 부모에 쓸 provider 가 «하나도» 없으면(NoLlmProviderAvailableError) BRAIN-FAST 이전처럼 «지연 해석»
203
+ // brain 을 돌려준다 — 생성 시점에 throw 하면 implement seam 전체가 자식을 띄우기도 전에 죽는다
204
+ // (0.2.23 게이트 회귀 · 자식 LLM 은 따로 정해질 수 있다). provider 결정은 decide 시점 streamLLM 이 다시 한다.
205
+ // ⛔ 다른 오류(예: provider 충돌)는 그대로 던진다.
206
+ const deferred = (error: unknown): ReturnType<typeof createLlmControlBrain> => {
207
+ if (!(error instanceof NoLlmProviderAvailableError)) throw error;
208
+ debug.log('self-implement', 'brain.model', { provider: null, model: opts.model ?? null, source: 'unresolved-deferred' }, { level: 'warn' });
209
+ return createLlmControlBrain({ ...opts, systemHint: SELF_IMPLEMENT_COMPLETION_REPORT_HINT });
210
+ };
211
+ let role: ReturnType<typeof resolveRoleLlm>;
212
+ try {
213
+ role = resolveRoleLlm('classify');
214
+ } catch (error) {
215
+ return deferred(error);
216
+ }
217
+ const explicit = role.source === 'flag' || role.source === 'config-role';
218
+ if (!opts.model && opts.provider && explicit && opts.provider !== role.provider) {
219
+ throw new Error(`brain provider conflict: caller=${opts.provider}, classify=${role.provider}`);
220
+ }
221
+ let provider: ReturnType<typeof resolveActiveProvider>;
222
+ try {
223
+ provider = opts.model ? (opts.provider ?? resolveActiveProvider(getUserConfig()))
224
+ : explicit ? role.provider : (opts.provider ?? resolveActiveProvider(getUserConfig()));
225
+ } catch (error) {
226
+ return deferred(error);
227
+ }
228
+ const budget = !opts.model && !explicit ? lookupLlmTierSpec(provider, 'budget') : undefined;
229
+ const model = opts.model ?? (explicit ? role.model : budget!.model);
230
+ const source = opts.model ? 'caller' : explicit ? role.source : 'tier-budget';
231
+ debug.log('self-implement', 'brain.model', { provider, model, source });
232
+ return createLlmControlBrain({ ...opts, model, provider,
233
+ ...(budget?.reasoningLevel ? { reasoningLevel: budget.reasoningLevel } : {}),
234
+ systemHint: SELF_IMPLEMENT_COMPLETION_REPORT_HINT });
202
235
  }
203
236
 
204
237
  function git(cwd: string, argv: string[]): { ok: boolean; out: string; stdout: string } {
@@ -986,7 +1019,7 @@ export interface DefaultSeamsOptions {
986
1019
  runAndroidUnitTestGate?: (io: { args: readonly string[]; cwd: string }) => number;
987
1020
  runIosUnitTestGate?: (io: { args: readonly string[]; cwd: string }) => number;
988
1021
  /** Source-policy gate adapter for focused seam tests. */
989
- runHarnessPolicyGates?: typeof runHarnessPolicyGates;
1022
+ runHarnessPolicyGates?: (input: Parameters<typeof runHarnessPolicyGates>[0]) => Awaited<ReturnType<typeof runHarnessPolicyGates>> | ReturnType<typeof runHarnessPolicyGates>;
990
1023
  runExposeGate?: typeof runExposeGate;
991
1024
  /** Dependency-wide validation adapter for focused seam tests. */
992
1025
  runDependencyChangeGate?: typeof runDependencyChangeGate;
@@ -1020,6 +1053,8 @@ export interface DefaultSeamsOptions {
1020
1053
  * agent-substrate·staged 하니스와 동일 엔진) 배선. 미주입 시 reviewDiff 미노출(gate 통과=바로 병합결정·
1021
1054
  * 리뷰 스킵). dev-harness 의 llmReview 와 동일 형태(streamLLM 래퍼). */
1022
1055
  llmReview?: (prompt: string) => Promise<string>;
1056
+ /** Optional independent reviewer for reviewDiff only; other judgment calls retain llmReview. */
1057
+ subscriptionReviewLLM?: (prompt: string) => Promise<string>;
1023
1058
  /**
1024
1059
  * 이 리뷰 심이 파일을 스스로 읽을 수 있나. **선택 선언** — 안 주면 reviewDiff 가 칸을 만들지 않고
1025
1060
  * 오케스트레이터 관측은 `'unknown'` 이다(`false` 와 같은 값으로 접지 않는다).
@@ -2073,7 +2108,7 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
2073
2108
  // tsc-깨짐(F1 refFacts 미정의)을 결정론 차단. 변경 전체(.ts·테스트 포함)를 tsc 로 검사(변경 경로만 카운트).
2074
2109
  const tc = changedFileTypecheck(cwd, changedAll);
2075
2110
  debug.log('self-implement', 'gate.tsc', { checked: tc.checked, passed: tc.passed, errors: tc.errors, exempted: tc.exempted, noInspectionReason: tc.noInspectionReason }, { level: tc.passed ? 'info' : 'warn' });
2076
- const policy = (o.runHarnessPolicyGates ?? runHarnessPolicyGates)({ cwd, changedFiles: changedAll });
2111
+ const policy = await (o.runHarnessPolicyGates ?? runHarnessPolicyGates)({ cwd, changedFiles: changedAll });
2077
2112
  debug.log('self-implement', 'gate.policy', {
2078
2113
  passed: policy.passed, failures: policy.failures.map((failure) => failure.gate), skipped: policy.skipped,
2079
2114
  });
@@ -2530,7 +2565,7 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
2530
2565
  ...(ctx.round !== undefined ? { round: ctx.round } : {}),
2531
2566
  },
2532
2567
  } : {}),
2533
- }, o.llmReview!);
2568
+ }, o.subscriptionReviewLLM ?? o.llmReview!);
2534
2569
  debug.log('self-implement', 'review.done', {
2535
2570
  verdict: rr.verdict, reviewed: rr.reviewed ?? false, mustFix: rr.mustFix.length, shouldFix: rr.shouldFix.length,
2536
2571
  gateEvidenceLines: evidenceNote?.split(/\r?\n/).length ?? 0,
@@ -111,6 +111,7 @@ export function singleRunAsJobResult(feature: string, r: SelfImplementResultWith
111
111
  ...(r.harvestable === true && r.branch ? { harvestable: true } : {}),
112
112
  ...(r.worktreePath ? { worktreePath: r.worktreePath } : {}),
113
113
  ...(r.prUrl ? { prUrl: r.prUrl } : {}),
114
+ ...(r.prNumber !== undefined ? { prNumber: r.prNumber } : {}),
114
115
  // TA-LIVE-REVIEW-POD — 작업 트리 없는 런(Pod)의 live review 가 «런이 낸 PR 머리»를 확인하는 근거.
115
116
  ...(r.checkedHeadCommit !== undefined ? { checkedHeadCommit: r.checkedHeadCommit } : {}),
116
117
  ...(r.merged !== undefined ? { merged: r.merged } : {}),
@@ -121,6 +122,11 @@ export function singleRunAsJobResult(feature: string, r: SelfImplementResultWith
121
122
  ...(r.decomposeProposal ? { decomposeProposal: r.decomposeProposal } : {}),
122
123
  ...(r.goalPlanRevision ? { goalPlanRevision: r.goalPlanRevision } : {}),
123
124
  ...(r.salvage !== undefined ? { salvage: r.salvage } : {}),
125
+ ...(r.review?.reviewed === true && r.review.verdict === 'pass'
126
+ && r.reviewedHeadCommit && /^[0-9a-f]{40}$/i.test(r.reviewedHeadCommit)
127
+ ? { selfReview: { verdict: r.review.verdict, head: r.reviewedHeadCommit,
128
+ // TA-LAND-MUSTFIX-ZERO — must-fix 수를 같이 나른다(목록이 없으면 «모름» = 안 싣는다 · land 관문이 막는다).
129
+ ...(Array.isArray(r.review.mustFix) && r.review.mustFix.every((fix) => typeof fix === 'string') ? { mustFixCount: r.review.mustFix.length } : {}) } } : {}),
124
130
  ...(r.review?.reviewed !== undefined ? { reviewed: r.review.reviewed } : {}),
125
131
  ...(r.review?.failureReason !== undefined ? { reviewReason: r.review.failureReason } : {}),
126
132
  // ⭐ 대표 지시(2026-09-08) — 걸음을 슈퍼바이저까지 나른다.
@@ -0,0 +1,158 @@
1
+ /** LAND-QUEUE-P3 — the merge train's integration gate (changed-file tsc · changed tests · PWA reach/build) for ONE
2
+ * integration commit, run only on the gate host (node-b) through the GATE-REMOTE path (`runOnRemote`).
3
+ * Unlike `dispatchHeavyCheck` it never falls back to a local run: a busy host or an infra failure is «unmeasured».
4
+ * The only local commands are git (cat-file · rev-parse · push · diff). */
5
+ import { debug } from '../debug/log.js';
6
+ import { getDefaultLogStore } from '../mss/logging/log-store.js';
7
+ import {
8
+ realGateRemoteRunner, resolveGateRemoteSettings, runOnRemote,
9
+ type GateRemoteRunner, type GateRemoteSettings, type RemoteRunOutcome,
10
+ } from './gate-remote.js';
11
+
12
+ export type TrainGateOutcome = 'pass' | 'fail' | 'unmeasured';
13
+
14
+ export interface TrainGateInput {
15
+ repo: string;
16
+ /** The integration commit (40-char sha, present locally — need not be checked out). */
17
+ commit: string;
18
+ /** The base the changed-file checks measure against (TSC_BASE_REF). */
19
+ baseSha: string;
20
+ /** Repo-relative changed paths of the integration commit vs baseSha. */
21
+ changedFiles: readonly string[];
22
+ /** Paths deleted by the integration commit — kept in `changedFiles` for tsc/PWA reach, never run as tests. */
23
+ deletedFiles?: readonly string[];
24
+ settings?: GateRemoteSettings;
25
+ }
26
+
27
+ export interface TrainGateResult { outcome: TrainGateOutcome; host: string; ms?: number; rc?: number; reason?: string }
28
+
29
+ export interface TrainGateObservation {
30
+ host: string; commit: string; baseSha: string; outcome: TrainGateOutcome;
31
+ rc?: number; ms?: number; reason?: string; changedFiles: number;
32
+ }
33
+
34
+ export interface TrainGateDeps {
35
+ sleep?: (ms: number) => Promise<void>;
36
+ now?: () => number;
37
+ /** Observation sink (default: category `merge-queue` in the log store, so a standalone CLI records it too). */
38
+ observe?: (entry: TrainGateObservation) => void;
39
+ }
40
+
41
+ const quote = (value: string) => `'${value.replaceAll("'", `'\\''`)}'`;
42
+ const TEST_FILE = /\.test\.[cm]?[jt]sx?$/;
43
+
44
+ /** The host-side shell body: each step runs only if the one before it passed. Exported for tests. */
45
+ export function trainGateScript(baseSha: string, changedFiles: readonly string[], deleted: ReadonlySet<string> = new Set()): string {
46
+ // A deleted test file is a changed path (tsc/PWA reach) but not something to run.
47
+ const tests = changedFiles.filter((file) => TEST_FILE.test(file) && !deleted.has(file));
48
+ const steps = [
49
+ `TSC_BASE_REF=${quote(baseSha)} bun scripts/ci-typecheck-changed.ts --local`,
50
+ ...(tests.length ? [`bun run test:deterministic ${tests.map(quote).join(' ')}`] : []),
51
+ `bun scripts/ci-pwa-build-gate.ts --changed-files ${changedFiles.map(quote).join(' ')}`,
52
+ ];
53
+ return steps.join(' && ');
54
+ }
55
+
56
+ async function loadSettings(): Promise<GateRemoteSettings> {
57
+ try {
58
+ const { getUserConfig } = await import('../user-config.js');
59
+ return resolveGateRemoteSettings(getUserConfig().gateRemote);
60
+ } catch { return resolveGateRemoteSettings(undefined); }
61
+ }
62
+
63
+ function defaultObserve(entry: TrainGateObservation): void {
64
+ const store = getDefaultLogStore();
65
+ if (!store) return;
66
+ store.insertBatch([{ rec: { ts: new Date().toISOString(), category: 'merge-queue', event: 'train-gate', data: entry }, surface: 'merge-queue' }]);
67
+ }
68
+
69
+ /** The integration gate runs only on the gate host (LAND-QUEUE-P3 · review must-fix): another configured host is «unmeasured». */
70
+ export const TRAIN_GATE_HOST = 'node-b';
71
+
72
+ export async function runTrainGateOnHost(input: TrainGateInput, runner: GateRemoteRunner = realGateRemoteRunner, deps: TrainGateDeps = {}): Promise<TrainGateResult> {
73
+ const settings = input.settings ?? await loadSettings();
74
+ const host = settings.host;
75
+ if (host !== TRAIN_GATE_HOST) {
76
+ const entry: TrainGateObservation = { host, commit: input.commit, baseSha: input.baseSha, outcome: 'unmeasured', reason: `host-not-gate-host (${host} ≠ ${TRAIN_GATE_HOST})`, changedFiles: input.changedFiles.length };
77
+ debug.log('merge-queue', 'train-gate', entry);
78
+ try { (deps.observe ?? defaultObserve)(entry); } catch { /* observation only */ }
79
+ return { outcome: 'unmeasured', host, reason: entry.reason };
80
+ }
81
+ const sleep = deps.sleep ?? ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)));
82
+ const now = deps.now ?? Date.now;
83
+ const deadline = now() + settings.slotWaitSeconds * 1000;
84
+ const script = trainGateScript(input.baseSha, input.changedFiles, new Set(input.deletedFiles ?? []));
85
+ let outcome: RemoteRunOutcome;
86
+ for (;;) {
87
+ try {
88
+ outcome = runOnRemote({
89
+ repo: input.repo, host, mirror: settings.mirror, commit: input.commit, refs: [input.baseSha],
90
+ argv: ['sh', '-c', script], installPwa: true, hostCap: settings.hostCap,
91
+ }, runner);
92
+ } catch (error) {
93
+ outcome = { kind: 'infra', reason: `exception: ${error instanceof Error ? error.message : String(error)}` };
94
+ }
95
+ if (outcome.kind !== 'busy') break;
96
+ const left = deadline - now();
97
+ if (left <= 0) break;
98
+ await sleep(Math.min(15_000, left));
99
+ if (now() >= deadline) break;
100
+ }
101
+ const result: TrainGateResult = outcome.kind === 'ran'
102
+ ? { outcome: outcome.rc === 0 ? 'pass' : 'fail', host, ms: outcome.ms, rc: outcome.rc }
103
+ : { outcome: 'unmeasured', host, reason: outcome.kind === 'busy' ? `host-busy (cap ${settings.hostCap} held for ${settings.slotWaitSeconds}s)` : outcome.reason };
104
+ const entry: TrainGateObservation = {
105
+ host, commit: input.commit, baseSha: input.baseSha, outcome: result.outcome,
106
+ rc: result.rc, ms: result.ms, reason: result.reason, changedFiles: input.changedFiles.length,
107
+ };
108
+ debug.log('merge-queue', 'train-gate', entry);
109
+ try { (deps.observe ?? defaultObserve)(entry); } catch (error) {
110
+ debug.log('merge-queue', 'train-gate-observe-failed', { error: error instanceof Error ? error.message : String(error) });
111
+ }
112
+ return result;
113
+ }
114
+
115
+ /** The merge train's `gate` seam: `(commitSha, prNumbers) → 'pass' | 'fail' | 'unmeasured'`. Changed files are the
116
+ * integration commit's diff against `baseSha` (local git only); a diff failure is «unmeasured», never a local run. */
117
+ export type TrainGate = (commitSha: string, prNumbers: readonly number[]) => Promise<TrainGateOutcome>;
118
+
119
+ export function trainGateOnHost(opts: { repo: string; baseSha: string; settings?: GateRemoteSettings }, runner: GateRemoteRunner = realGateRemoteRunner, deps: TrainGateDeps = {}): TrainGate {
120
+ const unmeasured = (commitSha: string, reason: string): 'unmeasured' => {
121
+ const entry: TrainGateObservation = { host: opts.settings?.host ?? TRAIN_GATE_HOST, commit: commitSha, baseSha: opts.baseSha, outcome: 'unmeasured', reason, changedFiles: 0 };
122
+ debug.log('merge-queue', 'train-gate', entry);
123
+ try { (deps.observe ?? defaultObserve)(entry); } catch { /* observation only */ }
124
+ return 'unmeasured';
125
+ };
126
+ return async (commitSha) => {
127
+ try {
128
+ const diff = runner.local('git', ['diff', '--name-status', '-z', opts.baseSha, commitSha], opts.repo);
129
+ if (diff.rc !== 0 || diff.error) return unmeasured(commitSha, 'changed-files-unavailable');
130
+ const { changedFiles, deletedFiles } = parseNameStatus(diff.stdout);
131
+ return (await runTrainGateOnHost({ repo: opts.repo, commit: commitSha, baseSha: opts.baseSha, changedFiles, deletedFiles, settings: opts.settings }, runner, deps)).outcome;
132
+ } catch (error) {
133
+ // Any preparation failure (local git spawn, parse, settings) is «unmeasured» — never a rejected promise, never a local run.
134
+ return unmeasured(commitSha, `prepare-failed: ${error instanceof Error ? error.message : String(error)}`.slice(0, 200));
135
+ }
136
+ };
137
+ }
138
+
139
+ /** `git diff --name-status -z` → changed paths (renames contribute both sides) ⊕ deleted paths. Exported for tests. */
140
+ export function parseNameStatus(out: string): { changedFiles: string[]; deletedFiles: string[] } {
141
+ const parts = out.split('\0').filter((part) => part !== '');
142
+ const changed: string[] = [];
143
+ const deleted: string[] = [];
144
+ for (let i = 0; i < parts.length;) {
145
+ const status = parts[i++]!;
146
+ if (/^[RC]/.test(status)) {
147
+ const from = parts[i++]; const to = parts[i++];
148
+ if (from) { changed.push(from); if (status.startsWith('R')) deleted.push(from); }
149
+ if (to) changed.push(to);
150
+ } else {
151
+ const path = parts[i++];
152
+ if (!path) break;
153
+ changed.push(path);
154
+ if (status === 'D') deleted.push(path);
155
+ }
156
+ }
157
+ return { changedFiles: [...new Set(changed)], deletedFiles: [...new Set(deleted)] };
158
+ }
@@ -365,6 +365,15 @@ const SESSION_TOOL_FAMILY_RULES: SessionToolFamilyRule[] = [
365
365
  '왜 실패', '기억', '회상', '알림', '이상 없', '뭐 돌', '뭐 하는 중',
366
366
  ]),
367
367
  },
368
+ {
369
+ id: 'release-read',
370
+ description: 'Read-only release status, features, cells, schedules, and current operations.',
371
+ names: ['release_status', 'context_now'],
372
+ match: (text) => hasAny(text, [
373
+ 'release', 'version', 'checklist', '발행', '버전', '릴리스', '피처',
374
+ '체크리스트', '칸', '컷', '일정', '판올림', '다음 판', '이번 판', '운영 상태',
375
+ ]),
376
+ },
368
377
  {
369
378
  id: 'runtime-debug',
370
379
  description: 'Runtime inspection, traces, and input/debug history.',
@@ -1721,7 +1730,7 @@ const ESSENTIAL_NATIVE_RULE_IDS = [
1721
1730
  // Keep dev-harness in the assembly candidate set so the catalog policy below is the single model-exposure authority.
1722
1731
  'agent', 'agent-output', 'agent-reply', 'agent-stop', 'agent-list', 'self-implement', 'self-orchestrate', 'dev-harness',
1723
1732
  ] as const;
1724
- const ESSENTIAL_HOST_FAMILY_IDS = ['self-ops'] as const;
1733
+ const ESSENTIAL_HOST_FAMILY_IDS = ['self-ops', 'release-read'] as const;
1725
1734
  const ESSENTIAL_RUNTIME_FAMILY_IDS = ['bash', 'run-shell', 'pty-shell', 'run-tests', 'elanous_skills_list', 'skill_exec', 'code-grounding'] as const;
1726
1735
  const ESSENTIAL_OPTIONAL_TOOL_NAMES = [
1727
1736
  'GetDashboardState',
@@ -80,6 +80,9 @@ export interface FetchApiWithRetryOpts {
80
80
  /** Fallbacks still unused. When > 0, k consecutive overload-class
81
81
  * failures throw OverloadFailoverError before another retry sleep. */
82
82
  remainingFallbacks?: number;
83
+ /** BEDROCK-PROVIDER — 재시도 «직전»마다 요청을 다시 만든다(SigV4 서명은 `x-amz-date` 기준 수 분만 유효 —
84
+ * `retry-after` 대기가 길면 옛 서명은 403). 없으면 종전처럼 같은 `init` 을 다시 쓴다(다른 provider 불변). */
85
+ refreshInit?: () => Promise<RequestInit>;
83
86
  }
84
87
 
85
88
  /** Raised when overload repeats k times and a fallback is still unused.
@@ -128,6 +131,8 @@ export async function fetchApiWithRetry(
128
131
  let lastErr: unknown;
129
132
  while (attempt < maxAttempts) {
130
133
  let response: Response | null = null;
134
+ // ⛔ try «밖» — 재서명 실패(자격 부재 등)는 재시도할 네트워크 오류가 아니다. 그대로 던진다.
135
+ if (attempt > 0 && opts.refreshInit) init = await opts.refreshInit();
131
136
  try {
132
137
  response = await fetch(url, init);
133
138
  if (response.ok) {
@@ -179,7 +184,12 @@ export async function fetchApiWithRetry(
179
184
  const fp = fingerprintError(err, `api:${opts.provider}`);
180
185
  const doomStatus = tracker.record(fp);
181
186
  const retryAfter = err instanceof ApiHttpError ? err.retryAfter : undefined;
182
- const decision = decideRetry(err, {
187
+ // OpenRouter may report an upstream transient as a non-5xx HTTP status.
188
+ // Keep the original status/error for callers, but classify this specific body as retryable.
189
+ const policyError = opts.provider === 'openrouter' && err instanceof ApiHttpError
190
+ && /Provider returned error/i.test(err.bodyText)
191
+ ? Object.assign(new Error(err.message), { code: '503' }) : err;
192
+ const decision = decideRetry(policyError, {
183
193
  attempt,
184
194
  doomStatus,
185
195
  retryAfter,