elanous 0.2.29 → 0.2.31

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 (709) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{058a98ba.7eb28d5e6dc03565.js → 0bb0ff36.b8d418980951e5ba.js} +7 -7
  5. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +27 -0
  8. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +287 -0
  9. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +62 -0
  10. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/{6013-2f769370d8b4c2c6.js → 1335-6731f392c35216eb.js} +3 -3
  12. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{8332.6f0f49df772e163b.js → 1654.32de4b324981a188.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1834-50625904996a8fa8.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
  17. package/apps/pwa/out/_next/static/chunks/{8795.32573a185af18c7b.js → 1913.7cc6fb6055b1ed3f.js} +2 -2
  18. package/apps/pwa/out/_next/static/chunks/{419.736c0d6f426249a7.js → 2001.6c7e0fd02190886c.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{6767.1fcfc9b8be83975f.js → 2213.2ccbada92c33ea0f.js} +16 -16
  24. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/{4759.1f76713aefb87db5.js → 2871.0bca6137343b3f76.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/{6776.06ff1e3b464cc607.js → 2898.fd781bc7cf01a7b7.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/{1782-59db1b5aa06df38a.js → 2940-619bfd8ef337c611.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/{8471.8d2a8c74f09c36ff.js → 2985.39ccdecd36848b12.js} +4 -4
  31. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +115 -0
  32. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +64 -0
  33. package/apps/pwa/out/_next/static/chunks/{bc324b7c.02a09dd93f6a399b.js → 3267c0e6.d34854e7b3984a6e.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3278.2e5d15b53a4091c8.js +2 -0
  35. package/apps/pwa/out/_next/static/chunks/{7725-4f83d5541fbdb81b.js → 3541-ce3a5424ed5ad7f1.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +34 -0
  39. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{46bd8bea.2f4b4099172fcdb7.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{1142.65d002789ab3af7d.js → 4174.92ed04922709ac9e.js} +2 -2
  43. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +36 -0
  45. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +286 -0
  49. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +77 -0
  50. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +226 -0
  51. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +79 -0
  53. package/apps/pwa/out/_next/static/chunks/5173-233188df2f42c626.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/5307.60f2209e809bd627.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{3396-97b97928c49190c9.js → 5458-16cd7a2b51b74c8c.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/{3403.7199205e65124486.js → 5525.86debf231e181813.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{9143.ff14585db1d275ff.js → 5543.a438b8ab5a13ea47.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +74 -0
  65. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +94 -0
  67. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{8398.73a19b39715eda04.js → 6092.a7f99e68b188ca66.js} +1 -1
  70. package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/{5591.a35e7a217734a8b9.js → 6157.0c9af021de4fb31b.js} +2 -2
  72. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/{7375.050ea0d72968e49f.js → 6433.fc573af22bbc9ab7.js} +17 -17
  75. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +90 -0
  77. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +32 -0
  78. package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +104 -0
  80. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +24 -0
  85. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
  86. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{1852.7f7b53991fcb99ef.js → 7502.ccd5b8065545edd0.js} +2 -2
  93. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
  94. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{6534.1ab00f370db7b105.js → 7862.30a8d6482bb238eb.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/8097-92f87bd108322f66.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
  109. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.js → 9221.7d22eaf353a2d4e7.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{8767-2f6a634f5abeaa01.js → 9279-d28c5b7754d010ae.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
  121. package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.js → 9989.3694300e5f000b14.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-bf3634a117322df7.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-3535a4a69f1fafaa.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-b9f51447f757fbf2.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-a5635eba0d73b84e.js → page-2ebb8fd59b9461f9.js} +1 -1
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-a2fc4e49a4fa4ba8.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5a503541353e60a8.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-6025101384e361a5.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-f4b630cc8b5273cd.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-a645f00a06483e9a.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-61ac22cbab1ee4ec.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e9bab7413b028b28.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-c992eafe028b642e.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-e547e6ce55f1fb33.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-d27e1b9850fd54bf.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-805ac2e137b7a121.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-0fec29c7ba01894b.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-339a07410cd6f36b.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-349f2752d8cd37ad.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-d5c6dcf31c25cecc.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-2fd93ed8c9f16580.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-9b564dbff0fefc35.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-62f4475d3c38fb9b.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-814ba51385225776.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-397d479626e5a459.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-af1bba4e3251b728.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ad3be5e7d3fdce9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-f219ccdbc0bf27df.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4da93ad35d4a8d28.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-456666766e5ce6fc.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-7404e377e8adb8c5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-14456240ed2a36ad.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-3a658d5fa6d16a25.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-0157de6e85f8bb6b.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-0a07363b130182a1.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-841d73d4ac44ed49.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6f43a3d1146e6377.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/{page-29900ed0011b2c83.js → page-521ee23ac8c0abfa.js} +1 -1
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-a9992ee285efaa83.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-3d48e85fa89ec04f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d2ced71132fac9b2.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-f08358bdf251adb9.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-233c71cd5f68f0d7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-70151d78de2f375e.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-dcac33a3e2cb72c0.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/{page-9f92737b8766009a.js → page-149dc1caba411bb9.js} +1 -1
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0448145ccd5c45c1.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-9cb0c444903da65d.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-17e504c396e0e389.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
  175. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
  183. package/apps/pwa/out/_next/static/css/{72becfd42807b50d.css → 3f5fc6f96e2cf7b2.css} +1 -1
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +23 -23
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +23 -23
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +23 -23
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +22 -22
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +22 -22
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +23 -23
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +22 -22
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +23 -23
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +23 -23
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +22 -22
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +23 -23
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +23 -23
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +23 -23
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +23 -23
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +22 -22
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +22 -22
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +23 -23
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +23 -23
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +23 -23
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +22 -22
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +22 -22
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +23 -23
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +23 -23
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +22 -22
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +22 -22
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +22 -22
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +23 -23
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +23 -23
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +22 -22
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +23 -23
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +23 -23
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +23 -23
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +23 -23
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +23 -23
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +22 -22
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +23 -23
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +23 -23
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +23 -23
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +23 -23
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +23 -23
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +23 -23
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +23 -23
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +23 -23
  277. package/bin/elanous.mjs +7 -3
  278. package/graphs/context/nightly-condense.yaml +1 -0
  279. package/graphs/intake/intake-daily.yaml +8 -1
  280. package/graphs/intake/recipes.yaml +5 -0
  281. package/graphs/lecture/lecture-note.yaml +2 -2
  282. package/graphs/ops/harness-gc.yaml +1 -0
  283. package/graphs/release/recipes.yaml +3 -0
  284. package/graphs/release/release-loop.yaml +9 -5
  285. package/graphs/units/recipes.yaml +3 -0
  286. package/graphs/units/release-gate-recheck.yaml +15 -0
  287. package/package.json +2 -1
  288. package/scripts/check-native-tool-wiring.ts +3 -2
  289. package/scripts/ci-android-unit-tests.ts +16 -0
  290. package/scripts/ci-typecheck-changed.ts +37 -9
  291. package/scripts/coord-channel-watch.sh +22 -16
  292. package/scripts/coord-role-pack.ts +81 -2
  293. package/scripts/cron-run.ts +96 -3
  294. package/scripts/detect-test-interference.ts +38 -5
  295. package/scripts/gate-pr-cache.ts +65 -0
  296. package/scripts/gh-surface/capture.ts +126 -0
  297. package/scripts/gh-surface/gh +40 -0
  298. package/scripts/import-graph-scc.ts +38 -0
  299. package/scripts/install.ps1 +19 -0
  300. package/scripts/intake-social.ts +181 -0
  301. package/scripts/lecture-note/node.ts +71 -4
  302. package/scripts/lib/android-toolchain.ts +32 -0
  303. package/scripts/lib/deterministic-env.ts +62 -0
  304. package/scripts/lib/gate-test-env.ts +19 -0
  305. package/scripts/measure-goal-grounding-corpus.ts +2 -1
  306. package/scripts/ratchets/test-interference-patterns.allowlist.txt +257 -0
  307. package/scripts/ratchets/test-interference-patterns.ts +367 -0
  308. package/scripts/release-loop/cut-branch.ts +4 -3
  309. package/scripts/release-loop/export-check-node.ts +0 -1
  310. package/scripts/release-loop/fixtures/warm-failure-assertion/sample.junit.xml +8 -0
  311. package/scripts/release-loop/fixtures/warm-job-029/sample.json +1 -0
  312. package/scripts/release-loop/fixtures/warm-job-029/sample.junit.xml +10 -0
  313. package/scripts/release-loop/gate-closure.ts +12 -8
  314. package/scripts/release-loop/gate-diff.ts +1 -1
  315. package/scripts/release-loop/gate-host-mirror.ts +66 -0
  316. package/scripts/release-loop/gate-node.ts +523 -75
  317. package/scripts/release-loop/gate-partial.ts +106 -9
  318. package/scripts/release-loop/gate-pr-cache.ts +66 -0
  319. package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
  320. package/scripts/release-loop/gate-r2-verdict.ts +189 -0
  321. package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
  322. package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
  323. package/scripts/release-loop/import-graph-scc-run.ts +54 -0
  324. package/scripts/release-loop/import-graph-scc.ts +215 -0
  325. package/scripts/release-loop/node-verdict.ts +2 -0
  326. package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
  327. package/scripts/release-loop/resume-release.ts +33 -4
  328. package/scripts/release-loop/resume.ts +13 -5
  329. package/scripts/release-loop/spawn-lane.ts +2 -19
  330. package/scripts/release-loop/tui-sim-node.ts +3 -2
  331. package/scripts/release-loop/unattended-release.ts +16 -0
  332. package/scripts/test-deterministic.ts +5 -61
  333. package/scripts/train-reach-grouping.ts +48 -0
  334. package/scripts/tsc-incremental-cache.ts +86 -0
  335. package/scripts/tsc-incremental-diagnostics.ts +76 -0
  336. package/scripts/tsc-main-safety-net.ts +2 -2
  337. package/src/acp/client.ts +4 -1
  338. package/src/acp/core-turn-bridge.ts +50 -5
  339. package/src/ad-pipeline/run.ts +4 -2
  340. package/src/agent/runner.ts +169 -3
  341. package/src/agent/subagent-callable.ts +3 -2
  342. package/src/agent-mission/review-loop.ts +6 -3
  343. package/src/agent-substrate/acp-implementer.ts +14 -2
  344. package/src/agent-substrate/pr-reviewer.ts +12 -0
  345. package/src/agent-substrate/self-review-cli.ts +30 -4
  346. package/src/autopilot/pr-manager.ts +62 -7
  347. package/src/briefing/brief-items.ts +24 -22
  348. package/src/capture/tui-self-report.ts +15 -0
  349. package/src/chat/chat-cli.ts +10 -2
  350. package/src/chat/index.ts +77 -11
  351. package/src/chat/input-control-key.ts +5 -3
  352. package/src/chat/tool-interrupt-behavior.ts +38 -0
  353. package/src/chat/tool-render/dispatch.ts +5 -1
  354. package/src/chat/turn-typeahead.ts +75 -20
  355. package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
  356. package/src/cli/agent-cli.ts +41 -13
  357. package/src/cli/config-audit.ts +123 -0
  358. package/src/cli/decisions-cli.ts +80 -6
  359. package/src/cli/log-event-names.ts +7 -0
  360. package/src/cli/mcp-login.ts +21 -5
  361. package/src/cli/msg-cli.ts +88 -0
  362. package/src/cli/pr-cli.ts +214 -57
  363. package/src/cli/pr-land-heavy-remote.ts +2 -2
  364. package/src/cli/pr-land-overlap-evidence.ts +63 -9
  365. package/src/cli/pr-land-pod-shadow-job.ts +83 -0
  366. package/src/cli/pr-land-pod-shadow.ts +16 -3
  367. package/src/cli/pr-land-virtual-rebase.ts +108 -0
  368. package/src/cli/release-cli.ts +80 -14
  369. package/src/cli/seat-cli.ts +138 -3
  370. package/src/cli/self-update.ts +5 -2
  371. package/src/cli/tasks-cli.ts +97 -19
  372. package/src/context-bus/context-first.ts +13 -0
  373. package/src/context-bus/context-now.ts +13 -2
  374. package/src/context-bus/ops-events.ts +75 -0
  375. package/src/control-plane/lease-holder.ts +12 -8
  376. package/src/control-plane/ledger.ts +163 -4
  377. package/src/control-plane/server.ts +91 -11
  378. package/src/core-turn/run-core-turn.ts +1 -0
  379. package/src/core-turn/run-goal-loop.ts +222 -3
  380. package/src/core-turn/seat-turn-cap.ts +79 -0
  381. package/src/core-turn/short-question.ts +38 -6
  382. package/src/core-turn/types.ts +3 -0
  383. package/src/dashboard/acp-boot.ts +3 -0
  384. package/src/dashboard/index.ts +224 -615
  385. package/src/dashboard/input/chat-main-entry-runtime.ts +1 -1
  386. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
  387. package/src/dashboard/input/chat-main-session.ts +8 -1
  388. package/src/dashboard/input/chat-main-turn.ts +12 -3
  389. package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
  390. package/src/dashboard/input/external-input-host.ts +26 -0
  391. package/src/dashboard/input/internal-turn.ts +261 -0
  392. package/src/dashboard/input/seat-autowake.ts +318 -0
  393. package/src/dashboard/input/turn-steer-bridge.ts +70 -0
  394. package/src/dashboard/loop-scheduler.ts +72 -0
  395. package/src/dashboard/seat-boot-preamble.ts +18 -0
  396. package/src/dashboard/skill-runtime.ts +2 -0
  397. package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
  398. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
  399. package/src/dashboard/slash-runtime/index.ts +13 -0
  400. package/src/dashboard/turn-busy-teardown.ts +50 -0
  401. package/src/decisions/decision-ledger.ts +45 -4
  402. package/src/discord-self-message.ts +4 -4
  403. package/src/domains/release-tool.ts +18 -1
  404. package/src/field-note/transcribe.ts +17 -0
  405. package/src/github/remote-call.ts +81 -0
  406. package/src/goals/registry.ts +46 -6
  407. package/src/goals/types.ts +7 -1
  408. package/src/graph-runner/runner.ts +1 -0
  409. package/src/grok/credential.ts +26 -0
  410. package/src/harness/harness-clean.ts +2 -1
  411. package/src/harness/harness-cli-command.ts +52 -5
  412. package/src/harness/harness-gc.ts +2 -1
  413. package/src/harness/harness-incidents.ts +57 -20
  414. package/src/harness/harness-pod-dispatch.ts +87 -10
  415. package/src/harness/harness-queue.ts +53 -4
  416. package/src/harness/harness-stop.ts +4 -3
  417. package/src/harness/harness-substrate-default.ts +78 -7
  418. package/src/harness/harness-worktree-auto.ts +2 -1
  419. package/src/harness/harness-worktrees.ts +3 -2
  420. package/src/hooks/dispatch.ts +2 -1
  421. package/src/index.ts +152 -25
  422. package/src/input/external-input-queue.ts +33 -1
  423. package/src/intake-plane/slash.ts +14 -3
  424. package/src/keybindings.ts +4 -1
  425. package/src/llm/tool-loop-steered-rejection.ts +33 -0
  426. package/src/llm.ts +138 -19
  427. package/src/loops/consensus.ts +348 -0
  428. package/src/loops/msg-wake.ts +206 -4
  429. package/src/loops/observe.ts +19 -3
  430. package/src/loops/orchestrator/tick.ts +64 -10
  431. package/src/loops/orchestrator/traffic.ts +64 -1
  432. package/src/loops/registry.ts +30 -0
  433. package/src/market/signed-index.ts +14 -0
  434. package/src/mcp/mcp-oauth.ts +54 -5
  435. package/src/models/prompts.ts +28 -0
  436. package/src/msg/msg-sse-client.ts +223 -0
  437. package/src/msg/msg-store.ts +86 -2
  438. package/src/mss/logging/log-store.ts +225 -1
  439. package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
  440. package/src/nexus/api/http-server.ts +54 -15
  441. package/src/nexus/api/loop-resources.ts +19 -3
  442. package/src/nexus/api/ops-api.ts +11 -0
  443. package/src/nexus/daemon-thin-inventory.md +37 -0
  444. package/src/nexus/index.ts +70 -0
  445. package/src/nexus/state/state.ts +1 -0
  446. package/src/oauth/store.ts +32 -7
  447. package/src/onboarding/first-run.ts +28 -3
  448. package/src/ops/overview-cache.ts +16 -4
  449. package/src/ops/resources.ts +82 -0
  450. package/src/plugins/maker/connector-maker.ts +41 -0
  451. package/src/plugins/maker/skill-maker.ts +42 -0
  452. package/src/pr-tool/census.ts +288 -0
  453. package/src/prompt-library/chat-conciseness.ts +13 -0
  454. package/src/prompt-library/universal-preamble.ts +10 -5
  455. package/src/release-loop/gate-host-reservation.ts +97 -0
  456. package/src/release-loop/landing-freeze.ts +5 -0
  457. package/src/release-loop/light-rc.ts +5 -2
  458. package/src/release-loop/placement.ts +92 -1
  459. package/src/release-loop/rehearsal-shard-plan.ts +149 -0
  460. package/src/release-loop/rehearsal.ts +73 -17
  461. package/src/repl/index.ts +20 -2
  462. package/src/seat-loop/seat-knowhow.ts +282 -0
  463. package/src/seat-loop/seat-loop.ts +41 -2
  464. package/src/seat-loop/traffic-signal.ts +3 -0
  465. package/src/self-dev/ask-launch-flow.ts +24 -3
  466. package/src/self-dev/decompose-compose-graph.ts +28 -27
  467. package/src/self-dev/decompose-proposal.ts +53 -38
  468. package/src/self-dev/decompose.ts +17 -0
  469. package/src/self-dev/dev-pipeline.ts +31 -2
  470. package/src/self-dev/draft-residue.ts +24 -9
  471. package/src/self-dev/draft-sweep.ts +59 -4
  472. package/src/self-dev/external-call-zero.ts +77 -0
  473. package/src/self-dev/launch-preflight-text.ts +6 -0
  474. package/src/self-dev/launch-preflight.ts +25 -3
  475. package/src/self-dev/local-supervisor-judge.ts +185 -0
  476. package/src/self-dev/run-supervisor.ts +229 -19
  477. package/src/self-dev/run-types.ts +20 -0
  478. package/src/self-dev/shard-aggregate.ts +13 -2
  479. package/src/self-dev/shard-plan.ts +47 -0
  480. package/src/self-dev/shard-run.ts +112 -10
  481. package/src/self-dev/spawn-lane-files.ts +19 -0
  482. package/src/self-implement/app-api-budget.ts +51 -11
  483. package/src/self-implement/config-gate.ts +2 -1
  484. package/src/self-implement/expose-gate.ts +2 -1
  485. package/src/self-implement/gate-artifacts.ts +405 -0
  486. package/src/self-implement/gate-cli.ts +201 -16
  487. package/src/self-implement/gate-remote.ts +110 -25
  488. package/src/self-implement/gate-scenario.ts +85 -0
  489. package/src/self-implement/goal-author.ts +160 -8
  490. package/src/self-implement/graph-authority.ts +38 -6
  491. package/src/self-implement/graph-overlay-condition.ts +92 -1
  492. package/src/self-implement/heal-triage.ts +79 -0
  493. package/src/self-implement/host-regate.ts +61 -3
  494. package/src/self-implement/orchestrator.ts +14 -123
  495. package/src/self-implement/pr-title.ts +123 -0
  496. package/src/self-implement/run-checkpoint.ts +235 -0
  497. package/src/self-implement/run-ledger.ts +155 -10
  498. package/src/self-implement/run-stop.ts +4 -3
  499. package/src/self-implement/run-ttl.ts +28 -4
  500. package/src/self-implement/seams.ts +2 -0
  501. package/src/self-implement/shadow-stage.ts +7 -6
  502. package/src/self-implement/stop-autoheal.ts +2 -1
  503. package/src/self-implement/train-gate-remote.ts +37 -8
  504. package/src/self-implement/train-reach-grouping.ts +157 -0
  505. package/src/self-implement/train-scenario-layers.ts +133 -0
  506. package/src/self-implement/uncommitted-work.ts +2 -0
  507. package/src/session/pending-input.ts +19 -0
  508. package/src/session/session-start.ts +224 -0
  509. package/src/session-runtime/parallel-dispatch.ts +22 -5
  510. package/src/skills/tools/dev-harness.ts +6 -4
  511. package/src/skills/tools/shell.ts +1 -1
  512. package/src/steward/resync-tick.ts +114 -23
  513. package/src/steward/ta-repair-event-collect.ts +158 -0
  514. package/src/task-agent/card-evidence.ts +25 -1
  515. package/src/task-agent/green-sweep.ts +8 -3
  516. package/src/task-agent/judge.ts +76 -0
  517. package/src/task-agent/land-queue.ts +79 -0
  518. package/src/task-agent/live-moves.ts +30 -9
  519. package/src/task-agent/postland-card.ts +5 -0
  520. package/src/task-agent/prelaunch-already-done.ts +98 -0
  521. package/src/task-agent/real-launch-guard.ts +37 -0
  522. package/src/task-agent/rejudge-on-head.ts +89 -12
  523. package/src/task-agent/remote-rejudge-bind.ts +28 -8
  524. package/src/task-agent/repair-cycle.ts +45 -7
  525. package/src/task-agent/repair-worker.ts +7 -0
  526. package/src/task-agent/run-identity.ts +200 -0
  527. package/src/task-agent/shadow.ts +50 -3
  528. package/src/task-agent/task-hand.ts +158 -5
  529. package/src/task-agent/train-landing.ts +77 -0
  530. package/src/task-agent/work-order.ts +104 -0
  531. package/src/task-orchestrator/surfaces/pod-command-job.ts +88 -28
  532. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
  533. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
  534. package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
  535. package/src/task-orchestrator/surfaces/pod-install-slots.ts +121 -9
  536. package/src/task-orchestrator/surfaces/pod-lease.ts +20 -6
  537. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
  538. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +27 -0
  539. package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
  540. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +63 -0
  541. package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
  542. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
  543. package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
  544. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
  545. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +208 -0
  546. package/src/task-orchestrator/surfaces/self-implement-pod.ts +132 -15
  547. package/src/telegram.ts +2 -4
  548. package/src/tui/input/pickers.ts +732 -0
  549. package/src/tui/slash/mission.ts +492 -0
  550. package/src/tui/slash/term.ts +877 -0
  551. package/src/tui-client/dashboard-session.ts +9 -0
  552. package/src/tui.ts +48 -0
  553. package/src/user-config/gemini-server-tools.ts +9 -0
  554. package/src/user-config.ts +53 -16
  555. package/src/util/spawn-sync-output.ts +7 -0
  556. package/src/ux-sim/fake-bin.ts +154 -0
  557. package/src/ux-sim/fake-clock.ts +36 -0
  558. package/src/ux-sim/headless-tui.ts +72 -0
  559. package/src/ux-sim/in-process-cli.ts +2 -1
  560. package/src/ux-sim/temp-git-remote.ts +82 -0
  561. package/src/version/packed-revision.json +1 -1
  562. package/src/video-pipeline/recipes/vlog.ts +25 -7
  563. package/apps/pwa/out/_next/static/chunks/1015-9cba22a5a4554797.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
  567. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
  569. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
  572. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
  573. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
  576. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
  578. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
  584. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
  588. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
  599. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
  605. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
  608. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
  609. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
  610. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
  613. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
  615. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
  616. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
  617. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
  619. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
  625. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
  632. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
  635. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
  640. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
  642. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
  703. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
  709. /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_ssgManifest.js +0 -0
@@ -43,6 +43,8 @@ import {
43
43
  type CoreTurnContext,
44
44
  type CoreTurnDispatchTool,
45
45
  } from '../core-turn/index.js';
46
+ import { stripGoalRepeatReadbackPreface } from '../core-turn/run-goal-loop.js';
47
+ import { parseSeatTurnCapConfig, resolveSeatTurnCap } from '../core-turn/seat-turn-cap.js';
46
48
  import { getUserConfig } from '../user-config.js';
47
49
  import { getModelFamily } from '../models/prompts.js';
48
50
  import { resolveModelContextWindow } from '../models/context-window.js';
@@ -50,7 +52,7 @@ import type { AcpServerOptions, AcpTurnContext } from './server.js';
50
52
  import { acpToolDenialResult } from './tool-approval.js';
51
53
  import { readOriginSessionMeta } from './origin-session-meta.js';
52
54
  import { isFactQuestion } from './fact-question.js';
53
- import { classifyTuiChatIntent, formatTuiRouteLine, type TuiChatRoute } from '../core-turn/short-question.js';
55
+ import { classifyTuiChatIntent, formatTuiRouteLine, isSeatOpsDirective, type TuiChatRoute } from '../core-turn/short-question.js';
54
56
  import { HARNESS_ROLE_ENV } from '../harness/harness-space.js';
55
57
 
56
58
  const FACT_QUESTION_INSTRUCTION = '사실·최신 정보 질문이다. WebSearch 를 1~2회 쓰고 검색 결과(제목·스니펫·URL)로 답하라. 출처 링크를 붙여라. 셸·브라우저·파일 도구는 검색 결과로 부족할 때만. 도구 예산에 닿으면 지금까지 근거로 답하고 끝에 «더 찾아볼까요?»를 붙여라.';
@@ -64,7 +66,8 @@ type QuickTuiRoute = Exclude<TuiChatRoute, '코딩·구현' | '읽기·분석'>;
64
66
  const QUICK_TOOLS: Record<QuickTuiRoute, readonly string[]> = {
65
67
  '조회': ['decisions_pending', 'ops_seats', 'ops_status', 'release_status', 'logs_query', 'context_now', 'memory_recall', 'Read'],
66
68
  '설정 변경': ['DashboardConfigGet', 'DashboardConfigSet', 'LlmListAvailableModels', 'prompt_getRuntimeConfig', 'prompt_setRuntimeConfig', 'view_getConfig', 'view_applyRuntimeConfig', 'view_saveConfig', 'memory_recall'],
67
- '조사': ['WebSearch', 'OmniSearch', 'Grep', 'Glob', 'Read', 'fact_check', 'memory_recall'],
69
+ // MsgList is a read-only ledger listing (never acks); MsgPost · MsgAck · RunShell · Bash stay out (TUI-QUICK-ROUTE-EXPLICIT-CMD).
70
+ '조사': ['WebSearch', 'OmniSearch', 'Grep', 'Glob', 'Read', 'fact_check', 'memory_recall', 'MsgList'],
68
71
  '상시 일': ['schedule_manage', 'schedule_list', 'schedule_create', 'schedule_update', 'session_manage', 'ops_status', 'memory_recall'],
69
72
  };
70
73
 
@@ -133,6 +136,9 @@ export interface CoreTurnBridgeDeps {
133
136
  abortPollMs?: number;
134
137
  /** Only the in-process dashboard session opts into TUI routing; daemon ACP stays unchanged. */
135
138
  tuiRouting?: boolean;
139
+ /** TUI-H1-SEAT-GOALLOOP — the seat this TUI works for (`detectSeatTui`), read per turn. null/absent = a human
140
+ * conversation TUI (routing unchanged). A seat TUI sends operational directives to the goal loop. */
141
+ resolveSeat?: () => string | null;
136
142
  }
137
143
 
138
144
  /** Default abort-poll cadence. 50ms = 20 Hz: responsive without
@@ -228,16 +234,24 @@ export function bridgeCoreTurnToAcp(
228
234
  // Only a goal-driven harness child (explicit executor role — dev-harness · self-implement surfaces) keeps every
229
235
  // turn on the goal loop. A human TUI inside a harness space (one-word `dev --elanous`, `--hold`) is routed (UX 10-07).
230
236
  const harness = process.env[HARNESS_ROLE_ENV]?.trim() === 'executor';
237
+ // seatKnown=false: no resolver (or it threw) — routed as a human TUI, but the log keeps «unknown», not «not a seat».
238
+ let seat: string | null = null;
239
+ let seatKnown = false;
240
+ if (deps.tuiRouting && !harness && deps.resolveSeat) {
241
+ try { seat = deps.resolveSeat(); seatKnown = true; }
242
+ catch (error) { debug.log('chat.route', 'seat-unresolved', { error: String(error) }, { level: 'warn' }); }
243
+ }
231
244
  const route = deps.tuiRouting && !harness
232
245
  ? classifyTuiChatIntent(turnCtx.userText, {
233
246
  hasAttachments: turnCtx.promptBlocks?.some((block) => block.type !== 'text') ?? false,
247
+ seat: seat !== null,
234
248
  })
235
249
  : { route: '코딩·구현' as const, reason: harness ? 'harness' : 'legacy', goalLoop: true };
236
250
  const tools = !route.goalLoop && route.route !== '코딩·구현' && route.route !== '읽기·분석'
237
251
  ? toolsForTuiRoute(availableTools, route.route)
238
252
  : availableTools;
239
253
  if (deps.tuiRouting) {
240
- debug.log('chat.route', 'decided', { route: route.route, reason: route.reason, goalLoop: route.goalLoop });
254
+ debug.log('chat.route', 'decided', { route: route.route, reason: route.reason, goalLoop: route.goalLoop, seat, seatKnown });
241
255
  // Only a quick route is announced: a coding turn's transcript stays exactly as before (preservation).
242
256
  // Awaited so the route line precedes the answer; a failed write is observed, not fatal to the turn.
243
257
  if (!route.goalLoop) {
@@ -253,6 +267,17 @@ export function bridgeCoreTurnToAcp(
253
267
  // 하드코딩 기본 ON 아님 — config 로 아밍(안전).
254
268
  const goalLoopCfg = getUserConfig().llm.goalLoop;
255
269
  const armGoalLoop = goalLoopCfg?.enabled === true && route.goalLoop;
270
+ // 인지(TUI-H1-SEAT-GOALLOOP) — 자리 TUI 의 운영 지시가 그래도 단일 턴이면(예: llm.goalLoop 꺼짐) 경고로 남긴다.
271
+ // 빠른 짧은 물음(short-*)은 자리에서도 «의도적» 단일 턴이라 경고에서 뺀다(«다음 행이 뭐야?»).
272
+ if (deps.tuiRouting && seat !== null && !armGoalLoop && !route.reason.startsWith('short-')
273
+ && isSeatOpsDirective(turnCtx.userText)) {
274
+ try {
275
+ debug.log('chat.route', 'seat-ops-single-turn', {
276
+ seat, route: route.route, reason: route.reason, goalLoop: route.goalLoop,
277
+ goalLoopEnabled: goalLoopCfg?.enabled === true,
278
+ }, { level: 'warn' });
279
+ } catch { /* observation cannot interrupt a turn */ }
280
+ }
256
281
  // 사실 질문 예산은 «단일 턴» 전용이다 — goal loop 와 겹치면 예산을 다 쓴 뒤에도 루프가 계속 재촉해
257
282
  // 매 continuation 이 «Tool budget reached» 로 거부되고, 모델은 그것을 도구 장애로 읽어 blocked 를 남긴다
258
283
  // (10-14 13:48 운영 TUI OP: route short-question·goalLoop ⊕ factQuestion → 소진 뒤 헛호출 7회).
@@ -307,10 +332,17 @@ export function bridgeCoreTurnToAcp(
307
332
  safeguard: 'context-pressure-bail',
308
333
  });
309
334
  }
335
+ // TUI-SEAT-TURN-CAP — 자리 판정으로 goal loop 에 온 턴만 core 턴 상한·«할 일 0» 판정을 받는다(사람 TUI·하니스 자식 0).
336
+ const seatTurnCap = armGoalLoop && seat !== null && route.reason.startsWith('seat-')
337
+ ? { seat, ...resolveSeatTurnCap(parseSeatTurnCapConfig(getUserConfig().chat?.seatTurnCap)) }
338
+ : undefined;
310
339
  const runTurnDispatch = (c: CoreTurnContext): Promise<unknown> =>
311
340
  armGoalLoop
312
341
  ? runGoalLoop(c, {
313
342
  ...(goalLoopCfg?.maxIterations !== undefined ? { maxIterations: goalLoopCfg.maxIterations } : {}),
343
+ // #29 처방 — 자리 판정으로 goal loop 에 «되돌아온» 턴만 빈 evidence 완료를 답으로 받는다.
344
+ ...(route.reason.startsWith('seat-') ? { lenientCompletionEvidence: true } : {}),
345
+ ...(seatTurnCap !== undefined ? { seatTurnCap } : {}),
314
346
  ...(goalCtxWindow > 0 ? { contextTokenLimit: goalCtxWindow } : {}),
315
347
  })
316
348
  : runCoreTurn(c);
@@ -462,10 +494,19 @@ export function bridgeCoreTurnToAcp(
462
494
  const visibleFinalText = needsFollowup ? extractLastAssistantText(completedMessages) : finalAssistantText;
463
495
  const originalFinalStreamed = needsFollowup && finalAssistantText !== null
464
496
  && streamedTextSum.endsWith(finalAssistantText);
497
+ // TUI-GOAL-REPEAT-ANSWER — 골 루프가 «인사 + 같은 답» 재방출을 화면에서 가리면(원장은 그대로)
498
+ // 브리지의 스트림 합계에는 그 답이 없다. 그대로 보면 «마지막 답을 못 그렸다»고 재표면화로 다시
499
+ // 그린다 — 이전 답이 이미 화면에 있는데도. 인사를 뗀 답 부분이 스트림 꼬리에 있으면 «그렸다»로
500
+ // 본다(골 루프 경로에서만 — 다른 경로의 판정은 그대로).
501
+ const goalRepeatStrippedFinalText = armGoalLoop && visibleFinalText !== null
502
+ ? stripGoalRepeatReadbackPreface(visibleFinalText)
503
+ : visibleFinalText;
465
504
  const synthesisAlreadyStreamed =
466
505
  visibleFinalText !== null
467
506
  && visibleFinalText.length > 0
468
- && streamedTextSum.endsWith(visibleFinalText);
507
+ && (streamedTextSum.endsWith(visibleFinalText)
508
+ || (goalRepeatStrippedFinalText !== null && goalRepeatStrippedFinalText.length > 0
509
+ && streamedTextSum.endsWith(goalRepeatStrippedFinalText)));
469
510
  // ⭐ 최종 답 = 모델 답 ⊕ 런타임 검증 보충이면 사용자에겐 «모델 답»만 보인다 — 보충은 로그로(#25).
470
511
  // 대화 이력(completedMessages)엔 그대로 남아 다음 턴 맥락은 바뀌지 않는다.
471
512
  const supplement = finalSupplement !== null && finalAssistantText === finalSupplement.finalText
@@ -491,7 +532,11 @@ export function bridgeCoreTurnToAcp(
491
532
  });
492
533
  }
493
534
  if (supplement !== null) {
494
- const answerStreamed = supplement.answer.length > 0 && streamedTextSum.trimEnd().endsWith(supplement.answer);
535
+ // TUI-GOAL-REPEAT-ANSWER — 위와 같은 이유: 인사를 뗀 답 부분이 스트림 꼬리에 있으면 그렸다(골 루프만).
536
+ const answerStreamed = supplement.answer.length > 0
537
+ && (streamedTextSum.trimEnd().endsWith(supplement.answer)
538
+ || (armGoalLoop
539
+ && streamedTextSum.trimEnd().endsWith(stripGoalRepeatReadbackPreface(supplement.answer))));
495
540
  try {
496
541
  // 보충 «전체»를 남긴다 — 한 행이 저장 전에 잘리지 않게 조각(part/parts)으로 나눈다(리뷰 r3·r4).
497
542
  const redacted = redactSecretText(supplement.supplement);
@@ -223,6 +223,8 @@ export interface AdProductionDeps {
223
223
  readonly render?: CommandRunner;
224
224
  /** Optional calibrated thresholds; omitted thresholds intentionally preserve unmeasured QC findings. */
225
225
  readonly qcThresholds?: QcThresholds;
226
+ /** Platform that decides whether on-screen text OCR (macOS Vision via swiftc) is planned; defaults to `process.platform`. */
227
+ readonly qcPlatform?: NodeJS.Platform;
226
228
  }
227
229
 
228
230
  export interface AdOutputIdentity {
@@ -828,7 +830,7 @@ async function runQc(
828
830
  captionedMasterPath?: string,
829
831
  ): Promise<QcResult | undefined> {
830
832
  if (!production?.render || !scene || !masterPath) return undefined;
831
- const { measurements, unavailableTextRegions } = await measureQc(production, buildQcMeasurementPlan(scene, masterPath));
833
+ const { measurements, unavailableTextRegions } = await measureQc(production, buildQcMeasurementPlan(scene, masterPath, production.qcPlatform ?? process.platform));
832
834
  if (unavailableTextRegions !== undefined) {
833
835
  debug.log('ad-pipeline.qc', 'text-regions-unavailable', { reason: unavailableTextRegions });
834
836
  }
@@ -851,7 +853,7 @@ async function runQc(
851
853
  debug.log('ad-pipeline.qc', 'captioned-master-absent', { reason: !captionedMasterPath ? 'captioned-master-unavailable' : 'no-caption-lines' });
852
854
  return baseResult;
853
855
  }
854
- const captionedPlan = buildQcMeasurementPlan(scene, captionedMasterPath, process.platform, {
856
+ const captionedPlan = buildQcMeasurementPlan(scene, captionedMasterPath, production.qcPlatform ?? process.platform, {
855
857
  textFrameAtSeconds: (line.startMs + line.endMs) / 2000,
856
858
  });
857
859
  const captionedMeasurement = await measureQc(production, captionedPlan, (step) => step === 'probe' || step.startsWith('text-'));
@@ -13,6 +13,9 @@
13
13
  // generator terminates instead of hanging.
14
14
 
15
15
  import {
16
+ inferProviderFromModel,
17
+ isModelCompatible,
18
+ resolveDefaultProvider,
16
19
  streamLLMWithTools,
17
20
  type LLMMessage,
18
21
  type LLMToolSpec,
@@ -20,6 +23,7 @@ import {
20
23
  import { debug } from '../debug/log.js';
21
24
  import { buildUniversalPreamble } from '../prompt-library/universal-preamble.js';
22
25
  import { getModelFamily } from '../models/prompts.js';
26
+ import { resolveModelAlias } from '../intelligence-map/model-alias.js';
23
27
  import type {
24
28
  AgentDefinition, AgentEvent, AgentSpawnOpts, AgentTask,
25
29
  } from './types.js';
@@ -57,6 +61,151 @@ class AsyncEventQueue<T> {
57
61
  }
58
62
  }
59
63
 
64
+ // ── Model resolution (TUI-AGENT-MODEL-FALLBACK · 결함 #34) ──
65
+ //
66
+ // A definition's frontmatter `model:` is a REQUEST, not a guarantee. The
67
+ // runner must check it against the provider the child will actually run
68
+ // on BEFORE handing it to streamLLMWithTools — a codex parent used to
69
+ // request `haiku` verbatim and die (the provider chain re-routed the
70
+ // Claude-family id to Anthropic, 결함 #34, 2026-10-14).
71
+ //
72
+ // `model: undefined` in the result means "inherit the parent": the child
73
+ // then rides streamLLMWithTools's own provider decision
74
+ // (`opts.provider ?? resolveDefaultProvider(opts.model)`), exactly like a
75
+ // spawn with no model hint at all.
76
+
77
+ /** Why resolveAgentModel returned the model it did. Six distinct exits —
78
+ * never collapse them into one value: "fell back to parent" and "sent an
79
+ * unrecognized id verbatim" must stay separable in the logs. */
80
+ export type AgentModelResolutionReason =
81
+ | 'no-definition-model'
82
+ | 'declared-inherit'
83
+ | 'definition'
84
+ | 'incompatible-provider'
85
+ | 'unknown-model'
86
+ | 'provider-unknown';
87
+
88
+ export interface AgentModelResolution {
89
+ /** Canonical model id; undefined = inherit the parent's model. */
90
+ model: string | undefined;
91
+ reason: AgentModelResolutionReason;
92
+ }
93
+
94
+ /** Injection seams so tests can pin the provider / inference without
95
+ * touching user config. Defaults are the production functions. */
96
+ export interface ResolveAgentModelDeps {
97
+ currentProviderName: () => string;
98
+ isCompatible: (providerName: string, model: string) => boolean;
99
+ inferProvider: (model: string) => string | null;
100
+ }
101
+
102
+ /** Production `currentProviderName` — the provider a model-less spawn
103
+ * would run on right now (the parent-configured default). A lookup
104
+ * failure is NOT hidden behind a made-up name: it throws, and
105
+ * resolveAgentModel turns it into the separate `provider-unknown` exit
106
+ * (judging compatibility against a fake name like 'auto' would drop a
107
+ * usable definition model to inherit). */
108
+ function productionCurrentProviderName(): string {
109
+ return resolveDefaultProvider().name;
110
+ }
111
+
112
+ const defaultResolveAgentModelDeps: ResolveAgentModelDeps = {
113
+ currentProviderName: productionCurrentProviderName,
114
+ isCompatible: isModelCompatible,
115
+ inferProvider: inferProviderFromModel,
116
+ };
117
+
118
+ /** Resolve a definition model against the provider the child would run
119
+ * on RIGHT NOW. Decision order — each step guards the next:
120
+ * 1. no model → { undefined, 'no-definition-model' }
121
+ * 2. `inherit` (trimmed, case-insensitive; an inheritance MARKER, not
122
+ * a model name) → { undefined, 'declared-inherit' }
123
+ * 3. resolveModelAlias → canonical id
124
+ * 4. inferProvider(canonical) === null → { canonical, 'unknown-model' }
125
+ * — do NOT fall back: free-form names ride the provider as-is
126
+ * (isModelCompatible's "unknown prefix is the provider's problem"
127
+ * stance; dropping a local free-form name to inherit is a regression)
128
+ * 5. isCompatible(currentProviderName, canonical)
129
+ * true → { canonical, 'definition' }
130
+ * false → { undefined, 'incompatible-provider' } (parent fallback)
131
+ * currentProviderName throws → { undefined, 'provider-unknown' } —
132
+ * compatibility cannot be judged, so the definition model is NOT
133
+ * sent (sending it could re-route the provider by model name); the
134
+ * child inherits the parent model — the goal's «can't call it →
135
+ * parent model» intent, kept as its own reason so a lookup failure
136
+ * is never confused with a real incompatibility
137
+ *
138
+ * Inference (4) runs BEFORE compatibility (5) because isModelCompatible
139
+ * returns true on null inference — checking compatibility first would
140
+ * mislabel every unknown model as compatible and the unknown-model exit
141
+ * would be unreachable. */
142
+ export function resolveAgentModel(
143
+ defModel: string | undefined,
144
+ deps: Partial<ResolveAgentModelDeps> = {},
145
+ ): AgentModelResolution {
146
+ const d: ResolveAgentModelDeps = { ...defaultResolveAgentModelDeps, ...deps };
147
+ if (defModel === undefined || defModel.trim() === '') {
148
+ return { model: undefined, reason: 'no-definition-model' };
149
+ }
150
+ const trimmed = defModel.trim();
151
+ if (trimmed.toLowerCase() === 'inherit') {
152
+ return { model: undefined, reason: 'declared-inherit' };
153
+ }
154
+ const canonical = resolveModelAlias(trimmed) ?? trimmed;
155
+ if (d.inferProvider(canonical) === null) {
156
+ return { model: canonical, reason: 'unknown-model' };
157
+ }
158
+ let providerName: string;
159
+ try {
160
+ providerName = d.currentProviderName();
161
+ } catch {
162
+ return { model: undefined, reason: 'provider-unknown' };
163
+ }
164
+ if (d.isCompatible(providerName, canonical)) {
165
+ return { model: canonical, reason: 'definition' };
166
+ }
167
+ return { model: undefined, reason: 'incompatible-provider' };
168
+ }
169
+
170
+ /** Resolve + record exactly one `agent.model` observation. Every runtime
171
+ * resolution goes through here (runAgent ⊕ a direct buildAgentMessages call
172
+ * without a pre-resolved `model`) so «one observation per resolution» holds
173
+ * on both paths. incompatible-provider (parent fallback), unknown-model
174
+ * (verbatim pass-through of an unrecognizable id) and provider-unknown
175
+ * (provider lookup failed, inherited the parent unjudged) are the exits an
176
+ * operator must tell apart from a log line alone — they get warn level. */
177
+ function resolveAgentModelObserved(
178
+ def: Pick<AgentDefinition, 'name' | 'model'>,
179
+ pinnedProviderName?: string,
180
+ ): AgentModelResolution {
181
+ let providerError: string | undefined;
182
+ let currentProviderName: string | undefined = pinnedProviderName;
183
+ const resolution = resolveAgentModel(def.model, {
184
+ currentProviderName: () => {
185
+ if (currentProviderName !== undefined) return currentProviderName;
186
+ try {
187
+ currentProviderName = productionCurrentProviderName();
188
+ return currentProviderName;
189
+ } catch (error) {
190
+ providerError = error instanceof Error ? error.message : String(error);
191
+ throw error;
192
+ }
193
+ },
194
+ });
195
+ debug.log('agent.model', 'resolved', {
196
+ agent: def.name,
197
+ declared: def.model,
198
+ model: resolution.model,
199
+ reason: resolution.reason,
200
+ provider: currentProviderName ?? null,
201
+ ...(providerError !== undefined ? { providerError } : {}),
202
+ }, resolution.reason === 'incompatible-provider' || resolution.reason === 'unknown-model'
203
+ || resolution.reason === 'provider-unknown'
204
+ ? { level: 'warn' as const }
205
+ : undefined);
206
+ return resolution;
207
+ }
208
+
60
209
  // ── Helpers ──
61
210
 
62
211
  /** Assemble the initial message history. The parent's rendered system
@@ -74,7 +223,7 @@ export function buildAgentMessages(
74
223
  def: AgentDefinition,
75
224
  prompt: string,
76
225
  systemPromptPrefix?: string,
77
- ctx: { cwd?: string; enabledTools?: readonly string[] } = {},
226
+ ctx: { cwd?: string; enabledTools?: readonly string[]; model?: string } = {},
78
227
  ): LLMMessage[] {
79
228
  let effectivePrefix: string | undefined = systemPromptPrefix;
80
229
  if (def.omitInheritedContext) {
@@ -108,7 +257,15 @@ export function buildAgentMessages(
108
257
  // omitInheritedContext contract stable we honor it strictly.
109
258
  let universalPreamble: LLMMessage[] = [];
110
259
  if (!def.omitInheritedContext && ctx.cwd) {
111
- const agentModelFamily = def.model ? getModelFamily(def.model) : undefined;
260
+ // TUI-AGENT-MODEL-FALLBACK: the preamble's modelFamily must track the
261
+ // model the run will actually use. runAgent passes the already-resolved
262
+ // model (one resolution + one `agent.model` observation per spawn);
263
+ // direct callers that omit `model` resolve here so a definition model
264
+ // the current provider can't run never reaches the preamble either.
265
+ const effectiveModel = 'model' in ctx
266
+ ? ctx.model
267
+ : resolveAgentModelObserved(def).model;
268
+ const agentModelFamily = effectiveModel ? getModelFamily(effectiveModel) : undefined;
112
269
  universalPreamble = buildUniversalPreamble({
113
270
  cwd: ctx.cwd,
114
271
  ...(agentModelFamily !== undefined ? { modelFamily: agentModelFamily } : {}),
@@ -206,6 +363,14 @@ export async function* runAgent(
206
363
  // `Agent` → search-vs-spawn split, `TaskCreate` → don't batch).
207
364
  const tools = filterAgentTools(opts.tools, task.definition.tools);
208
365
 
366
+ // TUI-AGENT-MODEL-FALLBACK (결함 #34): resolve the definition model
367
+ // against the provider the child will ACTUALLY run on — the pinned
368
+ // `opts.provider` when the dispatcher chose one, otherwise the
369
+ // parent-configured default (what streamLLMWithTools picks for a
370
+ // model-less spawn). `model: undefined` = inherit: the child then takes
371
+ // the same provider/model decision path as the parent.
372
+ const modelResolution = resolveAgentModelObserved(task.definition, opts.provider?.name);
373
+
209
374
  // Build history on the task so callers can inspect it after the run.
210
375
  // PFC-S1 P5: pass task.cwd so the slim-context notice (when
211
376
  // omitInheritedContext) can name the child's working directory.
@@ -214,6 +379,7 @@ export async function* runAgent(
214
379
  task.prompt,
215
380
  opts.systemPromptPrefix,
216
381
  {
382
+ model: modelResolution.model,
217
383
  ...(task.cwd ? { cwd: task.cwd } : {}),
218
384
  ...(tools ? { enabledTools: tools.map(t => t.name) } : {}),
219
385
  },
@@ -252,7 +418,7 @@ export async function* runAgent(
252
418
  dispatchTool,
253
419
  },
254
420
  {
255
- model: task.definition.model,
421
+ model: modelResolution.model,
256
422
  tools,
257
423
  signal: task.controller.signal,
258
424
  provider: opts.provider,
@@ -132,7 +132,7 @@ export function createGlobalSubagentCallable(
132
132
  const done = drainToResult(handle.events, () => ({
133
133
  durationMs: Date.now() - startedAt,
134
134
  modelId: effectiveDefinition.model,
135
- }));
135
+ }), () => handle.task.controller?.signal.aborted ?? (signal?.aborted === true));
136
136
 
137
137
  return { address, done };
138
138
  };
@@ -154,6 +154,7 @@ async function drainToResult(
154
154
  unknown
155
155
  >,
156
156
  closing: () => { durationMs: number; modelId?: string },
157
+ signalAborted: () => boolean,
157
158
  ): Promise<{
158
159
  status: 'completed' | 'failed' | 'cancelled';
159
160
  output: string;
@@ -190,7 +191,7 @@ async function drainToResult(
190
191
 
191
192
  const close = closing();
192
193
  const baseModel = close.modelId ? { modelId: close.modelId } : {};
193
- if (aborted) {
194
+ if (aborted || signalAborted()) {
194
195
  return { status: 'cancelled', output: accumulated, durationMs: close.durationMs, ...baseModel };
195
196
  }
196
197
  if (errorMsg !== null) {
@@ -361,9 +361,12 @@ export function extractAppliedReviewItems(comments: readonly NonNullable<LatestR
361
361
  /** 브랜치의 열린 PR 코멘트에서 이전 self-dev 반영분을 fail-soft로 읽는다. */
362
362
  export function fetchAppliedReviewItemsForBranch(branch: string, runGh: (args: string[]) => string = gh): AppliedReviewItems {
363
363
  try {
364
- const raw = runGh(['pr', 'view', branch, '--json', 'comments']);
365
- const source = JSON.parse(raw) as LatestReviewSource;
366
- const signals = filterReviewSignals(source);
364
+ // A Pod repair uses the synthetic worktree base `pr-N`; GitHub knows that
365
+ // source by PR number, not by the synthetic branch name.
366
+ const source = /^pr[:-]([1-9]\d*)$/.exec(branch)?.[1] ?? branch;
367
+ const raw = runGh(['pr', 'view', source, '--json', 'comments']);
368
+ const reviewSource = JSON.parse(raw) as LatestReviewSource;
369
+ const signals = filterReviewSignals(reviewSource);
367
370
  return { basePrLocated: true, ...analyzeAppliedReviewItems(signals.selfAuthoredComments) };
368
371
  } catch {
369
372
  return { basePrLocated: false, items: [], headlineComments: 0 };
@@ -85,6 +85,18 @@ export interface AcpImplementerResult {
85
85
 
86
86
  const OBS = 'agent-substrate.acp-implementer';
87
87
 
88
+ /** Claude ACP's default preset imports user/project plugins and MCP servers into every
89
+ * prompt snapshot. The implementation child only needs the built-in coding tools. */
90
+ export const CLAUDE_IMPLEMENTER_META = {
91
+ claudeCode: { options: {
92
+ tools: ['Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep'],
93
+ settingSources: [],
94
+ plugins: [],
95
+ mcpServers: {},
96
+ strictMcpConfig: true,
97
+ } },
98
+ } as const;
99
+
88
100
  export function makeAcpImplementer(opts: AcpImplementerOpts): (prompt: string) => Promise<AcpImplementerResult> {
89
101
  return async (prompt) => {
90
102
  const spawn = subscriptionReviewerSpawn(opts.spec ?? { provider: 'claude-acp' }, opts.env ?? process.env, opts.proxyBaseUrl);
@@ -119,10 +131,10 @@ export function makeAcpImplementer(opts: AcpImplementerOpts): (prompt: string) =
119
131
  await withinHandshake(agent.start());
120
132
  let sid: string;
121
133
  if (opts.resumeSessionId) {
122
- await withinHandshake(agent.loadSession({ sessionId: opts.resumeSessionId, cwd: opts.worktree }));
134
+ await withinHandshake(agent.loadSession({ sessionId: opts.resumeSessionId, cwd: opts.worktree, _meta: CLAUDE_IMPLEMENTER_META }));
123
135
  sid = opts.resumeSessionId;
124
136
  } else {
125
- sid = await withinHandshake(agent.newSession());
137
+ sid = await withinHandshake(agent.newSession(CLAUDE_IMPLEMENTER_META));
126
138
  }
127
139
  if (opts.model) await withinHandshake(agent.selectSessionModel(sid, opts.model));
128
140
  debug.log(OBS, 'start', { cwd: opts.worktree, model: opts.model ?? '(default)', resumed: Boolean(opts.resumeSessionId) });
@@ -652,6 +652,17 @@ export function buildReviewPrompt(
652
652
  * `none of the tests …`. 표지 낱말로 시작하는 실제 블로커를 지우면 PASS/WARN 리뷰에서 블로커가 사라진다. */
653
653
  const NONE_WORD = String.raw`(?:없음|해당\s*없음|n\/a|none|nothing)`;
654
654
  const BARE_SENTINEL = new RegExp(String.raw`^${NONE_WORD}\s*[.。]?$`, 'i');
655
+ // GLM 은 비어 있는 mustFix 항목이나 괄호 안의 한 문장으로 무소견을 적는다.
656
+ // 괄호 전체만 검사한다. 중간에 "no blockers" 가 있어도 뒤에 지적이 이어지면 버리지 않는다.
657
+ const BRACKETED_PLACEHOLDER = /^[((]\s*([\s\S]*?)\s*[))]$/;
658
+ const PLACEHOLDER_ONLY = /^(?:없음|해당\s*없음|none|n\/a|no\s+blockers?)$/i;
659
+ const PLACEHOLDER_END = /(?:블로커|차단)\s*없음$|no\s+blockers?$/i;
660
+ function isBracketedPlaceholder(text: string): boolean {
661
+ const bracketed = BRACKETED_PLACEHOLDER.exec(text);
662
+ if (!bracketed) return false;
663
+ const inside = bracketed[1]!.trim().replace(/(?:\s*(?:…|\.{2,}|[.。]))+\s*$/, '').trim();
664
+ return PLACEHOLDER_ONLY.test(inside) || PLACEHOLDER_END.test(inside);
665
+ }
655
666
  const DASH_ONLY_SENTINEL = /^[([(【]\s*[-—–]\s*[)\])】]$/;
656
667
  // 목록 항목의 바깥 `- `와 별개로, 리뷰어가 괄호 안에도 장식 대시를 둘 수 있다: `- (- 없음 -)`.
657
668
  const DASH_WRAPPED_BRACKETED_SENTINEL = new RegExp(String.raw`^[([(【]\s*(?:[-—–]+\s*)?${NONE_WORD}\s*(?:[-—–]+\s*)?[)\])】]$`, 'i');
@@ -685,6 +696,7 @@ function isLongNoFindingBracket(text: string): boolean {
685
696
  * ⭐ export — `parseReviewResultOutput` 가 «같은» 판정으로 저장된 결과의 표지 줄을 다시 접는다(PR-LAND-MUSTFIX-NONE · 복제 금지). */
686
697
  export function isNoneSentinelFinding(finding: string): boolean {
687
698
  const text = finding.trim();
699
+ if (!text || isBracketedPlaceholder(text)) return true;
688
700
  if (/^[-—–]+$/.test(text)) return true;
689
701
  const markerText = text.replace(/^[—–-]+\s*|\s*[—–-]+$/g, '').trim();
690
702
  if (markerText && (BARE_SENTINEL.test(markerText) || DASH_ONLY_SENTINEL.test(markerText) || DASH_WRAPPED_BRACKETED_SENTINEL.test(markerText))) return true;
@@ -1125,6 +1125,24 @@ function roleAcpErrorReason(error: unknown): 'acp-handshake-timeout' | 'acp-erro
1125
1125
 
1126
1126
  type AcpFallbackSkip = { backend: string; reason: string };
1127
1127
 
1128
+ function validateReviewDenyBackends(value: unknown, now: number): string[] | null {
1129
+ if (value === undefined) return [];
1130
+ if (!Array.isArray(value)) return null;
1131
+ const denied: string[] = [];
1132
+ for (const entry of value) {
1133
+ if (typeof entry === 'string' && entry.trim()) { denied.push(entry); continue; }
1134
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return null;
1135
+ const item = entry as Record<string, unknown>;
1136
+ if (Object.keys(item).some((key) => key !== 'backend' && key !== 'expiresAt')
1137
+ || typeof item.backend !== 'string' || !item.backend.trim()
1138
+ || typeof item.expiresAt !== 'string' || !/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d+)?Z$/.test(item.expiresAt)
1139
+ || !Number.isFinite(Date.parse(item.expiresAt)) || new Date(item.expiresAt).toISOString().slice(0, 19) !== item.expiresAt.slice(0, 19)
1140
+ || Date.parse(item.expiresAt) <= now) return null;
1141
+ denied.push(item.backend);
1142
+ }
1143
+ return denied;
1144
+ }
1145
+
1128
1146
  function orderedAcpReviewFallbackBackends(configuredBackend: string | undefined, denyBackends: readonly string[] = []): {
1129
1147
  backends: string[];
1130
1148
  skipped: AcpFallbackSkip[];
@@ -1294,10 +1312,17 @@ async function runSelfReviewCliCommandPinned(
1294
1312
  const acpBackend = acpBackendResolution.backend;
1295
1313
  const requestedModel = opts.model?.trim() || undefined;
1296
1314
  const rawReviewDenyBackends = (getUserConfig().raw?.acp as { reviewDenyBackends?: unknown } | undefined)?.reviewDenyBackends;
1297
- const configuredReviewDenyBackends = Array.isArray(rawReviewDenyBackends)
1298
- ? rawReviewDenyBackends.filter((backend): backend is string => typeof backend === 'string')
1299
- : [];
1300
- const automaticFallbacks = orderedAcpReviewFallbackBackends(opts.configuredAcpBackend, opts.reviewDenyBackends ?? configuredReviewDenyBackends);
1315
+ const denyCheckedAt = Date.now();
1316
+ const configuredReviewDenyBackends = validateReviewDenyBackends(rawReviewDenyBackends, denyCheckedAt);
1317
+ const reviewDenyBackends = validateReviewDenyBackends(opts.reviewDenyBackends, denyCheckedAt);
1318
+ if (configuredReviewDenyBackends === null || reviewDenyBackends === null) {
1319
+ const message = 'acp.reviewDenyBackends 설정이 유효하지 않거나 만료됐습니다 — 리뷰를 실행하지 않습니다.';
1320
+ deps.log('review-deny-invalid', { reason: 'invalid-or-expired-review-deny-backends' }, { level: 'warn' });
1321
+ deps.error(message);
1322
+ return { results: opts.json ? [{ error: message }] : [], failed: 1 };
1323
+ }
1324
+ const automaticFallbacks = orderedAcpReviewFallbackBackends(opts.configuredAcpBackend,
1325
+ opts.reviewDenyBackends === undefined ? configuredReviewDenyBackends : reviewDenyBackends);
1301
1326
  const fallbackAcpBackends = opts.acpBackend
1302
1327
  ? [canonicalizeBackendId(opts.acpBackend)]
1303
1328
  : automaticFallbacks.backends;
@@ -1632,6 +1657,7 @@ async function runSelfReviewCliCommandPinned(
1632
1657
  const reviewProvenance = {
1633
1658
  reviewRoute,
1634
1659
  fallbackAttempted,
1660
+ ...(requestedModel ? { requestedModel } : {}),
1635
1661
  ...(fallbackBackend ? { fallbackBackend } : {}),
1636
1662
  ...(fallbackBackend ? { requestedModel: primaryModel, actualBackend: `acp:${fallbackBackend}` } : {}),
1637
1663
  ...(fallbackNotAttemptedReason ? { fallbackNotAttemptedReason } : {}),