elanous 0.2.22 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (705) hide show
  1. package/NOTICE +7 -0
  2. package/README.md +32 -22
  3. package/apps/pwa/out/404/index.html +1 -1
  4. package/apps/pwa/out/404.html +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
  9. package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
  11. package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
  12. package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
  21. package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
  23. package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
  24. package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
  27. package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/272-b23d2e92161d11fd.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
  35. package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3961-fbef064c213b2b18.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
  39. package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
  52. package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
  53. package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
  56. package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
  59. package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
  64. package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
  69. package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
  71. package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
  73. package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
  74. package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
  78. package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
  83. package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
  84. package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
  85. package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
  86. package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
  87. package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
  90. package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
  97. package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
  99. package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
  101. package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
  105. package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
  110. package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
  111. package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
  112. package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
  114. package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
  116. package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
  117. package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
  120. package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
  123. package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5341ac96203a983.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ad3bd8084048bee4.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/{page-80ed511e02c81412.js → page-6168a7c43e6ef8f5.js} +1 -1
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-a648bc464c9dc754.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-2bd9ce9c020d02d4.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-48fb31810693c357.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/page-cb154acadb025414.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-745d9b6c015076f8.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
  184. package/apps/pwa/out/_next/static/css/5619d59e87eddf66.css +1 -0
  185. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
  186. package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_buildManifest.js +1 -1
  187. package/apps/pwa/out/approvals/index.html +1 -1
  188. package/apps/pwa/out/approvals/index.txt +23 -23
  189. package/apps/pwa/out/autopilot/index.html +1 -1
  190. package/apps/pwa/out/autopilot/index.txt +23 -23
  191. package/apps/pwa/out/board/index.html +1 -1
  192. package/apps/pwa/out/board/index.txt +23 -23
  193. package/apps/pwa/out/botlab/index.html +1 -1
  194. package/apps/pwa/out/botlab/index.txt +22 -22
  195. package/apps/pwa/out/bots/index.html +1 -1
  196. package/apps/pwa/out/bots/index.txt +22 -22
  197. package/apps/pwa/out/ceo/index.html +1 -1
  198. package/apps/pwa/out/ceo/index.txt +23 -23
  199. package/apps/pwa/out/chat/index.html +1 -1
  200. package/apps/pwa/out/chat/index.txt +22 -22
  201. package/apps/pwa/out/consult/index.html +1 -1
  202. package/apps/pwa/out/consult/index.txt +23 -23
  203. package/apps/pwa/out/control/index.html +1 -1
  204. package/apps/pwa/out/control/index.txt +23 -23
  205. package/apps/pwa/out/decisions/index.html +1 -1
  206. package/apps/pwa/out/decisions/index.txt +22 -22
  207. package/apps/pwa/out/design-check/index.html +1 -1
  208. package/apps/pwa/out/design-check/index.txt +23 -23
  209. package/apps/pwa/out/editor/index.html +1 -1
  210. package/apps/pwa/out/editor/index.txt +24 -23
  211. package/apps/pwa/out/exec/index.html +1 -1
  212. package/apps/pwa/out/exec/index.txt +23 -23
  213. package/apps/pwa/out/field/index.html +1 -1
  214. package/apps/pwa/out/field/index.txt +23 -23
  215. package/apps/pwa/out/healthz +1 -1
  216. package/apps/pwa/out/index.html +1 -1
  217. package/apps/pwa/out/index.txt +22 -22
  218. package/apps/pwa/out/inside/index.html +1 -1
  219. package/apps/pwa/out/inside/index.txt +22 -22
  220. package/apps/pwa/out/intake/index.html +1 -1
  221. package/apps/pwa/out/intake/index.txt +23 -23
  222. package/apps/pwa/out/live/index.html +1 -1
  223. package/apps/pwa/out/live/index.txt +23 -23
  224. package/apps/pwa/out/live-run/index.html +1 -1
  225. package/apps/pwa/out/live-run/index.txt +24 -23
  226. package/apps/pwa/out/loops/index.html +1 -1
  227. package/apps/pwa/out/loops/index.txt +22 -22
  228. package/apps/pwa/out/market/index.html +1 -1
  229. package/apps/pwa/out/market/index.txt +22 -22
  230. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  231. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  232. package/apps/pwa/out/morning/index.html +1 -1
  233. package/apps/pwa/out/morning/index.txt +23 -23
  234. package/apps/pwa/out/observatory/index.html +1 -1
  235. package/apps/pwa/out/observatory/index.txt +23 -23
  236. package/apps/pwa/out/ops/checklist/index.html +1 -1
  237. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  238. package/apps/pwa/out/ops/release/index.html +1 -1
  239. package/apps/pwa/out/ops/release/index.txt +22 -22
  240. package/apps/pwa/out/ops/seats/index.html +1 -1
  241. package/apps/pwa/out/ops/seats/index.txt +22 -22
  242. package/apps/pwa/out/outputs/index.html +1 -1
  243. package/apps/pwa/out/outputs/index.txt +22 -22
  244. package/apps/pwa/out/reflection/index.html +1 -1
  245. package/apps/pwa/out/reflection/index.txt +23 -23
  246. package/apps/pwa/out/scheduler/index.html +1 -1
  247. package/apps/pwa/out/scheduler/index.txt +23 -23
  248. package/apps/pwa/out/sessions/index.html +1 -1
  249. package/apps/pwa/out/sessions/index.txt +22 -22
  250. package/apps/pwa/out/settings/devices/index.html +1 -1
  251. package/apps/pwa/out/settings/devices/index.txt +23 -23
  252. package/apps/pwa/out/settings/index.html +1 -1
  253. package/apps/pwa/out/settings/index.txt +23 -23
  254. package/apps/pwa/out/setup/done/index.html +1 -1
  255. package/apps/pwa/out/setup/done/index.txt +23 -23
  256. package/apps/pwa/out/setup/index.html +1 -1
  257. package/apps/pwa/out/setup/index.txt +23 -23
  258. package/apps/pwa/out/share/index.html +1 -1
  259. package/apps/pwa/out/share/index.txt +23 -23
  260. package/apps/pwa/out/showroom/index.html +1 -1
  261. package/apps/pwa/out/showroom/index.txt +22 -22
  262. package/apps/pwa/out/tasks/index.html +1 -1
  263. package/apps/pwa/out/tasks/index.txt +23 -23
  264. package/apps/pwa/out/term/index.html +1 -1
  265. package/apps/pwa/out/term/index.txt +23 -23
  266. package/apps/pwa/out/today/index.html +1 -1
  267. package/apps/pwa/out/today/index.txt +23 -23
  268. package/apps/pwa/out/trace/index.html +1 -1
  269. package/apps/pwa/out/trace/index.txt +23 -23
  270. package/apps/pwa/out/vault/index.html +1 -1
  271. package/apps/pwa/out/vault/index.txt +23 -23
  272. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  273. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  274. package/apps/pwa/out/workflows/index.html +1 -1
  275. package/apps/pwa/out/workflows/index.txt +23 -23
  276. package/apps/pwa/out/workspace/index.html +1 -1
  277. package/apps/pwa/out/workspace/index.txt +23 -23
  278. package/apps/pwa/out/worktrees/index.html +1 -1
  279. package/apps/pwa/out/worktrees/index.txt +23 -23
  280. package/catalog/models/anthropic/claude-haiku-5-5.yaml +32 -0
  281. package/catalog/models/anthropic/claude-opus-5-5.yaml +5 -0
  282. package/catalog/models/anthropic/claude-sonnet-5-5.yaml +31 -0
  283. package/catalog/models/anthropic/claude-sonnet-5.yaml +8 -2
  284. package/catalog/models/openai/gpt-6-astra.yaml +6 -0
  285. package/catalog/models/openai/gpt-6-luna.yaml +6 -0
  286. package/catalog/models/openai/gpt-6-sol.yaml +6 -0
  287. package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
  288. package/graphs/log-horizon/recipes.yaml +3 -0
  289. package/graphs/release/recipes.yaml +1 -1
  290. package/graphs/release/release-loop.yaml +6 -2
  291. package/graphs/release-rehearsal/recipes.yaml +12 -0
  292. package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
  293. package/package.json +4 -1
  294. package/scripts/bench-report.ts +82 -3
  295. package/scripts/ci-typecheck-changed.ts +10 -1
  296. package/scripts/hq/hq-fence-wrapper.sh +148 -0
  297. package/scripts/lib/typecheck-ratchet.ts +51 -0
  298. package/scripts/openai-relay-server.ts +5 -1
  299. package/scripts/release-loop/docs-node.ts +258 -43
  300. package/scripts/release-loop/gate-method.ts +59 -0
  301. package/scripts/release-loop/gate-node.ts +73 -7
  302. package/scripts/release-loop/gate-wall.ts +208 -0
  303. package/scripts/release-loop/known-issues-node.ts +53 -8
  304. package/scripts/release-loop/publish-at.ts +14 -0
  305. package/scripts/release-loop/publish-node.ts +17 -2
  306. package/scripts/release-loop/resume-release.ts +34 -4
  307. package/scripts/release-loop/resume.ts +53 -0
  308. package/scripts/release-loop/shard-plan.ts +3 -11
  309. package/scripts/release-loop/tui-node-checks.ts +22 -0
  310. package/scripts/release-loop/unattended-release.ts +8 -1
  311. package/scripts/rhythm/daily.ts +51 -2
  312. package/scripts/rhythm/weekly.ts +3 -2
  313. package/scripts/tsc-main-safety-net.ts +189 -0
  314. package/scripts/usage-rollup.ts +8 -4
  315. package/src/acp/codex-plugins.ts +48 -6
  316. package/src/agent/monad-agent-turn.ts +67 -5
  317. package/src/agent/run-context.ts +10 -0
  318. package/src/agent/tool-profile.ts +28 -2
  319. package/src/agent-mission/acp-judge.ts +8 -2
  320. package/src/agent-mission/capabilities-cli.ts +16 -1
  321. package/src/agent-mission/driver.ts +1 -1
  322. package/src/agent-mission/pr-review-watch.ts +6 -2
  323. package/src/agent-mission/review-loop.ts +33 -5
  324. package/src/agent-substrate/acp-reviewer.ts +17 -8
  325. package/src/agent-substrate/pr-reviewer.ts +164 -28
  326. package/src/agent-substrate/review-intent.ts +6 -4
  327. package/src/agent-substrate/self-review-cli.ts +111 -16
  328. package/src/agent-substrate/shard-boundary-intent.ts +92 -26
  329. package/src/ask-user-question/pending-questions.ts +8 -2
  330. package/src/autopilot/build/llm-conflict-merge.ts +216 -12
  331. package/src/autopilot/codebase-grounding.ts +44 -0
  332. package/src/autopilot/llm-control-brain.ts +13 -1
  333. package/src/autopilot/mission-codebase-gate.ts +8 -77
  334. package/src/autopilot/pr-manager.ts +12 -3
  335. package/src/boot/acp-server.ts +4 -7
  336. package/src/boot/acp-socket-path.ts +7 -0
  337. package/src/briefing/brief-items.ts +21 -13
  338. package/src/chat/index.ts +12 -3
  339. package/src/cli/agent-cli.ts +20 -0
  340. package/src/cli/brief-cli.ts +27 -21
  341. package/src/cli/cli-user-error.ts +9 -2
  342. package/src/cli/log-event-names.ts +3 -0
  343. package/src/cli/logs-cli.ts +1 -0
  344. package/src/cli/mcp-login.ts +111 -37
  345. package/src/cli/plugin-cli.ts +21 -1
  346. package/src/cli/pod-cli.ts +26 -0
  347. package/src/cli/pr-cli.ts +30 -2
  348. package/src/cli/pr-land-overlap-evidence.ts +131 -0
  349. package/src/cli/release-cli.ts +53 -11
  350. package/src/cli/self-update.ts +173 -10
  351. package/src/cli/skills-cli.ts +12 -3
  352. package/src/cli/tasks-cli.ts +133 -27
  353. package/src/context-bus/context-first.ts +51 -2
  354. package/src/context-bus/context-now-surfaces.ts +13 -2
  355. package/src/context-bus/long-term-memory.ts +3 -1
  356. package/src/context-bus/nightly-condense.ts +3 -2
  357. package/src/core-turn/run-goal-loop.ts +86 -2
  358. package/src/dashboard/chat-fold.ts +20 -0
  359. package/src/dashboard/first-screen-band.ts +151 -1
  360. package/src/dashboard/index.ts +27 -5
  361. package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -3
  362. package/src/dashboard/stale-install-check.ts +13 -2
  363. package/src/dashboard/turn-stream-formatter.ts +25 -0
  364. package/src/debug/log-diet.ts +159 -0
  365. package/src/debug/log.ts +52 -17
  366. package/src/display/coordinator.ts +25 -2
  367. package/src/domains/coo-admin-tool.ts +27 -0
  368. package/src/domains/cron-match.ts +1 -0
  369. package/src/domains/outbound-alert.ts +17 -6
  370. package/src/domains/release-tool.ts +119 -10
  371. package/src/domains/schedule-registry.ts +10 -7
  372. package/src/domains/schedule-runner.ts +1 -0
  373. package/src/elanous-config-dir.ts +2 -2
  374. package/src/elanous-daemon.ts +3 -3
  375. package/src/execution-loop/launch-gate.ts +1 -1
  376. package/src/expression/i18n/messages.en.ts +5 -0
  377. package/src/expression/i18n/messages.ja.ts +5 -0
  378. package/src/expression/i18n/messages.ko.ts +5 -0
  379. package/src/expression/i18n/messages.zh.ts +5 -0
  380. package/src/expression/i18n/types.ts +8 -0
  381. package/src/github/pr-labels.ts +1 -0
  382. package/src/graph-runner/runner.ts +54 -5
  383. package/src/harness/dispatch-backpressure.ts +259 -0
  384. package/src/harness/harness-cli-command.ts +107 -28
  385. package/src/harness/harness-seams.ts +2 -20
  386. package/src/harness/harness-substrate-default.ts +72 -1
  387. package/src/harness/nested-elanous-policy.ts +4 -2
  388. package/src/hq/fence-wrapper.ts +7 -0
  389. package/src/hq/hq.ts +33 -2
  390. package/src/hq/lease.ts +13 -0
  391. package/src/hq/seats.ts +114 -18
  392. package/src/index.ts +163 -64
  393. package/src/intake-plane/collect-github.ts +19 -1
  394. package/src/intake-plane/digest.ts +45 -20
  395. package/src/intake-plane/lens.ts +36 -8
  396. package/src/intelligence-map/model-alias.ts +6 -0
  397. package/src/intelligence-map/model-catalog.ts +41 -0
  398. package/src/knowledge/kgs/pack.ts +5 -2
  399. package/src/knowledge/kgs/sqlite-store.ts +15 -0
  400. package/src/knowledge/tools/knowledge-query.ts +20 -2
  401. package/src/knowledge/write.ts +234 -2
  402. package/src/llm/bedrock-provider.ts +175 -0
  403. package/src/llm/bedrock.ts +345 -0
  404. package/src/llm/provider-credentials.ts +3 -1
  405. package/src/llm.ts +306 -35
  406. package/src/loops/budget.ts +150 -0
  407. package/src/loops/orchestrator/seat-share.ts +6 -49
  408. package/src/loops/orchestrator/traffic.ts +5 -81
  409. package/src/market/signed-index.ts +42 -0
  410. package/src/mcp/mcp-oauth.ts +136 -17
  411. package/src/model-tier/llm-tier-map.ts +48 -4
  412. package/src/models/prompts.ts +22 -1
  413. package/src/mss/logging/horizon-watch.ts +168 -0
  414. package/src/mss/logging/log-store.ts +204 -15
  415. package/src/native-tool-catalog.ts +1 -1
  416. package/src/nexus/api/consult-requests.ts +7 -10
  417. package/src/nexus/api/discord-trigger-bot.ts +6 -3
  418. package/src/nexus/api/error-reports.ts +30 -8
  419. package/src/nexus/api/http-server.ts +8 -0
  420. package/src/nexus/api/loop-resources.ts +42 -0
  421. package/src/nexus/api/outbound-report.ts +8 -3
  422. package/src/nexus/api/telegram-trigger-bot.ts +6 -3
  423. package/src/nexus/index.ts +10 -0
  424. package/src/nexus/outbound/format.ts +2 -0
  425. package/src/nexus/outbound/router.ts +198 -13
  426. package/src/oauth/codex-account-rotation.ts +16 -18
  427. package/src/oauth/codex-account-store.ts +134 -5
  428. package/src/oauth/fallback-chain.ts +28 -6
  429. package/src/onboarding.ts +2 -1
  430. package/src/plugins/adapters/claude-package.ts +4 -12
  431. package/src/plugins/core/capability-policy.ts +141 -0
  432. package/src/plugins/core/host.ts +21 -8
  433. package/src/plugins/core/manifest.ts +19 -2
  434. package/src/plugins/core/trust-store.ts +15 -0
  435. package/src/plugins/core/types.ts +12 -0
  436. package/src/plugins/install/market-fetch.ts +68 -16
  437. package/src/plugins/install/plugin-install.ts +187 -16
  438. package/src/plugins/maker/plugin-maker.ts +25 -20
  439. package/src/plugins/maker/wizard-generate.ts +16 -2
  440. package/src/policy/llm-policy.ts +14 -1
  441. package/src/process/pid-liveness.ts +1 -1
  442. package/src/prompt-cache/openai.ts +10 -6
  443. package/src/prompt-cache/openrouter.ts +94 -0
  444. package/src/prompt-enhance/enhance.ts +46 -5
  445. package/src/prompt-library/family-prompt-coverage.ts +1 -0
  446. package/src/prompt-library/universal-preamble.ts +2 -2
  447. package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
  448. package/src/registry/loader.ts +6 -1
  449. package/src/release-loop/checklist.ts +24 -9
  450. package/src/release-loop/feature-store.ts +3 -0
  451. package/src/release-loop/gate-shards.ts +48 -4
  452. package/src/release-loop/landed-to-green.ts +81 -0
  453. package/src/release-loop/light-rc.ts +11 -1
  454. package/src/release-loop/merged-pr-checklist.ts +10 -0
  455. package/src/release-loop/placement.ts +91 -22
  456. package/src/release-loop/rehearsal.ts +317 -0
  457. package/src/release-loop/release-schedule.ts +13 -1
  458. package/src/release-loop/rubric-types.ts +1 -0
  459. package/src/release-loop/rubric.ts +2 -2
  460. package/src/retro/daily.ts +23 -9
  461. package/src/seat-loop/seat-loop.ts +34 -1
  462. package/src/seat-loop/traffic-signal.ts +44 -0
  463. package/src/self-dev/ask-launch-flow.ts +2 -2
  464. package/src/self-dev/dev-cli.ts +67 -3
  465. package/src/self-dev/dev-pipeline.ts +4 -6
  466. package/src/self-dev/draft-residue.ts +463 -0
  467. package/src/self-dev/draft-sweep.ts +151 -10
  468. package/src/self-dev/draft-triage-rules.ts +27 -1
  469. package/src/self-dev/launch-preflight-text.ts +549 -0
  470. package/src/self-dev/launch-preflight.ts +10 -545
  471. package/src/self-dev/orchestrate-cli.ts +57 -2
  472. package/src/self-dev/orchestrate-summary-line.ts +13 -0
  473. package/src/self-dev/orchestrate.ts +8 -135
  474. package/src/self-dev/review-provider-fallback.ts +115 -19
  475. package/src/self-dev/run-store.ts +1 -3
  476. package/src/self-dev/run-supervisor.ts +3 -22
  477. package/src/self-dev/run-types.ts +178 -0
  478. package/src/self-dev/shard-aggregate.ts +61 -13
  479. package/src/self-dev/shard-plan.ts +5 -1
  480. package/src/self-dev/shard-run.ts +23 -5
  481. package/src/self-dev/supervisor-verdict-edges.ts +2 -4
  482. package/src/self-implement/blocked-draft-policy.ts +3 -19
  483. package/src/self-implement/draft-on-stop-mode.ts +18 -0
  484. package/src/self-implement/follow-up-goals.ts +114 -38
  485. package/src/self-implement/gate-baseline-reap.ts +157 -0
  486. package/src/self-implement/gate-baseline.ts +78 -16
  487. package/src/self-implement/gate-cli.ts +12 -2
  488. package/src/self-implement/gate-remote.ts +17 -6
  489. package/src/self-implement/goal-author.ts +24 -4
  490. package/src/self-implement/goal-digest.ts +19 -0
  491. package/src/self-implement/graph-overlay-condition.ts +4 -0
  492. package/src/self-implement/headless-elanous-driver.ts +11 -9
  493. package/src/self-implement/host-regate.ts +120 -29
  494. package/src/self-implement/l8-merge-queue.ts +67 -5
  495. package/src/self-implement/merge-train.ts +131 -0
  496. package/src/self-implement/off-diff-evidence.ts +9 -0
  497. package/src/self-implement/orchestrator.ts +133 -16
  498. package/src/self-implement/review-finding-recurrence.ts +28 -0
  499. package/src/self-implement/rework-policy.ts +2 -1
  500. package/src/self-implement/round-summary-card.ts +63 -0
  501. package/src/self-implement/run-ledger.ts +4 -3
  502. package/src/self-implement/run-step-projection.ts +147 -0
  503. package/src/self-implement/run-stop.ts +1 -1
  504. package/src/self-implement/seams.ts +36 -3
  505. package/src/self-implement/self-implement-cli.ts +3 -1
  506. package/src/self-implement/train-gate-remote.ts +158 -0
  507. package/src/session-runtime/index.ts +10 -1
  508. package/src/session-runtime/retry-api.ts +11 -1
  509. package/src/skills/gift-install.ts +119 -0
  510. package/src/skills/runner.ts +59 -2
  511. package/src/skills/skill-feedback.ts +31 -1
  512. package/src/skills/skill-tier.ts +1 -0
  513. package/src/smart-wizard/capability-index.ts +231 -0
  514. package/src/smart-wizard/rung.ts +74 -0
  515. package/src/steward/launch.ts +20 -9
  516. package/src/steward/triage.ts +4 -2
  517. package/src/storage/file-lock.ts +8 -1
  518. package/src/task-agent/actions.ts +4 -0
  519. package/src/task-agent/card-evidence.ts +59 -13
  520. package/src/task-agent/judge.ts +4 -3
  521. package/src/task-agent/land-worktree.ts +201 -0
  522. package/src/task-agent/live-move-history.ts +133 -0
  523. package/src/task-agent/live-moves.ts +106 -19
  524. package/src/task-agent/parent-host.ts +117 -8
  525. package/src/task-agent/rejudge-on-head.ts +297 -0
  526. package/src/task-agent/review-result-capture.ts +218 -0
  527. package/src/task-agent/shadow.ts +103 -7
  528. package/src/task-agent/task-hand.ts +136 -11
  529. package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
  530. package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
  531. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
  532. package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
  533. package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
  534. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
  535. package/src/task-orchestrator/surfaces/pod-pool.ts +66 -14
  536. package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
  537. package/src/task-orchestrator/surfaces/self-implement.ts +6 -2
  538. package/src/telegram-service.ts +5 -1
  539. package/src/telegram.ts +17 -4
  540. package/src/time/format.ts +13 -4
  541. package/src/tool-runtime/goal-author-runtime.ts +1 -0
  542. package/src/tool-runtime/self-cognition-catalog.ts +23 -0
  543. package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
  544. package/src/user-config.ts +132 -24
  545. package/src/ux-sim/slash-menu-frames.ts +168 -0
  546. package/src/version/packed-revision.json +1 -1
  547. package/src/web-terminal/preview-tap-registry.ts +5 -2
  548. package/src/workflow-runtime/triggers/scheduler.ts +1 -0
  549. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
  550. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
  551. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
  552. package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
  554. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
  555. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
  556. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
  558. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
  563. package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
  572. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
  573. package/apps/pwa/out/_next/static/chunks/2489-d238d3e2eb5b2bf5.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
  586. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
  594. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
  599. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
  601. package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
  605. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
  610. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
  615. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
  616. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
  618. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
  619. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
  627. package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
  630. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
  640. package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
  643. package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
  647. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
  648. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/approvals/page-88459e0903da2803.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d85c43f46f58716b.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/board/page-4e645600579ae952.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/botlab/page-87edbfd19117823b.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/chat/page-cbaf66b1e1804adf.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/control/page-9f5610caaa06178c.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/decisions/page-ec8f3575e339de74.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/exec/page-2a19c5cd3b562580.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/field/page-b6a09cde2e07521a.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/loops/page-abd86cd832aaa011.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8c3f168fc3f91939.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/morning/page-786fb4504d0f2fa9.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7ec8e289b4c14df6.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-8c8ac17d52be2a79.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d359ab048d63a9d9.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/settings/page-f151cc10ad026940.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/share/page-bf495a1e284f4e00.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/term/page-9abcfac07e02a542.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/workflows/page-69cb93d1a2e57e0e.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/workspace/page-72ec543928d67c3e.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
  704. package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +0 -1
  705. /package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
@@ -3,7 +3,7 @@ import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSy
3
3
  import { spawn } from 'node:child_process';
4
4
  import { createHash, randomBytes } from 'node:crypto';
5
5
  import { dirname, isAbsolute, join, normalize, relative, resolve, sep } from 'node:path';
6
- import { groundMissionInCodebase, isRepositoryImplementationCandidate, type CodebaseGrounding } from '../autopilot/mission-codebase-gate.js';
6
+ import { isRepositoryImplementationCandidate, type CodebaseGrounding } from '../autopilot/codebase-grounding.js';
7
7
  import { extractSlugSource, generateMissionSlug, slugify } from '../autopilot/mission-registry.js';
8
8
  import { enhancePrompt, type EnhanceOpts, type EnhanceResult } from '../prompt-enhance/enhance.js';
9
9
  import type { LLMUsage } from '../prompt-cache/types.js';
@@ -44,7 +44,7 @@ import { extractGoalDocSections, type GoalDocSourceLine } from './goal-doc/secti
44
44
  import { isGoalAuthorFileName } from './goal-document.js';
45
45
  import { resolveGoalDocumentsDir } from './goal-documents-dir.js';
46
46
  import { REQUIRED_EVIDENCE_COMMAND_SEPARATOR } from './off-diff-evidence.js';
47
- import { renderLaunchPreflight, siblingTestPath, type LaunchPreflightResult } from '../self-dev/launch-preflight.js';
47
+ import { renderLaunchPreflight, siblingTestPath, type LaunchPreflightResult } from '../self-dev/launch-preflight-text.js';
48
48
  import { quoteShellArg } from '../cli/logs-cli.js';
49
49
  import type { HarnessGroundingProvenance } from './context-capsule.js';
50
50
  import { hasGoalStepCodeName } from './goal-step-code-name.js';
@@ -121,6 +121,21 @@ export interface GoalAuthorGroundingResult {
121
121
  facts: CodebaseGrounding;
122
122
  }
123
123
 
124
+ // A function-local slot is initialized only on access, after cyclic ESM evaluation has finished.
125
+ function goalAuthorGroundMissionSlot(): { fn?: NonNullable<GoalAuthorGroundingDeps['groundMission']> } {
126
+ const key = Symbol.for('elanous.goalAuthor.groundMission');
127
+ const registry = globalThis as typeof globalThis & { [key: symbol]: { fn?: NonNullable<GoalAuthorGroundingDeps['groundMission']> } };
128
+ return registry[key] ??= {};
129
+ }
130
+
131
+ export function registerGoalAuthorGroundMission(fn: NonNullable<GoalAuthorGroundingDeps['groundMission']> | undefined): void {
132
+ goalAuthorGroundMissionSlot().fn = fn;
133
+ }
134
+
135
+ export function hasGoalAuthorGroundMission(): boolean {
136
+ return goalAuthorGroundMissionSlot().fn !== undefined;
137
+ }
138
+
124
139
  export interface GoalAuthorPersistentGroundingDecision {
125
140
  readonly enabled: boolean;
126
141
  readonly source: ObserveOnlySource;
@@ -5583,12 +5598,17 @@ export async function groundForGoalAuthor(
5583
5598
  cwd: string,
5584
5599
  deps: GoalAuthorGroundingDeps = {},
5585
5600
  ): Promise<GoalAuthorGroundingResult> {
5601
+ const groundMission = deps.groundMission ?? goalAuthorGroundMissionSlot().fn;
5602
+ if (!groundMission) {
5603
+ debug.log('goal-author.grounding', 'route-unregistered', { cwd });
5604
+ throw new Error('route-unregistered: mission-codebase-gate 를 로드하라');
5605
+ }
5586
5606
  return {
5587
5607
  path: 'groundMissionInCodebase',
5588
5608
  // ⛔⭐ 사람이 ask 에 «이름을 댄» 경로를 접지에 «넘긴다» — 접지가 그것을 후보로 쓴다.
5589
5609
  // ⛔ 추출기를 «새로 만들지 않는다» — 이 파일이 이미 갖고 있는 askPathTokens 하나를 쓴다
5590
5610
  // (2026-08-11 72차: 같은 것에 두 이름을 준 병을 하루에 여섯 번 셌다).
5591
- facts: await (deps.groundMission ?? groundMissionInCodebase)(ask, {
5611
+ facts: await groundMission(ask, {
5592
5612
  cwd,
5593
5613
  seedPaths: askPathTokens(ask),
5594
5614
  ...(deps.persistent !== undefined ? { persistent: deps.persistent } : {}),
@@ -5694,7 +5714,7 @@ export function defaultGoalAuthorDeps(cwd: string): GoalAuthorDeps {
5694
5714
  * 이 칸을 «안 주므로» 기본값 `coverage-gate` 로 종전 문면을 그대로 받는다.
5695
5715
  */
5696
5716
  enhance(ask, opts) {
5697
- return enhancePrompt(ask, { ...opts, checklistUse: 'authoring' });
5717
+ return enhancePrompt(ask, { ...opts, checklistUse: 'authoring', config: opts?.config ?? getUserConfig() });
5698
5718
  },
5699
5719
  readSourceFile: createRepositoryReferencedFileReader(cwd),
5700
5720
  runHelpProbe: (argv) => runDefaultHelpProbe(cwd, argv),
@@ -89,6 +89,25 @@ function scaled(limit: number): { reserved: number; minSection: number } {
89
89
  return { reserved: Math.floor(RESERVED_FOR_NOTICE * k), minSection: Math.max(40, Math.floor(MIN_SECTION_CHARS * k)) };
90
90
  }
91
91
 
92
+ /** 골 문서에서 `판정 신호` 절만 뽑아 리뷰 acceptance 로 쓴다. 계보 = self-implement seams. */
93
+ export function extractHarnessReviewAcceptance(goalDocument: string | undefined): { goal: string | undefined; acceptance: string | undefined } {
94
+ let goal: string | undefined;
95
+ try {
96
+ goal = goalDocument?.trim() || undefined;
97
+ } catch {
98
+ return { goal: undefined, acceptance: undefined };
99
+ }
100
+ if (!goal) return { goal: undefined, acceptance: undefined };
101
+ try {
102
+ const acceptance = splitGoalSections(supervisorGoalDigest(goal, 3000).text)
103
+ .find((section) => isSupervisorDecisionSection(section.title) && section.title.includes('판정 신호'))
104
+ ?.body.trim() || undefined;
105
+ return { goal, acceptance };
106
+ } catch {
107
+ return { goal, acceptance: undefined };
108
+ }
109
+ }
110
+
92
111
  /** `## <제목>` 기준으로 절을 가른다. 헤더 앞 서두는 제목 `''` 로 담는다. */
93
112
  export function splitGoalSections(goal: string): Section[] {
94
113
  return extractGoalDocSections(goal, {
@@ -53,6 +53,10 @@ export function evaluateOverlayCondition(
53
53
  const { key, operator, literal } = parsed.condition;
54
54
  if (!(key in state)) return { kind: 'key-absent', key };
55
55
  const actual = state[key];
56
+ if (actual === undefined || actual === null) return { kind: 'key-absent', key };
57
+ // Measured boolean branch keys accept only a real boolean observation — any textual lookalike
58
+ // ('true', 'TRUE', 'yes', 1) is unknown, whatever the literal spelling in the condition.
59
+ if ((key === 'sibling_overlap' || key === 'main_sync_conflict') && typeof actual !== 'boolean') return { kind: 'key-absent', key };
56
60
 
57
61
  if (typeof literal === 'number') {
58
62
  // ⛔ 수 비교인데 값이 수가 아니면 「비교 불가」다 — 거짓으로 접지 않는다.
@@ -996,8 +996,8 @@ export interface HeadlessGoalLoopPtyOptions {
996
996
  /** 밖에서 쓴 이력 조회 심 — 기본은 실물(`pty-control-ipc`). ⭐ 테스트가 전역을 찌르지 않게
997
997
  * `spawn`·`ptyAvailable` 과 **같은 방식**으로 주입한다(새 패턴 아님 · 테스트 전용 export 도 아님). */
998
998
  externalWriteProvenance?: (ptyId: string) => { externalWrites: number; externalWriteAgoMs: number; externalWriteActor: string } | undefined;
999
- /** ★S4 P2b — brain 상담 1회 최대 대기(ms·기본 15초). 초과 시 abort + fail-soft(`brain.fail`).
1000
- * ⚠️ **테스트 seam 겸용**(리뷰 must-fix — 이게 없으면 timeout fail-soft 경로를 15초 없이 검증할 수
999
+ /** ★S4 P2b — brain 상담 1회 최대 대기(ms·기본 45초). 초과 시 abort + fail-soft(`brain.fail`).
1000
+ * ⚠️ **테스트 seam 겸용**(리뷰 must-fix — 이게 없으면 timeout fail-soft 경로를 45초 없이 검증할 수
1001
1001
  * 없다). 프로덕션은 기본값을 쓴다(호출부 미지정). */
1002
1002
  brainTimeoutMs?: number;
1003
1003
  /** ★S4 P3 **관측 시계 seam**(테스트 전용·기본 `Date.now`).
@@ -1520,8 +1520,8 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1520
1520
  let previousStallMetrics: { toolCalls: number; chars: number } | undefined;
1521
1521
  let keyframeSeq = 0; // 이 run 의 키프레임 순번(파일 키·seq 순 추출).
1522
1522
  // ⭐⭐ **wall-clock 상한**(리뷰 must-fix 2026-07-26) — 이 루프의 회계는 `i`(≈초·pollMs≈1000ms 가정)
1523
- // 기반이다. S4 P2b brain 상담이 tick 당 최대 `brainTimeoutMs`(기본 15초)를 **직렬 await** 하므로
1524
- // 전이가 반복되면 1 tick 이 ~16초가 되어 `maxWaitSec` 계약을 **최대 16배 초과**한다(600s → ~2.7h).
1523
+ // 기반이다. S4 P2b brain 상담이 tick 당 최대 `brainTimeoutMs`(기본 45초)를 **직렬 await** 하므로
1524
+ // 전이가 반복되면 1 tick 이 ~46초가 되어 `maxWaitSec` 계약을 초과할 수 있다.
1525
1525
  // ⇒ 기존 활동-grace 의미(i 기반)는 **그대로 두고** 절대 경과시간을 **추가 상한**으로만 얹는다.
1526
1526
  // 단조 안전: 더 **일찍** 멈출 뿐 늦게 멈추는 경우가 없다. brain 미주입이면 i≈초라 두 조건이 일치
1527
1527
  // (무회귀). ROADMAP §2 P1(종료 지연)의 회계 구조를 재작성하지 않는 최소 개입이다.
@@ -1563,7 +1563,7 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1563
1563
  debug.log('self-implement', 'poll.heartbeat', { ptyId, runId, i, alive: h.isAlive(), lastActivityI, silentFor, ...parentObservation });
1564
1564
  }
1565
1565
  // #24 finer 마커 — stall 시 "poll 루프 안(자식 구동·정상)" vs "다른 동기 op" 구분.
1566
- setEventLoopActivity(`headless:poll-${i}:alive-${h.isAlive() ? 1 : 0}`);
1566
+ setEventLoopActivity(`headless:poll:alive-${h.isAlive() ? 1 : 0}`);
1567
1567
  const delta = h.drainDelta();
1568
1568
  phase = 'snapshot';
1569
1569
  const snap = h.snapshot(); // ★ 1회 캡처 — 화면 릴레이 + GOAL-COMPLETE 공용(중복 snapshot 제거)
@@ -1697,6 +1697,7 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1697
1697
  if (opts.signal?.aborted) onBrainAbort();
1698
1698
  else opts.signal?.addEventListener('abort', onBrainAbort, { once: true });
1699
1699
  let timer: ReturnType<typeof setTimeout> | undefined;
1700
+ const brainStartedMs = Date.now();
1700
1701
  try {
1701
1702
  // Lost and unknown are the same ownership axis exercised by the stalled-screen
1702
1703
  // tests, not separate stances. Preserve their measured ownership and observation
@@ -1709,12 +1710,12 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1709
1710
  Promise.resolve(opts.brain.decide(controlObs, controller.signal)),
1710
1711
  new Promise<ControlDecision>((_, reject) => {
1711
1712
  // ⭐ **남은 절대 예산으로 clamp**(리뷰 must-fix 2R) — wall-clock 상한은 **tick 시작**에서만
1712
- // 검사하므로, deadline 직전에 시작된 상담이 그대로면 최대 brainTimeoutMs(기본 15초)만큼
1713
+ // 검사하므로, deadline 직전에 시작된 상담이 그대로면 최대 brainTimeoutMs(기본 45초)만큼
1713
1714
  // hard deadline 을 **초과**한다. 상담 자체를 남은 예산 안으로 묶어 창을 닫는다.
1714
1715
  // 최소 1ms(음수·0 이면 즉시 timeout → 다음 tick 상단 wall-clock 체크가 루프를 끊는다).
1715
1716
  const remainMs = Math.max(1, hardI * 1000 - (Date.now() - loopStartedMs));
1716
1717
  timer = setTimeout(() => { controller.abort(); reject(new Error('brain suggestion timeout')); },
1717
- Math.min(opts.brainTimeoutMs ?? 15_000, remainMs));
1718
+ Math.min(opts.brainTimeoutMs ?? 45_000, remainMs));
1718
1719
  }),
1719
1720
  ...(parentAbort ? [parentAbort] : []),
1720
1721
  ]);
@@ -1761,6 +1762,7 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1761
1762
  // 관측 계약은 화면 분류 원문을 보존한다. 완료 정보량·자동 정지는 아래의
1762
1763
  // `completionState` 폐쇄형 정규화만 소비하므로 blocked/idle 기록을 잃지 않는다.
1763
1764
  ptyId: h.id, runId, moment: 'in-round', step: i, trigger, state: curState, action: decision.action,
1765
+ durationMs: Date.now() - brainStartedMs,
1764
1766
  // `delivery-outcome` is a follow-up observation, not another verdict. Consumers count
1765
1767
  // either initial stage once per decision and can distinguish verdicts without input.
1766
1768
  supervisionRecordStage: decision.action === 'input' ? 'verdict-input' : 'verdict-no-input',
@@ -1848,7 +1850,7 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1848
1850
  }
1849
1851
  } catch (e) {
1850
1852
  // Parent cancel outranks suggestion observation: leave the poll loop immediately so PTY cleanup is not
1851
- // held by the 15s consultation timeout, even when a custom brain ignores its AbortSignal.
1853
+ // held by the 45s consultation timeout, even when a custom brain ignores its AbortSignal.
1852
1854
  if (opts.signal?.aborted) {
1853
1855
  timedOut = false;
1854
1856
  exitReason = 'abort';
@@ -1856,7 +1858,7 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1856
1858
  }
1857
1859
  debug.log('self-implement', 'brain.fail', {
1858
1860
  ptyId: h.id, runId, step: i, trigger, state: curState,
1859
- roundContextPresent,
1861
+ roundContextPresent, durationMs: Date.now() - brainStartedMs,
1860
1862
  error: String(e instanceof Error ? e.message : e).slice(0, 120),
1861
1863
  });
1862
1864
  } finally {
@@ -1,7 +1,7 @@
1
1
  import { spawnSync } from 'node:child_process';
2
- import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
2
+ import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
3
3
  import { tmpdir } from 'node:os';
4
- import { dirname, join } from 'node:path';
4
+ import { dirname, join, resolve } from 'node:path';
5
5
  import { debug } from '../debug/log.js';
6
6
  import { getUserConfig } from '../user-config.js';
7
7
  import { publicExposureFiles, runExposeGate } from './expose-gate.js';
@@ -9,23 +9,32 @@ import { admitLandingMerge } from './frozen-merges.js';
9
9
  import { releaseGitDiffPaths, releasePathHold, releasePathHoldShouldPost, releasePathHoldComment, releasePathHoldCommentsArgs, RELEASE_PATH_LABEL } from '../self-dev/release-path-guard.js';
10
10
  import { detectTestInterference, parseFailureCount, runBunTest } from '../../scripts/detect-test-interference.js';
11
11
  import { MAX_INSPECTED_TEST_FILES, runTestInterferenceGate } from '../../scripts/ci-test-interference-gate.js';
12
+ import { pwaGraph, pwaReach } from '../../scripts/ci-pwa-build-gate.js';
13
+
14
+ /** Use pr-land's PWA reachability (including its undecidable-graph build fallback), not a blanket src/** trigger. */
15
+ export function needsPwaBuild(files: readonly string[], repoRoot: string, graph: (root: string) => ReturnType<typeof pwaGraph> = pwaGraph): boolean {
16
+ return pwaReach(files, () => graph(repoRoot)).reaches;
17
+ }
12
18
 
13
19
  /**
14
- * The PWA's static build type-checks every `src/**` file it imports, under Next's stricter
15
- * `ProcessEnv` — a change that only touches `src/**` can break it while tsc and bun test stay
16
- * green (2026-09-27: two such changes kept main's PWA build red for two hours). Build whenever
17
- * app code or non-test source changed; test files are never imported by the PWA.
20
+ * Give a temporary checkout the source checkout's dependencies: link `<dir>/node_modules` when it is really installed
21
+ * there (its `marker` package exists), otherwise install into the candidate. Shared by host regate and the task agent's
22
+ * land worktree (TA-LAND-WORKTREE).
18
23
  */
19
- export function needsPwaBuild(files: readonly string[]): boolean {
20
- return files.some((file) => file.startsWith('apps/pwa/') || (file.startsWith('src/') && !/\.test\.tsx?$/.test(file)));
24
+ export function provideCheckoutDependencies(candidate: string, sourceRoot: string, dir: string, marker: string, install: (cwd: string) => void): void {
25
+ if (existsSync(join(candidate, dir, 'node_modules'))) return;
26
+ if (existsSync(join(sourceRoot, dir, 'node_modules', marker, 'package.json'))) {
27
+ symlinkSync(join(sourceRoot, dir, 'node_modules'), join(candidate, dir, 'node_modules'), 'dir');
28
+ } else install(join(candidate, dir));
21
29
  }
22
30
 
23
- export interface HostRegateInput { prNumber: number; headCommit: string; repoRoot: string; goalFile?: string; verifyOnly?: boolean; /** Called by a resume sweep that already holds this PR's claim. */ resumed?: true }
31
+ export interface HostRegateInput { prNumber: number; headCommit: string; repoRoot: string; goalFile?: string; verifyOnly?: boolean; /** TA-LIVE-LAND-2: run the full landing gates (release-path hold · neighbours · PR re-read) but stop before the freeze admission and `gh pr merge` — the task agent lands it later via `pr land --expected-head`. */ noMerge?: true; /** Called by a resume sweep that already holds this PR's claim. */ resumed?: true }
24
32
  export interface HostRegateResult { passed: boolean; failures: Array<{ step: string; detail: string }>; os: string; status?: 'passed' | 'failed' | 'unmeasured' | 'frozen'; /** verifyOnly: 실제로 얹어 잰 base 끝 */ baseCommit?: string }
25
33
  export type InterferenceVerdict = { passed: boolean; detail?: string; unmeasured?: boolean; /** neighbour tests left out so the selection fits the inspection cap */ neighborsTrimmed?: number };
26
34
  export type HostRegateDeps = {
27
35
  command?: (bin: string, args: readonly string[], cwd: string, env?: NodeJS.ProcessEnv) => { status: number | null; stdout: string; stderr: string };
28
36
  interference?: (files: readonly string[], cwd: string) => Promise<InterferenceVerdict>;
37
+ /** Legacy injection for callers that supply an ephemeral worktree instead of a locked slot. */
29
38
  makeTemp?: () => string;
30
39
  removeTemp?: (path: string) => void;
31
40
  acquire?: (repoRoot: string) => Promise<() => void>;
@@ -104,7 +113,7 @@ function slotOwnerAlive(slot: string): boolean {
104
113
  }
105
114
  }
106
115
 
107
- export async function acquireSlot(repoRoot: string, opts: { waitMs?: number; pollMs?: number; now?: () => number } = {}): Promise<() => void> {
116
+ export async function acquireSlot(repoRoot: string, opts: { waitMs?: number; pollMs?: number; now?: () => number } = {}): Promise<(() => void) & { worktree: string }> {
108
117
  const gitDir = spawnSync('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], { cwd: repoRoot, encoding: 'utf8' });
109
118
  if (gitDir.status !== 0 || !gitDir.stdout.trim()) throw new Error('git common directory unavailable for host regate lock');
110
119
  const root = join(gitDir.stdout.trim(), 'elanous-host-regate');
@@ -117,7 +126,7 @@ export async function acquireSlot(repoRoot: string, opts: { waitMs?: number; pol
117
126
  try {
118
127
  mkdirSync(slot);
119
128
  writeFileSync(join(slot, 'pid'), String(process.pid));
120
- return () => rmSync(slot, { recursive: true, force: true });
129
+ return Object.assign(() => rmSync(slot, { recursive: true, force: true }), { worktree: join(root, `worktree-${i}`) });
121
130
  } catch (error) {
122
131
  if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;
123
132
  // A slot left by a crashed host process would otherwise block every later run.
@@ -133,6 +142,24 @@ export async function acquireSlot(repoRoot: string, opts: { waitMs?: number; pol
133
142
  }
134
143
  }
135
144
 
145
+ function removeBrokenSlotRegistration(repoRoot: string, worktree: string): void {
146
+ const gitDir = spawnSync('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], { cwd: repoRoot, encoding: 'utf8' });
147
+ if (gitDir.status !== 0 || !gitDir.stdout.trim()) throw new Error('git common directory unavailable for slot repair');
148
+ const registrations = join(gitDir.stdout.trim(), 'worktrees');
149
+ if (!existsSync(registrations)) return;
150
+ for (const name of readdirSync(registrations)) {
151
+ const registration = join(registrations, name);
152
+ if (!lstatSync(registration).isDirectory()) continue;
153
+ const pointer = join(registration, 'gitdir');
154
+ if (!existsSync(pointer) || lstatSync(pointer).isSymbolicLink()) continue;
155
+ if (resolve(readFileSync(pointer, 'utf8').trim()) !== resolve(worktree, '.git')) continue;
156
+ rmSync(registration, { recursive: true });
157
+ }
158
+ }
159
+
160
+ /** Callers: podSelfImplementSpawn in src/task-orchestrator/surfaces/self-implement-pod.ts calls
161
+ * (options.hostRegate ?? runHostRegate)({ prNumber, headCommit, repoRoot: hostRoot, ... });
162
+ * sweepFrozenMerges in frozen-merges.ts also calls runHostRegate(entry); landing queue serialization stays there. */
136
163
  export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps = {}): Promise<HostRegateResult> {
137
164
  const command = deps.command ?? defaultCommand;
138
165
  const log = deps.log ?? ((event: 'passed' | 'failed' | 'unmeasured' | 'base-raced', data: Record<string, unknown>) => debug.log('harness.host-regate', event, data));
@@ -141,6 +168,19 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
141
168
  let base = '';
142
169
  let worktree: string | undefined;
143
170
  let attached = false;
171
+ let ephemeral = false;
172
+ let slotCommonDir: string | undefined;
173
+ const verifySlot = (): void => {
174
+ if (!worktree || !slotCommonDir || lstatSync(worktree).isSymbolicLink() || !lstatSync(worktree).isDirectory()) throw new Error('slot worktree mismatch');
175
+ const pointer = join(worktree, '.git');
176
+ if (!lstatSync(pointer).isFile() || lstatSync(pointer).isSymbolicLink()) throw new Error('slot worktree mismatch');
177
+ const common = realpathSync(run('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], worktree));
178
+ const registration = realpathSync(run('git', ['rev-parse', '--path-format=absolute', '--git-dir'], worktree));
179
+ if (common !== slotCommonDir || dirname(registration) !== join(slotCommonDir, 'worktrees')
180
+ || resolve(readFileSync(join(registration, 'gitdir'), 'utf8').trim()) !== resolve(pointer)
181
+ || resolve(readFileSync(pointer, 'utf8').trim().replace(/^gitdir: /, '')) !== registration
182
+ || run('git', ['rev-parse', '--show-toplevel'], worktree) !== worktree) throw new Error('slot worktree mismatch');
183
+ };
144
184
  let release: (() => void) | undefined;
145
185
  let endLanding: ((merged?: boolean) => void) | undefined;
146
186
  let landed = false;
@@ -168,16 +208,57 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
168
208
  const baseRefName = view.baseRefName;
169
209
  // verifyOnly(승인 탭): PR 에 기록된 base(baseRefOid)는 main 의 «지금 끝»보다 늙을 수 있다 — 지금 끝에 얹어 잰다.
170
210
  let baseCommit = view.baseRefOid!;
211
+ // REGATE-STALE-BASE: GitHub's baseRefOid can stay at the PR-open tip after main moves. After the bounded re-reads the
212
+ // regate measures on the fetched base tip (what the squash merge lands on) and records the stale PR base instead of failing.
213
+ // The closing PR re-read must still show the last PR base seen here (a PR that changed again is not the PR we measured).
214
+ let stalePrBase: string | undefined;
215
+ const initialPrBase = baseCommit;
216
+ let buildPwa = false;
171
217
  try {
172
218
  run('git', ['fetch', 'origin', `refs/heads/${baseRefName}`], input.repoRoot);
173
- const fetchedBase = run('git', ['rev-parse', 'FETCH_HEAD'], input.repoRoot);
219
+ let fetchedBase = run('git', ['rev-parse', 'FETCH_HEAD'], input.repoRoot);
174
220
  if (input.verifyOnly) { baseCommit = fetchedBase; verifiedBase = fetchedBase; }
175
- else if (fetchedBase !== baseCommit) throw new Error('fetched PR base differs from checked SHA');
221
+ else {
222
+ for (let attempt = 1; fetchedBase !== baseCommit; attempt++) {
223
+ debug.log('harness.host-regate', 'base-moved-retry', { pr: input.prNumber, attempt, checked: baseCommit, fetched: fetchedBase });
224
+ if (attempt === 3) {
225
+ stalePrBase = baseCommit;
226
+ debug.log('harness.host-regate', 'base-stale', { pr: input.prNumber, prBaseRefOidInitial: initialPrBase, prBaseRefOid: baseCommit, fetched: fetchedBase, candidateBase: fetchedBase });
227
+ baseCommit = fetchedBase;
228
+ break;
229
+ }
230
+ await new Promise((resolve) => setTimeout(resolve, 1_000));
231
+ view = readPr();
232
+ if (view.headRefOid !== input.headCommit || view.state !== 'OPEN' || view.isDraft !== false || view.baseRefName !== baseRefName || !/^[0-9a-f]{40}$/i.test(view.baseRefOid ?? '')) {
233
+ return result('unmeasured', 'pr-head', 'PR head, base commit, ready state or open state unavailable or changed');
234
+ }
235
+ baseCommit = view.baseRefOid!;
236
+ run('git', ['fetch', 'origin', `refs/heads/${baseRefName}`], input.repoRoot);
237
+ fetchedBase = run('git', ['rev-parse', 'FETCH_HEAD'], input.repoRoot);
238
+ }
239
+ }
176
240
  run('git', ['fetch', 'origin', `refs/pull/${input.prNumber}/head`], input.repoRoot);
177
241
  if (run('git', ['rev-parse', 'FETCH_HEAD'], input.repoRoot) !== input.headCommit) throw new Error('fetched PR head differs from checked SHA');
178
- worktree = (deps.makeTemp ?? (() => mkdtempSync(join(tmpdir(), 'elanous-host-regate-'))))();
179
- run('git', ['worktree', 'add', '--detach', worktree, baseCommit], input.repoRoot);
180
- attached = true;
242
+ const slotWorktree = (release as (() => void) & { worktree?: string }).worktree;
243
+ ephemeral = !!deps.makeTemp || !slotWorktree;
244
+ worktree = deps.makeTemp?.() ?? slotWorktree ?? mkdtempSync(join(tmpdir(), 'host-regate-'));
245
+ if (ephemeral && slotWorktree && resolve(worktree) === resolve(slotWorktree)) throw new Error('temporary worktree overlaps locked slot');
246
+ if (!ephemeral && !deps.acquire) {
247
+ slotCommonDir = realpathSync(run('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], input.repoRoot));
248
+ }
249
+ if (!ephemeral && existsSync(worktree)) {
250
+ if (slotCommonDir) verifySlot();
251
+ attached = true;
252
+ // A previous host may have died mid-merge; never carry its index or untracked files into this run.
253
+ run('git', ['reset', '--hard'], worktree);
254
+ run('git', ['clean', '-fdx', '-e', 'node_modules', '-e', '.next', '-e', '*.tsbuildinfo'], worktree);
255
+ run('git', ['checkout', '--detach', baseCommit], worktree);
256
+ }
257
+ if (!attached) {
258
+ if (!ephemeral && !deps.acquire) removeBrokenSlotRegistration(input.repoRoot, worktree);
259
+ run('git', ['worktree', 'add', '--detach', worktree, baseCommit], input.repoRoot);
260
+ attached = true;
261
+ }
181
262
  if (run('git', ['rev-parse', 'HEAD'], worktree) !== baseCommit) throw new Error('worktree base HEAD mismatch');
182
263
  base = run('git', ['merge-base', baseCommit, input.headCommit], worktree);
183
264
  files = run('git', ['diff', '--name-only', base, input.headCommit], worktree).split('\n').filter(Boolean);
@@ -213,14 +294,10 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
213
294
  // a temporary checkout whose node_modules is empty or purged; linking it turned every gate into
214
295
  // «Cannot find package 'typescript'» (unmeasured · 2026-09-29 #21239). Install into the candidate instead.
215
296
  const candidate = worktree;
216
- const provide = (dir: string, marker: string): void => {
217
- if (existsSync(join(candidate, dir, 'node_modules'))) return;
218
- if (existsSync(join(input.repoRoot, dir, 'node_modules', marker, 'package.json'))) {
219
- symlinkSync(join(input.repoRoot, dir, 'node_modules'), join(candidate, dir, 'node_modules'), 'dir');
220
- } else run('bun', ['install', '--frozen-lockfile'], join(candidate, dir));
221
- };
297
+ const provide = (dir: string, marker: string): void => provideCheckoutDependencies(candidate, input.repoRoot, dir, marker, (cwd) => { run('bun', ['install', '--frozen-lockfile'], cwd); });
222
298
  provide('', 'typescript');
223
- if (needsPwaBuild(files) && existsSync(join(worktree, 'apps/pwa'))) provide('apps/pwa', 'next');
299
+ buildPwa = needsPwaBuild(files, worktree);
300
+ if (buildPwa && existsSync(join(worktree, 'apps/pwa'))) provide('apps/pwa', 'next');
224
301
  } catch (e) { return result('unmeasured', 'worktree', String(e)); }
225
302
  try {
226
303
  const interference = await (deps.interference ?? ((f: readonly string[], c: string) => defaultInterference(f, c, { neighbors: !input.verifyOnly })))(files, worktree);
@@ -244,19 +321,21 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
244
321
  try { run('bun', ['scripts/ci-isolation-hardcode-gate.ts', '--changed-files', ...files], worktree); }
245
322
  catch (e) { return result(/\[isolation-gate\] FAIL/.test(String(e)) ? 'failed' : 'unmeasured', 'isolation-gate', String(e)); }
246
323
  }
247
- if (needsPwaBuild(files)) {
324
+ if (buildPwa) {
248
325
  try { run('bun', ['bin/elanous.mjs', '--test', 'nexus', 'build'], worktree); }
249
326
  catch (e) { return result(String(e).includes('command unavailable') ? 'unmeasured' : 'failed', 'nexus-build', String(e)); }
250
327
  }
251
328
  let current: PrView;
252
329
  try { current = readPr(); }
253
330
  catch (e) { return result('unmeasured', 'pr-view', String(e)); }
254
- if (current.headRefOid !== input.headCommit || current.baseRefName !== baseRefName || (!input.verifyOnly && current.baseRefOid !== baseCommit) || current.state !== 'OPEN' || current.isDraft !== false) {
331
+ if (current.headRefOid !== input.headCommit || current.baseRefName !== baseRefName || (!input.verifyOnly && current.baseRefOid !== (stalePrBase ?? baseCommit)) || current.state !== 'OPEN' || current.isDraft !== false) {
255
332
  return result('unmeasured', 'pr-base-changed', 'PR head or base changed during host regate; rerun against the new base');
256
333
  }
257
334
  // --match-head-commit pins the head. gh has no base pin, so the base was re-read just
258
335
  // above; the seconds between that read and the merge are checked after the fact below.
259
336
  if (input.verifyOnly) return result('passed');
337
+ // TA-REJUDGE-ON-HEAD — 병합 없는 재게이트는 «잰 base 끝»을 같이 낸다(겹침 증거의 gate.baseCommit).
338
+ if (input.noMerge) return { ...result('passed'), status: 'passed', baseCommit };
260
339
  const landing = admitLandingMerge({ prNumber: input.prNumber, headCommit: input.headCommit, repoRoot: input.repoRoot, ...(input.goalFile ? { goalFile: input.goalFile } : {}) }, deps.freezeRoot, {}, input.resumed ? undefined : { prNumber: input.prNumber, repoRoot: input.repoRoot, headCommit: input.headCommit }, { prodFreezeRoot: deps.prodFreezeRoot });
261
340
  if (landing.kind !== 'merge') {
262
341
  debug.log('harness.merge', 'frozen', { pr: input.prNumber, ...(landing.kind === 'held' ? { reason: landing.freeze.reason, until: landing.freeze.until } : { resumedElsewhere: true }) });
@@ -295,10 +374,22 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
295
374
  return result('unmeasured', 'host-regate', String(e));
296
375
  } finally {
297
376
  try { endLanding?.(landed); } catch (e) { log('unmeasured', { pr: input.prNumber, files, os: process.platform, failedStep: 'landing-release', detail: String(e) }); }
298
- try { if (attached && worktree) run('git', ['worktree', 'remove', '--force', worktree], input.repoRoot); }
299
- catch (e) { log('unmeasured', { pr: input.prNumber, files, os: process.platform, failedStep: 'cleanup', detail: String(e) }); }
300
- try { if (worktree) (deps.removeTemp ?? ((path) => rmSync(path, { recursive: true, force: true })))(worktree); }
301
- catch (e) { log('unmeasured', { pr: input.prNumber, files, os: process.platform, failedStep: 'cleanup', detail: String(e) }); }
377
+ try {
378
+ if (attached && worktree) {
379
+ if (slotCommonDir) verifySlot();
380
+ run('git', ['reset', '--hard'], worktree);
381
+ run('git', ['clean', '-fdx', '-e', 'node_modules', '-e', '.next', '-e', '*.tsbuildinfo'], worktree);
382
+ }
383
+ } catch (e) { log('unmeasured', { pr: input.prNumber, files, os: process.platform, failedStep: 'cleanup', detail: String(e) }); }
384
+ if (ephemeral && worktree) {
385
+ try {
386
+ if (attached) run('git', ['worktree', 'remove', '--force', worktree], input.repoRoot);
387
+ } catch (e) { log('unmeasured', { pr: input.prNumber, files, os: process.platform, failedStep: 'cleanup', detail: String(e) }); }
388
+ try {
389
+ if (deps.removeTemp) deps.removeTemp(worktree);
390
+ else rmSync(worktree, { recursive: true, force: true });
391
+ } catch (e) { log('unmeasured', { pr: input.prNumber, files, os: process.platform, failedStep: 'cleanup', detail: String(e) }); }
392
+ }
302
393
  try { release?.(); }
303
394
  catch (e) { log('unmeasured', { pr: input.prNumber, files, os: process.platform, failedStep: 'lock', detail: String(e) }); }
304
395
  if (failures.length && failures[0]?.step !== 'release-path-hold') {
@@ -30,9 +30,27 @@ export type L8MergeQueueDeps = {
30
30
  };
31
31
 
32
32
  export type L8ShadowVerdict = { number: number; head: string; base?: string; verdict: 'pass' | 'conflict' | 'fail'; detail?: string; tests: string[]; at: string };
33
- export type L8ShadowQueueState = { pending: { number: number; head: string }[]; verdicts: L8ShadowVerdict[] };
33
+ export type L8ShadowQueueItem = {
34
+ number: number;
35
+ head: string;
36
+ files?: string[];
37
+ filesUnmeasured?: true;
38
+ overlapsWith?: number[];
39
+ overlapsUnknownWith?: number[];
40
+ };
41
+ export type L8ShadowQueueState = { pending: L8ShadowQueueItem[]; verdicts: L8ShadowVerdict[] };
42
+ export type L8ShadowEnqueueObservation = {
43
+ number: number;
44
+ head: string;
45
+ fileCount: number | null;
46
+ filesUnmeasured: boolean;
47
+ overlapsWith: number[];
48
+ overlapsUnknownWith: number[];
49
+ pendingAfter: number;
50
+ };
34
51
  export type L8ShadowQueueDeps = L8MergeQueueDeps & {
35
52
  observe?: (verdict: L8ShadowVerdict) => void | Promise<void>;
53
+ observeEnqueue?: (entry: L8ShadowEnqueueObservation) => void | Promise<void>;
36
54
  resolveConflict?: (file: string, conflicted: string, target: string, worktree: string) => Promise<string>;
37
55
  };
38
56
 
@@ -80,23 +98,67 @@ export function shadowPrNumber(raw: string): number {
80
98
  return number;
81
99
  }
82
100
 
101
+ // Keep the CLI's existing pending return shape; metadata remains in the shared ledger and enqueue observation.
102
+ function publicShadowQueueState(state: L8ShadowQueueState): L8ShadowQueueState {
103
+ return { ...state, pending: state.pending.map(({ number, head }) => ({ number, head })) };
104
+ }
105
+
83
106
  export async function statusL8ShadowQueue(cwd: string, deps: L8ShadowQueueDeps = {}): Promise<L8ShadowQueueState> {
84
- return withShadowQueue(cwd, deps, async (state) => state);
107
+ return withShadowQueue(cwd, deps, async (state) => publicShadowQueueState(state));
85
108
  }
86
109
 
87
110
  export async function enqueueL8ShadowQueue(cwd: string, number: number, deps: L8ShadowQueueDeps = {}): Promise<L8ShadowQueueState> {
88
111
  if (!Number.isSafeInteger(number) || number <= 0) throw new Error('expected a positive PR number');
89
112
  return withShadowQueue(cwd, deps, async (state, path) => {
90
113
  const execute = deps.command ?? command;
91
- const view = JSON.parse(shadowCommand(execute, 'gh', ['pr', 'view', String(number), '--json', 'headRefOid,baseRefName,state,isDraft,isCrossRepository'], cwd)) as {
114
+ const view = JSON.parse(shadowCommand(execute, 'gh', ['pr', 'view', String(number), '--json', 'headRefOid,baseRefName,state,isDraft,isCrossRepository,files'], cwd)) as {
92
115
  headRefOid?: string; baseRefName?: string; state?: string; isDraft?: boolean; isCrossRepository?: boolean;
116
+ files?: { path?: string }[];
93
117
  };
94
118
  if (!view.headRefOid || !/^[0-9a-f]{40}$/i.test(view.headRefOid) || view.baseRefName !== 'main'
95
119
  || view.state !== 'OPEN' || view.isDraft !== false || view.isCrossRepository !== false) throw new Error('PR is not an open, ready, same-repository main PR');
96
120
  if (state.pending.some((p) => p.number === number)) throw new Error(`PR #${number} already queued`);
97
- state.pending.push({ number, head: view.headRefOid });
121
+ const files = Array.isArray(view.files) && view.files.length < 100
122
+ && view.files.every((file) => typeof file?.path === 'string')
123
+ ? [...new Set(view.files.map((file) => file.path!))].sort()
124
+ : undefined;
125
+ const filesUnmeasured = !files;
126
+ const overlapsWith: number[] = [];
127
+ const overlapsUnknownWith: number[] = [];
128
+ const paths = new Set(files);
129
+ for (const previous of state.pending) {
130
+ if (filesUnmeasured || !Array.isArray(previous.files) || previous.filesUnmeasured) {
131
+ overlapsUnknownWith.push(previous.number);
132
+ } else if (previous.files.some((file) => paths.has(file))) {
133
+ overlapsWith.push(previous.number);
134
+ }
135
+ }
136
+ const item: L8ShadowQueueItem = {
137
+ number, head: view.headRefOid, ...(files ? { files } : { filesUnmeasured: true as const }),
138
+ overlapsWith, overlapsUnknownWith,
139
+ };
140
+ const entry: L8ShadowEnqueueObservation = {
141
+ number, head: view.headRefOid, fileCount: files?.length ?? null, filesUnmeasured,
142
+ overlapsWith, overlapsUnknownWith, pendingAfter: state.pending.length + 1,
143
+ };
144
+ state.pending.push(item);
98
145
  writeShadowQueue(path, state);
99
- return state;
146
+ try {
147
+ await (deps.observeEnqueue ?? ((data) => {
148
+ const store = getDefaultLogStore();
149
+ if (!store) {
150
+ if (process.env.NODE_ENV === 'test') return;
151
+ throw new Error('merge-queue observation store unavailable');
152
+ }
153
+ store.insertBatch([{ rec: { ts: new Date().toISOString(), category: 'merge-queue', event: 'enqueued', data }, surface: 'merge-queue' }]);
154
+ }))(entry);
155
+ } catch (error) {
156
+ // The shared queue is still locked: remove only this unobserved enqueue, leaving older items intact.
157
+ state.pending.pop();
158
+ writeShadowQueue(path, state);
159
+ throw error;
160
+ }
161
+ return publicShadowQueueState(state);
100
162
  });
101
163
  }
102
164