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
@@ -41,6 +41,10 @@ import { attachLifecycleBridge } from '../signal/lifecycle-bridge.js';
41
41
  import { getChannelBus } from '../terminal-matrix/index.js';
42
42
  import type { ChannelBus } from '../terminal-matrix/channel-bus.js';
43
43
  import { startChildLivenessHeartbeat } from './child-liveness-heartbeat.js';
44
+ import {
45
+ SEAT_IDLE_NO_WORK_NOTICE, SEAT_TURN_CAP_CONTINUE_PROMPT, SEAT_TURN_CAP_TOOL_NOTICE,
46
+ isEmptyMailListResult, isIdleWaitCall, type SeatTurnCapConfig,
47
+ } from './seat-turn-cap.js';
44
48
 
45
49
  export {
46
50
  CHILD_LIVENESS_HEARTBEAT_ENV,
@@ -259,6 +263,37 @@ export function buildRejectedToolCompletionPrompt(rejectedTools: readonly string
259
263
  ].join('\n');
260
264
  }
261
265
 
266
+ /** TUI-GOAL-REPEAT-ANSWER(0.2.32) — goal loop 반복에서 모델이 이전 답을 다시 말할 때 화면에
267
+ * 같은 답이 두 번 그려지는 중복을 스트림 쪽에서 가려내는 «읽기-되돌림 인사(readback preface)»
268
+ * 문형. completion 판정의 readbackPreface(이 파일 하단 duplicate-answer 판정)와 같은 문형을
269
+ * 스트림 쪽에서도 쓴다 — 화면 중복 제거와 원장 중복 제거가 같은 모양을 같은 것으로 본다. 스트림은
270
+ * 문형이 한 글자씩 이어지는 중에도 판정해야 하므로(regex 전체 매칭이 아니라) 어구를 펼쳐둔 목록이다. */
271
+ const GOAL_REPEAT_READBACK_VERBS = [
272
+ '', '했습니다', '했지만', '해보니', '해 보니', '해봤지만', '해 봤지만', '했으나', '했는데',
273
+ ] as const;
274
+ const GOAL_REPEAT_READBACK_PHRASES: readonly string[] = [
275
+ '확인 결과',
276
+ ...GOAL_REPEAT_READBACK_VERBS.flatMap((verb) => (verb === ''
277
+ ? ['다시 확인', '방금 다시 확인']
278
+ : [`다시 확인${verb}`, `방금 다시 확인${verb}`])),
279
+ ];
280
+ /** preface 뒤에 올 수 있는 구분자(여백·콜론·마침표 등) — 답 앞에 붙은 만큼 통째로 뗀다. */
281
+ const GOAL_REPEAT_PREFACE_SEPS = /^[\s::,.!?。!?-]+/u;
282
+ /** TUI-GOAL-REPEAT-ANSWER — 스트림 쪽 답 비교 정규화: 여백 종류를 하나로 접고 끝여백을 뗀다. */
283
+ function goalRepeatStreamNormalize(text: string): string {
284
+ return text.replace(/\s+/gu, ' ').trim();
285
+ }
286
+
287
+ /** TUI-GOAL-REPEAT-ANSWER — «읽기-되돌림 인사(readback preface) ⊕ 답»에서 인사+구분자를 뗀 나머지(답
288
+ * 부분)를 돌려준다. 인사가 없으면 원문 그대로. 골 루프의 화면 중복 제거(스트림 대기·버림)와 브리지의
289
+ * 재표면화 판정(이미 그린 답인가)이 같은 문형을 같은 것으로 보게 하려고 내보낸다. */
290
+ export function stripGoalRepeatReadbackPreface(text: string): string {
291
+ for (const phrase of GOAL_REPEAT_READBACK_PHRASES) {
292
+ if (text.startsWith(phrase)) return text.slice(phrase.length).replace(GOAL_REPEAT_PREFACE_SEPS, '');
293
+ }
294
+ return text;
295
+ }
296
+
262
297
  export interface GoalLoopOptions {
263
298
  /** 목표 문구(관측·프레이밍용). 생략 시 마지막 user 메시지에서 추출. */
264
299
  objective?: string;
@@ -296,8 +331,22 @@ export interface GoalLoopOptions {
296
331
  * 최대 2번 재촉한다. 생략하면 harness role 이 executor 인 프로세스에서만 활성 provider 로 푼다.
297
332
  * null = 가드 꺼짐. 시험은 이 인자를 명시해 env 에 기대지 않는다. */
298
333
  intentStallProvider?: string | null;
334
+ /** TUI-H1-SEAT-GOALLOOP(#29 처방) — 자리 TUI 의 운영·읽기 지시를 goal loop 로 되돌린 턴에서만 참.
335
+ * update_goal(complete) 의 evidence 가 비었을 때 «증거 없음» 반려(재주입) 대신 그 턴의 (비지 않은) 답을 증거로 받아 끝낸다
336
+ * (10-14 OPT: 완료 선언 → 증거 부족 반려 → 재호출이 14회 · 사용자 답에 사과 문장). 시험 실패·거부된 도구 반려는 그대로다. */
337
+ lenientCompletionEvidence?: boolean;
338
+ /** TUI-SEAT-TURN-CAP — 자리 TUI 의 goal loop 에서만 준다(브리지가 route.reason 'seat-*' 로 판정). 없으면 상한·idle 판정 0(종전).
339
+ * ⓐ core 턴 1회당 도구 수·벽시계 상한 — 닿으면 넘는 도구는 실행하지 않고 «한 줄 진행 요약 ⊕ 턴 마감» 을 안내,
340
+ * 턴이 끝나면 stopReason 을 max_turns 로 두고 다음 반복으로 잇는다(반복 하드캡 maxIterations 는 그대로).
341
+ * ⓑ 같은 core 턴의 «새 항목 0» 우편 조회가 연속 idleEmptyMsgListLimit 번이면 «할 일 0» 으로 goal 을 완료한다(idle-no-work). */
342
+ seatTurnCap?: SeatTurnCapConfig & { seat: string };
343
+ /** Test seam — 벽시계(ms). 기본 Date.now. */
344
+ now?: () => number;
299
345
  }
300
346
 
347
+ /** TUI-SEAT-TURN-CAP — 상한·idle 안내 «뒤» 에도 도구 호출이 이만큼 넘게 오면 그 core 턴을 끝낸다. */
348
+ const SEAT_CAP_REFUSAL_BACKSTOP = 3;
349
+
301
350
  export type GoalLoopStopReason =
302
351
  | CoreTurnStopReason // aborted | error | end_turn | max_turns (마지막 turn 것)
303
352
  | 'goal_complete' // update_goal(complete)+evidence 로 완료 선언
@@ -466,6 +515,8 @@ export async function runGoalLoop(
466
515
  const tools: LLMToolSpec[] = [...ctx.tools, updateGoalSpec];
467
516
 
468
517
  const noProgressLimit = opts.noProgressLimit ?? 2;
518
+ const now = opts.now ?? Date.now;
519
+ let seatCapHits = 0;
469
520
  let iterations = 0;
470
521
  let noProgress = 0;
471
522
  let blockedStreak = 0;
@@ -632,6 +683,57 @@ export async function runGoalLoop(
632
683
  let iterUsageMissing = 0;
633
684
  let postToolSoftStop = false;
634
685
  const turnAbortController = new AbortController();
686
+ // TUI-SEAT-TURN-CAP — 이번 core 턴의 상한·idle 상태(반복마다 새로).
687
+ const seatCap = opts.seatTurnCap;
688
+ const turnStartedAt = now();
689
+ let seatTools = 0;
690
+ let seatClosing: 'tools' | 'wall' | 'idle' | null = null;
691
+ let seatRefusedAfterClose = 0;
692
+ let seatCapAborted = false;
693
+ let emptyMailStreak = 0;
694
+ // 벽시계는 «다음 도구 호출» 에서 잰다 — 도는 스트림·도구는 끊지 않는다(끊고 멈춤이 아니라 마감 안내).
695
+ // ⛔ 상한이 없으면(사람 TUI·하니스 자식) caller dispatcher 의 Promise 를 «그대로» 돌려준다 — async 로 감싸면
696
+ // 새 Promise 가 되어 caller-side dispatch 동일성 계약(core-turn-goal-loop.test)이 깨진다(열차 r19d 회귀).
697
+ // 기본 실행기는 `ctx.dispatchTool(...)` 를 «메서드로» 부른다 — 꺼내 담아 부르면 수신자(this)가 빠진다(리뷰 r5).
698
+ const seatDispatch = (
699
+ name: string, args: Record<string, unknown>, dctx: Parameters<CoreTurnContext['dispatchTool']>[2],
700
+ execute?: CoreTurnContext['dispatchTool'],
701
+ ): Promise<unknown> => {
702
+ const run: CoreTurnContext['dispatchTool'] = execute ?? ((n, a, c) => ctx.dispatchTool(n, a, c));
703
+ if (!seatCap) return run(name, args, dctx);
704
+ return seatCappedDispatch(seatCap, name, args, dctx, run);
705
+ };
706
+ const seatCappedDispatch = async (
707
+ cap: SeatTurnCapConfig, name: string, args: Record<string, unknown>,
708
+ dctx: Parameters<CoreTurnContext['dispatchTool']>[2], execute: CoreTurnContext['dispatchTool'],
709
+ ): Promise<unknown> => {
710
+ if (seatClosing === null && now() - turnStartedAt >= cap.maxWallMs) seatClosing = 'wall';
711
+ if (seatClosing === null && seatTools >= cap.maxTools) seatClosing = 'tools';
712
+ if (seatClosing !== null) {
713
+ seatRefusedAfterClose += 1;
714
+ // 받침 — 안내를 받고도 도구를 계속 부르면 이 core 턴만 끝낸다(goal loop 는 다음 반복으로 잇는다).
715
+ if (seatRefusedAfterClose > SEAT_CAP_REFUSAL_BACKSTOP) {
716
+ seatCapAborted = true;
717
+ turnAbortController.abort();
718
+ }
719
+ return { error: seatClosing === 'idle'
720
+ ? SEAT_IDLE_NO_WORK_NOTICE(cap.idleEmptyMsgListLimit)
721
+ : SEAT_TURN_CAP_TOOL_NOTICE(seatClosing, cap) };
722
+ }
723
+ seatTools += 1;
724
+ const result = await execute(name, args, dctx);
725
+ if (isEmptyMailListResult(name, result)) {
726
+ emptyMailStreak += 1;
727
+ if (emptyMailStreak >= cap.idleEmptyMsgListLimit) {
728
+ seatClosing = 'idle';
729
+ return { ...(result as Record<string, unknown>), notice: SEAT_IDLE_NO_WORK_NOTICE(cap.idleEmptyMsgListLimit) };
730
+ }
731
+ } else if (!isIdleWaitCall(name, args)) {
732
+ // 새 우편이 왔거나(비지 않은 조회) 다른 일을 했다 — «할 일 0» 연속이 끊긴다. 대기용 sleep 은 끊지 않는다.
733
+ emptyMailStreak = 0;
734
+ }
735
+ return result;
736
+ };
635
737
  const abortForCaller = () => turnAbortController.abort(ctx.signal.reason);
636
738
  if (ctx.signal.aborted) abortForCaller();
637
739
  else ctx.signal.addEventListener('abort', abortForCaller, { once: true });
@@ -639,6 +741,34 @@ export async function runGoalLoop(
639
741
  postToolSoftStop = true;
640
742
  turnAbortController.abort();
641
743
  };
744
+ // TUI-GOAL-REPEAT-ANSWER(0.2.32) — goal loop 반복에서 모델이 이전 iteration 의 답을
745
+ // 다시 말하면 화면에 같은 답이 두 번 그려진다(관측 2026-10-14 05:37). 원장 쪽 중복은
746
+ // 아래 completion 판정이 이미 접는다 — 이 검은 화면 push 만 담당한다: 이번 iteration 의
747
+ // 스트림이 «읽기-되돌림 인사(preface) ⊕ 이전 답»의 접두사로만 진행되는 동안 caller 의
748
+ // onText 로 흘리지 않고 대기하다, 갈라지는 순간(새 내용) 모은 걸 한 번에 흘린 뒤 그대로
749
+ // 흘린다. iteration 마감의 순수 중복 판정·버림은 onTurnComplete 에서 한다.
750
+ const previousFinalText = lastResult.finalText;
751
+ const goalRepeatPreviousAnswer = goalRepeatStreamNormalize(previousFinalText);
752
+ let goalRepeatWithheld = '';
753
+ let goalRepeatWithholding = goalRepeatPreviousAnswer.length > 0;
754
+ const goalRepeatStreamConsistent = (text: string): boolean => {
755
+ if (previousFinalText.startsWith(text)) return true;
756
+ const normalized = goalRepeatStreamNormalize(text);
757
+ if (goalRepeatPreviousAnswer.startsWith(normalized)) return true;
758
+ for (const phrase of GOAL_REPEAT_READBACK_PHRASES) {
759
+ if (phrase.startsWith(normalized)) return true;
760
+ if (!normalized.startsWith(phrase)) continue;
761
+ const rest = normalized.slice(phrase.length).replace(GOAL_REPEAT_PREFACE_SEPS, '');
762
+ if (goalRepeatPreviousAnswer.startsWith(rest)) return true;
763
+ }
764
+ return false;
765
+ };
766
+ const flushGoalRepeatWithheld = (full: string): void => {
767
+ if (goalRepeatWithheld === '') return;
768
+ const withheld = goalRepeatWithheld;
769
+ goalRepeatWithheld = '';
770
+ ctx.callbacks?.onText?.(withheld, full);
771
+ };
642
772
  const turnCtx: CoreTurnContext = {
643
773
  ...ctx,
644
774
  messages,
@@ -646,6 +776,8 @@ export async function runGoalLoop(
646
776
  signal: turnAbortController.signal,
647
777
  // 진입 시 한 번 정한 사람 문장을 매 라운드에 그대로 내린다(위 주석 참조).
648
778
  ...(surfaceUserText !== undefined ? { userText: surfaceUserText } : {}),
779
+ // TUI-GOAL-LOOP-FRICTION(#46·#63) — update_goal 은 도구 예산 거부를 받지 않고, 답과 함께 오면 그 턴으로 마감한다.
780
+ terminalToolNames: [...(ctx.terminalToolNames ?? []), UPDATE_GOAL_TOOL_NAME],
649
781
  // update_goal 은 종결 신호 — 실 dispatcher 로 새지 않게 가로채 ack 만 돌려준다.
650
782
  dispatchTool: (name, args, dctx) => {
651
783
  dispatchCount += 1;
@@ -660,12 +792,34 @@ export async function runGoalLoop(
660
792
  // Observability must not prevent the selected tool from dispatching.
661
793
  }
662
794
  if (name === UPDATE_GOAL_TOOL_NAME) {
663
- return Promise.resolve({ ok: true, recorded: (args as { status?: unknown }).status ?? null });
795
+ const ack = () => Promise.resolve({ ok: true, recorded: (args as { status?: unknown }).status ?? null });
796
+ // TUI-SEAT-TURN-CAP — 진행 선언도 «다른 일» 이다: 빈 우편 조회 연속을 끊는다(리뷰 r1).
797
+ emptyMailStreak = 0;
798
+ // 완료 신호(complete)는 상한 «뒤» 에도 받고 도구로 세지 않는다 — 상한 안내가 바로 «마감하라» 이고,
799
+ // 종결 신호는 예산 거부를 받지 않는다(#28503 terminalToolNames 계약과 같은 방향). 그 밖의 진행 선언
800
+ // (in_progress·blocked)은 도구 한 번으로 세고 상한 뒤엔 같은 안내로 거부한다(리뷰 r2 — 61번 넘게 불러도 안 막히던 구멍).
801
+ if ((args as { status?: unknown }).status === 'complete') return ack();
802
+ return seatDispatch(name, args, dctx, ack);
664
803
  }
665
- return ctx.dispatchTool(name, args, dctx);
804
+ return seatDispatch(name, args, dctx);
666
805
  },
667
806
  callbacks: {
668
807
  ...ctx.callbacks,
808
+ // TUI-GOAL-REPEAT-ANSWER — 이번 iteration 의 스트림이 이전 답의 재방출로만 진행되는
809
+ // 동안은 caller 의 onText 로 흘리지 않고 대기한다(중복 후보). 갈라지는 순간 모은 걸
810
+ // 한 번에 흘리고 이후 그대로 흘린다. 빈 청크(라운드 경계·commit)는 상태와 무관하게
811
+ // 그대로 흘린다 — TUI 의 라운드 확정 신호를 끊지 않는다.
812
+ onText: (delta, full) => {
813
+ if (delta !== '' && goalRepeatWithholding) {
814
+ if (goalRepeatStreamConsistent(goalRepeatWithheld + delta)) {
815
+ goalRepeatWithheld += delta;
816
+ return;
817
+ }
818
+ goalRepeatWithholding = false;
819
+ flushGoalRepeatWithheld(full);
820
+ }
821
+ ctx.callbacks?.onText?.(delta, full);
822
+ },
669
823
  // OH8 후속 PR-2 — run_tests 결과를 캡처(last-wins). 텍스트 파싱이 아니라 구조체 ok 를 본다.
670
824
  onToolResult: (call) => {
671
825
  if (call.name === 'run_tests' && call.result && typeof call.result === 'object') {
@@ -706,6 +860,17 @@ export async function runGoalLoop(
706
860
  }
707
861
  },
708
862
  onTurnComplete: (msgs) => {
863
+ // TUI-GOAL-REPEAT-ANSWER — iteration 마감: 순수 중복이면(이전 답 ± preface 전부)
864
+ // 흴린 건 버린다 — 이전 답이 이미 화면에 그려져 있어 두 번째는 필요 없다. 아니면
865
+ // 모은 걸 한 번에 흘린 다음 마감을 넘긴다(브리지 재표면화 판정이 흘린 분량을 본다).
866
+ if (goalRepeatWithholding) {
867
+ goalRepeatWithholding = false;
868
+ const normalized = goalRepeatStreamNormalize(goalRepeatWithheld);
869
+ const pureRepeat = normalized === goalRepeatPreviousAnswer
870
+ || GOAL_REPEAT_READBACK_PHRASES.some((phrase) => normalized.startsWith(phrase)
871
+ && normalized.slice(phrase.length).replace(GOAL_REPEAT_PREFACE_SEPS, '') === goalRepeatPreviousAnswer);
872
+ if (!pureRepeat) flushGoalRepeatWithheld(normalized);
873
+ }
709
874
  turnNewMessages = msgs;
710
875
  ctx.callbacks?.onTurnComplete?.(msgs);
711
876
  },
@@ -732,12 +897,20 @@ export async function runGoalLoop(
732
897
  },
733
898
  };
734
899
 
735
- const previousFinalText = lastResult.finalText;
736
900
  try {
737
901
  lastResult = await runTurn(turnCtx);
738
902
  } finally {
739
903
  ctx.signal.removeEventListener('abort', abortForCaller);
740
904
  }
905
+ // TUI-SEAT-TURN-CAP — 상한·idle 안내 뒤 «정상 마감» 했거나 받침이 끊은 core 턴만 고쳐 읽는다.
906
+ // 사람 중단(caller signal)·error·auth_rejected 는 그대로 둔다 — 실제 오류를 상한으로 덮지 않는다(리뷰 r1).
907
+ const seatClosedTurn = seatCap !== undefined && !ctx.signal.aborted && seatClosing !== null
908
+ && (lastResult.stopReason === 'end_turn' || lastResult.stopReason === 'max_turns'
909
+ || (lastResult.stopReason === 'aborted' && seatCapAborted));
910
+ const seatCapHit = seatClosedTurn && (seatClosing === 'tools' || seatClosing === 'wall');
911
+ const seatIdleHit = seatClosedTurn && seatClosing === 'idle';
912
+ if (seatCapHit) lastResult = { ...lastResult, stopReason: 'max_turns' };
913
+ else if (seatIdleHit && lastResult.stopReason === 'aborted') lastResult = { ...lastResult, stopReason: 'end_turn' };
741
914
  messages.push(...turnNewMessages);
742
915
 
743
916
  const goalUpdate = findGoalUpdate(turnNewMessages);
@@ -757,6 +930,18 @@ export async function runGoalLoop(
757
930
  finalTextExcerpt: finalTextExcerpt.text, finalTextExcerptTruncated: finalTextExcerpt.truncated,
758
931
  }, { level: 'debug' });
759
932
 
933
+ // ①-0 #29 처방 — 자리 운영 턴은 빈 evidence 를 반려하지 않고 이 턴의 답을 증거로 받는다(관측 남김).
934
+ // 답도 비었으면 받을 증거가 없다 — 종전 반려(evidence required)로 그대로 간다.
935
+ const lenientAnswer = opts.lenientCompletionEvidence === true
936
+ ? boundReadableText(lastResult.finalText, 200).text.trim()
937
+ : '';
938
+ if (goalUpdate?.status === 'complete' && goalUpdate.evidence.trim().length === 0 && lenientAnswer.length > 0) {
939
+ goalUpdate.evidence = `(자리 운영 턴 — 답을 증거로 수용) ${lenientAnswer}`;
940
+ debug.log('goal.loop', 'complete-evidence-lenient', {
941
+ sessionId: ctx.sessionId, ...runAttribution, iterations, finalChars: lastResult.finalText.length,
942
+ }, { level: 'info' });
943
+ }
944
+
760
945
  // ① authoritative 완료 — update_goal(complete) + 비지 않은 evidence.
761
946
  if (goalUpdate?.status === 'complete') {
762
947
  if (goalUpdate.evidence.trim().length > 0) {
@@ -875,6 +1060,33 @@ export async function runGoalLoop(
875
1060
  });
876
1061
  }
877
1062
 
1063
+ // TUI-SEAT-TURN-CAP ⓑ — «할 일 0»(빈 우편 조회 연속): 이 반복을 완료로 보고 끝낸다(lenient · 대기는 H4/H5 몫).
1064
+ if (seatIdleHit && seatCap) {
1065
+ debug.log('goal.loop', 'idle-no-work', {
1066
+ sessionId: ctx.sessionId, ...runAttribution, seat: seatCap.seat, iteration: iterations,
1067
+ tools: seatTools, wallMs: now() - turnStartedAt, emptyMailStreak,
1068
+ }, { level: 'info' });
1069
+ return finish(
1070
+ { finalText: lastResult.finalText, iterations, stopReason: 'goal_complete', goalComplete: true },
1071
+ { summary: `idle-no-work — ${emptyMailStreak} consecutive empty mailbox checks (seat ${seatCap.seat})`, changedFiles: [] },
1072
+ );
1073
+ }
1074
+ // TUI-SEAT-TURN-CAP ⓐ — 도구·벽시계 상한으로 마감한 core 턴: 요약을 이어받아 다음 반복으로(하드캡이 이긴다).
1075
+ // ⛔ 빈 근거 complete 가 함께 온 턴은 여기서 잇지 않고 아래 «근거 없는 완료» 판정에 맡긴다(리뷰 r3) —
1076
+ // 적격 완료(lenient 답 수용)는 위 ① 에서 이미 끝났고, 남은 빈 근거 complete 는 종전 계약대로 근거를 다시 묻는다.
1077
+ if (seatCapHit && seatCap && goalUpdate?.status !== 'complete') {
1078
+ debug.log('goal.loop', 'seat-turn-cap', {
1079
+ sessionId: ctx.sessionId, ...runAttribution, seat: seatCap.seat, reason: seatClosing, iteration: iterations,
1080
+ tools: seatTools, wallMs: now() - turnStartedAt, maxTools: seatCap.maxTools, maxWallMs: seatCap.maxWallMs,
1081
+ backstopAborted: seatCapAborted, maxIterations,
1082
+ }, { level: 'info' });
1083
+ seatCapHits += 1;
1084
+ blockedStreak = 0;
1085
+ readbackStreak = 0;
1086
+ messages.push({ role: 'user', content: SEAT_TURN_CAP_CONTINUE_PROMPT });
1087
+ continue;
1088
+ }
1089
+
878
1090
  // Evidence-less completion is not authoritative; only retry after stop and terminal outcomes
879
1091
  // from this same turn have received priority.
880
1092
  if (goalUpdate?.status === 'complete') {
@@ -985,6 +1197,13 @@ export async function runGoalLoop(
985
1197
  }
986
1198
 
987
1199
  debug.log('goal.loop', 'max-iterations', { sessionId: ctx.sessionId, ...runAttribution, iterations }, { level: 'warn' });
1200
+ if (opts.seatTurnCap && seatCapHits > 0) {
1201
+ // 실패 시 누구에게(상한에 한 번이라도 닿은 런만 — 일반 하드캡 종료와 섞지 않는다 · 리뷰 r3) — 자리 TUI 가 반복 하드캡까지 다 쓰고 멈췄다: 자리 OP 가 보는 경고 이벤트.
1202
+ debug.log('goal.loop', 'seat-turn-cap-exhausted', {
1203
+ sessionId: ctx.sessionId, ...runAttribution, seat: opts.seatTurnCap.seat, iterations, maxIterations, capHits: seatCapHits,
1204
+ notify: 'seat-op',
1205
+ }, { level: 'warn' });
1206
+ }
988
1207
  return finish({ finalText: lastResult.finalText, iterations, stopReason: 'max_iterations', goalComplete: false });
989
1208
  } finally {
990
1209
  stopLivenessHeartbeat();
@@ -0,0 +1,79 @@
1
+ // TUI-SEAT-TURN-CAP(0.2.31 · OP #9266) — 자리 TUI 의 goal loop 에서만 쓰는 «한 core 턴» 상한 ⊕ «할 일 0» 판정.
2
+ //
3
+ // 배경(10-16 실측): H1(#28487)로 자리 TUI 운영 지시가 goal loop 를 타면서 «1턴 정지» 는 풀렸지만, 반대로 한 core 턴이
4
+ // 도구 121개·18분+ 이어졌다(운영 `llm.maxTurns.codex = null` = 무제한). 전역 config 는 하니스 자식까지 걸리므로
5
+ // 자리 TUI 한정 손잡이를 둔다. 또 일이 떨어진 뒤 빈 MsgList 를 연달아 부르며 턴 안에서 폴링했다(«할 일 0 = 완료» 신호 부재).
6
+ //
7
+ // ⛔ 이 모듈은 import 0 — user-config 가 파서를 가져다 쓴다(순환 없음).
8
+
9
+ export interface SeatTurnCapConfig {
10
+ /** core 턴 1회당 실행할 도구 수 상한. update_goal 진행 선언(in_progress·blocked)도 한 번으로 세고, 완료 신호(complete)만 뺀다.
11
+ * 넘는 호출은 실행하지 않는다. */
12
+ maxTools: number;
13
+ /** core 턴 1회당 벽시계 상한(ms). 넘으면 다음 도구 호출부터 실행하지 않는다. */
14
+ maxWallMs: number;
15
+ /** 같은 core 턴에서 «새 항목 0» 우편 조회(MsgList)가 연속 이만큼이면 «할 일 0» 으로 완료. */
16
+ idleEmptyMsgListLimit: number;
17
+ }
18
+
19
+ export const SEAT_TURN_CAP_DEFAULTS: SeatTurnCapConfig = {
20
+ maxTools: 60,
21
+ maxWallMs: 20 * 60_000,
22
+ idleEmptyMsgListLimit: 2,
23
+ };
24
+
25
+ function positiveInt(value: unknown): number | undefined {
26
+ return typeof value === 'number' && Number.isSafeInteger(value) && value > 0 ? value : undefined;
27
+ }
28
+
29
+ /** `chat.seatTurnCap` 원문을 읽는다. 객체가 아니거나 유효한 칸이 하나도 없으면 undefined(= 기본값). */
30
+ export function parseSeatTurnCapConfig(raw: unknown): Partial<SeatTurnCapConfig> | undefined {
31
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return undefined;
32
+ const r = raw as Record<string, unknown>;
33
+ const out: Partial<SeatTurnCapConfig> = {};
34
+ const maxTools = positiveInt(r.maxTools);
35
+ const maxWallMs = positiveInt(r.maxWallMs);
36
+ const idle = positiveInt(r.idleEmptyMsgListLimit);
37
+ if (maxTools !== undefined) out.maxTools = maxTools;
38
+ if (maxWallMs !== undefined) out.maxWallMs = maxWallMs;
39
+ if (idle !== undefined) out.idleEmptyMsgListLimit = idle;
40
+ return Object.keys(out).length > 0 ? out : undefined;
41
+ }
42
+
43
+ export function resolveSeatTurnCap(override: Partial<SeatTurnCapConfig> | undefined): SeatTurnCapConfig {
44
+ return { ...SEAT_TURN_CAP_DEFAULTS, ...(override ?? {}) };
45
+ }
46
+
47
+ /** 우편 조회 도구 이름(카탈로그 aliases). */
48
+ export const MAIL_LIST_TOOL_NAMES: ReadonlySet<string> = new Set(['MsgList', 'msg_list']);
49
+
50
+ /** 결과가 «새 항목 0» 인 우편 조회인가. 구조체 `count === 0` 만 본다(문자열·messages 길이 추정 없음 — 리뷰 r1). */
51
+ export function isEmptyMailListResult(name: string, result: unknown): boolean {
52
+ if (!MAIL_LIST_TOOL_NAMES.has(name)) return false;
53
+ if (!result || typeof result !== 'object') return false;
54
+ return (result as { count?: unknown }).count === 0;
55
+ }
56
+
57
+ /** 셸 도구 이름(카탈로그 aliases — RunShell·Bash 계열). */
58
+ export const SHELL_TOOL_NAMES: ReadonlySet<string> = new Set(['RunShell', 'run_shell', 'exec_argv', 'Bash', 'shell']);
59
+
60
+ /** 대기용 셸 호출(`sleep N`)인가 — 폴링 사이의 기다림은 «할 일 0» 연속을 끊지 않는다. 셸 도구에만 예외(리뷰 r2). */
61
+ export function isIdleWaitCall(name: string, args: unknown): boolean {
62
+ if (!SHELL_TOOL_NAMES.has(name)) return false;
63
+ if (!args || typeof args !== 'object') return false;
64
+ const command = (args as { command?: unknown }).command;
65
+ return typeof command === 'string' && /^\s*sleep\s+\d+(?:\.\d+)?[smh]?\s*;?\s*$/.test(command);
66
+ }
67
+
68
+ export const SEAT_TURN_CAP_TOOL_NOTICE = (reason: 'tools' | 'wall', cap: SeatTurnCapConfig): string =>
69
+ `SEAT TURN CAP — this core turn reached its ${reason === 'tools' ? `tool limit (${cap.maxTools} tools)` : `wall-clock limit (${Math.round(cap.maxWallMs / 60_000)} min)`}; this call was NOT run. `
70
+ + 'Do not call more tools in this turn. Write a one-line progress summary now (what is done · what remains) and end the turn; '
71
+ + 'the goal loop starts the next iteration and you continue the remaining work there.';
72
+
73
+ export const SEAT_IDLE_NO_WORK_NOTICE = (limit: number): string =>
74
+ `NO NEW WORK — ${limit} consecutive mailbox checks returned 0 new messages. Do not poll again in this turn. `
75
+ + 'Write a one-line status and end the turn; this goal is complete (waiting for new mail is handled outside the turn).';
76
+
77
+ export const SEAT_TURN_CAP_CONTINUE_PROMPT =
78
+ '앞 core 턴이 자리 턴 상한(도구 수 또는 벽시계)에 닿아 마감됐다. 위의 진행 요약을 이어받아 남은 일을 계속하라. '
79
+ + '다 끝났으면 update_goal(status:"complete", evidence) 로 마감하라.';
@@ -41,6 +41,10 @@ const WRITE_INTENT = /(?:(?:추가|작성|기록|반영|갱신|업데이트|개
41
41
  const DEBUG_INTENT = /(?:디버그|디버깅|에러|오류|크래시|깨져|깨짐|안\s*(?:돼|됨|되네|된다)|\b(?:debug|error|crash|broken|fails?|failing)\b)/i;
42
42
  const EXPLICIT_GOAL = /(?:^\/goal\b|목표\s*[::]|\bgoal\s*:)/i;
43
43
  const REPO_NOUN = /(?:코드|스크립트|소스|브랜치|서버|파일|레포|저장소|\bPR\b|\b(?:code|script|branch|server|file|repo)\b)/i;
44
+ // A named CLI command («(eln msg list --to OPT)» · «`git log`») or the seat mailbox is work the research
45
+ // allowlist cannot do (no RunShell · no MsgList) — it is a full-tool read, not the «조사» quick route
46
+ // (TUI-QUICK-ROUTE-EXPLICIT-CMD · 10-16 OPT: «우편 확인(eln msg list …) … 조사» answered «셸 도구가 없다»).
47
+ const EXPLICIT_COMMAND = /(?:(?<![\w-])(?:eln|elanous|git|gh)\s+[a-z][\w-]*|우편)/i;
44
48
 
45
49
  function writeDebugOrGoal(q: string): 'write-intent' | 'debug' | 'explicit-goal' | null {
46
50
  if (WRITE_INTENT.test(q)) return 'write-intent';
@@ -55,8 +59,23 @@ export interface TuiChatVerdict {
55
59
  goalLoop: boolean;
56
60
  }
57
61
 
58
- /** Request verbs a quick or read-only turn can carry out without writing to the repository. */
59
- const QUICK_REQUEST_VERBS = /^(?:보여|알려|확인해|찾아|찾아봐|조사해|검색해|정리해|요약해|바꿔|변경해|전환해|설정해|맞춰|수정해|고쳐|만들어|등록해|예약해|추가해|보내|설명해|읽어|읽어봐|살펴|살펴봐|훑어봐|비교해|분석해|검토해|평가해|제안해)$/;
62
+ /** 자리(무인) TUI 인가 — 호출부가 `detectSeatTui` 로 정한다. 없으면 사람 대화 TUI(종전 판정 그대로). */
63
+ export interface TuiChatContext extends ShortQuestionContext {
64
+ seat?: boolean;
65
+ }
66
+
67
+ // TUI-H1-SEAT-GOALLOOP — 자리 앞으로 온 «운영 지시» 꼴: 우편·오더 · 이름 있는 CLI 명령 · «OP 13:14:» 머리 · «계속 —» · «다음 행».
68
+ // (10-16 OPT 13:14 «OP 13:14: 계속 — draft 다음 행.» 이 읽기·분석 단일 턴으로 가 «다음 점검 13:20» 만 남기고 멈췄다.)
69
+ const SEAT_OPS_DIRECTIVE = /(?:우편|오더|(?<![\w-])(?:eln|elanous|git|gh)\s+[a-z][\w-]*|^\[?OP\s*\d{1,2}:\d{2}|(?:^|[\s::])계속(?:\s*[—–-]|\s*(?:해|하|진행)|[.!]?\s*$)|다음\s*행(?![가-힣]))/i;
70
+
71
+ /** 자리 운영 지시 꼴인가(인지 · 관측용으로도 내보낸다). */
72
+ export function isSeatOpsDirective(text: string): boolean {
73
+ return SEAT_OPS_DIRECTIVE.test(text.trim());
74
+ }
75
+
76
+ /** Request verbs a quick or read-only turn can carry out without writing to the repository.
77
+ * «봐줘·봐 줘·들여다봐줘» are reads (TUI-INITIATIVE-S ④ — «로그 좀 봐줘» used to fall to coding as request-verb). */
78
+ const QUICK_REQUEST_VERBS = /^(?:보여|알려|확인해|찾아|찾아봐|조사해|검색해|정리해|요약해|바꿔|변경해|전환해|설정해|맞춰|수정해|고쳐|만들어|등록해|예약해|추가해|보내|설명해|읽어|읽어봐|봐|봐봐|들여다봐|살펴|살펴봐|훑어봐|비교해|분석해|검토해|평가해|제안해)$/;
60
79
 
61
80
  /** True when the verb never appears, or each occurrence directly follows an allowed object. */
62
81
  function everyVerbTakes(text: string, verb: RegExp, object: RegExp): boolean {
@@ -66,8 +85,21 @@ function everyVerbTakes(text: string, verb: RegExp, object: RegExp): boolean {
66
85
  return true;
67
86
  }
68
87
 
69
- /** Write, debug, goal, mixed or attached requests retain the coding goal loop; a plain read question is one full-tool turn. */
70
- export function classifyTuiChatIntent(text: string, ctx: ShortQuestionContext = {}): TuiChatVerdict {
88
+ /** Write, debug, goal, mixed or attached requests retain the coding goal loop; a plain read question is one full-tool turn.
89
+ * A seat (unattended) TUI reverts #27531 for its work: a read/analysis turn (except a fast short question) and any
90
+ * operational directive (mail · order · named CLI command · «계속 —») ride the goal loop to completion evidence. */
91
+ export function classifyTuiChatIntent(text: string, ctx: TuiChatContext = {}): TuiChatVerdict {
92
+ const verdict = classifyTuiChatIntentBase(text, ctx);
93
+ // A fast short question («다음 행이 뭐야?») stays one turn even in a seat — only work rides the goal loop.
94
+ if (!ctx.seat || verdict.goalLoop || verdict.reason.startsWith('short-')) return verdict;
95
+ if (verdict.route === '읽기·분석') {
96
+ return { route: verdict.route, reason: `seat-${verdict.reason}`, goalLoop: true };
97
+ }
98
+ if (isSeatOpsDirective(text)) return { route: verdict.route, reason: `seat-ops-${verdict.reason}`, goalLoop: true };
99
+ return verdict;
100
+ }
101
+
102
+ function classifyTuiChatIntentBase(text: string, ctx: ShortQuestionContext): TuiChatVerdict {
71
103
  const q = text.trim();
72
104
  const coding = (reason: string): TuiChatVerdict => ({ route: '코딩·구현', reason, goalLoop: true });
73
105
  if (!q || ctx.hasAttachments) return coding(ctx.hasAttachments ? 'attachment' : 'empty');
@@ -86,8 +118,8 @@ export function classifyTuiChatIntent(text: string, ctx: ShortQuestionContext =
86
118
  // Debugging or a stated goal keeps the goal loop even on a quick-route word («오류 로그 요약» · «목표: 상태 요약»).
87
119
  if (DEBUG_INTENT.test(q)) return coding('debug');
88
120
  if (EXPLICIT_GOAL.test(q)) return coding('explicit-goal');
89
- // A repository noun, file path or code shape is no quick route; with no write, debug or goal intent it is a read.
90
- if (REPO_NOUN.test(q) || PATH_OR_CODE.test(q)) {
121
+ // A repository noun, file path, code shape or named command is no quick route; with no write, debug or goal intent it is a read.
122
+ if (REPO_NOUN.test(q) || PATH_OR_CODE.test(q) || EXPLICIT_COMMAND.test(q)) {
91
123
  const intent = writeDebugOrGoal(q);
92
124
  return intent ? coding(intent) : { route: '읽기·분석', reason: 'read-repo', goalLoop: false };
93
125
  }
@@ -155,6 +155,9 @@ export interface CoreTurnContext {
155
155
  * named tools (e.g. the PtyShell family driving a headless coding
156
156
  * agent) are actually being dispatched. Absent ⇒ no extension. */
157
157
  budgetGrant?: LLMOpts['budgetGrant'];
158
+ /** TUI-GOAL-LOOP-FRICTION — 종결 신호 도구 이름. `streamLLMWithTools` 의 `terminalToolNames` 로 그대로 간다
159
+ * (예산 거부 면제 · 신호뿐인 턴 ⊕ 답 = 마감). goal loop 가 `update_goal` 을 넣는다. */
160
+ terminalToolNames?: LLMOpts['terminalToolNames'];
158
161
  /** Optional model override (forwarded to `streamLLMWithTools`). */
159
162
  modelOverride?: string;
160
163
  }
@@ -36,6 +36,7 @@ import {
36
36
  import type { AcpTransportConnection } from '../acp/transport/index.js';
37
37
  import { debug } from '../debug/log.js';
38
38
  import { recordDashboardToolCatalog } from './tool-catalog-observability.js';
39
+ import { detectSeatTui } from './seat-boot-preamble.js';
39
40
 
40
41
  type DashboardAcpBootBranch = 'remote-daemon' | 'in-process';
41
42
 
@@ -232,6 +233,8 @@ export async function bootDashboardAcpSession(
232
233
  const model = deps.getActiveModel({ userText });
233
234
  return model ?? undefined;
234
235
  },
236
+ // TUI-H1-SEAT-GOALLOOP — 자리(무인) TUI 면 운영 지시를 goal loop 로(사람 대화 TUI 는 종전 그대로).
237
+ resolveSeat: () => detectSeatTui(deps.getCwd())?.seat ?? null,
235
238
  ...(deps.agentName !== undefined ? { agentName: deps.agentName } : {}),
236
239
  ...(deps.agentVersion !== undefined ? { agentVersion: deps.agentVersion } : {}),
237
240
  ...(gateway