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
@@ -11,6 +11,7 @@ import { runSelfGateCli, type SelfGateCliOptions, type SelfGateCliResult } from
11
11
  import { dispatchHeavyCheck, isValidGateHost, type DispatchDeps, type DispatchOptions } from '../self-implement/gate-remote.js';
12
12
  import { latestPublishedPreviousVersion } from '../../scripts/release-loop/unattended-release.js';
13
13
  import { baseVersion, isReleaseVersion } from '../../scripts/release-loop/release-version.js';
14
+ import { executeTuiNodeCheck, type ExecutedTuiCheck } from '../../scripts/release-loop/tui-node-checks.js';
14
15
 
15
16
  export const LIGHT_RC_ALWAYS_FILE = 'release/light-rc-always.txt';
16
17
  export const LIGHT_RC_DEFAULT_SHARDS = 4;
@@ -28,9 +29,14 @@ export interface LightRcOptions {
28
29
  /** Run on this machine (the remote child is re-invoked with it). */
29
30
  local?: boolean;
30
31
  shards?: number;
32
+ /** OP FU — pass `--fixed-shard-distribution` to self gate (sorted round-robin into `shards`, no RSS pre-measurement).
33
+ * Opt-in; absent = the measured planner, unchanged. Also carried to the remote child. */
34
+ fixedShardDistribution?: boolean;
31
35
  /** Release ledger root for the previous-version lookup (release run's deps.ledgerRoot). */
32
36
  ledgerRoot?: string;
33
37
  log?: (line: string) => void;
38
+ /** Rehearsal-only TUI screen check; other light-rc callers keep their current defaults. */
39
+ rehearsalTui?: boolean;
34
40
  }
35
41
 
36
42
  export interface LightRcResult {
@@ -57,6 +63,7 @@ export interface LightRcResult {
57
63
  /** LIGHT-RC-MEASURE ③ — why the gate produced no measurement (e.g. `shard-2`); null = it measured. Carried in the
58
64
  * JSON so the reason reaches the caller even when the remote child's human lines (stderr) do not. */
59
65
  unmeasured: string | null;
66
+ rehearsalTui?: ExecutedTuiCheck;
60
67
  }
61
68
 
62
69
  export interface LightRcDeps {
@@ -68,6 +75,7 @@ export interface LightRcDeps {
68
75
  dispatch?: (opts: DispatchOptions, deps?: DispatchDeps) => Promise<number>;
69
76
  /** Extra dispatch deps (runner · settings) — tests drive the real dispatch with a fake host. */
70
77
  dispatchDeps?: Omit<DispatchDeps, 'write'>;
78
+ tuiCheck?: typeof executeTuiNodeCheck;
71
79
  /** Detached checkout of `sha` for a local run whose tree is not at the measured commit (default: git worktree add
72
80
  * --detach in a temp dir ⊕ bun install); `cleanup` removes it. */
73
81
  checkout?: (sha: string, repo: string, log: (line: string) => void) => { dir: string; cleanup: () => void };
@@ -180,13 +188,21 @@ export async function runLightRc(version: string, opts: LightRcOptions = {}, dep
180
188
  let alwaysInclude = readList(cwd);
181
189
 
182
190
  let local: SelfGateCliResult | undefined;
183
- const runLocal = () => {
191
+ let localTui: ExecutedTuiCheck | undefined;
192
+ const runLocal = async () => {
184
193
  // ① The gate scopes by its tree's HEAD — so a tree that is not at the measured commit runs in a detached checkout of it.
185
194
  const checkout = worktreeHead === measuredCommit ? undefined : (deps.checkout ?? defaultCheckout)(measuredCommit, cwd, log);
186
195
  try {
187
196
  const dir = checkout?.dir ?? cwd;
188
197
  if (checkout) alwaysInclude = readList(dir);
189
- local = (deps.runGate ?? runSelfGateCli)(dir, { base, shards, alwaysInclude, includeImporterTests: true });
198
+ local = (deps.runGate ?? runSelfGateCli)(dir, { base, shards, ...(opts.fixedShardDistribution ? { fixedShardDistribution: true } : {}), alwaysInclude, includeImporterTests: true });
199
+ if (opts.rehearsalTui) {
200
+ const command = async (cmd: string, args: string[], tree: string, limitMs?: number) => {
201
+ const run = spawnSync(cmd, args, { cwd: tree, encoding: 'utf8', timeout: limitMs });
202
+ return { rc: run.status ?? 2, output: `${run.stdout ?? ''}\n${run.stderr ?? ''}` };
203
+ };
204
+ localTui = await (deps.tuiCheck ?? executeTuiNodeCheck)(measuredCommit, dir, command);
205
+ }
190
206
  } finally { checkout?.cleanup(); }
191
207
  for (const line of local.lines) log(line);
192
208
  return local.exitCode;
@@ -195,7 +211,7 @@ export async function runLightRc(version: string, opts: LightRcOptions = {}, dep
195
211
  const rc = await (deps.dispatch ?? dispatchHeavyCheck)({
196
212
  tool: 'self-gate', repo: cwd, installPwa: true, refs: [base], json: true, commit: measuredCommit,
197
213
  // The host re-runs this command with --local (and ELANOUS_GATE_REMOTE_CHILD=1), so it never recurses.
198
- remoteArgv: (sha) => ['bun', 'bin/elanous.mjs', 'release', 'light-rc', '--version', version, '--base', sha(base), '--head', measuredCommit, '--shards', String(shards), '--local', '--json'],
214
+ remoteArgv: (sha) => ['bun', 'bin/elanous.mjs', 'release', 'light-rc', '--version', version, '--base', sha(base), '--head', measuredCommit, '--shards', String(shards), ...(opts.fixedShardDistribution ? ['--fixed-shard-distribution'] : []), '--local', '--json', ...(opts.rehearsalTui ? ['--rehearsal-tui'] : [])],
199
215
  flags: { remote: opts.local ? undefined : opts.remote ?? true, local: !!opts.local },
200
216
  runLocal,
201
217
  }, {
@@ -236,11 +252,22 @@ export async function runLightRc(version: string, opts: LightRcOptions = {}, dep
236
252
  unmeasured: typeof remote.unmeasured === 'string' && remote.unmeasured
237
253
  ? remote.unmeasured
238
254
  : typeof remote.introduced === 'number' ? null : LIGHT_RC_REASON_NOT_REPORTED,
255
+ ...(remote.rehearsalTui ? { rehearsalTui: remote.rehearsalTui } : {}),
239
256
  };
240
257
  }
241
258
  // Unmeasured (null) or unclassified failures are never green; policy-gate findings in the gate output are reported
242
259
  // (gate rc), not a regression.
243
- result.ok = result.introduced === 0 && result.unclassified === 0;
260
+ if (opts.rehearsalTui) {
261
+ if (local) {
262
+ result.rehearsalTui = localTui ?? { outcome: 'unmeasured', detail: 'local TUI screen result missing' };
263
+ } else {
264
+ const tui = result.rehearsalTui;
265
+ result.rehearsalTui = tui && ['ok', 'fail', 'unmeasured'].includes(tui.outcome) && typeof tui.detail === 'string' && tui.detail.length > 0
266
+ ? tui : { outcome: 'unmeasured', detail: 'remote TUI screen result missing' };
267
+ }
268
+ }
269
+ result.ok = result.introduced === 0 && result.unclassified === 0 && result.unmeasured === null
270
+ && (!opts.rehearsalTui || result.rehearsalTui?.outcome === 'ok');
244
271
  debug.log('release.light-rc', 'done', { version, base, measuredCommit, worktreeHead, importerTests: result.importerTests, introduced: result.introduced, preexisting: result.preexisting, unclassified: result.unclassified, shards, remote: result.remote, unmeasured: result.unmeasured });
245
272
  return result;
246
273
  }
@@ -250,5 +277,6 @@ export function formatLightRc(result: LightRcResult): string[] {
250
277
  `${result.ok ? '✅' : '⛔'} light-rc ${result.version} · base ${result.base.slice(0, 12)} · measured ${result.measuredCommit.slice(0, 12)} · ${result.remote ? `host ${result.remote}` : 'local'} · shards ${result.shards}`,
251
278
  ` introduced ${result.introduced ?? '못 쟀다'} · preexisting ${result.preexisting ?? '못 쟀다'} · unclassified ${result.unclassified ?? '못 쟀다'} · importer tests ${result.importerTests ?? '못 쟀다'} · always-include ${result.alwaysInclude}${result.alwaysIncludeMissing.length ? ` (missing: ${result.alwaysIncludeMissing.join(', ')})` : ''} · gate rc ${result.gateExitCode}`,
252
279
  ...(result.unmeasured !== null ? [` shards: unmeasured (${result.unmeasured})`] : []),
280
+ ...(result.rehearsalTui ? [` TUI screens: ${result.rehearsalTui.outcome} (${result.rehearsalTui.detail})`] : []),
253
281
  ];
254
282
  }
@@ -6,7 +6,7 @@ import { resolveRepositoryName } from '../harness/repository-name.js';
6
6
  import { getElanousConfigDirOverride } from '../elanous-config-dir.js';
7
7
  import { effectiveInstanceRoot } from '../instance/resolve.js';
8
8
  import { userConfigPath } from '../user-config.js';
9
- import { addItem, checklistHistory, listChecklist, ownerMatches, parseOwner, setItem, validateCeoLoad, type ChecklistItem } from './checklist.js';
9
+ import { addItem, checklistHistory, inspectChecklistTargetPaths, listChecklist, ownerMatches, parseOwner, setItem, validateCeoLoad, type ChecklistItem } from './checklist.js';
10
10
  import { assignedVersions, move, releasedVersion } from './feature-store.js';
11
11
  import { debug } from '../debug/log.js';
12
12
  import { kstDay, listSchedules, type ReleaseSchedule } from './release-schedule.js';
@@ -110,6 +110,12 @@ function validCeoCap(cap: number): number {
110
110
 
111
111
  export function placementCeoDailyCap(): number { return validCeoCap(placementConfig().ceoDailyCap ?? 30); }
112
112
 
113
+ /** One configuration snapshot for the read-only pull-forward caller. */
114
+ export function pullForwardPlacementConfig(): { seatCap: Record<string, number>; ceoDailyCap: number; ceoCalendar: CeoCalendar } {
115
+ const config = placementConfig();
116
+ return { seatCap: config.seatCap ?? {}, ceoDailyCap: validCeoCap(config.ceoDailyCap ?? 30), ceoCalendar: config.ceoCalendar ?? {} };
117
+ }
118
+
113
119
  function validDay(day: string): boolean {
114
120
  return typeof day === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(day) && Number.isFinite(Date.parse(`${day}T00:00:00Z`))
115
121
  && new Date(`${day}T00:00:00Z`).toISOString().slice(0, 10) === day;
@@ -406,6 +412,91 @@ export function rebalance(version: string, deps: PlacementDeps = {}): RebalanceR
406
412
  return result;
407
413
  }
408
414
 
415
+ export interface PullForwardDeps {
416
+ now: Date;
417
+ schedules: readonly ReleaseSchedule[];
418
+ checklists: ReadonlyMap<string, readonly ChecklistItem[]>;
419
+ released: string;
420
+ merged24h: number;
421
+ seatCap: Record<string, number>;
422
+ ceoDailyCap: number;
423
+ ceoCalendar: CeoCalendar;
424
+ signal: { order?: readonly string[]; hold?: readonly string[] };
425
+ targetPathExists: (path: string) => boolean;
426
+ backlog?: readonly string[];
427
+ }
428
+
429
+ /** Read-only plan: every operational input is supplied by the caller. */
430
+ export function planPullForward(deps: PullForwardDeps): RebalanceResult {
431
+ if (typeof deps.targetPathExists !== 'function') throw new CliUserError('대상 저장소 경로 판정기가 필요하다');
432
+ const rows = [...deps.schedules].sort((a, b) => versionOrder(a.version, b.version));
433
+ const now = deps.now.getTime();
434
+ const backlog = deps.backlog ?? BACKLOG_VERSIONS;
435
+ const released = deps.released;
436
+ const open = rows.filter((row) => (!released || versionOrder(row.version, released) > 0) && available(row, now, backlog));
437
+ const target = open[0];
438
+ if (!target) throw new CliUserError('당겨올 판이 없다 — 착지 마감이 안 지난 판이 필요하다');
439
+ const result: RebalanceResult = { decisions: [], blocked: [] };
440
+ const source = rows.find((row) => versionOrder(row.version, target.version) > 0 && !backlog.includes(row.version));
441
+ if (!source || !available(source, now, backlog)) return result;
442
+ const sources = [...new Set([...rows.map((row) => row.version), ...deps.checklists.keys(), ...backlog])];
443
+ const snapshots = new Map(sources.map((version) => [version, [...(deps.checklists.get(version) ?? [])]]));
444
+ const remainingP0 = snapshots.get(target.version)!.filter((item) => item.priority === 'P0' && item.status !== 'green' && item.status !== 'done').length;
445
+ const hold = new Set(deps.signal?.hold ?? []);
446
+ const rank = new Map<string, number>();
447
+ for (const [index, id] of (deps.signal?.order ?? []).entries()) if (!rank.has(id)) rank.set(id, index);
448
+ // Untyped legacy cells are fail-closed on human-action words in either language. These
449
+ // conservative markers may exclude code about approvals, but must never move a manual gate.
450
+ const human = /\uD83D\uDC51|실기기|실기 |사람|대표|손|라이브 1회|녹화|세미나|수동|승인|검토|결정|HITL|manual|human|approval|sign.off|review|operator|ceo/i;
451
+ const complete = new Set<string>();
452
+ const incomplete = new Set<string>();
453
+ for (const items of snapshots.values()) for (const item of items) {
454
+ if (item.status === 'green' || item.status === 'done') complete.add(item.id);
455
+ else incomplete.add(item.id);
456
+ }
457
+ const targetPathsReady = (title: string): boolean => {
458
+ const check = inspectChecklistTargetPaths({ title }, { existsAtMain: deps.targetPathExists });
459
+ return check.targets.length > 0 && check.warnings.length === 0;
460
+ };
461
+ const candidates = snapshots.get(source.version)!.filter((item) =>
462
+ (item.priority === 'P0' || item.priority === 'P1') && item.status !== 'green' && item.status !== 'done'
463
+ && !hold.has(item.id) && !human.test(item.title) && (!item.dispatchKind || item.dispatchKind === 'code')
464
+ && (item.ceoMinutes === undefined || item.ceoMinutes === 0)
465
+ && targetPathsReady(item.title)
466
+ && (item.predecessors ?? []).every((id) => complete.has(id) && !incomplete.has(id)))
467
+ .map((item, index) => ({ item, index }))
468
+ .sort((a, b) => (rank.get(a.item.id) ?? Infinity) - (rank.get(b.item.id) ?? Infinity)
469
+ || (a.item.priority === 'P0' ? 0 : 1) - (b.item.priority === 'P0' ? 0 : 1) || a.index - b.index);
470
+ if (!candidates.length) return result;
471
+ if (Date.parse(target.landBy ?? target.cutAt) - now < 4 * 60 * 60 * 1000) {
472
+ for (const { item } of candidates)
473
+ result.blocked.push({ id: item.id, from: source.version, to: target.version, reason: `지금 판 ${target.version} 착지 마감까지 4시간 미만 — 당겨오기 보류` });
474
+ return result;
475
+ }
476
+ if (remainingP0 > 3) {
477
+ for (const { item } of candidates)
478
+ result.blocked.push({ id: item.id, from: source.version, to: target.version, reason: `지금 판 ${target.version} 남은 P0 ${remainingP0} > 3 — 당겨오기 보류` });
479
+ return result;
480
+ }
481
+ const rate = deps.merged24h;
482
+ if (!Number.isInteger(rate) || rate < 0) throw new CliUserError('24시간 병합 PR 수가 잘못됐다');
483
+ const caps = deps.seatCap;
484
+ const ceoCap = validCeoCap(deps.ceoDailyCap);
485
+ const calendar = deps.ceoCalendar;
486
+ for (const { item } of candidates) {
487
+ if (result.decisions.length >= 5) break;
488
+ const from = source.version;
489
+ // The pull-forward contract uses the schedule's cutAt only when landBy is absent.
490
+ const destination = { ...target, landBy: target.landBy ?? target.cutAt };
491
+ const violation = moveConstraint(item, destination, backlog, snapshots, now, rate, caps, rows, ceoCap, calendar, released);
492
+ if (violation) { result.blocked.push({ id: item.id, from, to: target.version, reason: violation }); continue; }
493
+ result.decisions.push({ id: item.id, from, version: target.version, reason: `다음 판 ${from} → 지금 판 ${target.version} 당겨오기 · 남은 P0 ${remainingP0} ≤ 3 · 착지 마감 ≥ 4h`, displaced: [] });
494
+ snapshots.set(from, snapshots.get(from)!.filter((cell) => cell.id !== item.id));
495
+ snapshots.get(target.version)!.push(item);
496
+ }
497
+ return result;
498
+ }
499
+
409
500
  /** Reasons that justify a second forward rollover of the same cell (대표 10-10 «계속 이월되지 않게»). */
410
501
  const SECOND_ROLLOVER_REASON_PREFIXES: readonly string[] = ['쪼개기:', '닫기:', '\u{1F451}:'];
411
502
 
@@ -0,0 +1,149 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { availableParallelism, cpus as hostCpus, freemem, totalmem } from 'node:os';
3
+ import { existsSync, readFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { selectGateTestFiles } from '../self-implement/gate-cli.js';
6
+ import { readFileMemory } from '../../scripts/release-loop/shard-plan.js';
7
+ import { gateShardsPath, readGateShards } from './gate-shards.js';
8
+ import { LIGHT_RC_ALWAYS_FILE, LIGHT_RC_DEFAULT_SHARDS, parseAlwaysIncludeList, previousCutBase } from './light-rc.js';
9
+
10
+ const FILE_MEMORY_SOURCE = 'docs/measurements/td1-whole-gate-mechanical-2026-10-01.tsv';
11
+
12
+ export interface RehearsalShardPlan {
13
+ shards: number;
14
+ testFiles: number | null;
15
+ /** Observed on the tick host, not necessarily the remote gate host. */
16
+ resources: { cpus: number; freeBytes: number; totalBytes: number };
17
+ gatePlanShards: number | null;
18
+ /** Local preflight budget, not a measured remote peak-RSS or a workload-specific guarantee. */
19
+ capacity?: { reserveBytes: number; bytesPerShard: number; memoryShards: number | null; requiredBytes: number; measuredFiles: number; peakFileBytes: number | null };
20
+ unmeasured: string | null;
21
+ /** The remote host's capacity is checked by the actual RC, after this preflight. */
22
+ remoteCapacityPending?: boolean;
23
+ rssRevisionPending?: boolean;
24
+ planningGaps?: string[];
25
+ remoteCapacityVerifiedBy?: string;
26
+ }
27
+
28
+ export interface RehearsalShardPlanDeps {
29
+ /** Rehearsal light RC dispatches remotely; local CPU/memory is evidence only, not a gate-host limit. */
30
+ remoteGate?: boolean;
31
+ select?: (checkout: string, options: { base: string; alwaysInclude: string[]; includeImporterTests: true }) => { testFiles: string[]; alwaysIncludeMissing?: readonly string[]; lookupFailed?: string | null; unrunImporterTotal?: number | null; skipTestStep?: boolean; routeLookupFailures?: readonly unknown[]; unverified?: readonly string[]; callerTestsOverflow?: readonly unknown[] };
32
+ resources?: () => RehearsalShardPlan['resources'];
33
+ board?: typeof readGateShards;
34
+ readAlways?: (path: string) => string;
35
+ resolveBase?: (version: string, checkout: string, root: string) => string;
36
+ fileMemory?: (path: string) => Map<string, number>;
37
+ }
38
+
39
+ /** Preflight only: the gate still performs its own selection at execution time. The local budget uses measured
40
+ * selected-file peak RSS with a 2 GiB floor per shard and reserves 1 GiB for the host. The RC result is the
41
+ * authority for whether execution on its actual gate host succeeded. */
42
+ const GIB = 1024 ** 3;
43
+ const RESERVE_BYTES = GIB;
44
+ const BYTES_PER_SHARD = 2 * GIB;
45
+
46
+ /** The dated TSV has no dependency graph/revision. Require the whole checkout to match its source commit;
47
+ * otherwise RSS is provisional until a completed RC measures this actual checkout on its gate host. */
48
+ function measurementMatchesCheckout(checkout: string): boolean {
49
+ const source = spawnSync('git', ['log', '-1', '--format=%H', '--', FILE_MEMORY_SOURCE], { cwd: checkout, encoding: 'utf8' });
50
+ const commit = source.stdout?.trim();
51
+ if (source.status !== 0 || !/^[0-9a-f]{40}$/.test(commit ?? '')) return false;
52
+ const diff = spawnSync('git', ['diff', '--quiet', commit!, 'HEAD', '--', '.'], { cwd: checkout, encoding: 'utf8' });
53
+ if (diff.status !== 0) return false;
54
+ const working = spawnSync('git', ['status', '--porcelain', '--untracked-files=all'], { cwd: checkout, encoding: 'utf8' });
55
+ return working.status === 0 && !working.stdout?.trim();
56
+ }
57
+
58
+ /** OS free memory can describe the entire host rather than the tick's container; bound it by cgroup headroom. */
59
+ export function rehearsalHostResources(read: (path: string) => string = (path) => readFileSync(path, 'utf8')): RehearsalShardPlan['resources'] {
60
+ const cpus = Math.max(1, Number(availableParallelism?.() ?? hostCpus()?.length ?? 1) || 1);
61
+ let freeBytes = freemem(), totalBytes = totalmem();
62
+ for (const [limitPath, usagePath] of [
63
+ ['/sys/fs/cgroup/memory.max', '/sys/fs/cgroup/memory.current'],
64
+ ['/sys/fs/cgroup/memory/memory.limit_in_bytes', '/sys/fs/cgroup/memory/memory.usage_in_bytes'],
65
+ ]) {
66
+ try {
67
+ const limit = Number(read(limitPath).trim()), usage = Number(read(usagePath).trim());
68
+ if (Number.isSafeInteger(limit) && limit > 0 && limit < totalBytes && Number.isSafeInteger(usage) && usage >= 0) {
69
+ totalBytes = limit;
70
+ freeBytes = Math.min(freeBytes, Math.max(0, limit - usage));
71
+ break;
72
+ }
73
+ } catch { /* not running inside this cgroup version */ }
74
+ }
75
+ return { cpus, freeBytes, totalBytes };
76
+ }
77
+
78
+ export function planRehearsalShards(version: string, root: string, checkout: string, deps: RehearsalShardPlanDeps = {}): RehearsalShardPlan {
79
+ const reasons: string[] = [];
80
+ let rssRevisionPending = false;
81
+ let resources: RehearsalShardPlan['resources'];
82
+ try { resources = (deps.resources ?? rehearsalHostResources)(); }
83
+ catch (error) {
84
+ resources = { cpus: 0, freeBytes: 0, totalBytes: 0 };
85
+ reasons.push(`host resource probe failed: ${error instanceof Error ? error.message : String(error)}`);
86
+ }
87
+ let gatePlanShards: number | null = null;
88
+ try {
89
+ const board = (deps.board ?? readGateShards)(gateShardsPath(version, root));
90
+ gatePlanShards = board?.version === version && board.shards.length && new Set(board.shards.map(shard => shard.id)).size === board.shards.length ? board.shards.length : null;
91
+ } catch (error) { reasons.push(`persisted gate shard plan unreadable: ${error instanceof Error ? error.message : String(error)}`); }
92
+ let testFiles: number | null = null;
93
+ let measuredFiles = 0;
94
+ let peakFileBytes: number | null = null;
95
+ try {
96
+ const path = join(checkout, LIGHT_RC_ALWAYS_FILE);
97
+ const text = deps.readAlways ? deps.readAlways(path) : existsSync(path) ? readFileSync(path, 'utf8') : undefined;
98
+ if (text === undefined) throw new Error(`${LIGHT_RC_ALWAYS_FILE} missing`);
99
+ const base = (deps.resolveBase ?? ((v, cwd, ledgerRoot) => previousCutBase(v, { cwd, ledgerRoot })))(version, checkout, root);
100
+ const selection = (deps.select ?? ((cwd, opts) => selectGateTestFiles(cwd, opts)))(checkout, { base, alwaysInclude: parseAlwaysIncludeList(text), includeImporterTests: true });
101
+ const files = [...new Set(selection.testFiles)];
102
+ testFiles = files.length;
103
+ try {
104
+ const memory = (deps.fileMemory ?? readFileMemory)(join(checkout, FILE_MEMORY_SOURCE));
105
+ const peaks = files.map(file => memory.get(file)).filter((value): value is number => value !== undefined && Number.isFinite(value) && value > 0);
106
+ measuredFiles = peaks.length;
107
+ if (peaks.length) peakFileBytes = Math.ceil(peaks.reduce((largest, value) => Math.max(largest, value), 0) * 1_000_000);
108
+ if (measuredFiles !== testFiles) reasons.push(`selected file memory not measured: ${testFiles - measuredFiles}/${testFiles}`);
109
+ if (!deps.fileMemory && files.length && !measurementMatchesCheckout(checkout)) {
110
+ if (deps.remoteGate) rssRevisionPending = true;
111
+ else reasons.push('selected file RSS measurement revision not verified against checkout');
112
+ }
113
+ } catch (error) { reasons.push(`selected file memory unavailable: ${error instanceof Error ? error.message : String(error)}`); }
114
+ if (selection.alwaysIncludeMissing?.length) reasons.push(`always-include missing: ${selection.alwaysIncludeMissing.join(', ')}`);
115
+ if (selection.lookupFailed) reasons.push(`importer lookup failed: ${selection.lookupFailed}`);
116
+ if (selection.unrunImporterTotal === undefined) reasons.push('importer coverage not reported');
117
+ if (selection.unrunImporterTotal === null || (selection.unrunImporterTotal ?? 0) > 0) reasons.push(`importer tests not run: ${selection.unrunImporterTotal ?? 'unknown'}`);
118
+ if (selection.routeLookupFailures?.length) reasons.push(`route lookup failed: ${selection.routeLookupFailures.length}`);
119
+ if (selection.unverified?.length) reasons.push(`unverified scope: ${selection.unverified.length}`);
120
+ if (selection.callerTestsOverflow?.length) reasons.push(`caller tests overflow: ${selection.callerTestsOverflow.length}`);
121
+ if (selection.skipTestStep) reasons.push('gate test step skipped');
122
+ if (!testFiles) reasons.push('selected test files empty');
123
+ } catch (error) { reasons.push(`test selection unavailable: ${error instanceof Error ? error.message : String(error)}`); }
124
+ if (gatePlanShards === null) reasons.push('persisted gate shard plan unavailable');
125
+ const cpuValid = Number.isSafeInteger(resources.cpus) && resources.cpus > 0;
126
+ const memoryValid = Number.isFinite(resources.freeBytes) && resources.freeBytes >= 0 && Number.isFinite(resources.totalBytes) && resources.totalBytes > 0 && resources.freeBytes <= resources.totalBytes;
127
+ if (!deps.remoteGate && (!cpuValid || !memoryValid)) reasons.push('host resources unavailable');
128
+ const bytesPerShard = Math.max(BYTES_PER_SHARD, peakFileBytes ?? 0);
129
+ const memoryShards = memoryValid ? Math.max(0, Math.floor((resources.freeBytes - RESERVE_BYTES) / bytesPerShard)) : null;
130
+ const candidate = Math.max(1, Math.min(gatePlanShards ?? LIGHT_RC_DEFAULT_SHARDS, testFiles ?? LIGHT_RC_DEFAULT_SHARDS, deps.remoteGate ? Number.MAX_SAFE_INTEGER : cpuValid ? resources.cpus : LIGHT_RC_DEFAULT_SHARDS));
131
+ if (!deps.remoteGate && peakFileBytes !== null && memoryValid && resources.freeBytes < RESERVE_BYTES + peakFileBytes) {
132
+ reasons.push(`selected file peak exceeds host memory: peak ${peakFileBytes}, free ${resources.freeBytes}, reserve ${RESERVE_BYTES} bytes`);
133
+ }
134
+ // Never treat a 0-slot host as sufficient for one shard. The caller must leave an unrun step retryable.
135
+ const shards = deps.remoteGate || memoryShards === null ? candidate : Math.max(1, Math.min(candidate, memoryShards));
136
+ const capacity = { reserveBytes: RESERVE_BYTES, bytesPerShard, memoryShards, requiredBytes: RESERVE_BYTES + shards * bytesPerShard, measuredFiles, peakFileBytes };
137
+ if (!deps.remoteGate && memoryShards === 0) reasons.push(`host memory insufficient: free ${resources.freeBytes} < required ${capacity.requiredBytes} bytes for 1 shard`);
138
+ // The exported local planner has no local RC caller to validate aggregate workload capacity. A prior board's
139
+ // shard count and individual file peaks cannot prove that hundreds of tests fit one shard.
140
+ if (!deps.remoteGate) reasons.push('local gate shard workload sufficiency not measured');
141
+ // A complete selected-file measurement plus the persisted shard count and a valid host budget is enough to
142
+ // select a candidate. Execution on another host is judged by the RC result, not by a permanent preflight warning.
143
+ const remoteCapacityReason = 'remote gate host resources unmeasured before RC';
144
+ const rssRevisionReason = 'selected file RSS measurement revision not verified before RC';
145
+ return { shards, testFiles, resources, gatePlanShards, capacity,
146
+ ...(deps.remoteGate ? { remoteCapacityPending: true, rssRevisionPending, planningGaps: reasons } : {}),
147
+ unmeasured: reasons.length || deps.remoteGate ? [...reasons, ...(rssRevisionPending ? [rssRevisionReason] : []), ...(deps.remoteGate ? [remoteCapacityReason] : [])].join('; ') : null,
148
+ };
149
+ }
@@ -1,11 +1,14 @@
1
1
  import { spawnSync } from 'node:child_process';
2
2
  import { randomUUID } from 'node:crypto';
3
- import { existsSync, linkSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
3
+ import { existsSync, linkSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
4
5
  import { dirname, join } from 'node:path';
5
6
  import { debug } from '../debug/log.js';
6
7
  import { sendOutbound } from '../domains/outbound-alert.js';
7
8
  import { releaseLedgerRoot } from '../instance/resolve.js';
8
- import { runLightRc, type LightRcResult } from './light-rc.js';
9
+ import { isValidGateHost } from '../self-implement/gate-remote.js';
10
+ import { LIGHT_RC_UNKNOWN_HOST, runLightRc, type LightRcResult } from './light-rc.js';
11
+ import { planRehearsalShards, type RehearsalShardPlan, type RehearsalShardPlanDeps } from './rehearsal-shard-plan.js';
9
12
  import { listSchedules, type ReleaseSchedule } from './release-schedule.js';
10
13
 
11
14
  export type StepId = 'rc-7h' | 'rc-150m';
@@ -50,6 +53,9 @@ export interface RehearsalStamp {
50
53
  summary?: string;
51
54
  regressionFiles?: string[];
52
55
  result?: LightRcResult;
56
+ shardPlan?: RehearsalShardPlan;
57
+ leakCheck?: { outcome: 'ok' | 'fail'; sha: string; exitCode: number | null };
58
+ selection?: { shards?: number; remote?: string };
53
59
  notifiedAt?: string;
54
60
  ownerPid?: number;
55
61
  }
@@ -58,14 +64,19 @@ export interface RehearsalOptions {
58
64
  apply?: boolean;
59
65
  checkout?: string;
60
66
  ledgerRoot?: string;
67
+ shards?: number;
68
+ remote?: string;
61
69
  }
62
70
 
63
71
  export interface RehearsalDeps {
64
72
  now?: () => Date;
65
73
  schedules?: (root: string) => ReleaseSchedule[];
66
- lightRc?: (version: string, checkout: string) => Promise<LightRcResult>;
74
+ lightRc?: (version: string, checkout: string, selection: { shards?: number; remote?: string }) => Promise<LightRcResult>;
75
+ shardPlan?: typeof planRehearsalShards;
76
+ shardPlanDeps?: RehearsalShardPlanDeps;
67
77
  notify?: (text: string) => void | boolean | Promise<void | boolean>;
68
78
  git?: (args: string[], cwd: string) => { rc: number | null; stdout: string; stderr?: string };
79
+ leakCheck?: (checkout: string) => { status: number | null };
69
80
  }
70
81
 
71
82
  export type RehearsalTickResult = RehearsalPlan & { applied?: boolean; stamps?: RehearsalStamp[]; notificationFailures?: number };
@@ -86,6 +97,17 @@ function gitResult(git: NonNullable<RehearsalDeps['git']>, args: string[], check
86
97
  return result.stdout.trim();
87
98
  }
88
99
 
100
+ /** Public export checks the pinned rehearsal checkout before any remote RC work. Its output is private and ephemeral. */
101
+ function runRehearsalLeakCheck(checkout: string): { status: number | null } {
102
+ const out = mkdtempSync(join(tmpdir(), 'elanous-rehearsal-export-'));
103
+ try {
104
+ const result = spawnSync('bun', ['scripts/public-export.ts', '--out', join(out, 'export')], {
105
+ cwd: checkout, encoding: 'utf8', timeout: 1_800_000, maxBuffer: 64 * 1024 * 1024,
106
+ });
107
+ return { status: result.status };
108
+ } finally { rmSync(out, { recursive: true, force: true }); }
109
+ }
110
+
89
111
  function oneLine(text: string): string { return text.replace(/\s+/g, ' ').trim(); }
90
112
 
91
113
  function outcomeLine(stamp: RehearsalStamp): string {
@@ -95,7 +117,11 @@ function outcomeLine(stamp: RehearsalStamp): string {
95
117
  if (!stamp.result) return `${head}${stamp.summary ? ` · ${stamp.summary}` : ''}`;
96
118
  const result = stamp.result;
97
119
  const duration = Math.max(0, Math.round((Date.parse(stamp.endedAt!) - Date.parse(stamp.startedAt)) / minute));
98
- return `${head} · 새 회귀 ${result.introduced ?? '못 쟀다'} · 기존 ${result.preexisting ?? '못 쟀다'} · 미분류 ${result.unclassified ?? '못 쟀다'} · ${result.remote ?? 'local'} · ${duration}분${stamp.outcome === 'error' ? ` · gate rc ${result.gateExitCode}${!result.ok ? ' · RC 실패' : ''}` : ''}${stamp.regressionFiles?.length ? ` · 파일 ${stamp.regressionFiles.slice(0, 3).join(', ')}` : ''}`;
120
+ const planningGap = stamp.shardPlan?.unmeasured
121
+ || (stamp.selection?.shards !== undefined && result.shards !== stamp.selection.shards)
122
+ || (stamp.selection?.remote !== undefined && result.remote !== stamp.selection.remote);
123
+ const detail = stamp.summary && (stamp.outcome === 'unmeasured' || stamp.outcome === 'error' && planningGap) ? ` · ${stamp.summary}` : '';
124
+ return `${head} · 새 회귀 ${result.introduced ?? '못 쟀다'} · 기존 ${result.preexisting ?? '못 쟀다'} · 미분류 ${result.unclassified ?? '못 쟀다'} · ${result.remote ?? 'local'} · ${duration}분${stamp.outcome === 'error' ? ` · gate rc ${result.gateExitCode}${!result.ok ? ' · RC 실패' : ''}` : ''}${stamp.regressionFiles?.length ? ` · 파일 ${stamp.regressionFiles.slice(0, 3).join(', ')}` : ''}${detail}`;
99
125
  }
100
126
 
101
127
  function persistStamp(path: string, stamp: RehearsalStamp): void {
@@ -207,6 +233,12 @@ function interruptStamp(path: string, saved: RehearsalStamp, now: Date): Rehears
207
233
 
208
234
  /** wx claim is permanent per version/step; a crashed run is reported as interrupted without running RC twice. */
209
235
  export async function runRehearsalTick(opts: RehearsalOptions = {}, deps: RehearsalDeps = {}): Promise<RehearsalTickResult> {
236
+ if (opts.shards !== undefined && (!Number.isSafeInteger(opts.shards) || opts.shards < 1)) {
237
+ throw new Error(`release rehearsal tick: invalid --shards count: ${opts.shards}`);
238
+ }
239
+ if (opts.remote !== undefined && !isValidGateHost(opts.remote)) {
240
+ throw new Error(`release rehearsal tick: invalid --remote host: ${opts.remote}`);
241
+ }
210
242
  const root = opts.ledgerRoot ?? releaseLedgerRoot();
211
243
  const now = (deps.now ?? (() => new Date()))();
212
244
  const schedules = (deps.schedules ?? listSchedules)(root);
@@ -289,26 +321,50 @@ export async function runRehearsalTick(opts: RehearsalOptions = {}, deps: Rehear
289
321
  gitResult(git, ['checkout', '-q', '--detach', 'origin/main'], checkout);
290
322
  stamp.sha = gitResult(git, ['rev-parse', 'HEAD'], checkout);
291
323
  if (!stamp.sha) throw new Error('git rev-parse HEAD returned no sha');
324
+ const leak = (deps.leakCheck ?? runRehearsalLeakCheck)(checkout);
325
+ stamp.leakCheck = { outcome: leak.status === 0 ? 'ok' : 'fail', sha: stamp.sha, exitCode: leak.status };
326
+ if (leak.status !== 0) throw new Error(`public export leak-check failed (rc=${leak.status ?? 'spawn'})`);
292
327
  const regressionFiles: string[] = [];
293
- const result = await (deps.lightRc ?? ((version, cwd) => runLightRc(version, { ledgerRoot: root, head: stamp.sha, log: (line) => {
294
- for (const entry of line.split(/\r?\n/)) {
295
- const file = /^- introduced: (.+?)(?: > |$)/.exec(entry)?.[1];
296
- if (file && regressionFiles.length < 3) regressionFiles.push(file);
297
- }
298
- console.error(line);
299
- } }, { cwd })))(plan.version, checkout);
328
+ const shardPlan = opts.shards === undefined ? (deps.shardPlan ?? planRehearsalShards)(plan.version, root, checkout, { ...deps.shardPlanDeps, remoteGate: true }) : undefined;
329
+ if (shardPlan) stamp.shardPlan = shardPlan;
330
+ const selection = { shards: opts.shards ?? shardPlan?.shards, remote: opts.remote };
331
+ stamp.selection = selection;
332
+ const result = await (deps.lightRc ?? ((version, cwd) => runLightRc(version, { ledgerRoot: root, head: stamp.sha, ...selection, rehearsalTui: true, log: (line) => {
333
+ for (const entry of line.split(/\r?\n/)) {
334
+ const file = /^- introduced: (.+?)(?: > |$)/.exec(entry)?.[1];
335
+ if (file && regressionFiles.length < 3) regressionFiles.push(file);
336
+ }
337
+ console.error(line);
338
+ } }, { cwd })))(plan.version, checkout, selection);
300
339
  stamp.result = result;
301
340
  if (regressionFiles.length) stamp.regressionFiles = regressionFiles;
302
- stamp.outcome = result.introduced === null || result.unclassified === null ? 'unmeasured'
303
- : result.introduced > 0 ? 'regression'
304
- : result.unclassified > 0 ? 'unmeasured'
305
- : !result.ok || result.gateExitCode !== 0 ? 'error' : 'ok';
306
- stamp.summary = oneLine(`introduced ${result.introduced} · preexisting ${result.preexisting ?? 'unmeasured'} · unclassified ${result.unclassified} · ${result.remote ?? 'local'} · gate rc ${result.gateExitCode}${!result.ok ? ' · RC 실패' : ''}`);
341
+ const shardMismatch = selection.shards !== undefined && result.shards !== selection.shards
342
+ ? `selected shards ${selection.shards} but RC reported ${result.shards}` : null;
343
+ const remoteMismatch = opts.remote && result.remote !== opts.remote
344
+ ? `requested remote ${opts.remote} but RC reported ${result.remote ?? 'local'}` : null;
345
+ if (shardPlan?.remoteCapacityPending && result.remote && result.remote !== LIGHT_RC_UNKNOWN_HOST
346
+ && !remoteMismatch && result.unmeasured === null
347
+ && result.introduced !== null && result.unclassified === 0 && result.ok
348
+ && result.gateExitCode === 0 && !shardMismatch) {
349
+ // Only the completed RC can validate capacity of the actual remote host. Keep independent
350
+ // selection/RSS gaps; clear just the provisional remote-capacity gap.
351
+ stamp.shardPlan = { ...shardPlan, remoteCapacityPending: false, rssRevisionPending: false,
352
+ remoteCapacityVerifiedBy: result.remote,
353
+ unmeasured: shardPlan.planningGaps?.length ? shardPlan.planningGaps.join('; ') : null };
354
+ }
355
+ const planningGap = stamp.shardPlan?.unmeasured || shardMismatch || remoteMismatch;
356
+ const missingEvidence = result.introduced === null || result.unclassified === null
357
+ || result.unmeasured !== null || result.unclassified > 0 || !!planningGap;
358
+ stamp.outcome = result.introduced !== null && result.introduced > 0 ? missingEvidence ? 'unmeasured' : 'regression'
359
+ : result.introduced === null || result.unclassified === null || result.unmeasured !== null || result.unclassified > 0 ? 'unmeasured'
360
+ : result.unmeasured === null && (!result.ok || result.gateExitCode !== 0) ? 'error'
361
+ : planningGap ? 'unmeasured' : 'ok';
362
+ stamp.summary = oneLine(`introduced ${result.introduced} · preexisting ${result.preexisting ?? 'unmeasured'} · unclassified ${result.unclassified} · ${result.remote ?? 'local'} · gate rc ${result.gateExitCode}${!result.ok ? ' · RC 실패' : ''}${result.unmeasured !== null ? ` · unmeasured: ${result.unmeasured || 'RC reason empty'}` : ''}${stamp.shardPlan?.unmeasured ? ` · unmeasured: ${stamp.shardPlan.unmeasured}` : ''}${shardMismatch ? ` · unmeasured: ${shardMismatch}` : ''}${remoteMismatch ? ` · unmeasured: ${remoteMismatch}` : ''}`);
307
363
  }
308
364
  }
309
365
  } catch (error) {
310
366
  stamp.outcome = 'error';
311
- stamp.summary = oneLine(String(error instanceof Error ? error.message : error).split(/\r?\n/, 1)[0] ?? 'unknown error');
367
+ stamp.summary = oneLine(`${String(error instanceof Error ? error.message : error).split(/\r?\n/, 1)[0] ?? 'unknown error'}${stamp.shardPlan?.unmeasured ? ` · unmeasured: ${stamp.shardPlan.unmeasured}` : ''}`);
312
368
  }
313
369
  await finish(path, stamp);
314
370
  }
package/src/render.ts CHANGED
@@ -572,6 +572,10 @@ function parseAndRenderTable(lines: string[]): string {
572
572
  * Render a tool call header like Claude Code:
573
573
  * ⏺ ToolName(description)
574
574
  */
575
+ export function singleLineToolHeaderText(text: string): string {
576
+ return text.replace(/[ \t]*(?:\r\n|\r|\n|\u2028|\u2029)[ \t]*/g, ' ↵ ');
577
+ }
578
+
575
579
  export function toolHeader(
576
580
  toolName: string,
577
581
  description: string,
@@ -585,7 +589,7 @@ export function toolHeader(
585
589
  case 'error': icon = applyColor(circle, 'error'); break;
586
590
  }
587
591
  const name = chalk.bold(toolName);
588
- const desc = description ? chalk.dim(`(${description})`) : '';
592
+ const desc = description ? chalk.dim(`(${singleLineToolHeaderText(description)})`) : '';
589
593
  return `${icon} ${name}${desc}`;
590
594
  }
591
595
 
package/src/repl/index.ts CHANGED
@@ -30,6 +30,7 @@ import {
30
30
  import {
31
31
  resolveSessionId,
32
32
  loadSession,
33
+ listSessions,
33
34
  setActiveSessionId,
34
35
  getActiveSessionId,
35
36
  } from '../session/index.js';
@@ -41,6 +42,7 @@ import {
41
42
  } from '../user-config.js';
42
43
  import { setAmbientSessionId, debug } from '../debug/log.js';
43
44
  import { decideSigintAction } from './sigint.js';
45
+ import { decideSessionStart, observeSessionStart } from '../session/session-start.js';
44
46
  import { buildReplayTurnsFromSession } from './replay.js';
45
47
  import type { LLMToolSpec, ContentBlock } from '../llm.js';
46
48
  import { inspectActiveProvider } from '../provider-summary.js';
@@ -58,6 +60,8 @@ export interface ReplOpts {
58
60
  initialSessionId: string | undefined;
59
61
  /** Force a fresh session even if active marker exists. */
60
62
  forceNew: boolean;
63
+ /** `--continue`/`--resume` — 활성 세션 이어하기(명시). 대표 #73: 기본은 새 세션. */
64
+ continueActive?: boolean;
61
65
  /** Enable the tool loop (Read/Grep/Bash/...). Default true — REPL
62
66
  * is the agent surface; users opt out with --no-tools. */
63
67
  enableTools: boolean;
@@ -445,11 +449,25 @@ export async function runRepl(opts: ReplOpts): Promise<number> {
445
449
  return 1;
446
450
  }
447
451
  initialId = id;
448
- } else if (!opts.forceNew) {
449
- initialId = getActiveSessionId() ?? undefined;
450
452
  }
453
+ const startDecision = decideSessionStart({
454
+ ...(initialId ? { explicitSessionId: initialId } : {}),
455
+ continueActive: opts.continueActive === true,
456
+ forceNew: opts.forceNew,
457
+ activeSessionId: () => getActiveSessionId(),
458
+ // TUI-H8-FOLLOW ① — 활성 표지가 사라진 세션이면 최신 세션으로.
459
+ sessionExists: (id) => loadSession(id) !== null,
460
+ latestSessionId: () => listSessions({ limit: 1 })[0]?.id ?? null,
461
+ });
462
+ initialId = startDecision.sessionIdHint;
451
463
  const session = ensureCliSession(cfg, initialId);
452
464
  setActiveSessionId(session.id);
465
+ observeSessionStart({
466
+ surface: 'repl',
467
+ origin: initialId && session.id === initialId ? startDecision.origin : 'new',
468
+ reason: initialId && session.id !== initialId ? 'resume-target-missing' : startDecision.reason,
469
+ sessionId: session.id,
470
+ });
453
471
  setAmbientSessionId(session.id);
454
472
  if (!opts.jsonOutput && (!initialId || session.id !== initialId)) {
455
473
  try {