elanous 0.2.28 → 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 (818) 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/{y1ltt7oCZxVpC6zVPhZ2O → LSXfY0u9QtfDbejY0Ukf_}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{ab4d57c2.e90bc2cb31949045.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/{5492-e05e26a033ba80d2.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/1654.32de4b324981a188.js +23 -0
  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/1913.7cc6fb6055b1ed3f.js +41 -0
  18. package/apps/pwa/out/_next/static/chunks/2001.6c7e0fd02190886c.js +1 -0
  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/{8578.dff22d988cc2b106.js → 2213.2ccbada92c33ea0f.js} +3 -3
  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/{5081.a240b63fad28663a.js → 2871.0bca6137343b3f76.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2940-619bfd8ef337c611.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/{2846.d6a433b8663819a5.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/{f4dfbfc0.a69fb12f854882aa.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/3541-ce3a5424ed5ad7f1.js +1 -0
  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/{3143.257997a5f1ed79df.js → 3902.e1e71aaac850a045.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{16e57f67.3ea19e893461e611.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/{1146.80d15ea7c6e6ee95.js → 4111.2bfedbb233ad206b.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/{1516.83dd2c1b86b4e507.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/{9938.b23e4d4dfa0114cd.js → 4999.c064a4000c2a9e94.js} +2 -2
  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/{1157.f08bf2b70915e176.js → 5304.04d24756f242a094.js} +2 -2
  57. package/apps/pwa/out/_next/static/chunks/{7752.5cbdd0b433c54af9.js → 5307.60f2209e809bd627.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{9917-9e26abc5f7772735.js → 5458-16cd7a2b51b74c8c.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/{6196.34d6b229079e9e28.js → 5525.86debf231e181813.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{4593.10f5b9bd702d4a6c.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/{7483.ba01c6c209b81bba.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/{9974.e77b4ff4884557b3.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/{3309.364573ceedbdfd5f.js → 6323.8672b4817a306928.js} +1 -1
  74. package/apps/pwa/out/_next/static/chunks/{94.4cfed21c0b781a06.js → 6433.fc573af22bbc9ab7.js} +4 -4
  75. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/{949.1e7d45ccb71580aa.js → 6517.4147878ac06d584d.js} +2 -2
  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/{2528.3868070ef1be69f9.js → 6767.ea607cf0c20a25af.js} +2 -2
  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/{1743.563d3168e95825ef.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/{5408.377c8c543635b81f.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/{65ebff95.081daeff622d238e.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/{2697.76ca2ac3efef6f3b.js → 8018.a32663f04a6fc5f9.js} +1 -1
  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/9138.b6e80031afb1d973.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/{4204.a409ab6250c0f6a8.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/{5785-ea8d2c633b6688e3.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/9398-6aed28f0a96d0d6f.js +1 -0
  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/997ce8a5-2ad501927003b41b.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{9311.24c8f5ea793253dd.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-fa46d4588e8442c2.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-ced0bcfc6542b3fc.js → page-349f2752d8cd37ad.js} +1 -1
  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-cb249e81ed339318.js → page-0a07363b130182a1.js} +1 -1
  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-521ee23ac8c0abfa.js +1 -0
  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-149dc1caba411bb9.js +1 -0
  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/{6def8a8e.c81f9ca41028eccf.js → b313b242.cb1265eea908db61.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{e87d89b9.2e71c0ae475d28a1.js → e5012ffe.f727e23c231f4342.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/{e117f801.e92bf10242653497.js → ebc7d829.264a0bcb6c750b50.js} +1 -1
  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 +15 -7
  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/plugins/agent-team/agents/research.md +1 -0
  289. package/scripts/check-native-tool-wiring.ts +3 -2
  290. package/scripts/ci-android-unit-tests.ts +16 -0
  291. package/scripts/ci-typecheck-changed.ts +40 -11
  292. package/scripts/coord-channel-watch.sh +45 -19
  293. package/scripts/coord-role-pack.ts +222 -0
  294. package/scripts/cron-run.ts +96 -3
  295. package/scripts/detect-test-interference.ts +38 -5
  296. package/scripts/gate-pr-cache.ts +65 -0
  297. package/scripts/gh-surface/capture.ts +126 -0
  298. package/scripts/gh-surface/gh +40 -0
  299. package/scripts/import-graph-scc.ts +38 -0
  300. package/scripts/install.ps1 +19 -0
  301. package/scripts/intake-social.ts +181 -0
  302. package/scripts/lecture-note/node.ts +71 -4
  303. package/scripts/lib/android-toolchain.ts +32 -0
  304. package/scripts/lib/deterministic-env.ts +62 -0
  305. package/scripts/lib/gate-test-env.ts +19 -0
  306. package/scripts/lib/morning-report-options.ts +41 -0
  307. package/scripts/measure-goal-grounding-corpus.ts +2 -1
  308. package/scripts/pr-land-extra-remote-gates.ts +49 -0
  309. package/scripts/ratchets/test-interference-patterns.allowlist.txt +257 -0
  310. package/scripts/ratchets/test-interference-patterns.ts +367 -0
  311. package/scripts/release-loop/cut-branch.ts +4 -3
  312. package/scripts/release-loop/export-check-node.ts +0 -1
  313. package/scripts/release-loop/fixtures/warm-failure-assertion/sample.junit.xml +8 -0
  314. package/scripts/release-loop/fixtures/warm-job-029/sample.json +1 -0
  315. package/scripts/release-loop/fixtures/warm-job-029/sample.junit.xml +10 -0
  316. package/scripts/release-loop/gate-batch-safe.ts +23 -0
  317. package/scripts/release-loop/gate-closure.ts +12 -8
  318. package/scripts/release-loop/gate-diff.ts +1 -1
  319. package/scripts/release-loop/gate-history.ts +422 -0
  320. package/scripts/release-loop/gate-host-mirror.ts +66 -0
  321. package/scripts/release-loop/gate-node.ts +806 -94
  322. package/scripts/release-loop/gate-partial.ts +106 -9
  323. package/scripts/release-loop/gate-pr-cache.ts +66 -0
  324. package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
  325. package/scripts/release-loop/gate-r2-verdict.ts +189 -0
  326. package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
  327. package/scripts/release-loop/gate-triage-node.ts +190 -0
  328. package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
  329. package/scripts/release-loop/import-graph-scc-run.ts +54 -0
  330. package/scripts/release-loop/import-graph-scc.ts +215 -0
  331. package/scripts/release-loop/node-verdict.ts +2 -0
  332. package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
  333. package/scripts/release-loop/resume-release.ts +33 -4
  334. package/scripts/release-loop/resume.ts +13 -5
  335. package/scripts/release-loop/spawn-lane.ts +51 -0
  336. package/scripts/release-loop/tui-node-checks.ts +23 -0
  337. package/scripts/release-loop/tui-sim-node.ts +3 -2
  338. package/scripts/release-loop/unattended-release.ts +16 -0
  339. package/scripts/release-loop/version-node.ts +62 -4
  340. package/scripts/test-deterministic.ts +46 -73
  341. package/scripts/train-reach-grouping.ts +48 -0
  342. package/scripts/tsc-incremental-cache.ts +86 -0
  343. package/scripts/tsc-incremental-diagnostics.ts +76 -0
  344. package/scripts/tsc-main-safety-net.ts +2 -2
  345. package/scripts/usage-rollup.ts +11 -3
  346. package/src/acp/client.ts +4 -1
  347. package/src/acp/core-turn-bridge.ts +145 -24
  348. package/src/acp/elanous-extensions.ts +2 -0
  349. package/src/acp/server.ts +2 -0
  350. package/src/ad-pipeline/run.ts +4 -2
  351. package/src/agent/ref-grounding.ts +18 -0
  352. package/src/agent/runner.ts +169 -3
  353. package/src/agent/subagent-callable.ts +3 -2
  354. package/src/agent-mission/review-loop.ts +6 -3
  355. package/src/agent-substrate/acp-implementer.ts +14 -2
  356. package/src/agent-substrate/pr-reviewer.ts +41 -21
  357. package/src/agent-substrate/self-review-cli.ts +30 -4
  358. package/src/autopilot/pr-manager.ts +62 -7
  359. package/src/briefing/brief-items.ts +24 -22
  360. package/src/budget/pty-usage-reemit.ts +7 -0
  361. package/src/budget/run-usage-rollup.ts +9 -0
  362. package/src/budget/usage-daily-store.ts +98 -0
  363. package/src/capture/tui-self-report.ts +37 -4
  364. package/src/chat/chat-cli.ts +10 -2
  365. package/src/chat/index.ts +107 -20
  366. package/src/chat/input-control-key.ts +5 -3
  367. package/src/chat/pickers/modal-runtime.ts +1 -0
  368. package/src/chat/pickers/modals.ts +3 -1
  369. package/src/chat/tool-interrupt-behavior.ts +38 -0
  370. package/src/chat/tool-render/dispatch.ts +5 -1
  371. package/src/chat/turn-typeahead.ts +191 -29
  372. package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
  373. package/src/cli/agent-cli.ts +41 -13
  374. package/src/cli/config-audit.ts +123 -0
  375. package/src/cli/dashboard-name-flag.ts +48 -0
  376. package/src/cli/decisions-cli.ts +80 -6
  377. package/src/cli/doctor-cli.ts +80 -0
  378. package/src/cli/log-event-names.ts +19 -0
  379. package/src/cli/mcp-login.ts +21 -5
  380. package/src/cli/msg-cli.ts +133 -2
  381. package/src/cli/pr-cli.ts +546 -112
  382. package/src/cli/pr-land-heavy-remote.ts +233 -0
  383. package/src/cli/pr-land-overlap-evidence.ts +167 -14
  384. package/src/cli/pr-land-pod-shadow-job.ts +83 -0
  385. package/src/cli/pr-land-pod-shadow.ts +16 -3
  386. package/src/cli/pr-land-virtual-rebase.ts +108 -0
  387. package/src/cli/pty-takeover-cli.ts +125 -16
  388. package/src/cli/release-cli.ts +122 -14
  389. package/src/cli/remote-resolve.ts +2 -1
  390. package/src/cli/seat-cli.ts +164 -19
  391. package/src/cli/self-update.ts +5 -2
  392. package/src/cli/tasks-cli.ts +105 -21
  393. package/src/cli/usage-cli.ts +146 -12
  394. package/src/cli/usage-daily-cli.ts +84 -0
  395. package/src/context-bus/context-first.ts +13 -0
  396. package/src/context-bus/context-now.ts +95 -7
  397. package/src/context-bus/ops-events.ts +75 -0
  398. package/src/control-plane/lease-holder.ts +12 -8
  399. package/src/control-plane/ledger.ts +163 -4
  400. package/src/control-plane/server.ts +91 -11
  401. package/src/core-turn/auth-rejected-notice.ts +41 -0
  402. package/src/core-turn/run-core-turn.ts +14 -2
  403. package/src/core-turn/run-goal-loop.ts +239 -4
  404. package/src/core-turn/seat-turn-cap.ts +79 -0
  405. package/src/core-turn/short-question.ts +78 -13
  406. package/src/core-turn/types.ts +10 -0
  407. package/src/dashboard/acp-active-model.ts +40 -0
  408. package/src/dashboard/acp-boot.ts +3 -0
  409. package/src/dashboard/auto-compact-runtime.ts +2 -0
  410. package/src/dashboard/boot-banner.ts +80 -0
  411. package/src/dashboard/dashboard-status-lines.ts +11 -0
  412. package/src/dashboard/detail-viewer-runtime.ts +15 -2
  413. package/src/dashboard/event-loop-stall-monitor.ts +4 -0
  414. package/src/dashboard/goal-loop-thinking.ts +16 -0
  415. package/src/dashboard/hitl-boot.ts +9 -4
  416. package/src/dashboard/index.ts +448 -998
  417. package/src/dashboard/input/chat-main-entry-runtime.ts +2 -0
  418. package/src/dashboard/input/chat-main-log-actions.ts +4 -0
  419. package/src/dashboard/input/chat-main-log-command.ts +12 -1
  420. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +176 -4
  421. package/src/dashboard/input/chat-main-session.ts +14 -3
  422. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  423. package/src/dashboard/input/chat-main-turn.ts +14 -4
  424. package/src/dashboard/input/compact-prepass-recovery.ts +130 -0
  425. package/src/dashboard/input/dashboard-chord-actions.ts +10 -1
  426. package/src/dashboard/input/dashboard-chord-runtime.ts +2 -0
  427. package/src/dashboard/input/external-input-host.ts +71 -0
  428. package/src/dashboard/input/internal-turn.ts +261 -0
  429. package/src/dashboard/input/log-fold-binding.ts +18 -0
  430. package/src/dashboard/input/mouse-wiring.ts +17 -4
  431. package/src/dashboard/input/seat-autowake.ts +318 -0
  432. package/src/dashboard/input/turn-steer-bridge.ts +164 -0
  433. package/src/dashboard/log-click-runtime.ts +5 -3
  434. package/src/dashboard/loop-scheduler.ts +72 -0
  435. package/src/dashboard/running-build-status.ts +74 -0
  436. package/src/dashboard/seat-boot-preamble.ts +131 -0
  437. package/src/dashboard/seat-local-instructions.ts +305 -0
  438. package/src/dashboard/skill-runtime.ts +2 -0
  439. package/src/dashboard/slash-runtime/dashboard-handlers.ts +220 -1203
  440. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
  441. package/src/dashboard/slash-runtime/index.ts +13 -0
  442. package/src/dashboard/slash-runtime/model-choices.ts +35 -0
  443. package/src/dashboard/term-slash-runtime.ts +15 -0
  444. package/src/dashboard/turn-busy-teardown.ts +50 -0
  445. package/src/dashboard/turn-preamble.ts +30 -2
  446. package/src/dashboard/turn-session-layers.ts +176 -0
  447. package/src/dashboard/turn-stream-formatter.ts +14 -6
  448. package/src/dashboard/turn-stream-presentation-applier.ts +8 -0
  449. package/src/decisions/decision-ledger.ts +45 -4
  450. package/src/discord-self-message.ts +4 -4
  451. package/src/domains/release-tool.ts +26 -10
  452. package/src/domains/surface-events.ts +4 -1
  453. package/src/domains/watch-default-scheduler.ts +8 -9
  454. package/src/field-note/transcribe.ts +17 -0
  455. package/src/fold-stack.ts +24 -1
  456. package/src/git-fs/dirty.ts +32 -4
  457. package/src/git-fs/index.ts +43 -1
  458. package/src/github/remote-call.ts +81 -0
  459. package/src/goals/registry.ts +46 -6
  460. package/src/goals/types.ts +7 -1
  461. package/src/graph-runner/runner.ts +2 -0
  462. package/src/grok/credential.ts +26 -0
  463. package/src/harness/harness-clean.ts +2 -1
  464. package/src/harness/harness-cli-command.ts +52 -5
  465. package/src/harness/harness-gc.ts +34 -6
  466. package/src/harness/harness-incidents.ts +57 -20
  467. package/src/harness/harness-pod-dispatch.ts +87 -10
  468. package/src/harness/harness-queue.ts +53 -4
  469. package/src/harness/harness-stop.ts +4 -3
  470. package/src/harness/harness-substrate-default.ts +78 -7
  471. package/src/harness/harness-worktree-auto.ts +2 -1
  472. package/src/harness/harness-worktrees.ts +3 -2
  473. package/src/hooks/dispatch.ts +2 -1
  474. package/src/index.ts +166 -26
  475. package/src/input/external-input-queue.ts +251 -0
  476. package/src/intake-plane/slash.ts +14 -3
  477. package/src/interactive-terminal-modal.ts +13 -0
  478. package/src/keybindings.ts +4 -1
  479. package/src/llm/route-decision.ts +25 -0
  480. package/src/llm/tool-loop-steered-rejection.ts +33 -0
  481. package/src/llm-stream-retry-display.ts +59 -0
  482. package/src/llm.ts +391 -74
  483. package/src/log-entry.ts +3 -3
  484. package/src/log-pane/search.ts +29 -4
  485. package/src/loops/agent-reply.ts +256 -0
  486. package/src/loops/budget.ts +37 -7
  487. package/src/loops/consensus.ts +348 -0
  488. package/src/loops/loop-cli.ts +3 -2
  489. package/src/loops/msg-address.ts +57 -0
  490. package/src/loops/msg-wake.ts +484 -0
  491. package/src/loops/observe.ts +19 -3
  492. package/src/loops/orchestrator/inbox.ts +60 -3
  493. package/src/loops/orchestrator/tick.ts +80 -6
  494. package/src/loops/orchestrator/traffic.ts +64 -1
  495. package/src/loops/registry.ts +72 -4
  496. package/src/market/signed-index.ts +14 -0
  497. package/src/mcp/mcp-oauth.ts +54 -5
  498. package/src/memory.ts +20 -5
  499. package/src/models/prompts.ts +28 -0
  500. package/src/msg/msg-sse-client.ts +223 -0
  501. package/src/msg/msg-store.ts +86 -2
  502. package/src/mss/logging/log-store.ts +225 -1
  503. package/src/native-tool-catalog.ts +125 -0
  504. package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
  505. package/src/nexus/api/http-server.ts +59 -15
  506. package/src/nexus/api/loop-resources.ts +19 -3
  507. package/src/nexus/api/ops-api.ts +13 -0
  508. package/src/nexus/api/project-autopsy.ts +127 -0
  509. package/src/nexus/api/terminals.ts +3 -0
  510. package/src/nexus/api/workflow-approvals.ts +2 -0
  511. package/src/nexus/daemon-thin-inventory.md +37 -0
  512. package/src/nexus/index.ts +70 -0
  513. package/src/nexus/onboarding/first-boot-wizard.ts +56 -2
  514. package/src/nexus/state/state.ts +1 -0
  515. package/src/oauth/codex-account-store.ts +15 -3
  516. package/src/oauth/codex-billing-route.ts +31 -0
  517. package/src/oauth/store.ts +32 -7
  518. package/src/onboarding/first-run.ts +28 -3
  519. package/src/ops/overview-cache.ts +16 -4
  520. package/src/ops/overview-collect.ts +19 -2
  521. package/src/ops/resources.ts +82 -0
  522. package/src/panes/log-pane.ts +67 -8
  523. package/src/persona/presets.ts +44 -0
  524. package/src/plugins/maker/connector-maker.ts +41 -0
  525. package/src/plugins/maker/skill-maker.ts +42 -0
  526. package/src/plugins/maker/wizard-generate.ts +6 -4
  527. package/src/pr-tool/census.ts +288 -0
  528. package/src/preview/terminal.ts +14 -1
  529. package/src/prompt-cache/types.ts +2 -0
  530. package/src/prompt-enhance/enhance.ts +24 -8
  531. package/src/prompt-library/chat-conciseness.ts +13 -0
  532. package/src/prompt-library/universal-preamble.ts +283 -61
  533. package/src/pty-shell/pty-control-ipc.ts +4 -1
  534. package/src/pty-shell/pty-manifest.ts +77 -5
  535. package/src/pty-shell/registry.ts +19 -2
  536. package/src/pty-shell/tui-run-state.ts +253 -0
  537. package/src/release-loop/gate-host-reservation.ts +97 -0
  538. package/src/release-loop/landing-freeze.ts +5 -0
  539. package/src/release-loop/light-rc.ts +32 -4
  540. package/src/release-loop/placement.ts +92 -1
  541. package/src/release-loop/rehearsal-shard-plan.ts +149 -0
  542. package/src/release-loop/rehearsal.ts +73 -17
  543. package/src/render.ts +5 -1
  544. package/src/repl/index.ts +20 -2
  545. package/src/seat-loop/seat-knowhow.ts +282 -0
  546. package/src/seat-loop/seat-loop.ts +41 -2
  547. package/src/seat-loop/seat-report.ts +42 -2
  548. package/src/seat-loop/traffic-signal.ts +3 -0
  549. package/src/self-dev/ask-launch-flow.ts +24 -3
  550. package/src/self-dev/decompose-compose-graph.ts +28 -27
  551. package/src/self-dev/decompose-proposal.ts +53 -38
  552. package/src/self-dev/decompose.ts +17 -0
  553. package/src/self-dev/dev-pipeline.ts +31 -2
  554. package/src/self-dev/draft-residue.ts +24 -9
  555. package/src/self-dev/draft-sweep.ts +59 -4
  556. package/src/self-dev/external-call-zero.ts +77 -0
  557. package/src/self-dev/launch-preflight-text.ts +6 -0
  558. package/src/self-dev/launch-preflight.ts +25 -3
  559. package/src/self-dev/local-supervisor-judge.ts +185 -0
  560. package/src/self-dev/run-supervisor.ts +300 -24
  561. package/src/self-dev/run-types.ts +20 -0
  562. package/src/self-dev/shard-aggregate.ts +15 -2
  563. package/src/self-dev/shard-plan.ts +47 -0
  564. package/src/self-dev/shard-run.ts +135 -12
  565. package/src/self-dev/spawn-lane-files.ts +19 -0
  566. package/src/self-health/signatures.ts +132 -0
  567. package/src/self-implement/app-api-budget.ts +51 -11
  568. package/src/self-implement/config-gate.ts +2 -1
  569. package/src/self-implement/doctor-visit.ts +118 -0
  570. package/src/self-implement/expose-gate.ts +2 -1
  571. package/src/self-implement/gate-artifacts.ts +405 -0
  572. package/src/self-implement/gate-cli.ts +212 -18
  573. package/src/self-implement/gate-remote.ts +110 -25
  574. package/src/self-implement/gate-scenario.ts +85 -0
  575. package/src/self-implement/goal-author-decompose.ts +80 -16
  576. package/src/self-implement/goal-author.ts +270 -76
  577. package/src/self-implement/goal-authoring-grounding.ts +1 -1
  578. package/src/self-implement/goal-file-name.ts +65 -0
  579. package/src/self-implement/graph-authority.ts +38 -6
  580. package/src/self-implement/graph-overlay-condition.ts +92 -1
  581. package/src/self-implement/ground-goal.ts +2 -1
  582. package/src/self-implement/heal-triage.ts +79 -0
  583. package/src/self-implement/host-regate.ts +74 -2
  584. package/src/self-implement/orchestrator.ts +14 -123
  585. package/src/self-implement/pr-title.ts +123 -0
  586. package/src/self-implement/review-mustfix-class.ts +115 -0
  587. package/src/self-implement/run-checkpoint.ts +235 -0
  588. package/src/self-implement/run-ledger.ts +266 -17
  589. package/src/self-implement/run-stop.ts +4 -3
  590. package/src/self-implement/run-ttl.ts +28 -4
  591. package/src/self-implement/running-runs.ts +10 -6
  592. package/src/self-implement/seams.ts +2 -0
  593. package/src/self-implement/self-implement-runtime.ts +32 -0
  594. package/src/self-implement/shadow-stage.ts +7 -6
  595. package/src/self-implement/stop-autoheal.ts +2 -1
  596. package/src/self-implement/train-gate-remote.ts +37 -8
  597. package/src/self-implement/train-reach-grouping.ts +157 -0
  598. package/src/self-implement/train-scenario-layers.ts +133 -0
  599. package/src/self-implement/uncommitted-work.ts +2 -0
  600. package/src/session/pending-input.ts +81 -11
  601. package/src/session/session-start.ts +224 -0
  602. package/src/session-runtime/index.ts +7 -1
  603. package/src/session-runtime/parallel-dispatch.ts +22 -5
  604. package/src/skills/tools/dev-harness.ts +6 -4
  605. package/src/skills/tools/ops-ledger.ts +707 -0
  606. package/src/skills/tools/persistent-grounding.ts +47 -7
  607. package/src/skills/tools/shell.ts +117 -1
  608. package/src/status/bar.ts +32 -2
  609. package/src/status/status-provider-info.ts +58 -0
  610. package/src/steward/resync-tick.ts +114 -23
  611. package/src/steward/ta-repair-event-collect.ts +158 -0
  612. package/src/task-agent/card-evidence.ts +25 -1
  613. package/src/task-agent/green-sweep.ts +8 -3
  614. package/src/task-agent/judge.ts +76 -0
  615. package/src/task-agent/land-queue.ts +79 -0
  616. package/src/task-agent/live-moves.ts +30 -9
  617. package/src/task-agent/postland-card.ts +5 -0
  618. package/src/task-agent/prelaunch-already-done.ts +98 -0
  619. package/src/task-agent/real-launch-guard.ts +37 -0
  620. package/src/task-agent/rejudge-on-head.ts +93 -13
  621. package/src/task-agent/remote-rejudge-bind.ts +62 -13
  622. package/src/task-agent/repair-cycle.ts +58 -7
  623. package/src/task-agent/repair-worker.ts +7 -0
  624. package/src/task-agent/run-identity.ts +200 -0
  625. package/src/task-agent/shadow.ts +50 -3
  626. package/src/task-agent/task-hand.ts +158 -5
  627. package/src/task-agent/train-landing.ts +77 -0
  628. package/src/task-agent/work-order.ts +104 -0
  629. package/src/task-orchestrator/surfaces/kubectl-transient-retry.ts +51 -0
  630. package/src/task-orchestrator/surfaces/pod-command-job.ts +138 -22
  631. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
  632. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
  633. package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
  634. package/src/task-orchestrator/surfaces/pod-install-slots.ts +122 -15
  635. package/src/task-orchestrator/surfaces/pod-lease.ts +20 -6
  636. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
  637. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +103 -0
  638. package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
  639. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +63 -0
  640. package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
  641. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
  642. package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
  643. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
  644. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +208 -0
  645. package/src/task-orchestrator/surfaces/self-implement-pod.ts +237 -46
  646. package/src/telegram.ts +2 -4
  647. package/src/terminal/session-registry.ts +6 -0
  648. package/src/thinking-line.ts +12 -3
  649. package/src/tool-runtime/index.ts +4 -0
  650. package/src/tool-runtime/ops-ledger-runtimes.ts +84 -0
  651. package/src/tool-runtime/ref-consult-runtime.ts +17 -2
  652. package/src/tool-runtime/run-shell-runtime.ts +4 -1
  653. package/src/tool-runtime/self-cognition-runtimes.ts +5 -1
  654. package/src/tui/input/pickers.ts +732 -0
  655. package/src/tui/slash/mission.ts +492 -0
  656. package/src/tui/slash/term.ts +877 -0
  657. package/src/tui-client/dashboard-session.ts +9 -0
  658. package/src/tui.ts +53 -0
  659. package/src/user-config/gemini-server-tools.ts +9 -0
  660. package/src/user-config.ts +106 -21
  661. package/src/util/spawn-sync-output.ts +7 -0
  662. package/src/ux-sim/fake-bin.ts +154 -0
  663. package/src/ux-sim/fake-clock.ts +36 -0
  664. package/src/ux-sim/fake-llm.ts +29 -0
  665. package/src/ux-sim/headless-tui.ts +72 -0
  666. package/src/ux-sim/in-process-cli.ts +176 -0
  667. package/src/ux-sim/temp-git-remote.ts +82 -0
  668. package/src/version/packed-revision.json +1 -1
  669. package/src/video-pipeline/recipes/vlog.ts +25 -7
  670. package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +0 -36
  675. package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/1454-29d1d773d5996a49.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +0 -27
  682. package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +0 -32
  688. package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/3259-86f3be56e43eaf6a.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +0 -287
  693. package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/4084.15ecaf4240bd9e77.js +0 -286
  698. package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +0 -8
  703. package/apps/pwa/out/_next/static/chunks/4565-67e4c620597965c8.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +0 -104
  706. package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +0 -149
  708. package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/599-56f2c0a5cc4a7295.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +0 -23
  718. package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +0 -77
  722. package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +0 -64
  724. package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +0 -2
  726. package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +0 -62
  734. package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/8085-1e5fce59500a2cc2.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +0 -226
  742. package/apps/pwa/out/_next/static/chunks/83a80514-b897b64df43ce108.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +0 -93
  744. package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +0 -24
  745. package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +0 -115
  748. package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +0 -41
  750. package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +0 -74
  751. package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +0 -94
  752. package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/973cbf1b.3bbcf2b41548eca7.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/approvals/page-5ab1e47978577c5e.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-24453f6a302816b4.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/board/page-6c131d30bb1cf871.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/bots/page-dc0772b11861af51.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/ceo/page-66ad46ed0279feb9.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/chat/page-5159dc8752c6cd29.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/consult/page-c5a2478861c08b87.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/control/page-f722a9dec084e08b.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/decisions/page-256ffd365d32e100.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e0de78ae7b99f01c.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/editor/page-cfbdc44b708d9801.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/exec/page-4c741eb760f2f77c.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/field/page-e9ba98f5f1440a21.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/inside/page-dafc901bb1b72b5f.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/intake/page-2f6f303fa114ec24.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/layout-1634081c5272006c.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/live-run/page-bb1f05cd51c38944.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/loops/page-646b50f63b6fe732.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/market/page-db069b48a59c8c00.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-f736324afa2117c1.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/morning/page-6f131b51193a36f9.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/not-found-435f5e2faf02bc01.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/observatory/page-497e0eedf20e7890.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-a8d28fdf995e16ea.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-8966452228753c5e.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fd5d18656cb432b6.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5663779cb1a37609.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/app/page-66a67eb19ebd976b.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/app/reflection/page-3b492aa78cf3c4a6.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c71267e7681da982.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/app/sessions/page-a21d1e1797172692.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/app/settings/page-781cfc5114e097da.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-478157214db6a023.js +0 -1
  794. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +0 -1
  795. package/apps/pwa/out/_next/static/chunks/app/setup/page-86141f12cf090b7f.js +0 -1
  796. package/apps/pwa/out/_next/static/chunks/app/share/page-7256c73bb1c36751.js +0 -1
  797. package/apps/pwa/out/_next/static/chunks/app/showroom/page-5c738ca7adef3de5.js +0 -1
  798. package/apps/pwa/out/_next/static/chunks/app/tasks/page-0138c8091ec17224.js +0 -1
  799. package/apps/pwa/out/_next/static/chunks/app/term/page-cc2f24f16d85e735.js +0 -1
  800. package/apps/pwa/out/_next/static/chunks/app/today/page-979d318a534e92da.js +0 -1
  801. package/apps/pwa/out/_next/static/chunks/app/trace/page-182d394f7e6e096b.js +0 -1
  802. package/apps/pwa/out/_next/static/chunks/app/vault/page-21050928a697ed7a.js +0 -1
  803. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-44b9d807005a9030.js +0 -1
  804. package/apps/pwa/out/_next/static/chunks/app/workflows/page-601fb77340e63c9a.js +0 -1
  805. package/apps/pwa/out/_next/static/chunks/app/workspace/page-75d3fb5d47af0edf.js +0 -1
  806. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-11bf9e5725a72c22.js +0 -1
  807. package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +0 -1
  808. package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +0 -1
  809. package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +0 -1
  810. package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +0 -1
  811. package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +0 -1
  812. package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +0 -1
  813. package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +0 -1
  814. package/src/dashboard/bench-slash-runtime.ts +0 -40
  815. package/src/dashboard/input/search-modal-router.ts +0 -9
  816. package/src/dashboard/modals/pane-key-router.ts +0 -27
  817. package/src/dashboard/view-slash-runtime.ts +0 -48
  818. /package/apps/pwa/out/_next/static/{y1ltt7oCZxVpC6zVPhZ2O → LSXfY0u9QtfDbejY0Ukf_}/_ssgManifest.js +0 -0
@@ -0,0 +1,98 @@
1
+ /** TA-PRELAUNCH-ALREADY-DONE: bounded evidence against a pinned, detached main tree. */
2
+ import { spawnSync } from 'node:child_process';
3
+ import { realpathSync } from 'node:fs';
4
+ import { isAbsolute } from 'node:path';
5
+ import { inspectGoalDoneBoundary } from '../self-implement/goal-author.js';
6
+
7
+ export interface AlreadyDoneCandidate { mainSha: string; repository: string; command: string; exitCode: 0 }
8
+ export interface AlreadyDoneDecision { candidate?: AlreadyDoneCandidate; reason: string }
9
+
10
+ type SafeCommand = { argv: string[]; path: string };
11
+ const SHA = /^[0-9a-f]{40}$/i;
12
+ const SAFE_PATH = /^[A-Za-z0-9_./-]+$/;
13
+
14
+ /** A lexical command declaration is not authority to run shell or project scripts. */
15
+ export function parseAlreadyDoneCommand(command: string): SafeCommand | null {
16
+ let input = command.trim();
17
+ while (input.length >= 2 && ((input.startsWith('`') && input.endsWith('`'))
18
+ || (input.startsWith('"') && input.endsWith('"')) || (input.startsWith("'") && input.endsWith("'"))))
19
+ input = input.slice(1, -1).trim();
20
+ if (!input || /[\n\r\t`$;&|<>\\'"*?()[\]{}!]/.test(input)) return null;
21
+ const argv = input.split(/ +/);
22
+ let path: string | undefined;
23
+ if (argv.length === 3 && argv[0] === 'test' && ['-f', '-e'].includes(argv[1]!)) path = argv[2];
24
+ else if (argv.length === 5 && argv[0] === 'git' && argv[1] === 'ls-files' && argv[2] === '--error-unmatch' && argv[3] === '--') path = argv[4];
25
+ else if (argv.length === 7 && argv[0] === 'git' && argv[1] === 'diff' && argv[2] === '--quiet'
26
+ && SHA.test(argv[3]!) && argv[4] === 'HEAD' && argv[5] === '--') path = argv[6];
27
+ if (!path || !SAFE_PATH.test(path) || isAbsolute(path) || path.startsWith('-')
28
+ || path.split('/').some((part) => part === '..' || part === '.' || !part)) return null;
29
+ return { argv, path };
30
+ }
31
+
32
+ export type PinnedGitResult = { status: number | null; stdout: string; error: boolean };
33
+ export type PrelaunchGitRunnerForTest = (cwd: string, argv: string[], timeout?: number) => PinnedGitResult;
34
+
35
+ export function runPinnedGit(cwd: string, argv: string[], timeout = 4_000, input?: string): PinnedGitResult {
36
+ // Trust boundary: the operator's own repository and Git config. Drop inherited GIT_* overrides,
37
+ // disable replace refs, hooks, and credential helpers; remote transport uses the operator's SSH config.
38
+ const env = { ...process.env };
39
+ for (const key of Object.keys(env)) if (key.startsWith('GIT_')) delete env[key];
40
+ const result = spawnSync('git', ['--no-replace-objects', '-c', 'core.hooksPath=/dev/null', '-c', 'credential.helper=', ...argv],
41
+ { cwd, env, encoding: 'utf8', timeout, maxBuffer: 64 * 1024, ...(input !== undefined ? { input } : {}) });
42
+ return { status: result.status, stdout: result.stdout ?? '', error: !!result.error };
43
+ }
44
+
45
+ function evaluatePinnedTree(root: string, sha: string, safe: SafeCommand, runGit: PrelaunchGitRunnerForTest): AlreadyDoneDecision {
46
+ const { argv, path } = safe;
47
+ // Every supported command names one tracked regular file in the pinned tree.
48
+ // A symlink's filesystem -e/-f meaning is not inferable from its Git object.
49
+ const entry = runGit(root, ['ls-tree', sha, '--', path]);
50
+ if (entry.status !== 0 || entry.error) return { reason: 'evidence-unmeasured' };
51
+ const match = /^(100644|100755|040000|120000) (blob|tree) [0-9a-f]{40}\t(.+)$/m.exec(entry.stdout);
52
+ if (!match || match[3] !== path) return { reason: 'evidence-not-passing' };
53
+ if (match[1] === '120000') return { reason: 'evidence-symlink-unmeasured' };
54
+ if (!['100644', '100755'].includes(match[1]!) || match[2] !== 'blob') return { reason: 'evidence-path-not-tracked-file' };
55
+ if (argv[0] === 'git' && argv[1] === 'diff') {
56
+ const base = argv[3]!;
57
+ if (base.toLowerCase() === sha.toLowerCase()) return { reason: 'diff-compares-main-to-itself' };
58
+ const ancestor = runGit(root, ['merge-base', '--is-ancestor', base, sha]);
59
+ if (ancestor.status !== 0) return { reason: 'diff-base-unverified' };
60
+ const diff = runGit(root, ['diff', '--no-ext-diff', '--no-textconv', '--quiet', base, sha, '--', path]);
61
+ return { reason: diff.status === 0 ? 'evidence-passed-on-main' : diff.status === 1 && !diff.error ? 'evidence-not-passing' : 'evidence-unmeasured' };
62
+ }
63
+ return { reason: 'evidence-passed-on-main' };
64
+ }
65
+
66
+ /** Only an explicit project repository qualifies. Unknown target means preserve the live launch. */
67
+ export function inspectPrelaunchAlreadyDone(text: string, projectTarget?: string,
68
+ deps: { runGit?: PrelaunchGitRunnerForTest; realpath?: (path: string) => string } = {}): AlreadyDoneDecision {
69
+ const boundary = inspectGoalDoneBoundary(text);
70
+ if (boundary.missing.length) return { reason: `boundary-missing:${boundary.missing.join(',')}` };
71
+ const command = boundary.values['완료 경계 증거 명령'] ?? '';
72
+ const safe = parseAlreadyDoneCommand(command);
73
+ if (!safe) return { reason: 'evidence-command-unsupported' };
74
+ const codeBoundary = boundary.values['완료 경계 코드'] ?? '';
75
+ const realBoundary = boundary.values['완료 경계 실물'] ?? '';
76
+ if (codeBoundary !== `기존 추적 파일 ${safe.path}` || realBoundary !== '원격 main의 일반 파일로 존재')
77
+ return { reason: 'evidence-boundary-not-file-existence' };
78
+ if (!projectTarget) return { reason: 'project-target-unverified' };
79
+ let root: string;
80
+ try { root = (deps.realpath ?? realpathSync)(projectTarget); } catch { return { reason: 'project-target-unreadable' }; }
81
+ const runGit = deps.runGit ?? runPinnedGit;
82
+ const top = runGit(root, ['rev-parse', '--show-toplevel']);
83
+ if (top.status !== 0 || top.stdout.trim() !== root) return { reason: 'project-root-unverified' };
84
+ const origin = runGit(root, ['remote', 'get-url', 'origin']);
85
+ const originUrl = origin.stdout.trim();
86
+ // Keep credentials and arbitrary transports out of both the verifier and its card evidence.
87
+ const repository = /^(?:https:\/\/github\.com\/|git@github\.com:)([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+?)(?:\.git)?$/.exec(originUrl)?.[1];
88
+ if (origin.status !== 0 || !repository) return { reason: 'origin-unverified' };
89
+ const local = runGit(root, ['rev-parse', 'refs/remotes/origin/main']).stdout.trim();
90
+ const remote = runGit(root, ['ls-remote', 'origin', 'refs/heads/main'], 7_000);
91
+ const sha = remote.stdout.trim().split(/\s+/)[0] ?? '';
92
+ if (remote.status !== 0 || !SHA.test(sha) || local !== sha) return { reason: 'main-unverified-or-stale' };
93
+ const evaluated = evaluatePinnedTree(root, sha, safe, runGit);
94
+ if (evaluated.reason !== 'evidence-passed-on-main') return evaluated;
95
+ const remoteAgain = runGit(root, ['ls-remote', 'origin', 'refs/heads/main'], 7_000);
96
+ if (remoteAgain.status !== 0 || remoteAgain.stdout.trim().split(/\s+/)[0] !== sha) return { reason: 'main-moved' };
97
+ return { candidate: { mainSha: sha, repository, command, exitCode: 0 }, reason: 'evidence-passed-on-main' };
98
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * ⛔ 시험 안의 «실물 발사» 거부 — 2026-10-16 사고(R7 · OP #8751) 의 구조 방어.
3
+ *
4
+ * 무엇이 있었나: 호스트 재게이트가 시험을 운영 HOME 그대로 돌렸고, seam 이 빠진 시험 둘이 `defaultTaskLauncher` 의
5
+ * 원격 부모 경로(`tryRemoteParent`)로 진짜 ssh 를 쏴 원격 prod 런 25 · draft PR 11 을 만들었다.
6
+ * 격리 env(재게이트 러너)와 시험 seam 은 «잊음»을 줄일 뿐 «다음 시험이 seam 을 빠뜨리는 것»은 못 막는다 — 그래서
7
+ * 발사 지점이 bun test 안에서는 명시 허용 없이 실물 발사를 «거부»한다(fail-closed · 큰소리).
8
+ *
9
+ * - 시험 밖(제품 경로): 아무 영향 없다 — `isUnderTestRunner()` 가 거짓이면 즉시 돌아간다.
10
+ * - 시험 안: 주입(가짜 ssh·spawn)을 쓰면 이 가드에 닿지 않는다. 실물이 정말 필요한 시험만
11
+ * `ELANOUS_TEST_ALLOW_REAL_LAUNCH=1` 로 명시 허용한다.
12
+ */
13
+ import { debug } from '../debug/log.js';
14
+ import { isUnderTestRunner } from '../oauth/store.js';
15
+
16
+ export const ALLOW_REAL_LAUNCH_UNDER_TEST_ENV = 'ELANOUS_TEST_ALLOW_REAL_LAUNCH';
17
+
18
+ export type RealLaunchKind = 'remote-parent-ssh' | 'local-harness-spawn';
19
+
20
+ export class RealLaunchRefusedUnderTestError extends Error {
21
+ constructor(readonly kind: RealLaunchKind, detail: string) {
22
+ super(`⛔ 시험 안에서 실물 발사를 거부했다(${kind}${detail ? ` · ${detail}` : ''}) — `
23
+ + (kind === 'remote-parent-ssh'
24
+ ? 'deps.parentHost: null(원격 끔) 또는 deps.ssh 가짜를 주입하라'
25
+ : 'deps.spawn 가짜(또는 handToTaskAgent:\'off\' · taskLauncher 가짜)를 주입하라')
26
+ + ` · 실물이 정말 필요하면 ${ALLOW_REAL_LAUNCH_UNDER_TEST_ENV}=1 (2026-10-16 시험 누수 사고 R7)`);
27
+ this.name = 'RealLaunchRefusedUnderTestError';
28
+ }
29
+ }
30
+
31
+ /** bun test 안이고 명시 허용이 없으면 던진다. 시험 밖에서는 아무것도 하지 않는다. */
32
+ export function refuseRealLaunchUnderTest(kind: RealLaunchKind, detail = '', env: NodeJS.ProcessEnv = process.env): void {
33
+ if (!isUnderTestRunner(env)) return;
34
+ if (env[ALLOW_REAL_LAUNCH_UNDER_TEST_ENV]?.trim() === '1') return;
35
+ try { debug.log('task-agent', 'real-launch-refused-under-test', { kind, detail }); } catch { /* fail-soft */ }
36
+ throw new RealLaunchRefusedUnderTestError(kind, detail);
37
+ }
@@ -35,6 +35,7 @@ import { tmpdir } from 'node:os';
35
35
  import { dirname, join } from 'node:path';
36
36
  import { debug } from '../debug/log.js';
37
37
  import { prodInstanceRoot } from '../instance/resolve.js';
38
+ import { getUserConfig } from '../user-config.js';
38
39
  import { loadRunLedger, type RunLedgerEntry } from '../self-implement/run-ledger.js';
39
40
  import type { DetachedSpawn } from '../cli/tasks-cli.js';
40
41
  import { remoteLedgerMirrorDir } from './parent-host.js';
@@ -46,6 +47,9 @@ import type { RepairCasOutcome, RepairCasRequest } from './repair-branch-cas.js'
46
47
  import { defaultLandPrHead, defaultPrHead, defaultReviewRepoCandidates, executeLiveLand, executeLiveReview, landRetryPending, type LiveMoveDeps, type LiveMoveResult, type PrHeadView, type ReviewRepoCandidate, type TaskAgentLiveMove } from './live-moves.js';
47
48
  import { capturedLandReview, captureReviewResults, parseReviewResultOutput, pendingReviewResults, reviewResultPath, type ParsedReviewResult } from './review-result-capture.js';
48
49
  import { boundPrTerminal, cardPrNumber, LIVE_MOVE_RESULT_EVENT, readTaskCard, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
50
+ import { verifiedTrainLanding, type TrainLanding } from './train-landing.js';
51
+ import { isGoalOnlyPr } from './judge.js';
52
+ import { defaultPrFiles } from './shadow.js';
49
53
 
50
54
  export const REJUDGE_ON_HEAD_EVENT = 'rejudge-on-head';
51
55
  /** 카드·PR 당 재게이트하는 머리 수 상한(머리가 바뀔 때마다 하나) — 넘으면 멈추고 사람에게 넘긴다. */
@@ -60,6 +64,7 @@ export type CatchUpDecision = 'pushed' | 'conflict' | 'cap-reached' | 'failed';
60
64
  export interface RejudgeOutcome {
61
65
  card: string; pr: number | null; fromHead: string | null; toHead: string | null; step: RejudgeStep; decision: string; reason: string;
62
66
  fromBase?: string; toBase?: string; newHead?: string;
67
+ repairRunId?: string; repairHead?: string;
63
68
  }
64
69
 
65
70
  export interface RegateRequest { card: string; pr: number; head: string; repoRoot: string; resultPath: string }
@@ -77,6 +82,8 @@ export type CatchUpGit = (cwd: string, args: string[]) => { status: number | nul
77
82
  export interface RejudgeDeps {
78
83
  live?: LiveMoveDeps;
79
84
  liveMoves: ReadonlySet<TaskAgentLiveMove>;
85
+ /** Complete PR target paths; undefined means the PR diff could not be measured. */
86
+ prFiles?: (pr: number, prUrl: string) => Promise<readonly string[] | undefined>;
80
87
  /** Only phase ① shadow callbacks may inspect a previously judged head without a regate. */
81
88
  shadowSameHead?: boolean;
82
89
  /** HQ mirror proof that the bound remote child has stopped. Test seam; absence fails closed. */
@@ -89,11 +96,15 @@ export interface RejudgeDeps {
89
96
  requestRepair?: (request: RepairLaunchRequest) => Promise<void>;
90
97
  applyRepair?: (request: RepairCasRequest) => RepairCasOutcome;
91
98
  notifyRepair?: (seat: string, body: string) => void;
99
+ /** Shared new-launch budget for this `tasks rejudge --all` call. */
100
+ repairBudget?: import('./repair-cycle.js').RepairTickBudget;
92
101
  /** TA-REJUDGE-REBASE-LOOP — origin/main 을 PR 가지에 3-way merge 하고 일반 push. 시험은 주입한다. */
93
102
  catchUpMain?: (request: CatchUpRequest) => Promise<CatchUpResult>;
94
103
  log?: (category: string, event: string, data: Record<string, unknown>) => void;
95
104
  /** 시험 seam — 결과 파일 읽기(없으면 ENOENT). */
96
105
  readFile?: (path: string) => string;
106
+ /** Verify a CLOSED component PR against the HQ train ledger and merged integration PR. */
107
+ trainLanding?: (pr: number, cwd: string) => TrainLanding | null;
97
108
  }
98
109
 
99
110
  /** PR binding alone does not mean a remote parent has stopped. Require its child edge and terminal ledger row. */
@@ -281,6 +292,15 @@ export function parseRegateResult(text: string, pr: number, head: string): Regat
281
292
  const sameUrl = (a: string, b: string) => a.trim().replace(/\/+$/, '').toLowerCase() === b.trim().replace(/\/+$/, '').toLowerCase();
282
293
  const sameHead = (a: string, b: string) => a.toLowerCase() === b.toLowerCase();
283
294
 
295
+ /**
296
+ * TA-REGATE-UNMEASURED — «못 잰» 재게이트(draft `pr-head` 거부·띄우기 실패 등 status=unmeasured)는 코드 판정이 아니다.
297
+ * 재게이트 상한(REJUDGE_HEAD_CAP)에 세지 않는다. 옛 결과 파일은 noMerge 에 status 가 없어서 draft 거부 문면으로도 가린다.
298
+ */
299
+ export function regateUnmeasured(entry: { passed?: boolean; status?: string; detail?: string }): boolean {
300
+ return entry.passed === false && (entry.status === 'unmeasured' || /^pr-head:.*\bisDraft=true\b/.test(entry.detail ?? ''));
301
+ }
302
+ const cappedRegates = <T extends { passed?: boolean; status?: string; detail?: string }>(entries: readonly T[]): T[] => entries.filter((entry) => !regateUnmeasured(entry));
303
+
284
304
  const defaultCatchUpGit: CatchUpGit = (cwd, args) => {
285
305
  const r = spawnSync('git', args, { cwd, encoding: 'utf8', timeout: 120_000 });
286
306
  return { status: r.status, stdout: String(r.stdout ?? ''), stderr: String(r.stderr ?? '') };
@@ -414,8 +434,6 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
414
434
  // 원격 부모는 node-b 의 liveMoves 가 꺼져 리뷰 이력이 0일 수 있다. HQ 거울의 종결 증거가 있을 때만 시작한다.
415
435
  const adopted = card.adoptedPr?.pr === pr && typeof card.pr === 'object'
416
436
  && !!card.pr.url && sameUrl(card.adoptedPr.url, card.pr.url) && /^[a-f0-9]{40}$/i.test(card.adoptedPr.head);
417
- if (!reviews.length && !adopted && (!card.parentHost || !(deps.remoteRunTerminal ?? remoteBoundRunTerminal)(card)))
418
- return target('not-started', 'no task-agent review on this PR yet (remote terminal unproven or run not stopped/judged)', pr);
419
437
  // 떼어 띄운 재게이트 결과를 «머리와 무관하게» 먼저 회수한다 — 결과가 나오기 전에 머리가 또 바뀌어도 그 머리의 결과는 카드에 남는다.
420
438
  for (const pending of (card.regates ?? []).filter((entry) => entry.pr === pr && entry.passed === undefined && entry.resultPath)) {
421
439
  let text: string | null = null;
@@ -433,7 +451,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
433
451
  wrote = true;
434
452
  return { ...current, regates: current.regates.map((entry) => entry.pr === pr && entry.head === pending.head && entry.at === pending.at ? { ...entry, ...patch } : entry) };
435
453
  });
436
- if (wrote) emit({ card: card.id, pr, fromHead: null, toHead: pending.head, step: 'regate', decision: patch.passed ? 'regate-passed' : 'regate-failed',
454
+ if (wrote) emit({ card: card.id, pr, fromHead: null, toHead: pending.head, step: 'regate', decision: patch.passed ? 'regate-passed' : regateUnmeasured(patch) ? 'regate-unmeasured' : 'regate-failed',
437
455
  reason: `head ${pending.head.slice(0, 12)} · base ${(patch as { baseCommit?: string }).baseCommit?.slice(0, 12) ?? '-'} · ${patch.detail}` }, true);
438
456
  }
439
457
  card = readTaskCard(card.id, statePath) ?? card;
@@ -451,15 +469,40 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
451
469
  if ('reason' in found) return target('pr-unreadable', found.reason, pr, fromHead);
452
470
  const { cwd, view } = found;
453
471
  const toHead = view.head;
472
+ const eligible = !!reviews.length || adopted || (!!card.parentHost && (deps.remoteRunTerminal ?? remoteBoundRunTerminal)(card));
473
+ const trustedTrain = view.state === 'CLOSED' && card.status === 'launched'
474
+ ? (() => { try { return (deps.trainLanding ?? verifiedTrainLanding)(pr, cwd); } catch { return null; } })() : null;
475
+ // An unreviewed or unproven remote card retains the old guard. Only verified train
476
+ // evidence may cross it; an arbitrary CLOSED PR must not disappear from rejudge.
477
+ if (!eligible && !trustedTrain)
478
+ return target('not-started', 'no task-agent review on this PR yet (remote terminal unproven or run not stopped/judged)', pr);
479
+ try {
480
+ const paths = await (deps.prFiles ?? defaultPrFiles)(pr, url);
481
+ if (isGoalOnlyPr(paths)) return target('goal-only-pr', `PR #${pr} target diff 0 (docs/goals/** only) — review·land·같은 골 재큐 중지`, pr, fromHead, toHead, true);
482
+ } catch (error) {
483
+ try { log('task-agent', 'pr-target-diff-unavailable', { card: card.id, pr,
484
+ reason: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
485
+ }
454
486
  if (view.state === 'MERGED' || view.state === 'CLOSED') {
455
487
  const at = now().toISOString();
488
+ const train = trustedTrain;
456
489
  updateTaskCard(statePath, card.id, (current) => {
457
490
  if (!current || cardPrNumber(current) !== pr || typeof current.pr !== 'object' || current.pr.url !== url) return undefined;
458
491
  const previous = boundPrTerminal(current);
459
- if (previous?.state === view.state && previous.head === toHead) return undefined;
460
- return { ...current, prTerminal: { pr, url, head: toHead, state: view.state as 'MERGED' | 'CLOSED', at } };
492
+ const alreadyLanded = train && current.trainLanding?.componentPr === pr
493
+ && current.trainLanding.integrationPr === train.integrationPr && current.trainLanding.mergeSha === train.mergeSha;
494
+ if (previous?.state === view.state && previous.head === toHead && (!train || alreadyLanded) && (!train || current.status === 'done')) return undefined;
495
+ return {
496
+ ...current,
497
+ ...(train ? { status: 'done' as const, trainLanding: alreadyLanded ? current.trainLanding : { ...train, at }, history: alreadyLanded ? current.history : [...(current.history ?? []), {
498
+ at, event: 'landed-via-train', pr, head: toHead, detail: `train #${train.integrationPr} merged ${train.mergeSha}`,
499
+ }] } : {}),
500
+ prTerminal: previous?.state === view.state && previous.head === toHead ? previous
501
+ : { pr, url, head: toHead, state: view.state as 'MERGED' | 'CLOSED', at },
502
+ };
461
503
  });
462
- return target('pr-not-open', `PR #${pr} is ${view.state}`, pr, fromHead, toHead);
504
+ return train ? target('landed-via-train', `PR #${pr} via train #${train.integrationPr} merge ${train.mergeSha}`, pr, fromHead, toHead)
505
+ : target('pr-not-open', `PR #${pr} is ${view.state}`, pr, fromHead, toHead);
463
506
  }
464
507
  if (view.state !== 'OPEN') return target('pr-not-open', `PR #${pr} is ${view.state}`, pr, fromHead, toHead);
465
508
  // An explicitly rejudged PR can be reopened. Clear the old marker before normal head judgement.
@@ -533,8 +576,10 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
533
576
  mustFix: mustFix ?? [], liveMoves: deps.liveMoves, now: now(), readFile: read,
534
577
  ...(deps.requestRepair ? { request: deps.requestRepair } : {}),
535
578
  ...(deps.applyRepair ? { apply: deps.applyRepair } : {}),
536
- ...(deps.notifyRepair ? { notify: deps.notifyRepair } : {}) });
537
- step('repair', result.decision, result.reason, true);
579
+ ...(deps.notifyRepair ? { notify: deps.notifyRepair } : {}),
580
+ ...(deps.repairBudget ? { repairBudget: deps.repairBudget } : {}) });
581
+ step('repair', result.decision, result.reason, true,
582
+ result.repairRunId && result.repairHead ? { repairRunId: result.repairRunId, repairHead: result.repairHead } : {});
538
583
  return outcomes;
539
584
  }
540
585
  }
@@ -582,6 +627,40 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
582
627
  return outcomes;
583
628
  }
584
629
 
630
+ // TA-LAND-AFTER-REVIEW: configured queue mode owns its one remote changed gate inside
631
+ // the queue adapter. The older host regate below is the direct-merge path only.
632
+ const queueMode = live.landQueueConfig === undefined ? getUserConfig().taskAgent?.landQueue : live.landQueueConfig;
633
+ if (queueMode) {
634
+ const latest = readTaskCard(card.id, statePath) ?? card;
635
+ const priorQueue = (latest.landAttempts ?? []).filter((entry) => entry.pr === pr && sameHead(entry.head, toHead));
636
+ if (priorQueue.length && !landRetryPending(latest, pr, toHead)) {
637
+ step('land', 'queue-skipped', `PR #${pr} head ${toHead.slice(0, 12)} already claimed or queued`, false);
638
+ return outcomes;
639
+ }
640
+ const review = capturedLandReview(latest, pr, toHead);
641
+ if (!review || review.mustFixCount !== 0) {
642
+ if (pendingReviewResults(latest).some((entry) => entry.pr === pr && sameHead(entry.head, toHead))) {
643
+ step('review', 'awaiting-review-result', 'exact-head review result pending', false);
644
+ } else if (!latest.reviewRequests?.some((entry) => entry.pr === pr && sameHead(entry.head, toHead)) && deps.liveMoves.has('review')) {
645
+ const before = { reviewRequests: latest.reviewRequests, landAttempts: latest.landAttempts };
646
+ const result = await executeLiveReview(latest, pr, { runId: latest.runId ?? null, stopReason: 'queue-exact-head', cwd }, { ...live, ...(deps.log ? { log: deps.log } : {}) });
647
+ recordMove(statePath, latest.id, latest.runId, 'review', result, pr, before, now, deps.log);
648
+ step('review', result.executed ? 'review-requested' : 'review-request-failed', result.detail, true);
649
+ } else step('review', 'not-landing', 'exact-head PASS/WARN mf0 review not captured', true);
650
+ return outcomes;
651
+ }
652
+ if (!readyConfirmed) { step('ready', 'ready-unconfirmed', 'exact-head ready PR not confirmed', false); return outcomes; }
653
+ if (!deps.liveMoves.has('propose-land')) { step('land', 'would-land', 'propose-land not enabled — queue shadow', false); return outcomes; }
654
+ const reviewResult = latest.reviewRequests?.find((entry) => entry.pr === pr && sameHead(entry.head, toHead) && entry.resultPath)?.resultPath;
655
+ if (!reviewResult) { step('land', 'not-landing', 'exact-head review JSON path missing', true); return outcomes; }
656
+ const before = { reviewRequests: latest.reviewRequests, landAttempts: latest.landAttempts };
657
+ const queued = await executeLiveLand(latest, pr, { runId: latest.runId ?? null, cycleId: `queue:${latest.id}:${toHead}`, cwd,
658
+ review, reviewResultPath: reviewResult }, { ...live, landQueueConfig: queueMode, ...(deps.log ? { log: deps.log } : {}) });
659
+ recordMove(statePath, latest.id, latest.runId, 'propose-land', queued, pr, before, now, deps.log);
660
+ step('land', queued.queued ? 'queued' : queued.ok && !queued.executed ? 'queue-skipped' : 'queue-refused', queued.detail, true);
661
+ return outcomes;
662
+ }
663
+
585
664
  const tryCatchUp = async (fromBase: string | undefined, why: string): Promise<boolean> => {
586
665
  const prior = catchUpHistory(card!, pr);
587
666
  // 상한은 «실제 push» 만 센다 — 충돌·실패 뒤 사람이 새 머리를 올리면 다시 시도할 수 있어야 한다.
@@ -650,8 +729,9 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
650
729
  if (!regate || staleBase || retryDraft) {
651
730
  const why = staleBase ? `base-stale-overlap — gate base ${staleBase.slice(0, 12)} went stale (${(stale!.reason ?? '').replace(/^base-stale-overlap:\s*/, '').slice(0, 160)})`
652
731
  : retryDraft ? 'draft rejection became stale after PR ready' : '';
653
- if (regates.length >= REJUDGE_HEAD_CAP) {
654
- step('regate', 'cap-reached', `${why ? `${why} · ` : ''}re-gated ${regates.length} times already (cap ${REJUDGE_HEAD_CAP}) — no more rejudge; needs owner`, true);
732
+ const counted = cappedRegates(regates).length;
733
+ if (counted >= REJUDGE_HEAD_CAP) {
734
+ step('regate', 'cap-reached', `${why ? `${why} · ` : ''}re-gated ${counted} times already (cap ${REJUDGE_HEAD_CAP} · unmeasured ${regates.length - counted} not counted) — no more rejudge; needs owner`, true);
655
735
  return outcomes;
656
736
  }
657
737
  if (!deps.liveMoves.has('propose-land')) step('regate', 'would-regate', `${why ? `${why} · ` : ''}propose-land not enabled in taskAgent.liveMoves — shadow`, false);
@@ -667,7 +747,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
667
747
  if (!current || held.some((entry) => sameHead(entry.head, toHead) && (staleBase ? entry.staleBase !== undefined && sameHead(entry.staleBase, staleBase)
668
748
  : retryDraft ? entry.readyRetry === true : true))) return undefined;
669
749
  // 상한은 잠금 안의 «지금» 카드로 다시 잰다 — 다른 머리를 본 두 틱이 겹쳐도 상한을 넘지 않게.
670
- if (held.length >= REJUDGE_HEAD_CAP) { capped = true; return undefined; }
750
+ if (cappedRegates(held).length >= REJUDGE_HEAD_CAP) { capped = true; return undefined; }
671
751
  claimed = true;
672
752
  return { ...current, regates: [...(current.regates ?? []), { pr, head: toHead, at, resultPath, ...(staleBase ? { staleBase } : {}), ...(retryDraft ? { readyRetry: true as const } : {}) }] };
673
753
  });
@@ -750,7 +830,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
750
830
  const before = { reviewRequests: latest.reviewRequests, landAttempts: latest.landAttempts };
751
831
  // 주기 id — base-stale 재게이트 뒤의 land 는 새 base 를 붙여 앞 land 의 주기 표시(모듈 전역)와 갈린다 · gateAt 이 앞 base-stale 시도를 소비한다.
752
832
  const cycleId = `rejudge:${card.id}:${toHead}${regate.staleBase ? `:${regate.baseCommit.slice(0, 12)}` : ''}`;
753
- const landed = await executeLiveLand(latest, pr, { runId: card.runId ?? null, cycleId, cwd, review, overlapEvidence, gateAt: regate.at },
833
+ const landed = await executeLiveLand(latest, pr, { runId: card.runId ?? null, cycleId, cwd, review, reviewResultPath: reviewResult, overlapEvidence, gateAt: regate.at },
754
834
  { ...live, ...(deps.log ? { log: deps.log } : {}) });
755
835
  // LAND-ORDER-LEDGER — executeLiveLand 직후 원장 한 줄(같은 pr+head 는 한 줄만). 쓰기가 실패해도 land 결과는 그대로(삼킨다).
756
836
  const landOrderLog = (event: 'appended' | 'append-failed') => { try { log('task-agent.land-order', event, { pr, head: toHead }); } catch { /* fail-soft */ } };
@@ -768,7 +848,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
768
848
  const attempt = landed.landAttempt?.class
769
849
  ? ` · land-class ${landed.landAttempt.class} (${landed.landAttempt.reason}) · attempt ${landed.landAttempt.attempt} · ${landed.landAttempt.class === 'base-stale' ? 'base-stale → re-gate on a new base next tick (cap counts)' : landed.landAttempt.retryAllowed ? 'retry allowed on this head' : 'no retry on this head'}`
770
850
  : '';
771
- step('land', landed.executed && landed.ok ? 'landed'
851
+ step('land', landed.queued ? 'queued' : landed.executed && landed.ok ? 'landed'
772
852
  : !landed.executed && landed.ok ? 'land-skipped' : 'land-rejected',
773
853
  `${landed.detail}${attempt} · overlap-evidence ${overlapEvidence}`, true);
774
854
  return outcomes;
@@ -1,30 +1,73 @@
1
1
  /** Bind remote TA parents from the HQ ledger mirror before `rejudge --all` selects PR cards. */
2
- import { dirname } from 'node:path';
2
+ import { existsSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
3
4
  import { debug } from '../debug/log.js';
4
5
  import { loadRunLedger } from '../self-implement/run-ledger.js';
5
- import { bindCardEvidence, podChildRunIds, readCardRunSnapshot, refreshCardRunBinding } from './card-evidence.js';
6
- import { remoteLedgerMirrorDir } from './parent-host.js';
6
+ import { bindCardEvidence, podChildRunIds, podTerminalPr, readCardRunSnapshot, refreshCardRunBinding } from './card-evidence.js';
7
+ import { mirrorRemoteRunLedgers, remoteLedgerMirrorDir } from './parent-host.js';
7
8
  import { cardPrNumber, type TaskCard } from './task-hand.js';
8
9
 
10
+ const RECENT_LAUNCH_MS = 24 * 60 * 60 * 1000;
11
+ /**
12
+ * TA-BIND-PULL-ONCE — an older launch whose parent ledger was never mirrored at HQ gets one pull («묶기만»).
13
+ * Bounded per tick so the first tick after deploy does not run hundreds of sequential ssh reads (backlog ≈690
14
+ * cards on 10-15 drains over ticks); a pulled mirror is then read locally and never pulled again by this rule.
15
+ */
16
+ export const UNMIRRORED_PULL_CAP_PER_TICK = 20;
17
+
18
+ type BindDeps = {
19
+ now?: () => number;
20
+ mirror?: typeof mirrorRemoteRunLedgers;
21
+ unmirroredPullCap?: number;
22
+ onFailure?: (failure: { card: string; runId: string; host: string; reason: string }) => void;
23
+ };
24
+
25
+ function recentlyLaunched(card: TaskCard, now: number): boolean {
26
+ const launch = [...card.history].reverse().find(event => event.event === 'launch');
27
+ const at = Date.parse(launch?.at ?? card.createdAt);
28
+ return Number.isFinite(at) && at <= now && now - at < RECENT_LAUNCH_MS;
29
+ }
30
+
9
31
  /**
10
32
  * A remote child PR can appear after the last HQ card refresh. A card without a PR is otherwise absent from
11
33
  * `rejudgeCandidates`, so the normal rejudge tick never reaches `mirrorRemoteCardLedger` or the binding replay.
12
- * Only an existing, launched TA-owned parent with a parent→child edge in its own host mirror is admitted. The
34
+ * Only an existing, launched parent (TA-owned or not — TA-BIND-WIDEN) with a parent→child edge in its own host
35
+ * mirror is bound; rejudge/land selection keeps its own taLand gate. The
13
36
  * launch registry (including foreign/test universes) and child-only ledgers are never scanned or adopted here.
14
37
  */
15
38
  export async function bindMirroredRemoteRejudgeCards(
16
39
  tasks: Readonly<Record<string, TaskCard>>, statePath: string,
17
- ): Promise<{ scanned: number; bound: number; skipped: number }> {
40
+ deps: BindDeps = {},
41
+ ): Promise<{ scanned: number; bound: number; skipped: number; pulledUnmirrored: number }> {
18
42
  const root = dirname(statePath);
43
+ const now = (deps.now ?? Date.now)();
44
+ const mirror = deps.mirror ?? mirrorRemoteRunLedgers;
45
+ const reportFailure = (card: TaskCard, reason: string): void => {
46
+ const failure = { card: card.id, runId: card.runId!, host: card.parentHost!.host, reason: reason.slice(0, 300) };
47
+ try { (deps.onFailure ?? ((data) => debug.log('task-agent', 'remote-rejudge-bind-failed', data)))(failure); }
48
+ catch { /* observation must not stop the other cards */ }
49
+ };
19
50
  let scanned = 0;
20
51
  let bound = 0;
21
52
  let skipped = 0;
53
+ let pulledUnmirrored = 0;
54
+ const unmirroredCap = deps.unmirroredPullCap ?? UNMIRRORED_PULL_CAP_PER_TICK;
22
55
  for (const card of Object.values(tasks)) {
23
- if (card.status !== 'launched' || card.taLand !== true || !card.parentHost || !card.runId
56
+ // TA-BIND-WIDEN — «묶기»는 taLand 와 무관하게 launched ⊕ runId 카드 전부. 묶여도 재판정(rejudge)·land 후보는
57
+ // `rejudgeCandidates`/`remoteBoundRunTerminal` 의 taLand 관문이 그대로 거른다 — 여기서 넓히는 것은 카드↔PR 연결뿐이다.
58
+ if (card.status !== 'launched' || !card.parentHost || !card.runId
24
59
  || cardPrNumber(card) !== undefined || card.refSource === 'manual') continue;
25
60
  scanned++;
26
61
  const dir = remoteLedgerMirrorDir(root, card.parentHost.host);
27
62
  try {
63
+ // This prepass runs before PR-based candidate selection. Pulling here breaks the otherwise circular
64
+ // dependency: cards with a remote PR cannot be selected while their parent/child ledgers are absent locally.
65
+ // Limit fresh remote pulls to recent launches, but keep binding older ledgers already mirrored at HQ.
66
+ if (recentlyLaunched(card, now)) mirror(card.parentHost, card.runId, root);
67
+ else if (!existsSync(join(dir, `${card.runId}.jsonl`)) && pulledUnmirrored < unmirroredCap) {
68
+ pulledUnmirrored++;
69
+ mirror(card.parentHost, card.runId, root);
70
+ }
28
71
  const snapshot = await readCardRunSnapshot(card, {
29
72
  loadLedger: (id) => loadRunLedger(id, dir),
30
73
  podFinishes: () => [],
@@ -34,12 +77,20 @@ export async function bindMirroredRemoteRejudgeCards(
34
77
  const childRunId = evidence.childRunId;
35
78
  const pr = evidence.pr;
36
79
  const child = childRunId ? snapshot.children[childRunId] : null;
80
+ if (snapshot.readErrors?.length) {
81
+ reportFailure(card, snapshot.readErrors.join('; '));
82
+ skipped++;
83
+ continue;
84
+ }
37
85
  // A PR event alone is not a completed remote run. The rejudge candidate must have the same exact
38
86
  // child PR and terminal status that remoteBoundRunTerminal will later require.
39
- if (snapshot.readErrors?.length || !parent || !childRunId || !pr?.url || !child
87
+ // TA-BIND-PR-TERMINAL — a blocked-draft child has no `pr-opened`; the parent's `pr-terminal` for that exact child,
88
+ // number and URL is the same PR evidence.
89
+ const terminal = parent ? podTerminalPr(parent, [childRunId ?? '']) : undefined;
90
+ if (!parent || !childRunId || !pr?.url || !child
40
91
  || !podChildRunIds(parent, card.runId).includes(childRunId)
41
- || !child.some((entry) => entry.event === 'pr-opened' && entry.data?.number === pr.number
42
- && entry.data?.url === pr.url)
92
+ || !(child.some((entry) => entry.event === 'pr-opened' && entry.data?.number === pr.number
93
+ && entry.data?.url === pr.url) || (terminal?.number === pr.number && terminal.url === pr.url))
43
94
  || !child.some((entry) => entry.event === 'run-status'
44
95
  && ['completed', 'failed', 'cancelled'].includes(String(entry.data?.runStatus)))) { skipped++; continue; }
45
96
  const result = await refreshCardRunBinding(card.id, statePath, {
@@ -53,10 +104,8 @@ export async function bindMirroredRemoteRejudgeCards(
53
104
  else skipped++;
54
105
  } catch (error) {
55
106
  skipped++;
56
- try { debug.log('task-agent', 'remote-rejudge-bind-failed', {
57
- card: card.id, runId: card.runId, host: card.parentHost.host, reason: error instanceof Error ? error.message : String(error),
58
- }); } catch { /* observation must not stop the other cards */ }
107
+ reportFailure(card, error instanceof Error ? error.message : String(error));
59
108
  }
60
109
  }
61
- return { scanned, bound, skipped };
110
+ return { scanned, bound, skipped, pulledUnmirrored };
62
111
  }
@@ -2,6 +2,8 @@
2
2
  import { spawn } from 'node:child_process';
3
3
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
4
  import { dirname, join, resolve, sep } from 'node:path';
5
+ import { debug } from '../debug/log.js';
6
+ import { readBudgetInputsLive, type BudgetInputs } from '../self-implement/budget-gate.js';
5
7
  import { mintRunId } from '../harness/harness-space.js';
6
8
  import { spawnElanousSync } from '../instance/spawn-elanous.js';
7
9
  import { passJourneyNode } from '../self-dev/graph-journey-nodes.js';
@@ -29,9 +31,19 @@ export interface RepairCycleInput {
29
31
  notify?: (seat: string, body: string) => void;
30
32
  observeLaunch?: (move: string, runId: string) => void;
31
33
  resolveOwner?: (card: TaskCard) => RepairOwner;
34
+ /** Shared only by one `tasks rejudge --all` invocation; a single-card rejudge has no cap. */
35
+ repairBudget?: RepairTickBudget;
36
+ /** Test seam; production reads the existing subscription quota signals. */
37
+ modelAvailability?: RepairModelAvailability;
38
+ /** Test seam for the same live quota reader used when availability is not injected. */
39
+ readBudgetInputs?: () => Promise<Pick<BudgetInputs, 'codexCandidates' | 'grokUsedPercent' | 'maxUsedPercent'>>;
32
40
  }
33
41
 
34
- export type RepairCycleOutcome = { decision: 'would-repair' | 'repair-requested' | 'repair-pending' | 'repair-applied' | 'repair-failed' | 'repair-stopped'; reason: string };
42
+ export interface RepairTickBudget { max: number; requested: number; capped: number }
43
+
44
+ export type RepairCycleOutcome = { decision: 'would-repair' | 'repair-requested' | 'repair-pending' | 'repair-applied' | 'repair-failed' | 'repair-stopped'; reason: string;
45
+ /** Present only when this tick actually consumed a bound worker result. */
46
+ repairRunId?: string; repairHead?: string };
35
47
  export type RepairOwner = { seat?: TaskSeat; source: string; reason?: string };
36
48
 
37
49
  /** A missing card seat may use only a uniquely identified checklist cell's valid seat. */
@@ -65,12 +77,39 @@ export function resolveRepairOwner(card: TaskCard, deps: {
65
77
  } catch { return { source: 'none', reason: `checklist owner invalid: ${cell.version}/${card.checklistId}` }; }
66
78
  }
67
79
 
68
- export function alternateRepairModel(card: TaskCard): { from: string; to: TaskChildLlm } {
80
+ export interface RepairModelAvailability { codexSubscription: boolean; grokSubscription: boolean }
81
+
82
+ export async function repairModelAvailability(readInputs: () => Promise<Pick<BudgetInputs, 'codexCandidates' | 'grokUsedPercent' | 'maxUsedPercent'>> = readBudgetInputsLive): Promise<RepairModelAvailability> {
83
+ try {
84
+ const input = await readInputs();
85
+ const codexCap = input.maxUsedPercent['openai-codex'] ?? 95;
86
+ const grokCap = input.maxUsedPercent.grok ?? 100;
87
+ return {
88
+ codexSubscription: input.codexCandidates.some((candidate) => candidate.reached !== true
89
+ && typeof candidate.usedPercent === 'number' && candidate.usedPercent < codexCap),
90
+ grokSubscription: typeof input.grokUsedPercent === 'number' && input.grokUsedPercent < grokCap,
91
+ };
92
+ } catch { return { codexSubscription: false, grokSubscription: false }; }
93
+ }
94
+
95
+ /** Repair stays inside the dispatch tier. A missing legacy tier is high, with Sol allowed only on measured subscription quota. */
96
+ export function alternateRepairModel(card: TaskCard, availability: RepairModelAvailability = { codexSubscription: false, grokSubscription: false }): { from: string; to: TaskChildLlm } {
69
97
  const last = card.repairs?.at(-1);
70
98
  const from = last?.toModel ?? (card.childLlm ? `${card.childLlm.provider}/${card.childLlm.model}` : 'unknown');
71
- const to = from.includes('openrouter/') || from.includes('glm')
72
- ? { provider: 'openai-codex', model: 'gpt-6-sol' }
73
- : { provider: 'openrouter', model: 'openrouter/z-ai/glm-5.3' };
99
+ const glm: TaskChildLlm = { provider: 'openrouter', model: 'openrouter/z-ai/glm-5.3' };
100
+ const sol: TaskChildLlm = { provider: 'openai-codex', model: 'gpt-6-sol' };
101
+ const grok: TaskChildLlm = { provider: 'grok', model: 'grok-4.6' };
102
+ const tier = card.tier ?? '상';
103
+ const pr = typeof card.pr === 'number' ? card.pr : card.pr?.number;
104
+ const mixEven = ((pr ?? [...card.id].reduce((sum, ch) => sum + ch.charCodeAt(0), 0)) % 2) === 0;
105
+ let to: TaskChildLlm;
106
+ if (tier === '특') to = sol;
107
+ else if (tier === '상' && availability.codexSubscription && mixEven && !from.includes('gpt-6-sol')) to = sol;
108
+ else if (tier === '상') to = availability.grokSubscription && from.includes('glm') ? grok
109
+ : from.includes('glm-5.3-flash') ? glm
110
+ : from.includes('glm-5.3') ? { provider: 'openrouter', model: 'openrouter/z-ai/glm-5.3-flash' } : glm;
111
+ else to = from.includes('glm-5.3-flash') ? glm : from.includes('glm-5.3')
112
+ ? { provider: 'openrouter', model: 'openrouter/z-ai/glm-5.3-flash' } : glm;
74
113
  return { from, to };
75
114
  }
76
115
 
@@ -126,6 +165,7 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
126
165
  runId: latest.runId, effect: status, detail: applied.ok ? applied.toHead : applied.reason }] } : undefined);
127
166
  } catch (error) { return { decision: 'repair-pending', reason: `repair confirmation card write failed: ${String(error).slice(-200)}` }; }
128
167
  const recorded = readTaskCard(card.id, statePath)?.repairs?.find((entry) => entry.runId === latest.runId)?.status === status;
168
+ // This confirms a result already claimed by another tick; it did not consume the worker result.
129
169
  return recorded ? { decision: applied.ok ? 'repair-applied' : 'repair-failed', reason: applied.ok ? `same PR #${pr} fast-forward ${latest.head.slice(0, 12)} → ${applied.toHead.slice(0, 12)}` : applied.reason }
130
170
  : { decision: 'repair-pending', reason: 'repair confirmation card changed concurrently' };
131
171
  }
@@ -182,7 +222,8 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
182
222
  runId: latest.runId, effect: status, detail }] } : undefined);
183
223
  } catch (error) { return { decision: 'repair-pending', reason: `repair card write failed after CAS: ${String(error).slice(-200)}` }; }
184
224
  const recorded = readTaskCard(card.id, statePath)?.repairs?.find((entry) => entry.runId === latest.runId)?.status === status;
185
- return recorded ? { decision: applied?.ok ? 'repair-applied' : applied?.unconfirmed ? 'repair-pending' : 'repair-failed', reason: detail }
225
+ return recorded ? { decision: applied?.ok ? 'repair-applied' : applied?.unconfirmed ? 'repair-pending' : 'repair-failed', reason: detail,
226
+ repairRunId: latest.runId, repairHead: latest.head }
186
227
  : { decision: 'repair-pending', reason: 'repair result card changed concurrently' };
187
228
  }
188
229
  if (latest?.status === 'applied' && latest.head.toLowerCase() === head.toLowerCase())
@@ -230,9 +271,18 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
230
271
  ? { ...current, status: 'failed', history: [...(current.history ?? []), { at: now.toISOString(), event: 'repair-owner-missing', pr, head, detail: reason }] } : undefined);
231
272
  return { decision: 'repair-stopped', reason };
232
273
  }
274
+ if (input.repairBudget && input.repairBudget.requested >= input.repairBudget.max) {
275
+ input.repairBudget.capped++;
276
+ const reason = `repairMaxPerTick 상한 ${input.repairBudget.max} · 다음 틱에 재판정`;
277
+ try { debug.log('task-agent', 'repair-tick-cap', { card: card.id, pr, head, max: input.repairBudget.max,
278
+ requested: input.repairBudget.requested, capped: input.repairBudget.capped, move: judged.judgement.move }); } catch { /* fail-soft */ }
279
+ return { decision: 'would-repair', reason };
280
+ }
233
281
  const next = attempts.length + 1;
234
282
  const runId = mintRunId();
235
- const { from, to } = alternateRepairModel(card);
283
+ const availability = input.modelAvailability ?? (card.tier === '특' || card.tier === '중' || card.tier === '하'
284
+ ? { codexSubscription: false, grokSubscription: false } : await repairModelAvailability(input.readBudgetInputs));
285
+ const { from, to } = alternateRepairModel(card, availability);
236
286
  const resultPath = repairResultPath(statePath, card.id, pr, head, next, runId);
237
287
  const goalFile = resultPath.replace(/\.json$/, '.goal.txt');
238
288
  const goal = `기존 PR #${pr}의 리뷰 때 head ${head}를 같은 가지에서 수리한다. 새 PR을 열지 말고 아래 must-fix 원문만 고쳐 commit-only 결과를 반환한다.\n\n${input.mustFix.map((item, i) => `${i + 1}. ${item}`).join('\n')}`;
@@ -251,6 +301,7 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
251
301
  try {
252
302
  await (input.request ?? defaultRequestRepair)({ card: card.id, pr, head, repo, resultPath, goalFile,
253
303
  runId, model: to, seat: owner.seat });
304
+ if (input.repairBudget) input.repairBudget.requested++;
254
305
  } catch (error) {
255
306
  const reason = `repair launch failed: ${error instanceof Error ? error.message : String(error)}`;
256
307
  updateTaskCard(statePath, card.id, (current) => current?.repairs?.some((entry) => entry.runId === runId && entry.status === 'requested')
@@ -4,6 +4,7 @@ import { mkdirSync, renameSync, writeFileSync } from 'node:fs';
4
4
  import { dirname } from 'node:path';
5
5
  import type { RepairCommitResult } from './repair-branch-cas.js';
6
6
  import type { TaskChildLlm } from './task-hand.js';
7
+ import { publishInsideEvent } from '../nexus/api/inside-events.js';
7
8
 
8
9
  const SHA40 = /^[0-9a-f]{40}$/i;
9
10
  const SHA256 = /^[0-9a-f]{64}$/i;
@@ -70,6 +71,12 @@ export async function runRepairWorker(request: RepairWorkerRequest): Promise<Rep
70
71
  const tmp = `${request.resultPath}.${process.pid}.tmp`;
71
72
  writeFileSync(tmp, JSON.stringify(result));
72
73
  renameSync(tmp, request.resultPath);
74
+ // The result file, rather than this best-effort notification, is the durable source.
75
+ try {
76
+ publishInsideEvent({ kind: 'ta.repair.completed', schema: 1, card: request.card,
77
+ pr: request.pr, head: request.head, runId: request.runId,
78
+ resultPath: request.resultPath, completedAt: new Date().toISOString() });
79
+ } catch { /* a missing daemon cannot change the worker result */ }
73
80
  return result;
74
81
  }
75
82