elanous 0.2.22 → 0.2.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (803) hide show
  1. package/NOTICE +7 -0
  2. package/README.md +32 -22
  3. package/apps/pwa/out/404/index.html +1 -1
  4. package/apps/pwa/out/404.html +1 -1
  5. package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → Q-7iofoxOEv1WX18S35of}/_buildManifest.js +1 -1
  6. package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
  9. package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
  10. package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
  11. package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
  12. package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
  13. package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
  15. package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
  24. package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
  25. package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
  28. package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/272-0eed0fb0aab716b6.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
  31. package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
  36. package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3961-aaae04ed1d32622f.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
  40. package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
  49. package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
  53. package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
  54. package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
  57. package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
  65. package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
  70. package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
  72. package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
  74. package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
  75. package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
  79. package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
  84. package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
  85. package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
  86. package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
  88. package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
  91. package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
  98. package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
  100. package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
  102. package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
  103. package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
  106. package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
  111. package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
  112. package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
  113. package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
  115. package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
  117. package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
  118. package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
  121. package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
  124. package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
  125. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/approvals/page-3b9fc39362473ae7.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f2b62c19ca68fef8.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/board/page-d7602d489edf5f37.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/botlab/page-24282bf9f90031a5.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/bots/page-8b7c5ab6b5bc8d64.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/ceo/page-4eb84d454f8c3415.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/chat/page-b2e494bdad57fcb5.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/consult/{page-80ed511e02c81412.js → page-c0ab229673a8b0eb.js} +1 -1
  134. package/apps/pwa/out/_next/static/chunks/app/control/page-3e2b45f3c36dbac4.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c22aa511b28743ad.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/design-check/page-26345242e4049f55.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/editor/page-bf88c0f558d8ef54.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/exec/page-52fec523e5b5d3ad.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/field/page-67723dfdcde92b31.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/inside/page-22725e2570f1126b.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/intake/page-1891335950d68b70.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/layout-3267af1ebdc73cf5.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live/page-c314b75c11234998.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/live-run/page-9f9c85415f61782b.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/loops/page-c1d4276059085587.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/market/page-833aab587f26ad4c.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8526c17ae38e6a50.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/morning/page-f998637a8402115c.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/not-found-b7bb53828b17b335.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/observatory/page-1b1850de0257e46d.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6f23159fedb41f67.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1d809a87139dd024.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-da9e570234d481fd.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/outputs/page-b92caddb5c715f30.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/page-8ce3a38e210b810a.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/reflection/page-57ffeeb6019440fd.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-abbb417bf514630b.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2c2b3f29cec1efa4.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-9369279f72fc7b51.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/settings/page-64861f14039499c3.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ddc4c93efd8ab94b.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/page-901a1391b81053bc.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/share/page-68d9bbaac9841a58.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/showroom/page-b5c0c996f329371e.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/tasks/page-89881ccbcf728978.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/term/page-0e87a803b3d7165e.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/today/page-58d4e5cb30ef4871.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/trace/page-02ce4c3b5f39e4d2.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/vault/page-e620d1bb8eadcec2.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-acf868c64d77f950.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workflows/page-54fa605fa6dba457.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workspace/page-bc79f0833533fa84.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d5c4398eea03d8f3.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
  180. package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
  185. package/apps/pwa/out/_next/static/css/72becfd42807b50d.css +1 -0
  186. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
  187. package/apps/pwa/out/approvals/index.html +1 -1
  188. package/apps/pwa/out/approvals/index.txt +23 -23
  189. package/apps/pwa/out/autopilot/index.html +1 -1
  190. package/apps/pwa/out/autopilot/index.txt +23 -23
  191. package/apps/pwa/out/board/index.html +1 -1
  192. package/apps/pwa/out/board/index.txt +23 -23
  193. package/apps/pwa/out/botlab/index.html +1 -1
  194. package/apps/pwa/out/botlab/index.txt +22 -22
  195. package/apps/pwa/out/bots/index.html +1 -1
  196. package/apps/pwa/out/bots/index.txt +22 -22
  197. package/apps/pwa/out/ceo/index.html +1 -1
  198. package/apps/pwa/out/ceo/index.txt +23 -23
  199. package/apps/pwa/out/chat/index.html +1 -1
  200. package/apps/pwa/out/chat/index.txt +22 -22
  201. package/apps/pwa/out/consult/index.html +1 -1
  202. package/apps/pwa/out/consult/index.txt +23 -23
  203. package/apps/pwa/out/control/index.html +1 -1
  204. package/apps/pwa/out/control/index.txt +23 -23
  205. package/apps/pwa/out/decisions/index.html +1 -1
  206. package/apps/pwa/out/decisions/index.txt +22 -22
  207. package/apps/pwa/out/design-check/index.html +1 -1
  208. package/apps/pwa/out/design-check/index.txt +23 -23
  209. package/apps/pwa/out/editor/index.html +1 -1
  210. package/apps/pwa/out/editor/index.txt +24 -23
  211. package/apps/pwa/out/exec/index.html +1 -1
  212. package/apps/pwa/out/exec/index.txt +23 -23
  213. package/apps/pwa/out/field/index.html +1 -1
  214. package/apps/pwa/out/field/index.txt +23 -23
  215. package/apps/pwa/out/healthz +1 -1
  216. package/apps/pwa/out/index.html +1 -1
  217. package/apps/pwa/out/index.txt +22 -22
  218. package/apps/pwa/out/inside/index.html +1 -1
  219. package/apps/pwa/out/inside/index.txt +22 -22
  220. package/apps/pwa/out/intake/index.html +1 -1
  221. package/apps/pwa/out/intake/index.txt +23 -23
  222. package/apps/pwa/out/live/index.html +1 -1
  223. package/apps/pwa/out/live/index.txt +23 -23
  224. package/apps/pwa/out/live-run/index.html +1 -1
  225. package/apps/pwa/out/live-run/index.txt +24 -23
  226. package/apps/pwa/out/loops/index.html +1 -1
  227. package/apps/pwa/out/loops/index.txt +22 -22
  228. package/apps/pwa/out/market/index.html +1 -1
  229. package/apps/pwa/out/market/index.txt +22 -22
  230. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  231. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  232. package/apps/pwa/out/morning/index.html +1 -1
  233. package/apps/pwa/out/morning/index.txt +23 -23
  234. package/apps/pwa/out/observatory/index.html +1 -1
  235. package/apps/pwa/out/observatory/index.txt +23 -23
  236. package/apps/pwa/out/ops/checklist/index.html +1 -1
  237. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  238. package/apps/pwa/out/ops/release/index.html +1 -1
  239. package/apps/pwa/out/ops/release/index.txt +22 -22
  240. package/apps/pwa/out/ops/seats/index.html +1 -1
  241. package/apps/pwa/out/ops/seats/index.txt +22 -22
  242. package/apps/pwa/out/outputs/index.html +1 -1
  243. package/apps/pwa/out/outputs/index.txt +22 -22
  244. package/apps/pwa/out/reflection/index.html +1 -1
  245. package/apps/pwa/out/reflection/index.txt +23 -23
  246. package/apps/pwa/out/scheduler/index.html +1 -1
  247. package/apps/pwa/out/scheduler/index.txt +23 -23
  248. package/apps/pwa/out/sessions/index.html +1 -1
  249. package/apps/pwa/out/sessions/index.txt +22 -22
  250. package/apps/pwa/out/settings/devices/index.html +1 -1
  251. package/apps/pwa/out/settings/devices/index.txt +23 -23
  252. package/apps/pwa/out/settings/index.html +1 -1
  253. package/apps/pwa/out/settings/index.txt +23 -23
  254. package/apps/pwa/out/setup/done/index.html +1 -1
  255. package/apps/pwa/out/setup/done/index.txt +23 -23
  256. package/apps/pwa/out/setup/index.html +1 -1
  257. package/apps/pwa/out/setup/index.txt +23 -23
  258. package/apps/pwa/out/share/index.html +1 -1
  259. package/apps/pwa/out/share/index.txt +23 -23
  260. package/apps/pwa/out/showroom/index.html +1 -1
  261. package/apps/pwa/out/showroom/index.txt +22 -22
  262. package/apps/pwa/out/tasks/index.html +1 -1
  263. package/apps/pwa/out/tasks/index.txt +23 -23
  264. package/apps/pwa/out/term/index.html +1 -1
  265. package/apps/pwa/out/term/index.txt +23 -23
  266. package/apps/pwa/out/today/index.html +1 -1
  267. package/apps/pwa/out/today/index.txt +23 -23
  268. package/apps/pwa/out/trace/index.html +1 -1
  269. package/apps/pwa/out/trace/index.txt +23 -23
  270. package/apps/pwa/out/vault/index.html +1 -1
  271. package/apps/pwa/out/vault/index.txt +23 -23
  272. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  273. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  274. package/apps/pwa/out/workflows/index.html +1 -1
  275. package/apps/pwa/out/workflows/index.txt +23 -23
  276. package/apps/pwa/out/workspace/index.html +1 -1
  277. package/apps/pwa/out/workspace/index.txt +23 -23
  278. package/apps/pwa/out/worktrees/index.html +1 -1
  279. package/apps/pwa/out/worktrees/index.txt +23 -23
  280. package/catalog/models/anthropic/claude-haiku-5-5.yaml +32 -0
  281. package/catalog/models/anthropic/claude-opus-5-5.yaml +5 -0
  282. package/catalog/models/anthropic/claude-sonnet-5-5.yaml +31 -0
  283. package/catalog/models/anthropic/claude-sonnet-5.yaml +8 -2
  284. package/catalog/models/openai/gpt-6-astra.yaml +6 -0
  285. package/catalog/models/openai/gpt-6-luna.yaml +6 -0
  286. package/catalog/models/openai/gpt-6-sol.yaml +6 -0
  287. package/catalog/models/openrouter/deepseek-v4-pro-0813.yaml +39 -0
  288. package/catalog/models/openrouter/deepseek-v4.1-flash.yaml +38 -0
  289. package/catalog/models/openrouter/glm-5.3-flash.yaml +35 -0
  290. package/catalog/providers/openrouter.yaml +2 -0
  291. package/graphs/implement-loop.yaml +31 -0
  292. package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
  293. package/graphs/log-horizon/recipes.yaml +3 -0
  294. package/graphs/ops/harness-gc.yaml +17 -0
  295. package/graphs/ops/recipes.yaml +3 -0
  296. package/graphs/overlays/README.md +1 -1
  297. package/graphs/overlays/stop-heal-ladder.yaml +105 -0
  298. package/graphs/release/recipes.yaml +1 -1
  299. package/graphs/release/release-loop.yaml +6 -2
  300. package/graphs/release-rehearsal/recipes.yaml +12 -0
  301. package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
  302. package/package.json +4 -1
  303. package/scripts/add-api-key.sh +1 -1
  304. package/scripts/bench-report.ts +82 -3
  305. package/scripts/ci-typecheck-changed.ts +80 -14
  306. package/scripts/fleet/bedrock-pod-secret.ts +122 -0
  307. package/scripts/fleet/node-setup-linux.sh +97 -0
  308. package/scripts/fleet/node-setup.sh +11 -0
  309. package/scripts/fleet/zai-pod-secret.ts +86 -0
  310. package/scripts/hq/hq-fence-wrapper.sh +148 -0
  311. package/scripts/land-global-checks.ts +3 -0
  312. package/scripts/lib/typecheck-ratchet.ts +51 -0
  313. package/scripts/measure-log-diet-2.ts +213 -0
  314. package/scripts/measure-tsc-affected-roots.ts +289 -0
  315. package/scripts/openai-relay-server.ts +5 -1
  316. package/scripts/release-loop/docs-node.ts +258 -43
  317. package/scripts/release-loop/gate-executor.ts +28 -0
  318. package/scripts/release-loop/gate-method.ts +59 -0
  319. package/scripts/release-loop/gate-node.ts +335 -33
  320. package/scripts/release-loop/gate-wall.ts +208 -0
  321. package/scripts/release-loop/known-issues-node.ts +53 -8
  322. package/scripts/release-loop/publish-at.ts +14 -0
  323. package/scripts/release-loop/publish-node.ts +17 -2
  324. package/scripts/release-loop/resume-release.ts +40 -4
  325. package/scripts/release-loop/resume.ts +94 -0
  326. package/scripts/release-loop/shard-plan.ts +3 -11
  327. package/scripts/release-loop/tui-node-checks.ts +22 -0
  328. package/scripts/release-loop/unattended-release.ts +29 -7
  329. package/scripts/rhythm/daily.ts +51 -2
  330. package/scripts/rhythm/weekly.ts +3 -2
  331. package/scripts/tsc-baseline-cache.ts +147 -0
  332. package/scripts/tsc-main-safety-net.ts +189 -0
  333. package/scripts/usage-rollup.ts +64 -8
  334. package/src/acp/codex-plugins.ts +48 -6
  335. package/src/agent/monad-agent-turn.ts +67 -5
  336. package/src/agent/run-context.ts +20 -0
  337. package/src/agent/tool-profile.ts +28 -2
  338. package/src/agent-mission/acp-judge.ts +8 -2
  339. package/src/agent-mission/capabilities-cli.ts +16 -1
  340. package/src/agent-mission/driver.ts +19 -4
  341. package/src/agent-mission/pr-review-watch.ts +6 -2
  342. package/src/agent-mission/resource-ladder.ts +8 -3
  343. package/src/agent-mission/review-loop.ts +41 -7
  344. package/src/agent-substrate/acp-implementer.ts +139 -0
  345. package/src/agent-substrate/acp-reviewer.ts +17 -8
  346. package/src/agent-substrate/pr-reviewer.ts +191 -28
  347. package/src/agent-substrate/review-intent.ts +6 -4
  348. package/src/agent-substrate/self-review-cli.ts +155 -21
  349. package/src/agent-substrate/shard-boundary-intent.ts +92 -26
  350. package/src/ask-user-question/pending-questions.ts +8 -2
  351. package/src/autopilot/build/llm-conflict-merge.ts +216 -12
  352. package/src/autopilot/codebase-grounding.ts +44 -0
  353. package/src/autopilot/llm-control-brain.ts +13 -1
  354. package/src/autopilot/mission-codebase-gate.ts +8 -77
  355. package/src/autopilot/mission-critique.ts +18 -5
  356. package/src/autopilot/mission-feasibility-negotiate.ts +11 -10
  357. package/src/autopilot/mission-trace.ts +12 -1
  358. package/src/autopilot/pr-manager.ts +12 -3
  359. package/src/autopilot/system-lookback-run.ts +16 -10
  360. package/src/bench/bench.ts +183 -0
  361. package/src/boot/acp-server.ts +4 -7
  362. package/src/boot/acp-socket-path.ts +7 -0
  363. package/src/briefing/brief-items.ts +21 -13
  364. package/src/budget/fetchers/grok.ts +15 -5
  365. package/src/budget/llm-cost.ts +37 -5
  366. package/src/budget/types.ts +8 -2
  367. package/src/budget/unified-usage.ts +88 -6
  368. package/src/chat/index.ts +12 -3
  369. package/src/cli/agent-cli.ts +20 -0
  370. package/src/cli/bench-cli.ts +34 -0
  371. package/src/cli/brief-cli.ts +27 -21
  372. package/src/cli/cli-user-error.ts +9 -2
  373. package/src/cli/guardian-cli.ts +26 -1
  374. package/src/cli/image-cli.ts +101 -0
  375. package/src/cli/log-event-names.ts +7 -0
  376. package/src/cli/logs-cli.ts +1 -0
  377. package/src/cli/mcp-login.ts +111 -37
  378. package/src/cli/plugin-cli.ts +21 -1
  379. package/src/cli/pod-cli.ts +26 -0
  380. package/src/cli/pr-cli.ts +90 -5
  381. package/src/cli/pr-land-overlap-evidence.ts +279 -0
  382. package/src/cli/release-cli.ts +63 -12
  383. package/src/cli/rfc-status.ts +52 -2
  384. package/src/cli/self-update.ts +277 -10
  385. package/src/cli/skills-cli.ts +12 -3
  386. package/src/cli/tasks-cli.ts +241 -30
  387. package/src/cli/usage-cli.ts +91 -8
  388. package/src/context-bus/context-first.ts +51 -2
  389. package/src/context-bus/context-now-surfaces.ts +13 -2
  390. package/src/context-bus/long-term-memory.ts +3 -1
  391. package/src/context-bus/nightly-condense.ts +3 -2
  392. package/src/core-turn/run-goal-loop.ts +87 -2
  393. package/src/dashboard/ad-run-setup-bindings.ts +279 -0
  394. package/src/dashboard/chat-fold.ts +20 -0
  395. package/src/dashboard/first-screen-band.ts +151 -1
  396. package/src/dashboard/index.ts +45 -281
  397. package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -3
  398. package/src/dashboard/stale-install-check.ts +24 -2
  399. package/src/dashboard/turn-stream-formatter.ts +25 -0
  400. package/src/debug/log-diet.ts +190 -0
  401. package/src/debug/log.ts +70 -17
  402. package/src/display/coordinator.ts +25 -2
  403. package/src/domains/coo-admin-tool.ts +27 -0
  404. package/src/domains/cron-match.ts +1 -0
  405. package/src/domains/outbound-alert.ts +17 -6
  406. package/src/domains/release-tool.ts +158 -10
  407. package/src/domains/schedule-registry.ts +10 -7
  408. package/src/domains/schedule-runner.ts +1 -0
  409. package/src/elanous-config-dir.ts +2 -2
  410. package/src/elanous-daemon.ts +3 -3
  411. package/src/error-report/report.ts +21 -4
  412. package/src/execution-loop/launch-gate.ts +1 -1
  413. package/src/expression/i18n/messages.en.ts +5 -0
  414. package/src/expression/i18n/messages.ja.ts +5 -0
  415. package/src/expression/i18n/messages.ko.ts +5 -0
  416. package/src/expression/i18n/messages.zh.ts +5 -0
  417. package/src/expression/i18n/types.ts +8 -0
  418. package/src/github/pr-labels.ts +2 -0
  419. package/src/graph-runner/graph-cli.ts +42 -1
  420. package/src/graph-runner/runner.ts +218 -8
  421. package/src/grok/usage.ts +23 -2
  422. package/src/grounding/ref-index.ts +253 -0
  423. package/src/harness/dispatch-backpressure.ts +267 -0
  424. package/src/harness/harness-clean.ts +199 -78
  425. package/src/harness/harness-cli-command.ts +229 -35
  426. package/src/harness/harness-gc.ts +331 -0
  427. package/src/harness/harness-seams.ts +2 -20
  428. package/src/harness/harness-stop.ts +4 -2
  429. package/src/harness/harness-substrate-default.ts +214 -8
  430. package/src/harness/launch-registry.ts +6 -0
  431. package/src/harness/nested-elanous-policy.ts +4 -2
  432. package/src/harness/worktree-branch-prefix.ts +9 -0
  433. package/src/hq/fence-wrapper.ts +7 -0
  434. package/src/hq/fence.ts +187 -0
  435. package/src/hq/hq.ts +33 -2
  436. package/src/hq/lease.ts +13 -0
  437. package/src/hq/seats.ts +133 -21
  438. package/src/images/image-ledger.ts +179 -0
  439. package/src/index.ts +250 -69
  440. package/src/instance/child-scope.ts +32 -1
  441. package/src/instance/dev-project.ts +133 -0
  442. package/src/instance/resolve.ts +24 -0
  443. package/src/instance/spawn-elanous.ts +45 -0
  444. package/src/intake-plane/collect-github.ts +19 -1
  445. package/src/intake-plane/digest.ts +45 -20
  446. package/src/intake-plane/lens.ts +36 -8
  447. package/src/intake-plane/ref-prefetch.ts +110 -0
  448. package/src/intelligence-map/model-alias.ts +6 -0
  449. package/src/intelligence-map/model-catalog.ts +113 -0
  450. package/src/knowledge/kgs/pack.ts +5 -2
  451. package/src/knowledge/kgs/sqlite-store.ts +15 -0
  452. package/src/knowledge/tools/knowledge-query.ts +20 -2
  453. package/src/knowledge/write.ts +234 -2
  454. package/src/llm/bedrock-eventstream.ts +215 -0
  455. package/src/llm/bedrock-provider.ts +248 -0
  456. package/src/llm/bedrock.ts +491 -0
  457. package/src/llm/openrouter-byok-cost.ts +96 -0
  458. package/src/llm/openrouter-deepseek.ts +151 -0
  459. package/src/llm/openrouter-upstream-pins.config.ts +25 -0
  460. package/src/llm/provider-credentials.ts +3 -1
  461. package/src/llm/zai-coding-plan.ts +700 -0
  462. package/src/llm.ts +383 -41
  463. package/src/loops/budget.ts +150 -0
  464. package/src/loops/checker.ts +148 -9
  465. package/src/loops/orchestrator/resync-shadow.ts +34 -7
  466. package/src/loops/orchestrator/seat-share.ts +6 -49
  467. package/src/loops/orchestrator/traffic.ts +5 -81
  468. package/src/market/signed-index.ts +42 -0
  469. package/src/maturity/feature-maturity.ts +2 -2
  470. package/src/mcp/mcp-oauth.ts +136 -17
  471. package/src/model-tier/llm-tier-map.ts +52 -4
  472. package/src/models/prompts.ts +23 -1
  473. package/src/mss/logging/horizon-watch.ts +168 -0
  474. package/src/mss/logging/log-store.ts +262 -26
  475. package/src/native-tool-catalog.ts +1 -1
  476. package/src/nexus/api/consult-requests.ts +7 -10
  477. package/src/nexus/api/discord-trigger-bot.ts +6 -3
  478. package/src/nexus/api/error-reports.ts +30 -8
  479. package/src/nexus/api/http-server.ts +8 -0
  480. package/src/nexus/api/loop-resources.ts +42 -0
  481. package/src/nexus/api/missions.ts +73 -2
  482. package/src/nexus/api/ops-api.ts +18 -0
  483. package/src/nexus/api/outbound-report.ts +8 -3
  484. package/src/nexus/api/telegram-trigger-bot.ts +6 -3
  485. package/src/nexus/index.ts +17 -75
  486. package/src/nexus/outbound/format.ts +2 -0
  487. package/src/nexus/outbound/router.ts +198 -13
  488. package/src/nexus/tools-kind.ts +78 -0
  489. package/src/oauth/codex-account-rotation.ts +55 -20
  490. package/src/oauth/codex-account-store.ts +451 -23
  491. package/src/oauth/fallback-chain.ts +75 -15
  492. package/src/onboarding/first-run.ts +37 -18
  493. package/src/onboarding/web-first.ts +20 -2
  494. package/src/onboarding.ts +2 -1
  495. package/src/ops/machine-heartbeat.ts +185 -0
  496. package/src/ops/overview-cache.ts +175 -0
  497. package/src/ops/overview.ts +8 -0
  498. package/src/plugins/adapters/claude-package.ts +4 -12
  499. package/src/plugins/core/capability-policy.ts +141 -0
  500. package/src/plugins/core/host.ts +21 -8
  501. package/src/plugins/core/manifest.ts +19 -2
  502. package/src/plugins/core/trust-store.ts +15 -0
  503. package/src/plugins/core/types.ts +12 -0
  504. package/src/plugins/install/market-fetch.ts +68 -16
  505. package/src/plugins/install/plugin-install.ts +187 -16
  506. package/src/plugins/maker/plugin-maker.ts +25 -20
  507. package/src/plugins/maker/wizard-generate.ts +16 -2
  508. package/src/policy/llm-policy.ts +14 -1
  509. package/src/process/pid-liveness.ts +1 -1
  510. package/src/prompt-cache/openai.ts +13 -6
  511. package/src/prompt-cache/openrouter.ts +94 -0
  512. package/src/prompt-cache/types.ts +5 -0
  513. package/src/prompt-enhance/enhance.ts +69 -5
  514. package/src/prompt-library/family-prompt-coverage.ts +1 -0
  515. package/src/prompt-library/universal-preamble.ts +2 -2
  516. package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
  517. package/src/registry/loader.ts +6 -1
  518. package/src/release-loop/checklist.ts +24 -9
  519. package/src/release-loop/feature-store.ts +3 -0
  520. package/src/release-loop/gate-shards.ts +48 -4
  521. package/src/release-loop/landed-to-green.ts +81 -0
  522. package/src/release-loop/light-rc.ts +11 -1
  523. package/src/release-loop/merged-pr-checklist.ts +10 -0
  524. package/src/release-loop/placement.ts +107 -23
  525. package/src/release-loop/rehearsal.ts +317 -0
  526. package/src/release-loop/release-schedule.ts +13 -1
  527. package/src/release-loop/rubric-types.ts +1 -0
  528. package/src/release-loop/rubric.ts +2 -2
  529. package/src/requirements/requirement-ledger.ts +536 -0
  530. package/src/retro/daily.ts +26 -12
  531. package/src/seat-loop/seat-loop.ts +66 -11
  532. package/src/seat-loop/traffic-signal.ts +44 -0
  533. package/src/self-dev/ask-launch-flow.ts +2 -2
  534. package/src/self-dev/dev-cli.ts +109 -11
  535. package/src/self-dev/dev-pipeline.ts +11 -8
  536. package/src/self-dev/draft-residue.ts +475 -0
  537. package/src/self-dev/draft-sweep.ts +254 -10
  538. package/src/self-dev/draft-triage-rules.ts +27 -1
  539. package/src/self-dev/graph-journey-route.ts +6 -0
  540. package/src/self-dev/launch-preflight-text.ts +549 -0
  541. package/src/self-dev/launch-preflight.ts +10 -545
  542. package/src/self-dev/orchestrate-cli.ts +82 -5
  543. package/src/self-dev/orchestrate-summary-line.ts +13 -0
  544. package/src/self-dev/orchestrate.ts +49 -141
  545. package/src/self-dev/review-provider-fallback.ts +115 -19
  546. package/src/self-dev/run-store.ts +1 -3
  547. package/src/self-dev/run-supervisor.ts +190 -36
  548. package/src/self-dev/run-types.ts +191 -0
  549. package/src/self-dev/shard-aggregate.ts +61 -13
  550. package/src/self-dev/shard-plan.ts +5 -1
  551. package/src/self-dev/shard-run.ts +23 -5
  552. package/src/self-dev/supervisor-verdict-edges.ts +3 -4
  553. package/src/self-implement/blocked-draft-policy.ts +3 -19
  554. package/src/self-implement/budget-gate.ts +53 -13
  555. package/src/self-implement/child-context-composition.ts +139 -0
  556. package/src/self-implement/child-llm-preference.ts +13 -5
  557. package/src/self-implement/claude-acp-implement.ts +67 -0
  558. package/src/self-implement/draft-on-stop-mode.ts +18 -0
  559. package/src/self-implement/flex-signals.ts +59 -0
  560. package/src/self-implement/follow-up-goals.ts +114 -38
  561. package/src/self-implement/frozen-merges.ts +8 -3
  562. package/src/self-implement/gate-baseline-reap.ts +157 -0
  563. package/src/self-implement/gate-baseline.ts +78 -16
  564. package/src/self-implement/gate-cli.ts +12 -2
  565. package/src/self-implement/gate-remote.ts +17 -6
  566. package/src/self-implement/goal-author-decompose.ts +10 -2
  567. package/src/self-implement/goal-author.ts +48 -13
  568. package/src/self-implement/goal-digest.ts +19 -0
  569. package/src/self-implement/graph-overlay-condition.ts +32 -0
  570. package/src/self-implement/graph-overlay-yaml.ts +41 -7
  571. package/src/self-implement/graph-templates.ts +33 -1
  572. package/src/self-implement/graph-yaml.ts +56 -0
  573. package/src/self-implement/headless-elanous-driver.ts +11 -9
  574. package/src/self-implement/heal-intake.ts +5 -1
  575. package/src/self-implement/host-regate.ts +120 -29
  576. package/src/self-implement/l8-merge-queue.ts +67 -5
  577. package/src/self-implement/merge-train.ts +131 -0
  578. package/src/self-implement/off-diff-evidence.ts +9 -0
  579. package/src/self-implement/orchestrator.ts +271 -25
  580. package/src/self-implement/review-finding-recurrence.ts +28 -0
  581. package/src/self-implement/rework-policy.ts +2 -1
  582. package/src/self-implement/round-summary-card.ts +63 -0
  583. package/src/self-implement/run-ledger.ts +4 -3
  584. package/src/self-implement/run-step-projection.ts +147 -0
  585. package/src/self-implement/run-stop.ts +1 -1
  586. package/src/self-implement/running-runs.ts +75 -5
  587. package/src/self-implement/seams.ts +83 -4
  588. package/src/self-implement/self-implement-cli.ts +12 -5
  589. package/src/self-implement/stop-autoheal.ts +69 -2
  590. package/src/self-implement/train-gate-remote.ts +158 -0
  591. package/src/session-runtime/index.ts +10 -1
  592. package/src/session-runtime/retry-api.ts +11 -1
  593. package/src/session-runtime/retry-policy.ts +2 -1
  594. package/src/skills/gift-install.ts +119 -0
  595. package/src/skills/runner.ts +59 -2
  596. package/src/skills/skill-feedback.ts +31 -1
  597. package/src/skills/skill-tier.ts +1 -0
  598. package/src/smart-wizard/capability-index.ts +231 -0
  599. package/src/smart-wizard/rung.ts +74 -0
  600. package/src/steward/launch.ts +22 -10
  601. package/src/steward/triage-budget.ts +62 -0
  602. package/src/steward/triage.ts +87 -24
  603. package/src/storage/file-lock.ts +8 -1
  604. package/src/task-agent/actions.ts +66 -5
  605. package/src/task-agent/card-evidence.ts +59 -13
  606. package/src/task-agent/completion-evidence.ts +5 -0
  607. package/src/task-agent/cover.ts +101 -3
  608. package/src/task-agent/judge.ts +20 -3
  609. package/src/task-agent/land-order-ledger.ts +95 -0
  610. package/src/task-agent/land-worktree.ts +201 -0
  611. package/src/task-agent/live-move-history.ts +219 -0
  612. package/src/task-agent/live-moves.ts +451 -34
  613. package/src/task-agent/parent-host.ts +117 -8
  614. package/src/task-agent/rejudge-on-head.ts +352 -0
  615. package/src/task-agent/review-prior-fix.ts +146 -0
  616. package/src/task-agent/review-result-capture.ts +218 -0
  617. package/src/task-agent/run-adopt.ts +136 -0
  618. package/src/task-agent/shadow.ts +154 -14
  619. package/src/task-agent/task-hand.ts +186 -14
  620. package/src/task-orchestrator/surfaces/pod-account-broker.ts +38 -5
  621. package/src/task-orchestrator/surfaces/pod-bedrock-child.ts +74 -0
  622. package/src/task-orchestrator/surfaces/pod-child-default.ts +50 -0
  623. package/src/task-orchestrator/surfaces/pod-child-providers.ts +42 -0
  624. package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
  625. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +94 -7
  626. package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
  627. package/src/task-orchestrator/surfaces/pod-lease.ts +110 -17
  628. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +32 -3
  629. package/src/task-orchestrator/surfaces/pod-pool.ts +86 -18
  630. package/src/task-orchestrator/surfaces/pod-zai-child.ts +101 -0
  631. package/src/task-orchestrator/surfaces/self-implement-pod.ts +463 -50
  632. package/src/task-orchestrator/surfaces/self-implement.ts +25 -3
  633. package/src/telegram-service.ts +5 -1
  634. package/src/telegram.ts +17 -4
  635. package/src/time/format.ts +13 -4
  636. package/src/tool-runtime/goal-author-runtime.ts +1 -0
  637. package/src/tool-runtime/self-cognition-catalog.ts +23 -0
  638. package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
  639. package/src/typecheck-ratchet.ts +1 -0
  640. package/src/user-config.ts +180 -32
  641. package/src/ux-sim/slash-menu-frames.ts +168 -0
  642. package/src/version/packed-revision.json +1 -1
  643. package/src/web-terminal/preview-tap-registry.ts +5 -2
  644. package/src/workflow-runtime/triggers/registry.ts +59 -0
  645. package/src/workflow-runtime/triggers/scheduler.ts +1 -0
  646. package/src/workflow-runtime/triggers/webhook-source.ts +35 -5
  647. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
  648. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
  649. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
  650. package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
  652. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
  653. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
  654. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
  656. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
  661. package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
  670. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
  671. package/apps/pwa/out/_next/static/chunks/2489-d238d3e2eb5b2bf5.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
  684. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
  692. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
  697. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
  699. package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
  703. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
  708. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
  713. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
  714. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
  716. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
  717. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
  725. package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
  728. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
  738. package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
  741. package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
  745. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
  746. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/approvals/page-88459e0903da2803.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d85c43f46f58716b.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/board/page-4e645600579ae952.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/botlab/page-87edbfd19117823b.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/chat/page-cbaf66b1e1804adf.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/control/page-9f5610caaa06178c.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/decisions/page-ec8f3575e339de74.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/exec/page-2a19c5cd3b562580.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/field/page-b6a09cde2e07521a.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/loops/page-abd86cd832aaa011.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8c3f168fc3f91939.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/morning/page-786fb4504d0f2fa9.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7ec8e289b4c14df6.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-8c8ac17d52be2a79.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d359ab048d63a9d9.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/settings/page-f151cc10ad026940.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/share/page-bf495a1e284f4e00.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/app/term/page-9abcfac07e02a542.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/app/workflows/page-69cb93d1a2e57e0e.js +0 -1
  794. package/apps/pwa/out/_next/static/chunks/app/workspace/page-72ec543928d67c3e.js +0 -1
  795. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +0 -1
  796. package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
  797. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
  798. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
  799. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
  800. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
  801. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
  802. package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +0 -1
  803. /package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → Q-7iofoxOEv1WX18S35of}/_ssgManifest.js +0 -0
@@ -21,8 +21,12 @@ import { ACP_BACKENDS, canonicalizeBackendId } from '../acp/backend-registry.js'
21
21
  import { buildManualReviewIntent, intentFromPr, prIntentSectionCoverage, reviewIntentTruncationFromPr, reviewIntentTruncationObservation } from './review-intent.js';
22
22
  import { budgetReviewerContext, reviewDiffBudgetObservation, splitDiffByFile, type ReviewImage, type ReviewInput, type ReviewerContextItem, type ReviewResult } from './pr-reviewer.js';
23
23
  import type { ReferencedFileReader } from '../self-implement/goal-file-reader.js';
24
+ import type { SubscriptionReviewerSpec } from '../user-config.js';
24
25
  import { listRunLedgers, lookupPrGoalAcceptance, lookupRunLedger, type PrGoalAcceptanceLookup, type RunLedgerEntry, type RunLedgerLookup } from '../self-implement/run-ledger.js';
25
26
 
27
+ /** SUBSCRIPTION-EXHAUST-REROUTE — API reviewer when the configured `roleLlm.reviewer` lane is unavailable (off codex). */
28
+ export const ROLE_REVIEWER_FALLBACK_MODEL = 'openrouter/z-ai/glm-5.3';
29
+
26
30
  export interface SelfReviewCliOpts {
27
31
  intent?: string | undefined;
28
32
  model?: string | undefined;
@@ -30,6 +34,8 @@ export interface SelfReviewCliOpts {
30
34
  acpModel?: string | undefined;
31
35
  acpBackend?: string | undefined;
32
36
  configuredAcpBackend?: string | undefined;
37
+ /** `roleLlm.reviewer` (same resolution as the harness). Used only when no explicit reviewer flag is given. */
38
+ roleReviewer?: SubscriptionReviewerSpec | undefined;
33
39
  acpTimeout?: string | undefined;
34
40
  context?: string[] | undefined;
35
41
  contextText?: string[] | undefined;
@@ -51,8 +57,13 @@ export interface SelfReviewCliDeps {
51
57
  * (`#7486` 리뷰 must-fix · 실제로 `index.ts` 래퍼가 그렇게 한 번 떨어뜨렸다). */
52
58
  reviewPullRequest(input: ReviewInput, llm: (prompt: string, images?: readonly ReviewImage[]) => Promise<string>): Promise<ReviewResult>;
53
59
  renderReview(review: ReviewResult): string;
54
- /** 기본 경로 리뷰어 LLM(API). */
55
- makeApiLlm(model: string): (prompt: string) => Promise<string>;
60
+ /**
61
+ * 기본 경로 리뷰어 LLM(API).
62
+ * `o.pinProvider` — 명시 `--model` 일 때 true: 구현은 streamLLM 의 provider 를 그 모델의 provider 로 고정해
63
+ * 라우터 폴백(grok 등)으로 조용히 넘어가지 않고 실패를 오류로 낸다.
64
+ * `o.onResolved` — streamLLM 이 «실제로 응답한» provider·model 을 알린다.
65
+ */
66
+ makeApiLlm(model: string, o?: { pinProvider?: boolean; onResolved?: (provider: string, model: string) => void }): (prompt: string) => Promise<string>;
56
67
  /** `--acp` 경로 리뷰어 LLM(독립 프로세스). */
57
68
  /**
58
69
  * ⭐ `P4b` — 두 번째 인자가 **멀티미디어 통로**다.
@@ -65,6 +76,19 @@ export interface SelfReviewCliDeps {
65
76
  * ⚠️ API 백엔드(`makeApiLlm`)는 이 인자를 안 받는다 — ACP 경로만 이미지를 나른다.
66
77
  */
67
78
  makeAcpLlm(o: { backend: string; model?: string; timeoutMs: number }): (prompt: string, images?: readonly ReviewImage[]) => Promise<string>;
79
+ /**
80
+ * Reviewer ACP lane selected by `roleLlm.reviewer` (no explicit flag). Returns the LLM when the
81
+ * subscription is usable, or a reason code when it is not — the caller then reviews on the API
82
+ * exactly as before. Absent seam = the lane is unavailable (`role-reviewer-seam-missing`).
83
+ */
84
+ makeRoleReviewerLlm?(spec: SubscriptionReviewerSpec, o: { timeoutMs: number }):
85
+ | { llm: (prompt: string, images?: readonly ReviewImage[]) => Promise<string>; backend: string }
86
+ | { reason: string };
87
+ /**
88
+ * SUBSCRIPTION-EXHAUST-REROUTE — API model used when `roleLlm.reviewer` is configured (no explicit flag) but its
89
+ * lane is unavailable or fails. Absent seam or empty answer = the codex-ladder default as before.
90
+ */
91
+ roleFallbackModel?(): string | undefined;
68
92
  /** 관측 sink 등록 — ⭐ 이 호출이 분기 밖에 있는지가 이 트랙의 계약이다. */
69
93
  registerSink(surface: string): Promise<void>;
70
94
  /** `data` 는 payload 객체 — 순수 헬퍼가 만든 관측 타입도 그대로 받는다(인덱스 시그니처 강요 금지). */
@@ -84,6 +108,8 @@ export interface SelfReviewCliDeps {
84
108
 
85
109
  export interface SelfReviewCliOutcome {
86
110
  results: Array<Record<string, unknown>>;
111
+ /** 리뷰하지 못한 PR 수(`gh pr diff` 실패 · ACP 리뷰 reviewed=false) — json·비json 둘 다 센다. index.ts 가 1 이상이면 rc=1. */
112
+ failed: number;
87
113
  }
88
114
 
89
115
  interface GhResult {
@@ -1083,6 +1109,12 @@ function reviewerContextOutput(loaded: LoadedReviewerContext, decomposition?: De
1083
1109
 
1084
1110
  const MAX_ACP_REVIEW_FALLBACK_CANDIDATES = 4;
1085
1111
 
1112
+ /** Same reason codes as the harness lane (`runSubscriptionReviewer`) — a raw message may carry account or proxy details. */
1113
+ function roleAcpErrorReason(error: unknown): 'acp-handshake-timeout' | 'acp-error' {
1114
+ const message = error instanceof Error ? error.message : String(error);
1115
+ return /handshake timeout/i.test(message) ? 'acp-handshake-timeout' : 'acp-error';
1116
+ }
1117
+
1086
1118
  type AcpFallbackSkip = { backend: string; reason: string };
1087
1119
 
1088
1120
  function orderedAcpReviewFallbackBackends(configuredBackend: string | undefined): {
@@ -1133,6 +1165,14 @@ export function renderReviewerContextStatus(loaded: LoadedReviewerContext, decom
1133
1165
  }
1134
1166
 
1135
1167
  /** `elanous self review <pr...>` 본문. read-only — 머지하지 않는다. */
1168
+ /**
1169
+ * `self review --json` stdout 한 줄 — 결과가 하나면 객체, 여럿이면 배열. index.ts 액션이 이것을 그대로 쓴다.
1170
+ * TA-REVIEW-RESULT-CAPTURE — task agent 는 떼어 띄운 리뷰의 stdout 을 파일로 받아 이 줄을 읽는다(형식 계약 = 이 함수).
1171
+ */
1172
+ export function selfReviewJsonLine(results: readonly unknown[]): string {
1173
+ return JSON.stringify(results.length === 1 ? results[0] : results) + '\n';
1174
+ }
1175
+
1136
1176
  export async function runSelfReviewCliCommand(
1137
1177
  prArgs: string[],
1138
1178
  opts: SelfReviewCliOpts,
@@ -1150,7 +1190,7 @@ export async function runSelfReviewCliCommand(
1150
1190
  invalidPrArgs: safeInvalidPrArgs,
1151
1191
  }, { level: 'warn' });
1152
1192
  deps.error(`PR 인자가 올바르지 않습니다: ${safeInvalidPrArgs.join(', ')}. PR 번호는 숫자 형식이어야 합니다 (예: elanous self review 5502).`);
1153
- return { results: [] };
1193
+ return { results: [], failed: 0 };
1154
1194
  }
1155
1195
 
1156
1196
  const useAcp = opts.acp === true;
@@ -1172,8 +1212,53 @@ export async function runSelfReviewCliCommand(
1172
1212
  if (useAcp) {
1173
1213
  acpReviewLLM = deps.makeAcpLlm({ backend: acpBackend, ...(acpModel ? { model: acpModel } : {}), timeoutMs: acpTimeoutSec * 1000 });
1174
1214
  }
1175
- const model = useAcp ? `acp:${acpBackend}${acpModel ? `/${acpModel}` : ''}` : (opts.model || deps.envModel() || tierModel('better'));
1215
+ // ⭐ Reviewer selection source. An explicit flag always wins byte-for-byte; only without one does
1216
+ // `roleLlm.reviewer` (the harness's reviewer row) pick the ACP lane. Worst case = today's API review.
1217
+ const explicitReviewerFlag = opts.acp === true || Boolean(opts.acpBackend) || Boolean(opts.acpModel?.trim()) || Boolean(opts.model?.trim());
1218
+ const reviewerSource: 'cli' | 'role-config' | 'default' = explicitReviewerFlag ? 'cli' : opts.roleReviewer ? 'role-config' : 'default';
1219
+ // SUBSCRIPTION-EXHAUST-REROUTE (0.2.24): when `roleLlm.reviewer` is configured but its lane is unavailable
1220
+ // (10-11 prod: «Claude subscription usage unavailable or at harness cap (60%)»), the API fallback was the codex
1221
+ // ladder default (`tierModel('better')` = gpt-6-sol) — the CLI read roleLlm.reviewer, then spent codex anyway.
1222
+ // ⇒ the role-config lane falls back to `roleFallbackModel()` (off codex) when the seam gives one. Explicit flag
1223
+ // and ELANOUS_PR_REVIEW_MODEL still win; no seam / no answer = today's default byte-for-byte.
1224
+ const envModel = deps.envModel();
1225
+ const roleFallbackModel = !useAcp && !opts.model && !envModel && reviewerSource === 'role-config'
1226
+ ? deps.roleFallbackModel?.()?.trim() || undefined : undefined;
1227
+ const model = useAcp ? `acp:${acpBackend}${acpModel ? `/${acpModel}` : ''}` : (opts.model || envModel || roleFallbackModel || tierModel('better'));
1228
+ let roleReviewer: { llm: (prompt: string, images?: readonly ReviewImage[]) => Promise<string>; model: string } | undefined;
1229
+ let roleReviewerUnavailableReason: string | undefined;
1230
+ let roleReviewerAvailabilityMs: number | undefined;
1231
+ // ⚠️ Availability (subscription ⊕ usage cap ⊕ proxy URL) is checked once per command, not per PR —
1232
+ // a mid-run change is caught by the per-PR review attempt failing and falling back to the API.
1233
+ if (reviewerSource === 'role-config' && opts.roleReviewer) {
1234
+ const availabilityStartedAt = deps.now();
1235
+ try {
1236
+ const made = deps.makeRoleReviewerLlm
1237
+ ? deps.makeRoleReviewerLlm(opts.roleReviewer, { timeoutMs: acpTimeoutSec * 1000 })
1238
+ : { reason: 'role-reviewer-seam-missing' };
1239
+ if ('llm' in made) roleReviewer = { llm: made.llm, model: `acp:${made.backend}` };
1240
+ else roleReviewerUnavailableReason = safeLogText(made.reason, 400);
1241
+ } catch (error) {
1242
+ roleReviewerUnavailableReason = roleAcpErrorReason(error);
1243
+ }
1244
+ roleReviewerAvailabilityMs = deps.now() - availabilityStartedAt;
1245
+ if (roleReviewerUnavailableReason) {
1246
+ deps.log('role-reviewer-fallback', {
1247
+ reviewerSource, roleReviewerProvider: opts.roleReviewer.provider, roleReviewerAvailabilityMs,
1248
+ stage: 'availability', reason: roleReviewerUnavailableReason, fallbackModel: safeLogText(model),
1249
+ fallbackModelSource: roleFallbackModel ? 'role-fallback' : 'default',
1250
+ }, { level: 'warn' });
1251
+ }
1252
+ }
1253
+ const primaryModel = roleReviewer?.model ?? model;
1254
+ const reviewerSourceObservation = (): Record<string, unknown> => ({
1255
+ reviewerSource,
1256
+ ...(reviewerSource === 'role-config' && opts.roleReviewer ? { roleReviewerProvider: opts.roleReviewer.provider } : {}),
1257
+ ...(roleReviewerAvailabilityMs !== undefined ? { roleReviewerAvailabilityMs } : {}),
1258
+ ...(roleReviewerUnavailableReason ? { roleReviewerFallbackReason: roleReviewerUnavailableReason } : {}),
1259
+ });
1176
1260
  const results: Array<Record<string, unknown>> = [];
1261
+ let failed = 0;
1177
1262
  const providedReviewerContext = loadReviewerContext(opts, deps.readReferencedFile);
1178
1263
  const hasProvidedReviewerContext = (opts.contextOrder?.length ?? 0) > 0 || (opts.context?.length ?? 0) > 0 || (opts.contextText?.length ?? 0) > 0;
1179
1264
  for (const pr of prArgs) {
@@ -1220,8 +1305,10 @@ export async function runSelfReviewCliCommand(
1220
1305
  if (!intent) intent = `PR ${pr}`;
1221
1306
  }
1222
1307
  const startObservation = (extra: Record<string, unknown> = {}) => deps.log('start', {
1223
- pr: safeLogText(pr), model: safeLogText(model),
1224
- backend: safeLogText(useAcp ? `acp:${acpBackend}` : 'api'),
1308
+ pr: safeLogText(pr), model: safeLogText(primaryModel),
1309
+ ...reviewerSourceObservation(),
1310
+ ...(roleReviewer ? { roleReviewerModel: safeLogText(roleReviewer.model) } : {}),
1311
+ backend: safeLogText(useAcp ? `acp:${acpBackend}` : roleReviewer ? roleReviewer.model : 'api'),
1225
1312
  ...(useAcp ? { acpBackend: safeLogText(acpBackend), acpBackendSource: acpBackendResolution.source } : {}),
1226
1313
  intentChars: intent.length, intentGiven: opts.intent !== undefined, intentSource,
1227
1314
  reviewerContextLoaded: reviewerContext.items.length, reviewerContextFailed: reviewerContext.failed.length,
@@ -1249,6 +1336,7 @@ export async function runSelfReviewCliCommand(
1249
1336
  const contextOutput = reviewerContextOutput(reviewerContext, decompositionContext);
1250
1337
  if (opts.json) results.push({ pr, error: err, ...contextOutput, ...comparisonData, ...(mismatchWarning ?? {}) });
1251
1338
  else deps.error(`PR ${pr}: ${err}\n${reviewerContextStatus}`);
1339
+ failed += 1;
1252
1340
  continue;
1253
1341
  }
1254
1342
  // ⭐ S2(2026-07-30) — 리뷰 증거를 **이 PR 이 저작한 변경**으로 좁힌다. 실측 7건에서 1건만
@@ -1279,7 +1367,7 @@ export async function runSelfReviewCliCommand(
1279
1367
  if (mismatchWarning) deps.error(mismatchWarning.warning);
1280
1368
  // ⚠️ 「1차」라고 못 박는다 — 폴백은 이 줄 «뒤»에 일어난다. 그냥 model= 로 두면
1281
1369
  // 사용자가 이 줄에서 «최종» 리뷰 주체를 읽으려다 오해한다(리뷰 should-fix).
1282
- if (!opts.json) deps.info(`[self-review] PR ${pr} · 1차 model=${model} · 리뷰 중…`);
1370
+ if (!opts.json) deps.info(`[self-review] PR ${pr} · 1차 model=${primaryModel} · 리뷰 중…`);
1283
1371
  const provenance = {
1284
1372
  headCommit: diffRead.headCommit,
1285
1373
  currentHeadCommit: diffRead.currentHeadCommit,
@@ -1295,24 +1383,30 @@ export async function runSelfReviewCliCommand(
1295
1383
  ...(mismatchWarning ?? {}),
1296
1384
  };
1297
1385
  if (diffRead.stale) {
1298
- deps.log('done', buildReviewObservation({
1299
- pr, model, intent, review: null, durationMs: 0,
1386
+ deps.log('done', { ...buildReviewObservation({
1387
+ pr, model: primaryModel, intent, review: null, durationMs: 0,
1300
1388
  ...intentTruncation,
1301
1389
  headCommit: diffRead.headCommit, headCommitState: diffRead.headCommitState,
1302
1390
  currentHeadCommit: diffRead.currentHeadCommit, currentHeadCommitState: diffRead.currentHeadCommitState,
1303
1391
  stale: true, refetched: diffRead.refetched,
1304
- }), { level: 'warn' });
1392
+ }), ...reviewerSourceObservation() }, { level: 'warn' });
1305
1393
  const contextOutput = reviewerContextOutput(reviewerContext, decompositionContext);
1306
1394
  const refused = {
1307
- pr, model, verdict: null, mustFix: [], shouldFix: [], reviewed: false,
1308
- refusal: 'stale-head', ...provenance, ...contextOutput,
1395
+ pr, model: primaryModel, verdict: null, mustFix: [], shouldFix: [], reviewed: false,
1396
+ refusal: 'stale-head', ...provenance, ...reviewerSourceObservation(), ...contextOutput,
1309
1397
  };
1310
1398
  if (opts.json) results.push(refused);
1311
- else deps.print(`\n━━ PR ${pr} (${model}) ━━\n${renderStaleRefusal(diffRead)}\n${reviewerContextStatus}`);
1399
+ else deps.print(`\n━━ PR ${pr} (${primaryModel}) ━━\n${renderStaleRefusal(diffRead)}\n${reviewerContextStatus}`);
1312
1400
  continue;
1313
1401
  }
1314
1402
  const startedAt = deps.now();
1315
- const llmReview = acpReviewLLM ?? deps.makeApiLlm(model);
1403
+ // Role-config lane builds the API reviewer only when it falls back (`made().api` stays 0 on ACP success).
1404
+ const responded: { provider?: string; model?: string } = {};
1405
+ const makeApi = () => deps.makeApiLlm(model, {
1406
+ pinProvider: Boolean(opts.model?.trim()),
1407
+ onResolved: (provider, respondedModel) => { responded.provider = provider; responded.model = respondedModel; },
1408
+ });
1409
+ const llmReview = roleReviewer ? undefined : (acpReviewLLM ?? makeApi());
1316
1410
  // ⛔ evidenceNote 는 **별도 채널**이다 — phaseIntent 에 섞으면 의도 채널이 오염된다(실측: 그렇게
1317
1411
  // 했다가 intent 배선 테스트 3개가 즉시 깨졌다).
1318
1412
  // ⛔ 사람 `--intent`(phaseIntent) 와 골 acceptance 는 다른 인자 — 충돌하지 않고, 충돌해도 intent 가 이긴다.
@@ -1325,15 +1419,41 @@ export async function runSelfReviewCliCommand(
1325
1419
  ...(deps.readReferencedFile ? { readReferencedFile: deps.readReferencedFile } : {}),
1326
1420
  ...(goalAcceptance.acceptance ? { acceptance: goalAcceptance.acceptance } : {}),
1327
1421
  };
1328
- let review = await deps.reviewPullRequest(reviewInput, llmReview);
1329
- let selectedModel = model;
1330
- let reviewRoute: 'api' | 'acp' | 'acp-fallback' = useAcp ? 'acp' : 'api';
1422
+ // ⭐ Role-config ACP lane: a completed ACP review is used as-is; anything else (throw, reviewed≠true)
1423
+ // falls to the same API review this command ran before the lane existed — and is observed.
1424
+ // ⚠️ Stricter than the harness lane on purpose: `runSubscriptionReviewer` accepts any non-empty text;
1425
+ // here only a parsed, completed review (`reviewed === true`) is adopted, else the API review runs.
1426
+ let roleReview: ReviewResult | undefined;
1427
+ let roleReviewerFallbackReason = roleReviewerUnavailableReason;
1428
+ let roleReviewMs: number | undefined;
1429
+ if (roleReviewer) {
1430
+ const roleStartedAt = deps.now();
1431
+ try {
1432
+ const attempt = await deps.reviewPullRequest(reviewInput, roleReviewer.llm);
1433
+ if (attempt.reviewed === true) roleReview = attempt;
1434
+ // Code, not the reviewer's raw failure text (same rule as the throw path above).
1435
+ else roleReviewerFallbackReason = 'acp-review-not-completed';
1436
+ } catch (error) {
1437
+ roleReviewerFallbackReason = roleAcpErrorReason(error);
1438
+ }
1439
+ roleReviewMs = deps.now() - roleStartedAt;
1440
+ if (!roleReview) {
1441
+ deps.log('role-reviewer-fallback', {
1442
+ roleReviewMs,
1443
+ pr: safeLogText(pr), reviewerSource, roleReviewerProvider: opts.roleReviewer?.provider,
1444
+ stage: 'review', reason: roleReviewerFallbackReason ?? 'acp-review-not-completed', fallbackModel: safeLogText(model),
1445
+ }, { level: 'warn' });
1446
+ }
1447
+ }
1448
+ let review = roleReview ?? await deps.reviewPullRequest(reviewInput, llmReview ?? acpReviewLLM ?? makeApi());
1449
+ let selectedModel = roleReview && roleReviewer ? roleReviewer.model : model;
1450
+ let reviewRoute: 'api' | 'acp' | 'acp-fallback' = useAcp || roleReview ? 'acp' : 'api';
1331
1451
  let fallbackAttempted = false;
1332
1452
  let fallbackBackend: string | undefined;
1333
1453
  let fallbackTriggerReason: string | undefined;
1334
1454
  let fallbackNotAttemptedReason: 'explicit-acp' | 'primary-review-succeeded' | undefined;
1335
1455
  const fallbackFailures: Array<{ backend: string; reason: string }> = [];
1336
- if (!useAcp && review.reviewed !== true) {
1456
+ if (!useAcp && !roleReview && review.reviewed !== true) {
1337
1457
  fallbackAttempted = true;
1338
1458
  fallbackTriggerReason = safeLogText(review.failureReason || 'reviewed=false', 400);
1339
1459
  for (const backend of fallbackAcpBackends) {
@@ -1374,6 +1494,16 @@ export async function runSelfReviewCliCommand(
1374
1494
  ...(fallbackFailures.length ? { fallbackFailures } : {}),
1375
1495
  ...(skippedAcpFallbackBackends.length ? { skippedAcpFallbackBackends } : {}),
1376
1496
  };
1497
+ // API 경로로 «성공한» 리뷰만 응답 provider·model 을 싣는다(요청 model 과 다르면 둘 다 보인다).
1498
+ // ⚠️ streamLLM 의 onResolvedProvider 는 시도 «전»에 불린다 — 실패한 리뷰에 실으면 응답 안 한 provider 를 «응답했다»로 적는다.
1499
+ const respondedOutput = reviewRoute === 'api' && review.reviewed === true && responded.provider
1500
+ ? { respondedProvider: responded.provider, respondedModel: responded.model }
1501
+ : {};
1502
+ // ⚠️ `buildReviewObservation` drops unknown keys — the selection rides next to it, not inside it.
1503
+ const reviewerSelection = {
1504
+ ...reviewerSourceObservation(),
1505
+ ...(roleReviewerFallbackReason !== undefined ? { roleReviewerFallbackReason } : {}),
1506
+ };
1377
1507
  // ⚠️ verdict=fail 은 **정상 동작**(리뷰가 일한 것)이라 warn 으로 올리지 않는다. 대신 `reviewed:false`
1378
1508
  // (fail-soft pass·리뷰 미실행)는 조용히 통과로 읽히면 위험하므로 warn 이다.
1379
1509
  deps.log('done',
@@ -1391,20 +1521,24 @@ export async function runSelfReviewCliCommand(
1391
1521
  }),
1392
1522
  goalLoaded: goalAcceptance.goalLoaded,
1393
1523
  acceptanceChars: goalAcceptance.acceptanceChars,
1524
+ ...reviewerSelection,
1394
1525
  },
1395
1526
  { level: review.reviewed === false ? 'warn' : 'info' });
1396
1527
  // --acp 는 대표가 명시 요청한 리뷰 — fail-soft(reviewed=false)면 조용히 pass 하지 말고 표면화(관측=acp-review).
1397
1528
  if (useAcp && review.reviewed === false) {
1398
1529
  const err = 'ACP 리뷰 실행 실패(reviewed=false) — 관측: elanous logs --category acp-review';
1399
1530
  const contextOutput = reviewerContextOutput(reviewerContext, decompositionContext);
1400
- if (opts.json) results.push({ pr, error: err, ...review, verdict: null, ...reviewProvenance, ...provenance, ...contextOutput });
1531
+ if (opts.json) results.push({ pr, error: err, ...review, verdict: null, ...reviewProvenance, ...respondedOutput, ...reviewerSelection, ...provenance, ...contextOutput });
1401
1532
  else deps.error(`PR ${pr}: ${err}\n${renderProvenance(diffRead)}\n${reviewerContextStatus}`);
1533
+ failed += 1;
1402
1534
  continue;
1403
1535
  }
1404
1536
  const contextOutput = reviewerContextOutput(reviewerContext, decompositionContext);
1405
1537
  const jsonReview = review.reviewed === true ? review : { ...review, verdict: null };
1406
- if (opts.json) results.push({ pr, model: selectedModel, ...jsonReview, ...reviewProvenance, ...provenance, ...contextOutput, evidence: evidence.evidence, prDiffFiles: evidence.prDiffFiles, ...(evidence.authoredFiles !== undefined ? { authoredFiles: evidence.authoredFiles } : {}) });
1538
+ if (opts.json) results.push({ pr, model: selectedModel, ...jsonReview, ...reviewProvenance, ...respondedOutput, ...reviewerSelection, ...provenance, ...contextOutput, evidence: evidence.evidence, prDiffFiles: evidence.prDiffFiles, ...(evidence.authoredFiles !== undefined ? { authoredFiles: evidence.authoredFiles } : {}) });
1407
1539
  else deps.print(`\n━━ PR ${pr} (${selectedModel}) ━━\n${renderProvenance(diffRead)}\n${evidenceLine}\n${reviewerContextStatus}\n${deps.renderReview(review)}`);
1540
+ // REVIEW-ERROR-RC — 기본(API)·role 경로가 1차·폴백 모두 실패해 reviewed≠true 로 끝나도 «못 리뷰한 PR» 이다(verdict:null).
1541
+ if (review.reviewed !== true) failed += 1;
1408
1542
  }
1409
- return { results };
1543
+ return { results, failed };
1410
1544
  }
@@ -7,36 +7,54 @@ interface ShardIdentity {
7
7
  }
8
8
 
9
9
  const SHARD_IDENTITY_SUFFIX = /(?:^|\n)## Shard identity\r?\n([\s\S]+?)\s*$/;
10
+ const SHARD_IDENTITY_HEADING = /(?:^|\n)## Shard identity\r?\n/g;
11
+ const ORIGINAL_ASK_FENCE = /(?:^|\n)Original ask \(verbatim, unmodified\):\r?\n(`{3,}|~{3,})[ \t]*\r?\n([\s\S]*?)\r?\n\1[ \t]*(?=\r?\n|$)/g;
12
+ const isInsideVerbatimAsk = (goalText: string, index: number): boolean =>
13
+ [...goalText.matchAll(ORIGINAL_ASK_FENCE)].some((match) => index > match.index! && index < match.index! + match[0].length);
10
14
  const MAX_BLOCK_CHARS = 800;
15
+ const MAX_CONTRACT_CHARS = 1400;
11
16
 
12
- /** Read the JSON footer emitted by shardIdentityFeature, without treating other goal text as identity. */
17
+ /** Read the emitted footer, including when a goal author preserved the entire ask in a fence. */
13
18
  export function parseShardIdentity(goalText: string): ShardIdentity | undefined {
14
- const match = SHARD_IDENTITY_SUFFIX.exec(goalText);
15
- if (!match) return undefined;
16
- try {
17
- const value: unknown = JSON.parse(match[1]!);
18
- if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;
19
- const identity = value as Record<string, unknown>;
20
- if (typeof identity.shardId !== 'string' || !identity.shardId.trim()
21
- || typeof identity.summary !== 'string'
22
- || !Number.isInteger(identity.totalShards) || (identity.totalShards as number) < 1
23
- || !Number.isInteger(identity.position) || (identity.position as number) < 1
24
- || (identity.position as number) > (identity.totalShards as number)
25
- || !Array.isArray(identity.siblings)
26
- || !identity.siblings.every((sibling: unknown) => {
27
- if (!sibling || typeof sibling !== 'object' || Array.isArray(sibling)) return false;
28
- const item = sibling as Record<string, unknown>;
29
- return typeof item.shardId === 'string' && !!item.shardId.trim() && typeof item.summary === 'string';
30
- })) return undefined;
31
- return identity as unknown as ShardIdentity;
32
- } catch {
33
- return undefined;
19
+ // A suffix may start inside a verbatim-ask fence but consume the closing fence and later
20
+ // goal sections. Try that intact suffix first; fall back only to authored ask fences.
21
+ const suffix = [...goalText.matchAll(SHARD_IDENTITY_HEADING)].at(-1);
22
+ const suffixText = suffix && !isInsideVerbatimAsk(goalText, suffix.index!)
23
+ ? goalText.slice(suffix.index! + suffix[0].length).trim() : undefined;
24
+ // A top-level footer is authoritative: if it is present but invalid, the identity is unknown —
25
+ // never fall back to an older identity quoted in the original ask (wrong shard ownership).
26
+ const candidates = suffixText !== undefined
27
+ ? [suffixText]
28
+ : [...goalText.matchAll(ORIGINAL_ASK_FENCE)].map((fence) => SHARD_IDENTITY_SUFFIX.exec(fence[2]!)?.[1]);
29
+ for (const candidate of candidates) {
30
+ if (!candidate) continue;
31
+ try {
32
+ const value: unknown = JSON.parse(candidate);
33
+ if (!value || typeof value !== 'object' || Array.isArray(value)) continue;
34
+ const identity = value as Record<string, unknown>;
35
+ if (typeof identity.shardId !== 'string' || !identity.shardId.trim()
36
+ || typeof identity.summary !== 'string'
37
+ || !Number.isInteger(identity.totalShards) || (identity.totalShards as number) < 1
38
+ || !Number.isInteger(identity.position) || (identity.position as number) < 1
39
+ || (identity.position as number) > (identity.totalShards as number)
40
+ || !Array.isArray(identity.siblings)
41
+ || !identity.siblings.every((sibling: unknown) => {
42
+ if (!sibling || typeof sibling !== 'object' || Array.isArray(sibling)) return false;
43
+ const item = sibling as Record<string, unknown>;
44
+ return typeof item.shardId === 'string' && !!item.shardId.trim() && typeof item.summary === 'string';
45
+ })) continue;
46
+ return identity as unknown as ShardIdentity;
47
+ } catch { /* Try the next authored identity source. */ }
34
48
  }
49
+ return undefined;
35
50
  }
36
51
 
37
- /** Remove only a successfully parsed footer; malformed metadata remains ordinary goal text. */
52
+ /** Remove only a successfully parsed top-level suffix; never edit the verbatim original ask. */
38
53
  export function withoutShardIdentity(goalText: string): string {
39
- return parseShardIdentity(goalText) ? goalText.replace(SHARD_IDENTITY_SUFFIX, '') : goalText;
54
+ const suffix = [...goalText.matchAll(SHARD_IDENTITY_HEADING)].at(-1);
55
+ if (!suffix || isInsideVerbatimAsk(goalText, suffix.index!)) return goalText;
56
+ const suffixText = goalText.slice(suffix.index! + suffix[0].length).trim();
57
+ return parseShardIdentity(`## Shard identity\n${suffixText}`) ? goalText.slice(0, suffix.index) : goalText;
40
58
  }
41
59
 
42
60
  function oneLine(value: string, limit: number): string {
@@ -45,11 +63,14 @@ function oneLine(value: string, limit: number): string {
45
63
  }
46
64
 
47
65
  /** Keep the sibling contract ahead of the goal body, with an explicit omission count. */
48
- export function shardBoundaryBlock(identity: ShardIdentity): string {
66
+ export function shardBoundaryBlock(identity: ShardIdentity, opts: { handoff?: 'should-fix' | 'out-of-scope' } = {}): string {
49
67
  const prefix = [
50
68
  `이 PR 은 조각 ${oneLine(String(identity.position), 20)}/${oneLine(String(identity.totalShards), 20)}(${oneLine(identity.shardId, 80)}): ${oneLine(identity.summary, 240)}.`,
51
- '형제 조각이 맡는 일(예: 등록·배선·화면)이 이 PR 에 없다는 이유로 must-fix 를 내지 말 것. 없어서 이 조각이 동작하지 않으면 should-fix 로 «형제 조각 <id> 에 의존» 한 줄.',
52
- '형제 조각이 맡는 일:',
69
+ opts.handoff === 'out-of-scope'
70
+ // The review contract has one classification for sibling-owned work: out-of-scope → owner.
71
+ ? '형제 조각이 맡는 일(예: 등록·배선·화면)이 이 PR 에 없다는 이유로 must-fix 를 내지 말 것 — 아래 out-of-scope 규칙으로 담당 형제에 넘긴다.'
72
+ : '형제 조각이 맡는 일(예: 등록·배선·화면)이 이 PR 에 없다는 이유로 must-fix 를 내지 말 것. 없어서 이 조각이 동작하지 않으면 should-fix 로 «형제 조각 <id> 에 의존» 한 줄.',
73
+ identity.siblings.length ? '형제 조각이 맡는 일:' : '형제 샤드: 없음(단일 조각). 다른 담당을 추측하지 말 것.',
53
74
  ];
54
75
  const items = identity.siblings.map((sibling) => `- ${oneLine(sibling.shardId, 80)}: ${oneLine(sibling.summary, 240)}`);
55
76
  const header = prefix.join('\n');
@@ -68,3 +89,48 @@ export function shardBoundaryBlock(identity: ShardIdentity): string {
68
89
  }
69
90
  return [...prefix, ...kept, ...(marker ? [marker] : [])].join('\n');
70
91
  }
92
+
93
+ /** A review-only contract: use declared scope, not guessed ownership from filenames. */
94
+ export function shardReviewContractBlock(
95
+ goalText: string,
96
+ identity: ShardIdentity,
97
+ boundaries: readonly string[],
98
+ changedFiles?: readonly string[],
99
+ ): string {
100
+ const verbatimAsk = [...goalText.matchAll(ORIGINAL_ASK_FENCE)].at(-1)?.[2];
101
+ const declarations = (verbatimAsk ?? goalText).split(/\r?\n/);
102
+ const targetLine = declarations.find((line) => /^대상 경로:\s*\S/.test(line));
103
+ const preservationLine = declarations.find((line) => /^보존 계약:\s*\S/.test(line));
104
+ const target = targetLine ?? (changedFiles?.length ? `대상 경로(변경 파일 관측 · 골 선언 아님): ${changedFiles.join(' · ')}` : '대상 경로: 골에 명시되지 않음');
105
+ const preservation = preservationLine ?? '보존 계약: 골에 명시되지 않음';
106
+ const fixed = [
107
+ '샤드 계약 — 리뷰 범위',
108
+ shardBoundaryBlock(identity, { handoff: 'out-of-scope' }),
109
+ '범위 밖 지적은 must-fix가 아니라 out-of-scope → 담당 형제 조각 <id>로 넘긴다. 담당을 특정할 수 없으면 미지정으로 적고 추측하지 말 것.',
110
+ 'must-fix마다 이 조각의 대상 경로·수용기준 위반 근거와 반증 확인 한 줄(재현 명령 또는 확인 방법·결과)을 반드시 적을 것.',
111
+ ];
112
+ // Reserve the rules and sibling owners before allocating the remaining space to goal text.
113
+ const available = Math.max(0, MAX_CONTRACT_CHARS - fixed.join('\n').length - 3);
114
+ const scope = [target, preservation, `의도적 경계: ${boundaries.length ? boundaries.map((boundary) => boundary.replace(/^의도적 경계:\s*/, '')).join(' · ') : '골에 명시되지 않음'}`];
115
+ // Water-fill: short lines keep their full text and hand their unused share to longer ones,
116
+ // so a long boundary cannot truncate the declared target paths when space remains.
117
+ const normalized = scope.map((line) => line.replace(/\s+/g, ' ').trim());
118
+ const limits = new Array<number>(scope.length).fill(0);
119
+ let remaining = available;
120
+ let open = normalized.map((_, index) => index);
121
+ while (open.length && remaining > 0) {
122
+ const share = Math.floor(remaining / open.length);
123
+ if (share <= 0) break;
124
+ const next: number[] = [];
125
+ for (const index of open) {
126
+ const need = normalized[index]!.length - limits[index]!;
127
+ const give = Math.min(need, share);
128
+ limits[index]! += give;
129
+ remaining -= give;
130
+ if (normalized[index]!.length > limits[index]!) next.push(index);
131
+ }
132
+ open = next;
133
+ }
134
+ const scoped = normalized.map((line, index) => oneLine(line, limits[index]!));
135
+ return [fixed[0], ...scoped, ...fixed.slice(1)].join('\n');
136
+ }
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, w
2
2
  import { join } from 'node:path';
3
3
 
4
4
  import { elanousStateRoot } from '../autopilot/state-paths.js';
5
+ import { assertNotTestWritingOps } from '../instance/test-write-guard.js';
5
6
  import { ASK_USER_QUESTION_DELIVERY_VALUES } from './types.js';
6
7
  import type { AskUserQuestionRequest, AskUserQuestionResult, HitlDelivery, Question, QuestionOption } from './types.js';
7
8
 
@@ -161,6 +162,7 @@ function pendingQuestionAnswerPath(id: string, root?: string): string {
161
162
 
162
163
  function writeAtomicRecord(id: string, value: unknown, dir: string, target: string, deps: PendingQuestionStoreDeps): void {
163
164
  const temp = join(dir, `.${encodeURIComponent(id)}.${process.pid}.${(deps.now ?? (() => new Date()))().getTime()}.${Math.random().toString(36).slice(2)}.tmp`);
165
+ assertNotTestWritingOps(target, 'write a pending question record');
164
166
  const remove = deps.removeFile ?? rmSync;
165
167
  try {
166
168
  (deps.makeDir ?? mkdirSync)(dir, { recursive: true });
@@ -230,13 +232,17 @@ export function readPendingQuestionAnswer(id: string, deps: PendingQuestionStore
230
232
 
231
233
  export function removePendingQuestionAnswer(id: string, deps: PendingQuestionStoreDeps = {}): void {
232
234
  const root = (deps.root ?? elanousStateRoot)();
233
- (deps.removeFile ?? rmSync)(pendingQuestionAnswerPath(id, root), { force: true });
235
+ const path = pendingQuestionAnswerPath(id, root);
236
+ assertNotTestWritingOps(path, 'remove a pending question answer');
237
+ (deps.removeFile ?? rmSync)(path, { force: true });
234
238
  }
235
239
 
236
240
  /** Best-effort lifecycle observation: callers deliberately ignore failures. */
237
241
  export function removePendingQuestion(id: string, deps: PendingQuestionStoreDeps = {}): void {
238
242
  const root = (deps.root ?? elanousStateRoot)();
239
- (deps.removeFile ?? rmSync)(pendingQuestionPath(id, root), { force: true });
243
+ const path = pendingQuestionPath(id, root);
244
+ assertNotTestWritingOps(path, 'remove a pending question');
245
+ (deps.removeFile ?? rmSync)(path, { force: true });
240
246
  }
241
247
 
242
248
  export function readPendingQuestions(deps: PendingQuestionStoreDeps = {}): PendingQuestionReadResult {