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,158 @@
1
+ /** Immediate TA repair collection. The card and atomic worker result remain authoritative. */
2
+ import { mkdirSync, readFileSync } from 'node:fs';
3
+ import { dirname, join, resolve } from 'node:path';
4
+ import { debug } from '../debug/log.js';
5
+ import { spawnElanous } from '../instance/spawn-elanous.js';
6
+ import { acquireLockSync } from '../storage/file-lock.js';
7
+ import { subscribeInsideEvent, type InsideLiveEvent } from '../nexus/api/inside-events.js';
8
+ import type { NexusEventBus } from '../nexus/api/event-bus.js';
9
+ import { parseRepairWorkerResult } from '../task-agent/repair-worker.js';
10
+ import { readTaskCard, taskAgentStatePath } from '../task-agent/task-hand.js';
11
+
12
+ const SHA40 = /^[0-9a-f]{40}$/i;
13
+ const CARD = /^ta-[a-z0-9-]{1,80}$/;
14
+ const TIMEOUT_MS = 10 * 60_000;
15
+ const OUTPUT_LIMIT = 1024 * 1024;
16
+
17
+ export interface TaRepairCompleted {
18
+ kind: 'ta.repair.completed'; schema: 1; card: string; pr: number; head: string;
19
+ runId: string; resultPath: string; completedAt: string;
20
+ }
21
+
22
+ export function parseTaRepairCompleted(value: unknown): TaRepairCompleted | null {
23
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
24
+ const v = value as Record<string, unknown>;
25
+ if (v.kind !== 'ta.repair.completed' || v.schema !== 1 || typeof v.card !== 'string' || !CARD.test(v.card)
26
+ || !Number.isSafeInteger(v.pr) || Number(v.pr) < 1 || typeof v.head !== 'string' || !SHA40.test(v.head)
27
+ || typeof v.runId !== 'string' || !/^run-[a-z0-9-]{1,100}$/i.test(v.runId)
28
+ || typeof v.resultPath !== 'string' || !v.resultPath.startsWith('/')
29
+ || typeof v.completedAt !== 'string' || !Number.isFinite(Date.parse(v.completedAt))) return null;
30
+ return v as unknown as TaRepairCompleted;
31
+ }
32
+
33
+ export interface TaRepairCollectDeps {
34
+ statePath?: string;
35
+ /** Test entry for a child that runs the real tasks CLI with isolated dependencies. */
36
+ cliBin?: string;
37
+ read?: (path: string) => string;
38
+ run?: (card: string) => Promise<{ code: number | null; output: string; truncated?: boolean }>;
39
+ now?: () => Date;
40
+ log?: (data: Record<string, unknown>) => void;
41
+ }
42
+
43
+ function defaultRun(card: string, statePath: string, cliBin?: string): Promise<{ code: number | null; output: string; truncated?: boolean }> {
44
+ return new Promise(done => {
45
+ const child = spawnElanous(['tasks', 'rejudge', card, '--json'], { stateDir: dirname(statePath),
46
+ ...(cliBin ? { bin: cliBin } : {}), stdio: ['ignore', 'pipe', 'pipe'] });
47
+ let output = '';
48
+ let truncated = false;
49
+ let settled = false;
50
+ let force: ReturnType<typeof setTimeout> | undefined;
51
+ const finish = (code: number | null) => {
52
+ if (settled) return;
53
+ settled = true;
54
+ clearTimeout(timer);
55
+ if (force) clearTimeout(force);
56
+ done({ code, output, truncated });
57
+ };
58
+ const timer = setTimeout(() => {
59
+ child.kill('SIGTERM');
60
+ // Keep the card lock until close confirms the child has stopped writing the card.
61
+ force = setTimeout(() => { child.kill('SIGKILL'); }, 5000);
62
+ }, TIMEOUT_MS);
63
+ const append = (chunk: unknown) => {
64
+ const next = output + String(chunk);
65
+ if (next.length > OUTPUT_LIMIT) { truncated = true; output = next.slice(-OUTPUT_LIMIT); }
66
+ else output = next;
67
+ };
68
+ child.stdout?.on('data', append);
69
+ child.stderr?.on('data', append);
70
+ // Node emits close after error, including spawn failure. An error can also
71
+ // describe a failed kill while the child is still alive: keep the lock.
72
+ child.once('error', (error) => { append(`\nchild error: ${String(error)}`); });
73
+ child.once('close', finish);
74
+ });
75
+ }
76
+
77
+ function childConsumedRepair(output: string, event: TaRepairCompleted): boolean {
78
+ for (const line of output.split(/\r?\n/).reverse()) {
79
+ if (!line.trimStart().startsWith('[')) continue;
80
+ try {
81
+ const rows: unknown = JSON.parse(line);
82
+ if (Array.isArray(rows) && rows.some(row => row && typeof row === 'object' && row.card === event.card
83
+ && row.pr === event.pr && row.repairRunId === event.runId && row.repairHead === event.head
84
+ && row.step === 'repair' && (row.decision === 'repair-applied' || row.decision === 'repair-failed'))) return true;
85
+ } catch { /* not a JSON result line */ }
86
+ }
87
+ return false;
88
+ }
89
+
90
+ /** One event may start one card rejudge. A periodic rejudge can race; its existing card CAS still owns side effects. */
91
+ export async function collectTaRepairCompleted(input: unknown, deps: TaRepairCollectDeps = {}): Promise<'invalid' | 'duplicate' | 'deferred' | 'collected'> {
92
+ const event = parseTaRepairCompleted(input);
93
+ if (!event) return 'invalid';
94
+ const statePath = deps.statePath ?? taskAgentStatePath();
95
+ const emit = (outcome: string, extra: Record<string, unknown> = {}) => {
96
+ const collectedAt = (deps.now?.() ?? new Date()).toISOString();
97
+ const data = { card: event.card, pr: event.pr, runId: event.runId, completedAt: event.completedAt,
98
+ collectedAt, ...(outcome === 'collected' ? { latencyMs: Date.parse(collectedAt) - Date.parse(event.completedAt) } : {}),
99
+ delivery: 'event', outcome, ...extra };
100
+ try { (deps.log ?? ((d) => debug.log('task-agent', 'ta.repair.collected', d)))(data); } catch { /* observability cannot change the result */ }
101
+ };
102
+ let card;
103
+ try { card = readTaskCard(event.card, statePath); } catch { emit('deferred', { reason: 'card unreadable' }); return 'deferred'; }
104
+ const repair = Array.isArray(card?.repairs) ? card.repairs.find(entry => entry && typeof entry === 'object' && entry.runId === event.runId) : undefined;
105
+ if (!repair || repair.pr !== event.pr || typeof repair.head !== 'string' || repair.head.toLowerCase() !== event.head.toLowerCase()
106
+ || typeof repair.resultPath !== 'string' || !repair.resultPath.startsWith('/')
107
+ || resolve(repair.resultPath) !== resolve(event.resultPath)) { emit('invalid', { reason: 'event differs from card binding' }); return 'invalid'; }
108
+ if (repair.status !== 'requested') { emit('duplicate', { reason: `repair ${repair.status}` }); return 'duplicate'; }
109
+ let result;
110
+ try { result = parseRepairWorkerResult((deps.read ?? ((path) => readFileSync(path, 'utf8')))(repair.resultPath), event.pr, event.head, event.runId); }
111
+ catch { /* periodic tick can recover a missing result */ }
112
+ if (!result) { emit('deferred', { reason: 'worker result missing or invalid' }); return 'deferred'; }
113
+
114
+ // Existing PID-aware lock recovers a dead daemon without making later events wait forever.
115
+ // A live holder keeps the lock through the child process; the card CAS covers periodic-tick races.
116
+ const lock = join(dirname(statePath), 'steward', 'ta-repair-collect', `${event.card}.lock`);
117
+ let release: () => void;
118
+ try {
119
+ mkdirSync(dirname(lock), { recursive: true });
120
+ release = acquireLockSync(lock, { breakDeadHolder: true, staleMs: TIMEOUT_MS + 60_000, maxTries: 2 });
121
+ }
122
+ catch { emit('deferred', { reason: 'collector busy; periodic fallback remains' }); return 'deferred'; }
123
+ try {
124
+ // Recheck after claiming: another collector or the periodic tick may have consumed the file.
125
+ const current = readTaskCard(event.card, statePath);
126
+ const latest = Array.isArray(current?.repairs) ? current.repairs.find(entry => entry && typeof entry === 'object' && entry.runId === event.runId) : undefined;
127
+ if (!latest || latest.status !== 'requested' || latest.pr !== event.pr || typeof latest.head !== 'string'
128
+ || latest.head.toLowerCase() !== event.head.toLowerCase() || typeof latest.resultPath !== 'string'
129
+ || !latest.resultPath.startsWith('/') || resolve(latest.resultPath) !== resolve(event.resultPath)) { emit('duplicate'); return 'duplicate'; }
130
+ const child = await (deps.run ?? ((card) => defaultRun(card, statePath, deps.cliBin)))(event.card);
131
+ const after = readTaskCard(event.card, statePath)?.repairs?.find(entry => entry.runId === event.runId);
132
+ const consumed = child.code === 0 && !child.truncated && after?.status !== 'requested' && after !== undefined
133
+ && childConsumedRepair(child.output, event);
134
+ const outcome = consumed ? 'collected' : child.truncated ? 'deferred' : after && after.status !== 'requested' ? 'duplicate' : 'deferred';
135
+ emit(outcome, { rc: child.code, repairStatus: after?.status,
136
+ ...(child.truncated ? { reason: 'rejudge output exceeded 1 MiB; event attribution unmeasured' } : {}),
137
+ detail: child.output.slice(-300) });
138
+ return consumed ? 'collected' : outcome === 'duplicate' ? 'duplicate' : 'deferred';
139
+ } catch (error) {
140
+ emit('deferred', { reason: String(error).slice(-300) });
141
+ return 'deferred';
142
+ } finally { release(); }
143
+ }
144
+
145
+ /** Bridge child-process inside events to Nexus pub/sub; keep the handler nonblocking. */
146
+ export function startTaRepairEventCollector(bus: NexusEventBus, deps: TaRepairCollectDeps = {}): () => void {
147
+ const unsubscribeBus = bus.subscribe(event => {
148
+ void collectTaRepairCompleted(event.detail, deps).catch(error => {
149
+ try { debug.log('task-agent', 'ta.repair.collect-error', { reason: String(error).slice(-300) }, { level: 'warn' }); }
150
+ catch { /* observer failure cannot reject the Nexus callback */ }
151
+ });
152
+ }, ['ta.repair.completed']);
153
+ const unsubscribeInside = subscribeInsideEvent((event: InsideLiveEvent) => {
154
+ if (event.kind !== 'ta.repair.completed') return;
155
+ bus.publish({ kind: 'ta.repair.completed', ts: Date.now(), detail: event as unknown as Record<string, unknown> });
156
+ });
157
+ return () => { unsubscribeInside(); unsubscribeBus(); };
158
+ }
@@ -76,7 +76,27 @@ export function podChildRunIds(host: readonly RunLedgerEntry[] | null, runId?: s
76
76
  && RUN_ID.test(entry.data.childRunId) && entry.data.childRunId !== runId).map((entry) => entry.data.childRunId as string))];
77
77
  }
78
78
 
79
- /** 순수 — 카드 런의 골 id · PR. PR 은 호스트 → 자식(나중 자식 먼저) → job-finished 순으로 처음 찾은 것. */
79
+ /**
80
+ * TA-BIND-PR-TERMINAL — 부모(호스트) 원장의 `pr-terminal{childRunId, prNumber, prUrl}`(draft-residue `applyPodTerminal`).
81
+ * gate-failed draft 자식은 `pr-opened` 없이 `rework-blocked-draft-pr`·`pr.comment.mode` 만 남겨서, PR 근거는 부모의 이 줄뿐이다.
82
+ * 자식은 부모의 `pod-child-run` 자식이어야 하고, url 은 같은 번호의 PR 주소여야 한다. 나중 줄이 먼저다.
83
+ */
84
+ export function podTerminalPr(host: readonly RunLedgerEntry[] | null, childRunIds: readonly string[]): { number: number; url: string; childRunId: string } | undefined {
85
+ const children = new Set(childRunIds);
86
+ for (let at = (host?.length ?? 0) - 1; at >= 0; at--) {
87
+ const entry = host![at]!;
88
+ if (entry.event !== 'pr-terminal') continue;
89
+ const childRunId = entry.data?.childRunId;
90
+ const number = entry.data?.prNumber;
91
+ const url = entry.data?.prUrl;
92
+ if (typeof childRunId !== 'string' || !children.has(childRunId) || !Number.isSafeInteger(number) || (number as number) <= 0
93
+ || typeof url !== 'string' || PR_URL.exec(url)?.[1] !== String(number)) continue;
94
+ return { number: number as number, url, childRunId };
95
+ }
96
+ return undefined;
97
+ }
98
+
99
+ /** 순수 — 카드 런의 골 id · PR. PR 은 호스트 → 자식(나중 자식 먼저) → 호스트 `pr-terminal` → job-finished 순으로 처음 찾은 것. */
80
100
  export function bindCardEvidence(card: Pick<TaskCard, 'runId'>, snapshot: CardRunSnapshot): CardRunEvidence {
81
101
  if (!card.runId || !snapshot.host) return { ledgerFound: false };
82
102
  const children = podChildRunIds(snapshot.host, card.runId).reverse();
@@ -88,6 +108,10 @@ export function bindCardEvidence(card: Pick<TaskCard, 'runId'>, snapshot: CardRu
88
108
  const found = entries ? lastPr(entries) : undefined;
89
109
  if (found) { pr = found; childRunId = id; }
90
110
  }
111
+ if (!pr) {
112
+ const terminal = podTerminalPr(snapshot.host, children);
113
+ if (terminal) { pr = { number: terminal.number, url: terminal.url }; childRunId = terminal.childRunId; }
114
+ }
91
115
  for (const id of children) {
92
116
  if (pr) break;
93
117
  const finish = [...(snapshot.podFinishes ?? [])].reverse().find((row) => row.childRunId === id && PR_URL.test(row.prUrl));
@@ -19,6 +19,7 @@ export interface GreenSweepPr {
19
19
  state: string;
20
20
  mergeSha?: string;
21
21
  url?: string;
22
+ viaTrain?: { integrationPr: number };
22
23
  }
23
24
  export interface GreenSweepDecision {
24
25
  cell: string;
@@ -112,7 +113,8 @@ export function decideGreenSweep(input: {
112
113
  const { item, candidate, pr } = input;
113
114
  const mergeSha = pr?.mergeSha && /^[a-f0-9]{40}$/i.test(pr.mergeSha) ? pr.mergeSha : null;
114
115
  const result = (verdict: GreenSweepVerdict, reason: string): GreenSweepDecision => {
115
- const evidence = `GREEN-FROM-LEDGER: PR #${candidate.pr}${mergeSha ? ` merged ${mergeSha}` : ''} · ${verdict} · ${reason}`;
116
+ const landing = pr?.viaTrain ? ` via train #${pr.viaTrain.integrationPr}` : '';
117
+ const evidence = `GREEN-FROM-LEDGER: PR #${candidate.pr}${landing}${mergeSha ? ` merged ${mergeSha}` : ''} · ${verdict} · ${reason}`;
116
118
  return { cell: item.id, pr: candidate.pr, mergeSha, source: candidate.source, verdict, reason,
117
119
  evidence, existingEvidence: item.evidence ?? '', plannedEvidence: appendGreenSweepEvidence(item.evidence, evidence) };
118
120
  };
@@ -122,6 +124,9 @@ export function decideGreenSweep(input: {
122
124
  if (input.repositoryMatches === false) return result('skip', 'repository-mismatch');
123
125
  if (input.repositoryMatches !== true) return result('record-only', 'repository-unreadable');
124
126
  if (pr.state !== 'MERGED') return result('skip', `pr-${pr.state.toLowerCase()}`);
127
+ if (pr.viaTrain && (candidate.card?.trainLanding?.componentPr !== candidate.pr
128
+ || candidate.card.trainLanding.integrationPr !== pr.viaTrain.integrationPr
129
+ || candidate.card.trainLanding.mergeSha !== pr.mergeSha)) return result('skip', 'train-binding-mismatch');
125
130
  if (!mergeSha) return result('skip', 'merge-sha-unreadable');
126
131
  if (input.ancestor === null) return result('record-only', 'origin-main-ref-unverified');
127
132
  if (!input.ancestor) return result('skip', 'merge-sha-not-on-origin-main');
@@ -159,8 +164,8 @@ export function decideGreenSweep(input: {
159
164
  if (typeof card.pr === 'object' && pr.url && card.pr.url
160
165
  && card.pr.url.replace(/\/+$/, '') !== pr.url.replace(/\/+$/, ''))
161
166
  return result('record-only', 'card-pr-url-mismatch');
162
- if (card.prTerminal?.state === 'CLOSED') return result('record-only', 'card-terminal-conflict');
163
- return result('green', card.postLand?.outcome === 'complete' ? 'bound-card-complete' : 'bound-card-merged');
167
+ if (card.prTerminal?.state === 'CLOSED' && !pr.viaTrain) return result('record-only', 'card-terminal-conflict');
168
+ return result('green', card.postLand?.outcome === 'complete' ? 'bound-card-complete' : pr.viaTrain ? 'bound-card-train-merged' : 'bound-card-merged');
164
169
  }
165
170
 
166
171
  /** Every candidate emits one structured decision, including refusals. */
@@ -24,6 +24,8 @@ export interface TaskJudgeInput {
24
24
  stopReason?: SupervisorStopReason;
25
25
  prState?: 'OPEN' | 'MERGED' | 'CLOSED';
26
26
  pr?: string | number;
27
+ /** Complete PR target paths when measured. Unknown is omitted, never treated as zero code diff. */
28
+ prTargetPaths?: readonly string[];
27
29
  /** `self review --json` 판정. 관측 못 했으면 비운다(«통과»로 읽지 않는다). */
28
30
  review?: 'pass' | 'fail';
29
31
  mustFix?: readonly string[];
@@ -36,6 +38,42 @@ export interface TaskJudgeInput {
36
38
  evidence?: { ok: boolean; ref: string };
37
39
  /** Only classified terminal evidence; an absent input preserves the existing stop-reason table. */
38
40
  terminalRun?: { kind: typeof STOP_CLASS_POD_FAILURE | typeof STOP_CLASS_NO_LAUNCH; reason: string; hasPr: boolean; hasHarvestBranch: boolean };
41
+ /**
42
+ * 같은 칸(checklistId)의 앞 런들 — 재발사 계열 수를 고르기 «전»에 받는 «선례»(RFC adaptive-graph-ops §9.10).
43
+ * 없으면 지금 표 그대로(입력이 비어도 동작한다 — RUN-TAG-REWORK 가 원장에 서명을 달면 여기 입력이 된다).
44
+ */
45
+ precedents?: readonly TaskPrecedent[];
46
+ /** 판정 관측 훅 — `task-agent.judge` 이벤트에 precedent {matched, priorRunId, signature} 를 싣는다. 없으면 관측 없이 종전 동작. */
47
+ observe?: (event: 'task-agent.judge', data: { precedent: { matched: boolean; priorRunId?: string; signature?: string } }) => void;
48
+ }
49
+
50
+ /** 같은 칸의 앞 런 한 건 — 결말(outcome)과 must-fix 서명. `outcome: 'alternative-failed'` 는 «대안도 같은 서명으로 실패했다»는 예약 결말이다. */
51
+ export interface TaskPrecedent {
52
+ runId: string;
53
+ outcome: string;
54
+ signature: string;
55
+ }
56
+
57
+ /** must-fix 서명의 분류 축(남은 must-fix 의 성격) — 해시에 함께 박는다. */
58
+ export const MUST_FIX_CLASSIFICATION = 'implementation-deficit';
59
+
60
+ /**
61
+ * 남은 must-fix 원문을 정규화(공백 접기·trim·정렬)한 해시 ⊕ 분류 — 같은 칸의 앞 런과 비교하는 «서명».
62
+ * must-fix 가 비면 서명도 없다(선례 비교 없음).
63
+ */
64
+ export function mustFixSignature(mustFix?: readonly string[]): string | undefined {
65
+ const normalized = [...(mustFix ?? [])]
66
+ .map(fix => (typeof fix === 'string' ? fix.trim().replace(/\s+/gu, ' ') : ''))
67
+ .filter(Boolean)
68
+ .sort();
69
+ if (!normalized.length) return undefined;
70
+ let hash = 0x811c9dc5;
71
+ const text = `${MUST_FIX_CLASSIFICATION}:${JSON.stringify(normalized)}`;
72
+ for (let i = 0; i < text.length; i++) {
73
+ hash ^= text.charCodeAt(i);
74
+ hash = Math.imul(hash, 0x01000193) >>> 0;
75
+ }
76
+ return `fnv1a-${hash.toString(16).padStart(8, '0')}`;
39
77
  }
40
78
 
41
79
  export interface TaskJudgement {
@@ -83,12 +121,22 @@ const RETRY_MOVE_OF_VARIANT: Record<RetryVariant, LiveRetryMove> = {
83
121
  alternative: 'alternative',
84
122
  };
85
123
 
124
+ /** Only a measured complete file list can establish zero implementation target diff. */
125
+ export function isGoalOnlyPr(paths: readonly string[] | undefined): boolean {
126
+ return paths !== undefined && paths.every((path) => /^docs\/goals\/[^/]+(?:\/.*)?$/.test(path));
127
+ }
128
+
86
129
  /** 실행부 `retry` 가 어느 수인가 — 갈래 없는 재발사(리뷰 fail 의 must-fix 재발사)는 «좁혀 재발사»다. */
87
130
  export function retryMoveOf(variant?: RetryVariant): LiveRetryMove {
88
131
  return RETRY_MOVE_OF_VARIANT[variant ?? 'narrow'];
89
132
  }
90
133
 
91
134
  function base(input: TaskJudgeInput): Omit<TaskJudgement, 'executorKind'> {
135
+ // A goal document is a launch artifact. Its PR cannot prove implementation progress,
136
+ // even when the PR has merged. Waiting also prevents the same goal's live retry.
137
+ if (input.pr && isGoalOnlyPr(input.prTargetPaths)) {
138
+ return { move: 'wait', stage: 'escalated', reason: `goal-only-pr — PR ${input.pr} target diff 0; 같은 골 재큐 중지·구현 근거 필요` };
139
+ }
92
140
  if (input.deliveryEvidence) return input.deliveryEvidence.ok
93
141
  ? { move: 'propose-green', stage: 'closing', reason: `전달 근거 확인: ${input.deliveryEvidence.files.join(', ')}` }
94
142
  : { move: 'wait', stage: 'waiting', reason: input.deliveryEvidence.reason };
@@ -139,16 +187,34 @@ function base(input: TaskJudgeInput): Omit<TaskJudgement, 'executorKind'> {
139
187
  /** 재발사 계열 — 대안(alternative)이 실패한 «같은 실패 흐름»에 속하는 수. */
140
188
  const RETRY_FAMILY: ReadonlySet<TaskMove> = new Set<TaskMove>(['narrow-relaunch', 'wait-retry', 'salvage-relaunch']);
141
189
 
190
+ /**
191
+ * 선례가 «같은 수로 재발사»를 막는 수 — narrow·salvage·그 자신(alternative).
192
+ * 대기 후 재시도(wait-retry)는 «같은 수로 재발사»가 아니므로 선례 승격에서는 제외.
193
+ */
194
+ const PRECEDENT_RELAUNCH_FAMILY: ReadonlySet<TaskMove> = new Set<TaskMove>(['narrow-relaunch', 'salvage-relaunch']);
195
+
142
196
  /**
143
197
  * 종료 어휘·관측에서 다음 한 수를 고른다. 같은 수 2회 실패 → 다른 수 → 그것도 실패 → 결정 카드.
144
198
  *
145
199
  * ⭐ 새 관측이 이긴다(사후 리뷰 must-fix · #24453): 병합된 PR(propose-green)·종료 미관측(wait)·표 밖 어휘(decision-card)는
146
200
  * 실패 셈과 무관하게 그대로 간다. 「대안도 실패 → 결정 카드」 승격은 지금 수가 같은 실패 흐름일 때만 —
147
201
  * 재발사 계열이거나, 그 수 자신이 이미 같은 수 한도만큼 실패했을 때다.
202
+ *
203
+ * ⭐ 선례(RFC adaptive-graph-ops §9.10): 이번 런의 must-fix 서명이 앞 런 서명과 같으면 같은 수로 재발사하지 않는다 —
204
+ * narrow/salvage → alternative, alternative 자신(또는 선례 결말이 `alternative-failed`)이면 결정 카드.
205
+ * 선례가 없으면 지금 표 그대로.
148
206
  */
149
207
  export function judgeNextMove(input: TaskJudgeInput): TaskJudgement {
150
208
  const failures = input.failures ?? {};
151
209
  let judged = base(input);
210
+ const signature = mustFixSignature(input.mustFix);
211
+ // 같은 서명 일치 «전체»를 스캔한다 — `alternative-failed` 유무는 목록 어느 위치에 있든 먼저 판정한다(anyMatch 우선, 순서 무관).
212
+ const sameSignature = signature !== undefined
213
+ ? (input.precedents ?? []).filter(prec => typeof prec?.signature === 'string' && prec.signature === signature
214
+ && typeof prec?.runId === 'string' && prec.runId !== '')
215
+ : [];
216
+ const matched = sameSignature[0];
217
+ input.observe?.('task-agent.judge', { precedent: { matched: matched !== undefined, priorRunId: matched?.runId, signature } });
152
218
  const escalatable = judged.move !== 'wait' && judged.move !== 'decision-card' && judged.move !== 'propose-green';
153
219
  const exhausted = escalatable && (failures[judged.move] ?? 0) >= SAME_MOVE_FAILURE_LIMIT;
154
220
  const inFailingFlow = RETRY_FAMILY.has(judged.move) || exhausted;
@@ -157,6 +223,16 @@ export function judgeNextMove(input: TaskJudgeInput): TaskJudgement {
157
223
  } else if (exhausted) {
158
224
  judged = { move: 'alternative', stage: 'repairing', reason: `같은 수 ${SAME_MOVE_FAILURE_LIMIT}회 실패 — 다른 수 선택 (${judged.move})` };
159
225
  }
226
+ // 선례 승격 — 실패 승격 다음: 이번 수가 같은 서명 앞 런의 수와 겹치지 않게 한다(같은 수로 재발사 차단).
227
+ if (matched !== undefined && (PRECEDENT_RELAUNCH_FAMILY.has(judged.move) || judged.move === 'alternative')) {
228
+ if (judged.move === 'alternative' || sameSignature.some(prec => prec.outcome === 'alternative-failed')) {
229
+ judged = { move: 'decision-card', stage: 'escalated',
230
+ reason: `같은 must-fix 서명 선례 ${matched.runId} — 대안도 같은 서명으로 실패 — 사람 결정 (서명 ${signature})` };
231
+ } else {
232
+ judged = { move: 'alternative', stage: 'repairing',
233
+ reason: `같은 must-fix 서명 선례 ${matched.runId} — 같은 수로 재발사하지 않고 다른 수 선택 (서명 ${signature})` };
234
+ }
235
+ }
160
236
  const executorKind = EXECUTOR_KIND[judged.move];
161
237
  const executorVariant = EXECUTOR_VARIANT[judged.move];
162
238
  if (!executorKind) return judged;
@@ -0,0 +1,79 @@
1
+ /** TA-LAND-AFTER-REVIEW: a configured queue adapter after exact-head review and remote changed gate. */
2
+ import { spawn } from 'node:child_process';
3
+ import { mkdirSync, readFileSync } from 'node:fs';
4
+ import { dirname, isAbsolute, join } from 'node:path';
5
+ import { randomUUID } from 'node:crypto';
6
+ import { parseReviewResultOutput } from './review-result-capture.js';
7
+
8
+ type CommandResult = { status: number; stdout: string; stderr: string };
9
+ export interface QueueLandingInput {
10
+ card: string; pr: number; head: string; cwd: string; statePath: string; reviewResult: string;
11
+ command: string; remote: string; entry: string; configDir: string;
12
+ }
13
+ export interface QueueLandingDeps {
14
+ run?: (command: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv) => Promise<CommandResult>;
15
+ read?: (path: string) => string;
16
+ }
17
+
18
+ async function run(command: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv): Promise<CommandResult> {
19
+ return new Promise((resolve, reject) => {
20
+ const child = spawn(command, args, { cwd, env: env ?? process.env, stdio: ['ignore', 'pipe', 'pipe'] });
21
+ let stdout = ''; let stderr = '';
22
+ child.stdout.on('data', (chunk: Buffer) => { stdout = (stdout + chunk.toString()).slice(-4000); });
23
+ child.stderr.on('data', (chunk: Buffer) => { stderr = (stderr + chunk.toString()).slice(-4000); });
24
+ child.once('error', reject);
25
+ child.once('close', (code) => resolve({ status: code ?? 1, stdout, stderr }));
26
+ });
27
+ }
28
+
29
+ /** The adapter owns no merge authority. Its only successful result is a confirmed queue row. */
30
+ export async function runQueuedLanding(input: QueueLandingInput, deps: QueueLandingDeps = {}): Promise<CommandResult> {
31
+ const invoke = deps.run ?? run;
32
+ const read = deps.read ?? ((path: string) => readFileSync(path, 'utf8'));
33
+ const fail = (stage: string, reason: string): CommandResult => ({ status: 1, stdout: '', stderr: `${stage}: ${reason.slice(-500)}` });
34
+ if (!/^[a-f0-9]{40}$/i.test(input.head) || !Number.isSafeInteger(input.pr) || input.pr < 1) return fail('input', 'invalid PR/head');
35
+ if (!isAbsolute(input.command) || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(input.remote)) return fail('config', 'land queue command/remote invalid');
36
+ let review: ReturnType<typeof parseReviewResultOutput>;
37
+ try { review = parseReviewResultOutput(read(input.reviewResult)); }
38
+ catch (error) { return fail('review', String(error)); }
39
+ if (!review || review.pr !== input.pr || review.head?.toLowerCase() !== input.head.toLowerCase()
40
+ || review.reviewed !== true || !['pass', 'warn'].includes(review.verdict ?? '') || review.mustFix !== 0 || review.error) {
41
+ return fail('review', `exact head #${input.pr} ${input.head.slice(0, 12)} PASS/WARN mf0 not proven`);
42
+ }
43
+ const git = async (args: string[]) => invoke(process.execPath, [input.entry, '--config-dir', input.configDir, 'git', ...args], input.cwd);
44
+ const fetched = await git(['fetch', '--quiet', 'origin', 'main']);
45
+ if (fetched.status !== 0) return fail('base-fetch', fetched.stderr || fetched.stdout || `exit ${fetched.status}`);
46
+ const base = await git(['rev-parse', '--verify', 'origin/main']);
47
+ const baseHead = base.stdout.trim().split(/\s+/)[0];
48
+ if (base.status !== 0 || !/^[a-f0-9]{40}$/i.test(baseHead ?? '')) return fail('base', 'origin/main commit unmeasured');
49
+ const local = await git(['rev-parse', '--verify', 'HEAD']);
50
+ if (local.status !== 0 || local.stdout.trim().split(/\s+/)[0]?.toLowerCase() !== input.head.toLowerCase()) return fail('head', 'queue worktree HEAD differs from PR head');
51
+ const safeCard = input.card.replace(/[^A-Za-z0-9._-]/g, '_');
52
+ const artifact = join(dirname(input.statePath), 'land-queue-gates', `${safeCard}-${input.pr}-${input.head.slice(0, 12)}-${randomUUID()}`);
53
+ mkdirSync(artifact, { recursive: true });
54
+ const gate = await invoke(process.execPath, [input.entry, '--config-dir', input.configDir,
55
+ 'self', 'gate', '--changed', '--base', baseHead!, '--remote', input.remote, '--shards', '4', '--artifact-dir', artifact], input.cwd);
56
+ if (gate.status !== 0) return fail('remote-changed-gate', gate.stderr || gate.stdout || `exit ${gate.status}`);
57
+ let summary: Record<string, unknown>;
58
+ try { summary = JSON.parse(read(join(artifact, 'summary.json'))) as Record<string, unknown>; }
59
+ catch (error) { return fail('remote-changed-gate', `summary unreadable: ${String(error)}`); }
60
+ if (summary.head40 !== input.head || summary.base40 !== baseHead || summary.remoteHost !== input.remote
61
+ || summary.verdict !== 'passed' || summary.exitCode !== 0 || summary.introduced !== 0
62
+ || summary.unknown !== 0 || summary.preconditionUnmet !== 0) {
63
+ return fail('remote-changed-gate', 'summary does not prove this head/base/remote passed with zero unknown');
64
+ }
65
+ const fresh = await invoke('gh', ['pr', 'view', String(input.pr), '--json', 'headRefOid,state,isDraft'], input.cwd);
66
+ let latest: { headRefOid?: unknown; state?: unknown; isDraft?: unknown };
67
+ try { latest = JSON.parse(fresh.stdout) as typeof latest; }
68
+ catch { return fail('pr-head', `current PR state unreadable: ${fresh.stderr || fresh.stdout || fresh.status}`); }
69
+ if (fresh.status !== 0 || latest.state !== 'OPEN' || latest.isDraft !== false
70
+ || typeof latest.headRefOid !== 'string' || latest.headRefOid.toLowerCase() !== input.head.toLowerCase()) {
71
+ return fail('pr-head', `PR #${input.pr} changed after gate or is not ready`);
72
+ }
73
+ const enrolled = await invoke(input.command, [String(input.pr), input.cwd, '--review', input.reviewResult, '--expected-head', input.head], input.cwd,
74
+ { ...process.env, LAND_RR_DIR: dirname(input.reviewResult) });
75
+ if (enrolled.status !== 0 || !new RegExp(`^OK #${input.pr} head=${input.head.slice(0, 12)}(?:\\s|$)`, 'm').test(enrolled.stdout)) {
76
+ return fail('land-enqueue-refused', enrolled.stdout || enrolled.stderr || `exit ${enrolled.status}`);
77
+ }
78
+ return { status: 0, stdout: `queued #${input.pr} head ${input.head.slice(0, 12)} gate ${artifact} · ${enrolled.stdout.slice(-250)}`, stderr: '' };
79
+ }
@@ -6,7 +6,7 @@
6
6
  * TA-REVIEW-RESULT-CAPTURE — 자식 stdout(`--json`)은 결과 파일로 받고, 자식 완료 뒤 해당 카드만 회수·재판정한다.
7
7
  * 회수한 pass 는 그 틱의 판단부·land 관문 입력(`selfReview`)이 될 뿐 land 판정 로직은 그대로다.
8
8
  * - `propose-green`: 카드에 green «제안»(`greenProposal`)만 적는다 — 체크리스트는 손대지 않는다.
9
- * - `propose-land`: 카드·현재 머리의 self review 통과(pass «또는» warn ⊕ must-fix 0 · TA-LAND-WARN-MUSTFIX0)·non-draft 를 확인하고 기존 `pr land` 를 머리 고정으로 한 번 부른다.
9
+ * - `propose-land`: 카드·현재 머리의 self review 통과(pass «또는» warn ⊕ must-fix 0 · TA-LAND-WARN-MUSTFIX0)·non-draft 를 확인한다. 큐 설정이 있으면 원격 changed gate 뒤 착지 줄에 등록하고, 없으면 기존 `pr land` 를 머리 고정으로 한 번 부른다.
10
10
  * - 사다리 R4: `narrow-relaunch` · `wait-retry` · `salvage-relaunch` · `alternative` 도 허용 목록 어휘다 — 실제 발사는 실행부
11
11
  * `executeNextAction`(`actions.ts`)이 «목록 ⊕ 같은 수 2회 상한 ⊕ 회당 1건 ⊕ 부하 관문»을 모두 넘을 때만 한다.
12
12
  * - `decision-card`: 막힌 과제를 «근거(서명 · 화면 · must-fix)» 붙은 결정 카드로 올린다 — 근거가 하나도 없으면 카드를 올리지 않는다.
@@ -28,6 +28,7 @@ import { decisionCardGrounds, decisionRaiseArgs, type DecisionCardEvidence, type
28
28
  import { pendingReviewResults, reviewResultPath, TA_REVIEW_COMPLETION_CARD_ENV, TA_REVIEW_COMPLETION_RESULT_ENV, TA_REVIEW_COMPLETION_STATE_ENV } from './review-result-capture.js';
29
29
  import { buildPriorFixContext, PRIOR_FIX_SCOPE_LINE, priorFixBlock, priorFixObservation, type PriorDiffReader, type PriorFixContext } from './review-prior-fix.js';
30
30
  import { createLandWorktree, localBranch, localHead, observeLandWorktree, type LandWorktree, type LandWorktreeFailure, type LandWorktreeInput, type LandWorktreeRemoval } from './land-worktree.js';
31
+ import { runQueuedLanding, type QueueLandingInput } from './land-queue.js';
31
32
 
32
33
  export const TASK_AGENT_LIVE_MOVES = ['review', 'propose-green', 'propose-land', 'decision-card', ...LIVE_RETRY_MOVES] as const;
33
34
  export type TaskAgentLiveMove = typeof TASK_AGENT_LIVE_MOVES[number];
@@ -90,6 +91,9 @@ export interface LiveMoveDeps {
90
91
  log?: (category: string, event: string, data: Record<string, unknown>) => void;
91
92
  /** TA-LAND-WORKTREE — cwd HEAD 읽기 · PR 머리 임시 워크트리 만들기(시험 주입 · 기본 = git). */
92
93
  landWorktree?: { localHead?: (cwd: string) => string | null; localBranch?: (cwd: string) => string | null; create?: (input: LandWorktreeInput) => Promise<LandWorktree | LandWorktreeFailure> };
94
+ /** TA-LAND-AFTER-REVIEW — injected queue adapter; absent uses configured command after a remote changed gate. */
95
+ queueLanding?: (input: QueueLandingInput) => Promise<{ status: number; stdout: string; stderr?: string }>;
96
+ landQueueConfig?: { command: string; remote: string } | null;
93
97
  }
94
98
 
95
99
  /** `executed` = 부작용을 실제로 냈다(리뷰를 띄웠다 · 제안을 적었다). ok 이지만 이미 한 수(같은 머리·이미 제안)면 false. */
@@ -101,6 +105,8 @@ export interface LiveMoveResult {
101
105
  resultPath?: string;
102
106
  /** TA-LAND-RETRY-ON-INFRA — 실행한 land 의 그 머리 몇 번째 시도인가 · 실패면 갈래(infra|judgement|base-stale)·사유·재시도 가능 여부. */
103
107
  landAttempt?: { attempt: number; class?: LandFailureClass; reason?: string; retryAllowed?: boolean };
108
+ /** A queue accepted this head. Merge confirmation belongs to the later train receipt. */
109
+ queued?: boolean;
104
110
  }
105
111
 
106
112
  export interface PrHeadView { head: string; state: string; branch?: string; url?: string }
@@ -543,10 +549,11 @@ export const LAND_RETRY_ON_INFRA_EVENT = 'land-retry-on-infra';
543
549
 
544
550
  const landedCycles = new Set<string>();
545
551
 
546
- /** `propose-land` — only a passing self review (pass or warn, with must-fix 0) of this exact OPEN, non-draft head may invoke pr land. */
552
+ /** `propose-land` — only a passing self review (pass or warn, with must-fix 0) of this exact OPEN, non-draft head may enqueue or invoke pr land. */
547
553
  export async function executeLiveLand(
548
554
  card: TaskCard | undefined, pr: number | undefined,
549
555
  ctx: { runId?: string | null; cycleId?: string; cwd?: string; produced?: { headCommit?: string; branch?: string; prUrl?: string }; review?: { verdict: 'pass' | 'warn' | 'fail'; head: string; /** TA-LAND-WARN-MUSTFIX0 — `false` 면 리뷰가 실제로 안 돌았다 → land 거부. 슈퍼바이저 입력은 reviewed 리뷰로만 만들어져 칸이 없다. */ reviewed?: boolean };
556
+ /** Exact bytes consumed by the queue's own review check; no path means queue mode cannot proceed. */ reviewResultPath?: string;
550
557
  /** TA-REJUDGE-ON-HEAD — 겹침 증거 파일(있으면 land 에 넘길 뿐 · 판정은 그대로). */ overlapEvidence?: string;
551
558
  /** REJUDGE base-stale — 증거의 재게이트를 요청한 시각 · 그 앞의 base-stale 시도는 소비됨(`openLandAttempts`). */ gateAt?: string },
552
559
  deps: LiveMoveDeps = {},
@@ -584,6 +591,10 @@ export async function executeLiveLand(
584
591
  const mustFixCount = (ctx.review as { mustFixCount?: unknown }).mustFixCount;
585
592
  if (typeof mustFixCount !== 'number' || !Number.isSafeInteger(mustFixCount) || mustFixCount < 0) return reject(card.id, `PR #${pr} review-must-fix-unknown`, reviewRepo);
586
593
  if (mustFixCount > 0) return reject(card.id, `PR #${pr} review-warn-with-must-fix: pass carries ${mustFixCount} must-fix`, reviewRepo);
594
+ const queueConfig = deps.landQueueConfig === undefined ? getUserConfig().taskAgent?.landQueue : deps.landQueueConfig;
595
+ if (queueConfig && (!isAbsolute(queueConfig.command) || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(queueConfig.remote)))
596
+ return reject(card.id, `PR #${pr} land queue command/remote invalid`, reviewRepo);
597
+ if (queueConfig && !ctx.reviewResultPath) return reject(card.id, `PR #${pr} queue review result path missing`, reviewRepo);
587
598
  const cycle = ctx.cycleId ?? ctx.runId;
588
599
  if (cycle && landedCycles.has(cycle)) return reject(card.id, `cycle ${cycle} already landed — stays shadow`, reviewRepo);
589
600
  const path = deps.statePath ?? taskAgentStatePath();
@@ -695,11 +706,16 @@ export async function executeLiveLand(
695
706
  let failure: LandFailureClassification | undefined;
696
707
  try {
697
708
  // The CLI rechecks the pinned PR/head immediately before merge, after its own gates and freeze admission.
698
- const outcome = overlapEvidence
699
- ? await (deps.land ?? defaultLand)(pr, view.head, landCwd, { overlapEvidence })
700
- : await (deps.land ?? defaultLand)(pr, view.head, landCwd);
709
+ const outcome = queueConfig
710
+ ? await (deps.queueLanding ?? runQueuedLanding)({ card: card.id, pr, head: view.head, cwd: landCwd, statePath: path,
711
+ reviewResult: ctx.reviewResultPath!, command: queueConfig.command, remote: queueConfig.remote,
712
+ entry: (await import('../cli/tasks-cli.js')).ELANOUS_CLI_ENTRY,
713
+ configDir: (await import('../elanous-config-dir.js')).getElanousConfigDirOverride() ?? (await import('../instance/resolve.js')).effectiveInstanceRoot() })
714
+ : overlapEvidence
715
+ ? await (deps.land ?? defaultLand)(pr, view.head, landCwd, { overlapEvidence })
716
+ : await (deps.land ?? defaultLand)(pr, view.head, landCwd);
701
717
  ok = outcome.status === 0;
702
- detail = (ok ? outcome.stdout || `land merged #${pr} head ${view.head.slice(0, 12)}` : outcome.stderr || outcome.stdout || `exit ${outcome.status}`).slice(-300);
718
+ detail = (ok ? outcome.stdout || `${queueConfig ? 'queued' : 'land merged'} #${pr} head ${view.head.slice(0, 12)}` : outcome.stderr || outcome.stdout || `exit ${outcome.status}`).slice(-300);
703
719
  if (!ok) failure = classifyLandFailure(outcome);
704
720
  } catch (error) {
705
721
  detail = (error instanceof Error ? error.message : String(error)).slice(-300);
@@ -708,8 +724,13 @@ export async function executeLiveLand(
708
724
  const retryAllowed = failure?.class === 'infra' && attempt < LAND_ATTEMPTS_PER_HEAD_ON_INFRA;
709
725
  // 인프라 실패로 재시도가 남으면 주기 표시도 푼다 — 같은 주기 id(재판정 틱의 `rejudge:<card>:<head>`)가 그 한 번을 막지 않게.
710
726
  if (retryAllowed && cycle) landedCycles.delete(cycle);
711
- if (worktree) {
712
- // 성공이든 실패든 걷는다.
727
+ if (worktree && queueConfig && ok) {
728
+ // The queue row pins this exact path until the train consumes it. Removing it here
729
+ // would turn a successful enqueue into a guaranteed missing-tree landing failure.
730
+ observeLandWorktree({ card: card.id, pr, head: view.head, created: worktree.created ?? null,
731
+ removed: false, reason: 'queued — train owns this exact-head worktree until its receipt' }, deps.log);
732
+ } else if (worktree) {
733
+ // Direct land and rejected queue attempts no longer need the temporary checkout.
713
734
  let removal: LandWorktreeRemoval;
714
735
  try { removal = worktree.cleanup(); } catch (error) { removal = { removed: false, reason: String(error).slice(-200) }; }
715
736
  observeLandWorktree({ card: card.id, pr, head: view.head, created: worktree.created ?? null, removed: removal.removed, ...(removal.branchRemoved !== undefined ? { branchRemoved: removal.branchRemoved } : {}),
@@ -746,7 +767,7 @@ export async function executeLiveLand(
746
767
  return observe(deps, withRepo({ kind, card: card.id, ok: false, executed: true, landAttempt,
747
768
  detail: `land ${ok ? 'succeeded' : 'failed'} but card update failed: ${String(error).slice(-230)}` }));
748
769
  }
749
- return observe(deps, withRepo({ kind, card: card.id, ok, executed: true, detail, landAttempt }));
770
+ return observe(deps, withRepo({ kind, card: card.id, ok, executed: true, detail, landAttempt, ...(queueConfig && ok ? { queued: true } : {}) }));
750
771
  }
751
772
 
752
773
  /** `propose-green` — 비지 않은 근거가 있을 때만 카드에 제안을 적는다(한 번). 체크리스트는 쓰지 않는다. */
@@ -2,6 +2,7 @@ import { debug } from '../debug/log.js';
2
2
  import { listChecklist, setItemIfSnapshot, type Checklist } from '../release-loop/checklist.js';
3
3
  import { judgeLandedCell, parseJudgeSignals, type GreenVerdict } from '../release-loop/landed-to-green.js';
4
4
  import { cardPrNumber, readTaskAgentState, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
5
+ import { isGoalOnlyPr } from './judge.js';
5
6
 
6
7
  export interface LandedTaskPr { number: number; url: string; headRefOid: string; state: string; baseRefName: string; mergedAt: string; files?: Array<{ path: string }> }
7
8
  export interface PostlandDeps {
@@ -32,6 +33,10 @@ export function candidateMergedTaskCells(number: number, statePath = taskAgentSt
32
33
  export function closeMergedTaskCard(pr: LandedTaskPr, cwd: string, deps: PostlandDeps): string | null {
33
34
  const log = deps.log ?? debug.log.bind(debug);
34
35
  if (pr.state !== 'MERGED' || pr.baseRefName !== 'main' || !/^[a-f0-9]{40}$/i.test(pr.headRefOid) || !pr.url) return null;
36
+ if (isGoalOnlyPr(pr.files?.map((file) => file.path))) {
37
+ log('task-agent', 'postland-card-skipped', { pr: pr.number, reason: 'goal-only-pr', targetDiff: 0 });
38
+ return null;
39
+ }
35
40
  const path = deps.statePath ?? taskAgentStatePath();
36
41
  const tasks = readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(path).tasks ?? {};
37
42
  const cards = Object.values(tasks).filter((card) => card.taLand && card.checklistId && cardPrNumber(card) === pr.number