elanous 0.2.29 → 0.2.32

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 (775) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → IVKr3AlRUVLKsw2fh7eXF}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{058a98ba.7eb28d5e6dc03565.js → 0bb0ff36.b8d418980951e5ba.js} +7 -7
  5. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +27 -0
  8. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +287 -0
  9. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +62 -0
  10. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/{6013-2f769370d8b4c2c6.js → 1335-6731f392c35216eb.js} +3 -3
  12. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{8332.6f0f49df772e163b.js → 1654.32de4b324981a188.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
  17. package/apps/pwa/out/_next/static/chunks/{8795.32573a185af18c7b.js → 1913.7cc6fb6055b1ed3f.js} +2 -2
  18. package/apps/pwa/out/_next/static/chunks/{419.736c0d6f426249a7.js → 2001.6c7e0fd02190886c.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{6767.1fcfc9b8be83975f.js → 2213.2ccbada92c33ea0f.js} +16 -16
  24. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/{4759.1f76713aefb87db5.js → 2871.0bca6137343b3f76.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/{6776.06ff1e3b464cc607.js → 2898.fd781bc7cf01a7b7.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/{1782-59db1b5aa06df38a.js → 2940-619bfd8ef337c611.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/{8471.8d2a8c74f09c36ff.js → 2985.39ccdecd36848b12.js} +4 -4
  31. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +115 -0
  32. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +64 -0
  33. package/apps/pwa/out/_next/static/chunks/{bc324b7c.02a09dd93f6a399b.js → 3267c0e6.d34854e7b3984a6e.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3278.2e5d15b53a4091c8.js +2 -0
  35. package/apps/pwa/out/_next/static/chunks/{7725-4f83d5541fbdb81b.js → 3541-ce3a5424ed5ad7f1.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +34 -0
  39. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{46bd8bea.2f4b4099172fcdb7.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{1142.65d002789ab3af7d.js → 4174.92ed04922709ac9e.js} +2 -2
  43. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +36 -0
  45. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +286 -0
  49. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +77 -0
  50. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +226 -0
  51. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +79 -0
  53. package/apps/pwa/out/_next/static/chunks/5173-233188df2f42c626.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/5307.60f2209e809bd627.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{3396-97b97928c49190c9.js → 5458-16cd7a2b51b74c8c.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/{3403.7199205e65124486.js → 5525.86debf231e181813.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{9143.ff14585db1d275ff.js → 5543.a438b8ab5a13ea47.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +74 -0
  65. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +94 -0
  67. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{8398.73a19b39715eda04.js → 6092.a7f99e68b188ca66.js} +1 -1
  70. package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/{5591.a35e7a217734a8b9.js → 6157.0c9af021de4fb31b.js} +2 -2
  72. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/{7375.050ea0d72968e49f.js → 6433.fc573af22bbc9ab7.js} +17 -17
  75. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +90 -0
  77. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +32 -0
  78. package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +104 -0
  80. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +24 -0
  85. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
  86. package/apps/pwa/out/_next/static/chunks/69-0a2c8209c6d4a158.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/{1852.7f7b53991fcb99ef.js → 7502.ccd5b8065545edd0.js} +2 -2
  94. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
  95. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{6534.1ab00f370db7b105.js → 7862.30a8d6482bb238eb.js} +1 -1
  97. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
  110. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.js → 9221.7d22eaf353a2d4e7.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{8767-2f6a634f5abeaa01.js → 9279-d28c5b7754d010ae.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
  118. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.js → 9989.3694300e5f000b14.js} +1 -1
  123. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/control/page-a27b1e5a0d1b308f.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/morning/page-32866485913d6a04.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/{page-29900ed0011b2c83.js → page-c219f2ed171131be.js} +1 -1
  163. package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/term/page-04d00ae9b0890349.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
  176. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
  184. package/apps/pwa/out/_next/static/css/b5d88eba78a3d7bf.css +1 -0
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +26 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/bin/elanous.mjs +7 -3
  279. package/graphs/context/nightly-condense.yaml +1 -0
  280. package/graphs/implement-loop.yaml +5 -0
  281. package/graphs/intake/intake-daily.yaml +8 -1
  282. package/graphs/intake/recipes.yaml +5 -0
  283. package/graphs/lecture/lecture-note.yaml +2 -2
  284. package/graphs/ops/harness-gc.yaml +1 -0
  285. package/graphs/release/recipes.yaml +3 -0
  286. package/graphs/release/release-loop.yaml +9 -5
  287. package/graphs/units/recipes.yaml +3 -0
  288. package/graphs/units/release-gate-recheck.yaml +15 -0
  289. package/package.json +2 -1
  290. package/scripts/check-native-tool-wiring.ts +3 -2
  291. package/scripts/ci-android-unit-tests.ts +16 -0
  292. package/scripts/ci-typecheck-changed.ts +63 -10
  293. package/scripts/coord-channel-watch.sh +22 -16
  294. package/scripts/coord-role-pack.ts +81 -2
  295. package/scripts/cron-run.ts +96 -3
  296. package/scripts/detect-test-interference.ts +38 -5
  297. package/scripts/gate-pr-cache.ts +65 -0
  298. package/scripts/gh-surface/capture.ts +126 -0
  299. package/scripts/gh-surface/gh +40 -0
  300. package/scripts/import-graph-scc.ts +38 -0
  301. package/scripts/install.ps1 +19 -0
  302. package/scripts/intake-social.ts +181 -0
  303. package/scripts/lecture-note/node.ts +71 -4
  304. package/scripts/lib/android-toolchain.ts +32 -0
  305. package/scripts/lib/deterministic-env.ts +62 -0
  306. package/scripts/lib/gate-test-env.ts +19 -0
  307. package/scripts/measure-goal-grounding-corpus.ts +2 -1
  308. package/scripts/measure-si-task-cpu.ts +143 -0
  309. package/scripts/ratchets/test-interference-patterns.allowlist.txt +255 -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-closure.ts +12 -8
  317. package/scripts/release-loop/gate-diff.ts +1 -1
  318. package/scripts/release-loop/gate-host-mirror.ts +66 -0
  319. package/scripts/release-loop/gate-node.ts +523 -75
  320. package/scripts/release-loop/gate-partial.ts +106 -9
  321. package/scripts/release-loop/gate-pr-cache.ts +66 -0
  322. package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
  323. package/scripts/release-loop/gate-r2-verdict.ts +189 -0
  324. package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
  325. package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
  326. package/scripts/release-loop/import-graph-scc-run.ts +54 -0
  327. package/scripts/release-loop/import-graph-scc.ts +215 -0
  328. package/scripts/release-loop/node-verdict.ts +2 -0
  329. package/scripts/release-loop/prepare-node.ts +102 -4
  330. package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
  331. package/scripts/release-loop/resume-release.ts +33 -4
  332. package/scripts/release-loop/resume.ts +13 -5
  333. package/scripts/release-loop/spawn-lane.ts +2 -19
  334. package/scripts/release-loop/tui-sim-node.ts +3 -2
  335. package/scripts/release-loop/unattended-release.ts +16 -0
  336. package/scripts/test-deterministic.ts +5 -61
  337. package/scripts/train-reach-grouping.ts +48 -0
  338. package/scripts/tsc-incremental-cache.ts +86 -0
  339. package/scripts/tsc-incremental-diagnostics.ts +76 -0
  340. package/scripts/tsc-main-safety-net.ts +2 -2
  341. package/src/acp/client.ts +4 -1
  342. package/src/acp/core-turn-bridge.ts +65 -8
  343. package/src/acp/elanous-extensions.ts +3 -0
  344. package/src/acp/server.ts +3 -0
  345. package/src/acp/tool-trace.ts +186 -11
  346. package/src/ad-pipeline/run.ts +4 -2
  347. package/src/agent/runner.ts +169 -3
  348. package/src/agent/self-ambient-cache.ts +156 -0
  349. package/src/agent/self-ambient.ts +8 -1
  350. package/src/agent/subagent-callable.ts +3 -2
  351. package/src/agent/task-notification.ts +5 -0
  352. package/src/agent-mission/review-loop.ts +6 -3
  353. package/src/agent-substrate/acp-implementer.ts +14 -2
  354. package/src/agent-substrate/pr-reviewer.ts +14 -0
  355. package/src/agent-substrate/self-review-cli.ts +30 -4
  356. package/src/ask-user-question/tool.ts +22 -0
  357. package/src/autopilot/build/llm-conflict-merge.ts +56 -10
  358. package/src/autopilot/pr-manager.ts +80 -7
  359. package/src/briefing/brief-items.ts +24 -22
  360. package/src/capture/frame-state-detect.ts +39 -0
  361. package/src/capture/tui-self-report.ts +149 -6
  362. package/src/chat/chat-cli.ts +10 -2
  363. package/src/chat/index.ts +138 -26
  364. package/src/chat/input-control-key.ts +5 -3
  365. package/src/chat/pickers/modal-runtime.ts +6 -0
  366. package/src/chat/pickers/modals.ts +8 -2
  367. package/src/chat/tool-interrupt-behavior.ts +38 -0
  368. package/src/chat/tool-render/dispatch.ts +5 -1
  369. package/src/chat/turn-typeahead.ts +75 -20
  370. package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
  371. package/src/cli/agent-cli.ts +41 -13
  372. package/src/cli/ask-bare.ts +1 -0
  373. package/src/cli/config-audit.ts +123 -0
  374. package/src/cli/decisions-cli.ts +80 -6
  375. package/src/cli/import-cli.ts +12 -0
  376. package/src/cli/log-event-names.ts +17 -0
  377. package/src/cli/mcp-login.ts +21 -5
  378. package/src/cli/msg-cli.ts +89 -0
  379. package/src/cli/pod-cli.ts +14 -3
  380. package/src/cli/pr-cli.ts +273 -81
  381. package/src/cli/pr-land-base-read.ts +34 -0
  382. package/src/cli/pr-land-heavy-remote.ts +82 -26
  383. package/src/cli/pr-land-overlap-evidence.ts +109 -11
  384. package/src/cli/pr-land-pod-shadow-job.ts +106 -0
  385. package/src/cli/pr-land-pod-shadow.ts +16 -3
  386. package/src/cli/pr-land-refusal.ts +20 -5
  387. package/src/cli/pr-land-virtual-rebase.ts +108 -0
  388. package/src/cli/pty-takeover-cli.ts +88 -14
  389. package/src/cli/release-cli.ts +80 -14
  390. package/src/cli/seat-cli.ts +138 -3
  391. package/src/cli/self-update.ts +5 -2
  392. package/src/cli/sim-cli.ts +18 -0
  393. package/src/cli/tasks-cli.ts +97 -19
  394. package/src/context-bus/context-first.ts +13 -0
  395. package/src/context-bus/context-now.ts +13 -2
  396. package/src/context-bus/ops-events.ts +79 -0
  397. package/src/control-plane/lease-holder.ts +12 -8
  398. package/src/control-plane/ledger.ts +163 -4
  399. package/src/control-plane/server.ts +91 -11
  400. package/src/core-turn/run-core-turn.ts +2 -0
  401. package/src/core-turn/run-goal-loop.ts +243 -3
  402. package/src/core-turn/seat-turn-cap.ts +79 -0
  403. package/src/core-turn/short-question.ts +38 -6
  404. package/src/core-turn/types.ts +6 -0
  405. package/src/dashboard/acp-active-model.ts +42 -1
  406. package/src/dashboard/acp-boot.ts +3 -0
  407. package/src/dashboard/background-jobs-status.ts +66 -0
  408. package/src/dashboard/index.ts +339 -657
  409. package/src/dashboard/input/agent-wake.ts +242 -0
  410. package/src/dashboard/input/chat-main-entry-runtime.ts +6 -1
  411. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
  412. package/src/dashboard/input/chat-main-session.ts +8 -1
  413. package/src/dashboard/input/chat-main-turn.ts +12 -3
  414. package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
  415. package/src/dashboard/input/external-input-host.ts +49 -9
  416. package/src/dashboard/input/internal-turn.ts +261 -0
  417. package/src/dashboard/input/mouse-wiring.ts +108 -11
  418. package/src/dashboard/input/seat-autowake.ts +318 -0
  419. package/src/dashboard/input/turn-steer-bridge.ts +70 -0
  420. package/src/dashboard/log-click-runtime.ts +118 -2
  421. package/src/dashboard/loop-scheduler.ts +72 -0
  422. package/src/dashboard/seat-boot-preamble.ts +18 -0
  423. package/src/dashboard/skill-runtime.ts +2 -0
  424. package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
  425. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
  426. package/src/dashboard/slash-runtime/index.ts +13 -0
  427. package/src/dashboard/turn-busy-teardown.ts +50 -0
  428. package/src/dashboard/turn-preamble.ts +116 -40
  429. package/src/dashboard/turn-session-layers.ts +4 -2
  430. package/src/dashboard/turn-start-segments.ts +222 -0
  431. package/src/decisions/decision-ledger.ts +45 -4
  432. package/src/discord-self-message.ts +4 -4
  433. package/src/display/prompt-row-owner.ts +146 -0
  434. package/src/display/resize-listener.ts +33 -2
  435. package/src/domains/release-tool.ts +18 -1
  436. package/src/field-note/transcribe.ts +17 -0
  437. package/src/fold-stack.ts +4 -2
  438. package/src/git-fs/index.ts +263 -36
  439. package/src/github/remote-call.ts +81 -0
  440. package/src/goals/registry.ts +46 -6
  441. package/src/goals/types.ts +7 -1
  442. package/src/graph-runner/runner.ts +1 -0
  443. package/src/grok/credential.ts +26 -0
  444. package/src/harness/gate-reserve.ts +87 -0
  445. package/src/harness/harness-clean.ts +2 -1
  446. package/src/harness/harness-cli-command.ts +52 -5
  447. package/src/harness/harness-gc.ts +2 -1
  448. package/src/harness/harness-incidents.ts +70 -20
  449. package/src/harness/harness-pod-dispatch.ts +87 -10
  450. package/src/harness/harness-queue.ts +68 -4
  451. package/src/harness/harness-stop.ts +4 -3
  452. package/src/harness/harness-substrate-default.ts +78 -7
  453. package/src/harness/harness-worktree-auto.ts +2 -1
  454. package/src/harness/harness-worktrees.ts +3 -2
  455. package/src/hooks/dispatch.ts +2 -1
  456. package/src/index.ts +156 -27
  457. package/src/input/external-input-queue.ts +64 -7
  458. package/src/intake-plane/slash.ts +14 -3
  459. package/src/keybindings.ts +4 -1
  460. package/src/llm/route-decision.ts +36 -0
  461. package/src/llm/tool-loop-steered-rejection.ts +41 -0
  462. package/src/llm-request-shape.ts +209 -0
  463. package/src/llm.ts +301 -283
  464. package/src/loops/consensus.ts +348 -0
  465. package/src/loops/msg-wake.ts +206 -4
  466. package/src/loops/observe.ts +19 -3
  467. package/src/loops/orchestrator/tick.ts +88 -12
  468. package/src/loops/orchestrator/traffic.ts +64 -1
  469. package/src/loops/registry.ts +30 -0
  470. package/src/market/signed-index.ts +14 -0
  471. package/src/maturity/feature-maturity.ts +1 -1
  472. package/src/mcp/mcp-oauth.ts +54 -5
  473. package/src/models/prompts.ts +28 -0
  474. package/src/msg/msg-sse-client.ts +223 -0
  475. package/src/msg/msg-store.ts +86 -2
  476. package/src/mss/logging/log-store.ts +225 -1
  477. package/src/mss/logging/render-categories.ts +5 -0
  478. package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
  479. package/src/nexus/api/http-server.ts +54 -15
  480. package/src/nexus/api/loop-resources.ts +19 -3
  481. package/src/nexus/api/ops-api.ts +11 -0
  482. package/src/nexus/daemon-thin-inventory.md +37 -0
  483. package/src/nexus/index.ts +70 -0
  484. package/src/nexus/state/state.ts +1 -0
  485. package/src/oauth/store.ts +32 -7
  486. package/src/onboarding/first-run.ts +28 -3
  487. package/src/ops/overview-cache.ts +16 -4
  488. package/src/ops/overview.ts +59 -2
  489. package/src/ops/resources.ts +82 -0
  490. package/src/plugins/maker/connector-maker.ts +41 -0
  491. package/src/plugins/maker/skill-maker.ts +42 -0
  492. package/src/pr-tool/census.ts +303 -0
  493. package/src/pr-tool/inflight-registry.ts +143 -0
  494. package/src/prompt-library/chat-conciseness.ts +13 -0
  495. package/src/prompt-library/universal-preamble.ts +10 -5
  496. package/src/pty-shell/pty-manifest.ts +12 -3
  497. package/src/pty-shell/tui-run-state.ts +34 -3
  498. package/src/release-loop/gate-host-reservation.ts +97 -0
  499. package/src/release-loop/landing-freeze.ts +5 -0
  500. package/src/release-loop/light-rc.ts +5 -2
  501. package/src/release-loop/placement.ts +92 -1
  502. package/src/release-loop/rehearsal-shard-plan.ts +149 -0
  503. package/src/release-loop/rehearsal.ts +73 -17
  504. package/src/repl/index.ts +20 -2
  505. package/src/seat-loop/seat-knowhow.ts +282 -0
  506. package/src/seat-loop/seat-loop.ts +41 -2
  507. package/src/seat-loop/traffic-signal.ts +5 -1
  508. package/src/self-dev/ask-launch-flow.ts +37 -3
  509. package/src/self-dev/decompose-compose-graph.ts +28 -27
  510. package/src/self-dev/decompose-proposal.ts +53 -38
  511. package/src/self-dev/decompose.ts +17 -0
  512. package/src/self-dev/dev-pipeline.ts +31 -2
  513. package/src/self-dev/draft-residue.ts +267 -33
  514. package/src/self-dev/draft-sweep.ts +59 -4
  515. package/src/self-dev/external-call-zero.ts +77 -0
  516. package/src/self-dev/launch-preflight-text.ts +6 -0
  517. package/src/self-dev/launch-preflight.ts +25 -3
  518. package/src/self-dev/local-supervisor-judge.ts +185 -0
  519. package/src/self-dev/run-supervisor.ts +229 -19
  520. package/src/self-dev/run-types.ts +20 -0
  521. package/src/self-dev/shard-aggregate.ts +13 -2
  522. package/src/self-dev/shard-plan.ts +56 -1
  523. package/src/self-dev/shard-run.ts +207 -12
  524. package/src/self-dev/spawn-lane-files.ts +19 -0
  525. package/src/self-implement/app-api-budget.ts +51 -11
  526. package/src/self-implement/config-gate.ts +2 -1
  527. package/src/self-implement/elanous-tui-spawn.ts +14 -0
  528. package/src/self-implement/expose-gate.ts +2 -1
  529. package/src/self-implement/follow-up-placement.ts +79 -0
  530. package/src/self-implement/gate-artifacts.ts +416 -0
  531. package/src/self-implement/gate-baseline.ts +96 -5
  532. package/src/self-implement/gate-cli.ts +207 -17
  533. package/src/self-implement/gate-remote.ts +136 -26
  534. package/src/self-implement/gate-scenario.ts +85 -0
  535. package/src/self-implement/goal-author.ts +160 -8
  536. package/src/self-implement/graph-authority.ts +38 -6
  537. package/src/self-implement/graph-overlay-condition.ts +92 -1
  538. package/src/self-implement/heal-triage.ts +79 -0
  539. package/src/self-implement/host-regate.ts +97 -7
  540. package/src/self-implement/orchestrator.ts +115 -134
  541. package/src/self-implement/pr-title.ts +123 -0
  542. package/src/self-implement/run-checkpoint.ts +235 -0
  543. package/src/self-implement/run-ledger.ts +162 -15
  544. package/src/self-implement/run-stop.ts +4 -3
  545. package/src/self-implement/run-ttl.ts +28 -4
  546. package/src/self-implement/seams.ts +2 -0
  547. package/src/self-implement/shadow-stage.ts +7 -6
  548. package/src/self-implement/stop-autoheal.ts +2 -1
  549. package/src/self-implement/train-gate-remote.ts +37 -8
  550. package/src/self-implement/train-reach-grouping.ts +157 -0
  551. package/src/self-implement/train-scenario-layers.ts +133 -0
  552. package/src/self-implement/uncommitted-work.ts +2 -0
  553. package/src/session/pending-input.ts +19 -0
  554. package/src/session/session-start.ts +224 -0
  555. package/src/session-runtime/index.ts +22 -267
  556. package/src/session-runtime/parallel-dispatch.ts +22 -5
  557. package/src/shell-runner/background-surface.ts +15 -5
  558. package/src/skills/tools/agent.ts +39 -6
  559. package/src/skills/tools/dev-harness.ts +6 -4
  560. package/src/skills/tools/list-dir.ts +11 -0
  561. package/src/skills/tools/schedule-wakeup.ts +408 -0
  562. package/src/skills/tools/shell.ts +246 -4
  563. package/src/status/bar.ts +26 -0
  564. package/src/steward/digest-delivery.ts +118 -0
  565. package/src/steward/hold-hygiene.ts +120 -0
  566. package/src/steward/resync-tick.ts +114 -23
  567. package/src/steward/ta-repair-event-collect.ts +158 -0
  568. package/src/steward/triage.ts +10 -0
  569. package/src/surface/shell-runner-boot.ts +5 -2
  570. package/src/task-agent/card-evidence.ts +25 -1
  571. package/src/task-agent/green-sweep.ts +8 -3
  572. package/src/task-agent/judge.ts +76 -0
  573. package/src/task-agent/land-queue.ts +79 -0
  574. package/src/task-agent/live-moves.ts +30 -9
  575. package/src/task-agent/postland-card.ts +5 -0
  576. package/src/task-agent/prelaunch-already-done.ts +98 -0
  577. package/src/task-agent/real-launch-guard.ts +37 -0
  578. package/src/task-agent/rejudge-on-head.ts +89 -12
  579. package/src/task-agent/remote-rejudge-bind.ts +28 -8
  580. package/src/task-agent/repair-cycle.ts +45 -7
  581. package/src/task-agent/repair-worker.ts +7 -0
  582. package/src/task-agent/run-identity.ts +200 -0
  583. package/src/task-agent/shadow.ts +50 -3
  584. package/src/task-agent/task-hand.ts +182 -5
  585. package/src/task-agent/train-landing.ts +77 -0
  586. package/src/task-agent/work-order.ts +104 -0
  587. package/src/task-orchestrator/surfaces/pod-command-job.ts +151 -37
  588. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
  589. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
  590. package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
  591. package/src/task-orchestrator/surfaces/pod-install-slots.ts +121 -9
  592. package/src/task-orchestrator/surfaces/pod-lease.ts +118 -6
  593. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +1 -1
  594. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
  595. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +27 -0
  596. package/src/task-orchestrator/surfaces/pod-pool.ts +3 -1
  597. package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
  598. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +67 -0
  599. package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
  600. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
  601. package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
  602. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +525 -0
  603. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
  604. package/src/task-orchestrator/surfaces/pod-warm-worker-runner.ts +90 -0
  605. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +362 -0
  606. package/src/task-orchestrator/surfaces/self-implement-pod.ts +138 -19
  607. package/src/telegram.ts +2 -4
  608. package/src/tui/chat/execution-badge.ts +5 -1
  609. package/src/tui/input/pickers.ts +732 -0
  610. package/src/tui/input-lag-probe.ts +230 -0
  611. package/src/tui/slash/mission.ts +492 -0
  612. package/src/tui/slash/term.ts +877 -0
  613. package/src/tui-client/dashboard-session.ts +9 -0
  614. package/src/tui.ts +52 -0
  615. package/src/user-config/gemini-server-tools.ts +9 -0
  616. package/src/user-config.ts +53 -16
  617. package/src/util/spawn-sync-output.ts +7 -0
  618. package/src/ux-sim/fake-bin.ts +154 -0
  619. package/src/ux-sim/fake-clock.ts +36 -0
  620. package/src/ux-sim/headless-tui.ts +72 -0
  621. package/src/ux-sim/in-process-cli.ts +2 -1
  622. package/src/ux-sim/scenario.ts +255 -0
  623. package/src/ux-sim/temp-git-remote.ts +82 -0
  624. package/src/version/packed-revision.json +1 -1
  625. package/src/video-pipeline/recipes/vlog.ts +25 -7
  626. package/apps/pwa/out/_next/static/chunks/1015-9cba22a5a4554797.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
  630. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
  632. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
  635. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
  636. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
  639. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
  641. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
  647. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
  651. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
  662. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
  668. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
  671. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
  672. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
  673. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
  676. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
  678. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
  679. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
  680. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
  682. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
  688. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
  695. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
  698. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
  703. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
  705. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/botlab/page-a5635eba0d73b84e.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9f92737b8766009a.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
  768. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
  774. package/apps/pwa/out/_next/static/css/72becfd42807b50d.css +0 -1
  775. /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → IVKr3AlRUVLKsw2fh7eXF}/_ssgManifest.js +0 -0
@@ -1,3 +1,5 @@
1
+ import { isGateSpawnLaneFile } from './spawn-lane-files.js';
2
+
1
3
  export interface GateTestShard {
2
4
  id: string;
3
5
  files: string[];
@@ -5,6 +7,35 @@ export interface GateTestShard {
5
7
  plannedSeconds: number;
6
8
  }
7
9
 
10
+ /** A requested shard count cannot hold the measured files; more shards may make the same plan valid. */
11
+ export class GateShardCapacityError extends Error {
12
+ constructor(message: string) { super(message); this.name = 'Error'; }
13
+ }
14
+
15
+ /** Keep real child/PTY tests out of ordinary self-gate shards, within the caller's shard budget. */
16
+ export function planSelfGateSpawnSeparatedShards(
17
+ files: readonly string[],
18
+ rssMb: ReadonlyMap<string, number>,
19
+ seconds: ReadonlyMap<string, number>,
20
+ budgetGiB: number,
21
+ shardCount: number,
22
+ ): GateTestShard[] {
23
+ const unique = [...new Set(files)];
24
+ const spawn = unique.filter(isGateSpawnLaneFile);
25
+ const regular = unique.filter((file) => !isGateSpawnLaneFile(file));
26
+ if (!spawn.length || !regular.length) return planGateTestShards(unique, rssMb, seconds, budgetGiB, shardCount);
27
+ if (shardCount < 2) throw new GateShardCapacityError('self gate spawn lane needs at least two shards when regular and spawn tests coexist');
28
+ // Three spawn bundles are the normal lane width, not a memory ceiling. A 5 GiB spawn file cannot share an 8 GiB
29
+ // bundle with another such file; retain lane isolation while allowing the measured plan to grow past three.
30
+ const neededSpawn = planGateTestShards(spawn, rssMb, seconds, budgetGiB).length;
31
+ const spawnCount = Math.min(spawn.length, shardCount - 1, Math.max(3, neededSpawn));
32
+ const planned = [
33
+ ...planGateTestShards(regular, rssMb, seconds, budgetGiB, shardCount - spawnCount),
34
+ ...planGateTestShards(spawn, rssMb, seconds, budgetGiB, spawnCount),
35
+ ];
36
+ return planned.map((shard, index) => ({ ...shard, id: `shard-${index + 1}` }));
37
+ }
38
+
8
39
  /** RSS values are the per-file rss_mb observations; the budget is in GiB (1 GiB = 1024 MB here). */
9
40
  export function planGateTestShards(
10
41
  files: readonly string[],
@@ -42,7 +73,7 @@ export function planGateTestShards(
42
73
  if (!shard) {
43
74
  const totalRssMb = sorted.reduce((sum, candidate) => sum + rssMb.get(candidate)!, 0);
44
75
  const largestRssMb = rssMb.get(sorted[0]!)!;
45
- throw new Error(`test files exceed ${shardCount} shard memory budgets (files=${unique.length} · totalRssMb=${Math.round(totalRssMb)} · largestRssMb=${Math.round(largestRssMb)} · budgetMb=${capacity} · neededShards≥${Math.ceil(totalRssMb / capacity)})`);
76
+ throw new GateShardCapacityError(`test files exceed ${shardCount} shard memory budgets (files=${unique.length} · totalRssMb=${Math.round(totalRssMb)} · largestRssMb=${Math.round(largestRssMb)} · budgetMb=${capacity} · neededShards≥${Math.ceil(totalRssMb / capacity)})`);
46
77
  }
47
78
  shard.files.push(file);
48
79
  shard.plannedRssMb += rss;
@@ -50,3 +81,27 @@ export function planGateTestShards(
50
81
  }
51
82
  return shards;
52
83
  }
84
+
85
+ /** OP FU (LAND-TRAIN-LIVE side) — opt-in `--fixed-shard-distribution`: no RSS/seconds measurement. Files are deduplicated,
86
+ * sorted by code point (input-order independent) and dealt round-robin into at most `shardCount` shards; real child/PTY
87
+ * tests keep their own lane exactly like the measured planner. Not a memory-safety guarantee — an over-budget shard
88
+ * surfaces as its own run result (signal/exit/incomplete JUnit ⇒ unmeasured), never as a pass. No empty shards. */
89
+ export function planFixedGateTestShards(files: readonly string[], shardCount: number): GateTestShard[] {
90
+ if (!Number.isSafeInteger(shardCount) || shardCount < 1) throw new Error('invalid shard count');
91
+ const sorted = [...new Set(files)].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
92
+ const deal = (subset: readonly string[], count: number): string[][] => {
93
+ const buckets: string[][] = Array.from({ length: Math.min(count, subset.length) }, () => []);
94
+ subset.forEach((file, index) => buckets[index % buckets.length]!.push(file));
95
+ return buckets;
96
+ };
97
+ const spawn = sorted.filter(isGateSpawnLaneFile);
98
+ const regular = sorted.filter((file) => !isGateSpawnLaneFile(file));
99
+ let groups: string[][];
100
+ if (!spawn.length || !regular.length) groups = deal(sorted, shardCount);
101
+ else {
102
+ if (shardCount < 2) throw new Error('self gate spawn lane needs at least two shards when regular and spawn tests coexist');
103
+ const spawnCount = Math.min(3, spawn.length, shardCount - 1);
104
+ groups = [...deal(regular, shardCount - spawnCount), ...deal(spawn, spawnCount)];
105
+ }
106
+ return groups.map((group, index) => ({ id: `shard-${index + 1}`, files: group, plannedRssMb: 0, plannedSeconds: 0 }));
107
+ }
@@ -1,11 +1,13 @@
1
- import { existsSync, mkdtempSync, readFileSync, rmSync, statSync } from 'node:fs';
2
- import { tmpdir } from 'node:os';
1
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statfsSync, statSync, writeFileSync } from 'node:fs';
2
+ import { availableParallelism, freemem, tmpdir } from 'node:os';
3
3
  import { join } from 'node:path';
4
4
  import { debug, redactSecretText } from '../debug/log.js';
5
5
  import { prepareDeterministicChildEnvironment } from '../../scripts/lib/deterministic-env.js';
6
+ import { withGateTestEnv } from '../../scripts/lib/gate-test-env.js';
6
7
  import { withBaselineWorktree } from '../self-implement/gate-baseline.js';
7
8
  import { aggregateGateTestShards, type GateShardAttempt, type GateShardAggregate } from './shard-aggregate.js';
8
- import { planGateTestShards, type GateTestShard } from './shard-plan.js';
9
+ import { GateShardCapacityError, planFixedGateTestShards, planSelfGateSpawnSeparatedShards, type GateTestShard } from './shard-plan.js';
10
+ import { isGateSpawnLaneFile } from './spawn-lane-files.js';
9
11
 
10
12
  export interface ShardRunResult {
11
13
  aggregate: GateShardAggregate;
@@ -13,6 +15,70 @@ export interface ShardRunResult {
13
15
  attempts: GateShardAttempt[];
14
16
  reason?: string;
15
17
  measurementFailures?: number;
18
+ /** The measured RSS plan needed more bundles than the requested count. */
19
+ expandedFrom?: number;
20
+ /** A fixed plan selected explicitly, or after the measured plan exceeds host expansion capacity. */
21
+ distribution?: 'fixed' | 'fixed-cap-fallback';
22
+ fallbackReason?: string;
23
+ /** OP FU (MK #8178 shard-9) — raw evidence of every failed shard process (exit≠0 · signal · no JUnit). Observation only:
24
+ * the aggregate never reads it. Absent = no shard process reported failure output. */
25
+ failureEvidence?: ShardFailureEvidence[];
26
+ /** Latest failed attempt's reason for each incomplete shard; copied into the gate artifact summary. */
27
+ unmeasuredByShard?: Record<string, string>;
28
+ }
29
+
30
+ /** What a failed shard process leaves behind so «test failure vs runner error» can be told apart after the fact. */
31
+ export interface ShardFailureOutput {
32
+ durationMs: number;
33
+ /** Last 64KB of the child's stdout/stderr (redacted). */
34
+ stdoutTail: string;
35
+ stderrTail: string;
36
+ }
37
+
38
+ export interface ShardFailureEvidence extends ShardFailureOutput {
39
+ shardId: string;
40
+ side: 'current' | 'baseline';
41
+ attempt: number;
42
+ files: string[];
43
+ exitCode: number | null;
44
+ signal: string | null;
45
+ }
46
+
47
+ export interface ShardRunMode {
48
+ /** OP FU — sorted round-robin into `count` shards, zero pre-measurement runs. Default off: the measured planner. */
49
+ fixedDistribution?: boolean;
50
+ /** Measured on the executing host; override only for deterministic planning tests. */
51
+ hostResources?: { cores: number; freeMemoryGiB: number; freeTmpGiB: number };
52
+ }
53
+
54
+ function hostResources(): ShardRunMode['hostResources'] | undefined {
55
+ try {
56
+ const tmp = statfsSync(tmpdir());
57
+ // Linux page cache is reclaimable. `freemem()` alone saw only ~10 GiB on a WSL host
58
+ // with 24 GiB MemAvailable and would incorrectly cap a two-shard plan at one.
59
+ let freeMemoryGiB = freemem() / (1024 ** 3);
60
+ if (process.platform === 'linux') {
61
+ const availableKiB = /^MemAvailable:\s+(\d+)\s+kB/m.exec(readFileSync('/proc/meminfo', 'utf8'))?.[1];
62
+ if (availableKiB) freeMemoryGiB = Number(availableKiB) / (1024 ** 2);
63
+ }
64
+ return {
65
+ cores: availableParallelism(),
66
+ freeMemoryGiB,
67
+ freeTmpGiB: Number(tmp.bavail) * Number(tmp.bsize) / (1024 ** 3),
68
+ };
69
+ } catch { return undefined; }
70
+ }
71
+
72
+ /** One expansion slot needs one CPU, one shard memory budget, and 1 GiB of free tmp space.
73
+ * Explicitly requested shards remain the caller's choice; this only limits automatic growth. */
74
+ export function maxAutomaticShardCount(requested: number, budgetGiB: number, resources: ShardRunMode['hostResources']): number {
75
+ if (!resources || !Number.isFinite(budgetGiB) || budgetGiB <= 0) return requested;
76
+ const limit = Math.min(
77
+ Math.floor(resources.cores),
78
+ Math.floor(resources.freeMemoryGiB / budgetGiB),
79
+ Math.floor(resources.freeTmpGiB),
80
+ );
81
+ return Math.max(requested, Number.isFinite(limit) ? limit : requested);
16
82
  }
17
83
 
18
84
  export type ShardProcess = (cwd: string, files: readonly string[]) => {
@@ -23,8 +89,37 @@ export type ShardProcess = (cwd: string, files: readonly string[]) => {
23
89
  seconds?: number;
24
90
  /** Bounded, redacted process output for an abnormal exit before JUnit exists. */
25
91
  diagnostic?: string;
92
+ /** Present only when the process failed (exit≠0 · signal · no JUnit) — observation only, never part of the verdict. */
93
+ failure?: ShardFailureOutput;
26
94
  };
27
95
 
96
+ export const SHARD_FAILURE_TAIL_BYTES = 64 * 1024;
97
+
98
+ function outputTail(bytes: Uint8Array | undefined): string {
99
+ if (!bytes?.length) return '';
100
+ const tail = bytes.length > SHARD_FAILURE_TAIL_BYTES ? bytes.subarray(bytes.length - SHARD_FAILURE_TAIL_BYTES) : bytes;
101
+ return redactSecretText(Buffer.from(tail).toString('utf8'));
102
+ }
103
+
104
+ /** `<shardId>.failure.json` per failed shard (shard ids are already `shard-<n>`). Top level = the latest current-side
105
+ * failure (else the latest baseline one); `failures` keeps every failed side/attempt. Returns the written paths. */
106
+ export function writeShardFailureEvidence(dir: string, evidence: readonly ShardFailureEvidence[]): string[] {
107
+ if (!evidence.length) return [];
108
+ mkdirSync(dir, { recursive: true });
109
+ const byShard = new Map<string, ShardFailureEvidence[]>();
110
+ for (const item of evidence) byShard.set(item.shardId, [...(byShard.get(item.shardId) ?? []), item]);
111
+ const written: string[] = [];
112
+ for (const [shardId, failures] of byShard) {
113
+ const primary = [...failures].reverse().find((item) => item.side === 'current') ?? failures[failures.length - 1]!;
114
+ const path = join(dir, `${shardId.replace(/[^A-Za-z0-9._-]/g, '_')}.failure.json`);
115
+ const { side, attempt, ...fields } = primary;
116
+ writeFileSync(path, `${JSON.stringify({ ...fields, side, attempt, failures }, null, 2)}\n`);
117
+ debug.log('self-dev.shard', 'failure-evidence', { shardId, path, failures: failures.length, exitCode: primary.exitCode, signal: primary.signal });
118
+ written.push(path);
119
+ }
120
+ return written;
121
+ }
122
+
28
123
  const DIAGNOSTIC_STREAM_LIMIT = 240;
29
124
 
30
125
  function boundedDiagnostic(stdout: Uint8Array, stderr: Uint8Array): string | undefined {
@@ -56,8 +151,17 @@ export function runShardedGateTests(
56
151
  run: ShardProcess = runBunShard,
57
152
  baselineWorktree: typeof withBaselineWorktree = withBaselineWorktree,
58
153
  budgetGiB = 8,
154
+ mode: ShardRunMode = {},
59
155
  ): ShardRunResult {
60
156
  if (!Number.isSafeInteger(count) || count < 1) throw new Error('invalid --shards count');
157
+ if (mode.fixedDistribution) {
158
+ // Opt-in: no per-file pre-measurement at all — the shard runs themselves (JUnit · rc · signal · baseline) decide.
159
+ let fixed: GateTestShard[];
160
+ try { fixed = planFixedGateTestShards(files, count); }
161
+ catch (error) { return { aggregate: { status: 'unmeasured', retryShardIds: [] }, shards: [], attempts: [], reason: String(error), distribution: 'fixed' }; }
162
+ debug.log('self-dev.shard', 'fixed-distribution', { shards: fixed.length, files: fixed.reduce((sum, shard) => sum + shard.files.length, 0) });
163
+ return { ...runPlannedShards(cwd, fixed, baseRef, run, baselineWorktree), distribution: 'fixed' };
164
+ }
61
165
  const rss = new Map<string, number>();
62
166
  const seconds = new Map<string, number>();
63
167
  const failedMeasurements: string[] = [];
@@ -88,13 +192,61 @@ export function runShardedGateTests(
88
192
  }
89
193
  }
90
194
  const measurementFailures = failedMeasurements.length || undefined;
91
- let shards: GateTestShard[];
195
+ const fixedAtHostCap = (maxCount: number, reason: string): ShardRunResult => {
196
+ try {
197
+ const fixed = planFixedGateTestShards(files, maxCount);
198
+ debug.log('self-dev.shard', 'host-cap-fixed-fallback', { requested: count, cap: maxCount,
199
+ files: new Set(files).size, reason, measurementFailures: measurementFailures ?? 0 });
200
+ return { ...runPlannedShards(cwd, fixed, baseRef, run, baselineWorktree), distribution: 'fixed-cap-fallback',
201
+ fallbackReason: reason, ...(measurementFailures ? { measurementFailures } : {}) };
202
+ } catch (error) {
203
+ return { aggregate: { status: 'unmeasured', retryShardIds: [] }, shards: [], attempts: [],
204
+ reason: `host-cap fixed fallback failed: ${String(error)}; measured plan: ${reason}`,
205
+ ...(measurementFailures ? { measurementFailures } : {}) };
206
+ }
207
+ };
208
+ let shards: GateTestShard[] | undefined;
209
+ let plannedCount = count;
92
210
  try {
93
- shards = planGateTestShards(files, rss, seconds, budgetGiB, count);
211
+ const fileCount = new Set(files).size;
212
+ const totalRss = [...rss.values()].reduce((sum, value) => sum + value, 0);
213
+ const lowerBound = Number.isFinite(budgetGiB) && budgetGiB > 0 ? Math.ceil(totalRss / (budgetGiB * 1024)) : count;
214
+ plannedCount = Math.max(count, Math.min(fileCount, lowerBound));
215
+ // The requested count may exceed the number of files. Only expansion is bounded by file count.
216
+ const maxCount = Math.max(count, Math.min(fileCount, maxAutomaticShardCount(count, budgetGiB, mode.hostResources ?? hostResources())));
217
+ if (plannedCount > maxCount) return fixedAtHostCap(maxCount, `host shard expansion cap ${maxCount} < needed ${plannedCount} (requested ${count}, measured RSS sum ${Math.round(totalRss)} MiB, budget ${budgetGiB} GiB)`);
218
+ for (; plannedCount <= maxCount; plannedCount++) {
219
+ try { shards = planSelfGateSpawnSeparatedShards(files, rss, seconds, budgetGiB, plannedCount); break; }
220
+ catch (error) {
221
+ if (!(error instanceof GateShardCapacityError)) throw error;
222
+ if (plannedCount === maxCount) return fixedAtHostCap(maxCount, `host shard expansion cap ${maxCount} < needed ≥${maxCount + 1} (requested ${count}, ${error.message})`);
223
+ }
224
+ }
94
225
  } catch (error) {
95
226
  return { aggregate: { status: 'unmeasured', retryShardIds: [] }, shards: [], attempts: [], reason: String(error), ...(measurementFailures ? { measurementFailures } : {}) };
96
227
  }
228
+ if (!shards) return { aggregate: { status: 'unmeasured', retryShardIds: [] }, shards: [], attempts: [], reason: 'shard planning produced no result' };
229
+ if (plannedCount > count) debug.log('self-dev.shard', 'plan-expanded', {
230
+ requested: count, planned: shards.length, files: new Set(files).size, budgetGiB,
231
+ measurementFailures: measurementFailures ?? 0,
232
+ });
233
+ return { ...runPlannedShards(cwd, shards, baseRef, run, baselineWorktree), ...(plannedCount > count ? { expandedFrom: count } : {}), ...(measurementFailures ? { measurementFailures } : {}) };
234
+ }
235
+
236
+ /** Shared by the measured and the fixed planner: current + baseline per shard, one retry round, one aggregate. */
237
+ function runPlannedShards(
238
+ cwd: string,
239
+ shards: GateTestShard[],
240
+ baseRef: string,
241
+ run: ShardProcess,
242
+ baselineWorktree: typeof withBaselineWorktree,
243
+ ): ShardRunResult {
97
244
  const attempts: GateShardAttempt[] = [];
245
+ const failureEvidence: ShardFailureEvidence[] = [];
246
+ const keepFailure = (shardId: string, side: ShardFailureEvidence['side'], attempt: number, files: readonly string[], result: ReturnType<ShardProcess>) => {
247
+ if (!result.failure) return;
248
+ failureEvidence.push({ shardId, side, attempt, files: [...files], exitCode: result.exitCode, signal: result.signal ?? null, ...result.failure });
249
+ };
98
250
  const baseline = baselineWorktree(cwd, baseRef, (dir) => {
99
251
  // LIGHT-RC-MEASURE ① — bun silently skips a path that is not in the baseline tree (exit 0), so a shard holding a
100
252
  // new test file could never yield a complete baseline JUnit. Run the baseline side on the files the base has; an
@@ -114,6 +266,8 @@ export function runShardedGateTests(
114
266
  }
115
267
  const current = runSafely(cwd, shard.files);
116
268
  const base = baselineFiles.length ? runSafely(dir, baselineFiles) : { exitCode: 0 };
269
+ keepFailure(shard.id, 'current', round, shard.files, current);
270
+ keepFailure(shard.id, 'baseline', round, baselineFiles, base);
117
271
  attempts.push({
118
272
  shardId: shard.id, attempt: round,
119
273
  currentJUnit: current.junit, baselineJUnit: base.junit,
@@ -128,22 +282,62 @@ export function runShardedGateTests(
128
282
  }
129
283
  return aggregateGateTestShards(shards, attempts);
130
284
  });
131
- if ('retryShardIds' in baseline) return { aggregate: baseline, shards, attempts, ...(measurementFailures ? { measurementFailures } : {}) };
132
- return { aggregate: { status: 'unmeasured', retryShardIds: shards.map((shard) => shard.id) }, shards, attempts, reason: baseline.log, ...(measurementFailures ? { measurementFailures } : {}) };
285
+ const evidence = failureEvidence.length ? { failureEvidence } : {};
286
+ if ('retryShardIds' in baseline) return {
287
+ aggregate: baseline, shards, attempts, ...evidence,
288
+ ...(baseline.retryShardIds.length ? { unmeasuredByShard: incompleteShardReasons(baseline.retryShardIds, attempts) } : {}),
289
+ };
290
+ const retryShardIds = shards.map((shard) => shard.id);
291
+ return {
292
+ aggregate: { status: 'unmeasured', retryShardIds }, shards, attempts, reason: baseline.log, ...evidence,
293
+ unmeasuredByShard: Object.fromEntries(retryShardIds.map((id) => [id, `baseline worktree: ${redactSecretText(baseline.log).replace(/[\r\n\t\x00-\x1f\x7f]+/g, ' ').slice(0, 500)}`])),
294
+ };
295
+ }
296
+
297
+ function incompleteShardReasons(shardIds: readonly string[], attempts: readonly GateShardAttempt[]): Record<string, string> {
298
+ return Object.fromEntries(shardIds.map((id) => {
299
+ const latest = attempts.filter((attempt) => attempt.shardId === id).at(-1);
300
+ if (!latest) return [id, 'no shard attempt recorded'];
301
+ const side = (name: string, rc: number | null, signal: string | null | undefined, junit: string | undefined, diagnostic: string | undefined): string => {
302
+ const safeDiagnostic = diagnostic ? redactSecretText(diagnostic).replace(/[\r\n\t\x00-\x1f\x7f]+/g, ' ').slice(0, 500) : undefined;
303
+ return `${name}: exit ${rc ?? 'unavailable'}, signal ${signal ?? 'none'}, JUnit ${junit === undefined ? 'missing' : 'present'}`
304
+ + (safeDiagnostic ? `; ${safeDiagnostic}` : '');
305
+ };
306
+ const statuses = [
307
+ side('current', latest.currentExitCode, latest.currentSignal, latest.currentJUnit, latest.currentDiagnostic),
308
+ ...(latest.baselineFiles?.length === 0 ? [] : [side('baseline', latest.baselineExitCode, latest.baselineSignal, latest.baselineJUnit, latest.baselineDiagnostic)]),
309
+ ];
310
+ return [id, `${statuses.join(' · ')} · aggregate rejected (incomplete, malformed JUnit, or exit/JUnit mismatch)`];
311
+ }));
312
+ }
313
+
314
+ export function selfGateShardTimeoutMs(files: readonly string[]): number {
315
+ const spawnFiles = files.filter(isGateSpawnLaneFile);
316
+ if (spawnFiles.length && spawnFiles.length !== files.length) throw new Error('self gate spawn lane mixed with regular tests');
317
+ return spawnFiles.length ? 120_000 : 300_000;
133
318
  }
134
319
 
135
320
  export function runBunShard(cwd: string, files: readonly string[]): ReturnType<ShardProcess> {
321
+ return runBunShardWithSpawn(cwd, files, Bun.spawnSync);
322
+ }
323
+
324
+ /** Child launch seam for verifying the actual command and process timeout. */
325
+ export function runBunShardWithSpawn(cwd: string, files: readonly string[], spawn: typeof Bun.spawnSync): ReturnType<ShardProcess> {
326
+ const timeout = selfGateShardTimeoutMs(files);
327
+ const spawnLane = timeout === 120_000;
136
328
  const dir = mkdtempSync(join(tmpdir(), 'elanous-shard-junit-'));
137
329
  const report = join(dir, 'result.xml');
138
- const isolated = prepareDeterministicChildEnvironment('elanous-shard-test-env-');
330
+ const isolated = prepareDeterministicChildEnvironment('elanous-shard-test-env-', { env: withGateTestEnv(process.env) });
139
331
  try {
140
332
  const measured = files.length === 1;
141
- const args = ['test', '--reporter=junit', `--reporter-outfile=${report}`, ...files];
333
+ const args = ['test', ...(spawnLane ? ['--timeout=120000'] : []), '--reporter=junit', `--reporter-outfile=${report}`, ...files];
142
334
  const started = performance.now();
143
- const result = Bun.spawnSync(['bun', ...args], {
144
- cwd, env: isolated.env, stdout: 'pipe', stderr: 'pipe', timeout: 300_000,
335
+ const result = spawn(['bun', ...args], {
336
+ cwd, env: isolated.env, stdout: 'pipe', stderr: 'pipe', timeout,
145
337
  });
338
+ const durationMs = performance.now() - started;
146
339
  const junit = existsSync(report) ? readFileSync(report, 'utf8') : undefined;
340
+ const failed = result.exitCode !== 0 || !!result.signalCode || junit === undefined;
147
341
  return {
148
342
  exitCode: result.exitCode,
149
343
  signal: result.signalCode ? String(result.signalCode) : undefined,
@@ -151,7 +345,8 @@ export function runBunShard(cwd: string, files: readonly string[]): ReturnType<S
151
345
  ...(junit === undefined && (result.exitCode !== 0 || result.signalCode)
152
346
  ? { diagnostic: boundedDiagnostic(result.stdout, result.stderr) } : {}),
153
347
  rssMb: measured ? result.resourceUsage.maxRSS / (1024 * 1024) : undefined,
154
- seconds: measured ? (performance.now() - started) / 1000 : undefined,
348
+ seconds: measured ? durationMs / 1000 : undefined,
349
+ ...(failed ? { failure: { durationMs: Math.round(durationMs), stdoutTail: outputTail(result.stdout), stderrTail: outputTail(result.stderr) } } : {}),
155
350
  };
156
351
  } finally {
157
352
  isolated.cleanup();
@@ -0,0 +1,19 @@
1
+ /** Real child/PTY test files. This list is shared by release and self gates. */
2
+ export const GATE_SPAWN_LANE_FILES = [
3
+ 'scripts/lib/tui-runshell-group-e2e.test.ts',
4
+ 'scripts/lib/tui-streaming-e2e.test.ts',
5
+ 'src/agent-mission/doc-guided-install.test.ts',
6
+ 'src/dashboard/first-screen-band-wiring.test.ts',
7
+ 'src/git-fs/spawn-discipline.test.ts',
8
+ 'src/self-implement/run-ledger.test.ts',
9
+ 'src/video-pipeline/recipes/reframe.test.ts',
10
+ 'test/ch5730-watch-delivery.test.ts',
11
+ 'test/cli-dev-command.test.ts',
12
+ 'test/preview-terminal.test.ts',
13
+ ] as const;
14
+
15
+ const SPAWN_FILES: ReadonlySet<string> = new Set(GATE_SPAWN_LANE_FILES);
16
+
17
+ export function isGateSpawnLaneFile(file: string): boolean {
18
+ return SPAWN_FILES.has(file);
19
+ }
@@ -1,6 +1,7 @@
1
1
  import { execFile as execFileCb } from 'node:child_process';
2
2
  import { promisify } from 'node:util';
3
3
  import { debug } from '../debug/log.js';
4
+ import { runGithubRemoteCall } from '../github/remote-call.js';
4
5
  import { releaseGitDiffPaths, releasePrFilePaths } from '../self-dev/release-path-guard.js';
5
6
 
6
7
  const defaultExecFile = promisify(execFileCb);
@@ -33,6 +34,25 @@ const GH_APP_CALLERS = {
33
34
 
34
35
  export type GhAppCaller = keyof typeof GH_APP_CALLERS;
35
36
 
37
+ /** Fixed routes keep `--body`, `-f body=…`, labels, and tokens out of both log categories. */
38
+ const GH_APP_ROUTES: Record<GhAppCaller, string> = {
39
+ 'post-pr-comment-history': 'repos/{owner}/{repo}/issues/:number/comments',
40
+ 'post-pr-comment': 'pr/:number/comment',
41
+ 'find-pr-comment': 'repos/{owner}/{repo}/issues/:number/comments',
42
+ 'edit-pr-comment': 'repos/{owner}/{repo}/issues/comments/:id',
43
+ 'add-pr-label-list': 'label/list',
44
+ 'add-pr-label-create': 'label/create',
45
+ 'add-pr-label': 'pr/:number/edit',
46
+ 'read-pr-files': 'repos/{owner}/{repo}/pulls/:number/files',
47
+ };
48
+
49
+ function observedGhMethod(args: readonly string[]): string | undefined {
50
+ if (args[0] !== 'api') return undefined; // gh pr/label may choose REST or GraphQL internally
51
+ const at = args.indexOf('--method');
52
+ const value = at >= 0 ? args[at + 1] : undefined;
53
+ return value && /^(GET|POST|PUT|PATCH|DELETE)$/.test(value) ? value : undefined;
54
+ }
55
+
36
56
  export const APP_API_RATE_LIMIT_RETRY_CAP_MS = 15 * 60_000;
37
57
 
38
58
  export class AppApiRateLimitError extends Error {
@@ -83,14 +103,32 @@ export async function waitForAppApiRateLimitReset(
83
103
  export async function runGhApp(
84
104
  caller: GhAppCaller,
85
105
  args: readonly string[],
86
- opts: { cwd: string; encoding: 'utf8'; timeout: number; maxBuffer?: number; env: NodeJS.ProcessEnv },
106
+ opts: { cwd: string; encoding: 'utf8'; timeout: number; maxBuffer?: number; env: NodeJS.ProcessEnv; retry?: number },
87
107
  ): Promise<{ stdout: string; stderr: string }> {
108
+ const { retry, ...execOpts } = opts;
88
109
  let stdout = '';
89
110
  let stderr = '';
90
111
  let status: number | undefined;
91
112
  let error: unknown;
92
113
  try {
93
- const result = await execFileImpl('gh', args, opts);
114
+ const result = await runGithubRemoteCall({
115
+ kind: args[0] === 'api' ? 'rest' : 'gh-command',
116
+ caller: GH_APP_CALLERS[caller],
117
+ route: GH_APP_ROUTES[caller],
118
+ method: observedGhMethod(args),
119
+ host: 'unmeasured', // gh may select the repo host even when GH_HOST is set
120
+ runId: opts.env.ELANOUS_RUN_ID,
121
+ retry,
122
+ }, () => execFileImpl('gh', args, execOpts), {
123
+ status: ({ failed, error: callError }) => {
124
+ if (!failed) return undefined; // gh exit 0 is not an observed HTTP 200
125
+ const raw = (callError as { stderr?: unknown })?.stderr;
126
+ const failureStderr = typeof raw === 'string' ? raw : '';
127
+ const header = ghHeader(failureStderr, 'HTTP') ?? ghHeader(failureStderr, 'status');
128
+ const code = header ? Number.parseInt(header, 10) : NaN;
129
+ return Number.isFinite(code) ? code : undefined;
130
+ },
131
+ });
94
132
  stdout = result.stdout;
95
133
  stderr = result.stderr ?? '';
96
134
  status = 200;
@@ -102,12 +140,14 @@ export async function runGhApp(
102
140
  status = ghStatusCode(stderr, caught);
103
141
  }
104
142
  const remaining = ghHeader(stderr, 'X-RateLimit-Remaining');
105
- debug.log('github.app-api', 'call', {
106
- caller: GH_APP_CALLERS[caller],
107
- endpoint: args.filter((arg) => !arg.startsWith('-')).at(-1) ?? 'gh',
108
- status: status ?? 0,
109
- remaining: remaining ?? '',
110
- });
143
+ try {
144
+ debug.log('github.app-api', 'call', {
145
+ caller: GH_APP_CALLERS[caller],
146
+ endpoint: GH_APP_ROUTES[caller],
147
+ status: status ?? 0,
148
+ remaining: remaining ?? '',
149
+ });
150
+ } catch { /* observation cannot replace the gh result or its original error */ }
111
151
  if (error) {
112
152
  const text = `${stderr}\n${error instanceof Error ? error.message : String(error)}`;
113
153
  if (isAppApiRateLimitFailure(status, text, remaining)) {
@@ -138,7 +178,7 @@ export async function readPrFilesWithRateLimitFallback(input: {
138
178
  `repos/{owner}/{repo}/pulls/${input.number}/files`,
139
179
  ];
140
180
  const ghOpts = { cwd: input.cwd, encoding: 'utf8' as const, timeout: GIT_TIMEOUT, maxBuffer: 64 * 1024 * 1024, env };
141
- const fromApi = async () => releasePrFilePaths(JSON.parse((await runGhApp('read-pr-files', endpoint, ghOpts)).stdout));
181
+ const fromApi = async (retry: number) => releasePrFilePaths(JSON.parse((await runGhApp('read-pr-files', endpoint, { ...ghOpts, retry })).stdout));
142
182
  const fromGit = async (): Promise<string[]> => {
143
183
  const base = input.base ?? 'origin/main';
144
184
  const { stdout } = await execFileImpl('git', ['diff', '--find-renames', '--name-status', '-z', `${base}...HEAD`], {
@@ -147,7 +187,7 @@ export async function readPrFilesWithRateLimitFallback(input: {
147
187
  return releaseGitDiffPaths(stdout);
148
188
  };
149
189
  try {
150
- return await fromApi();
190
+ return await fromApi(0);
151
191
  } catch (error) {
152
192
  if (!(error instanceof AppApiRateLimitError)) throw error;
153
193
  try {
@@ -156,7 +196,7 @@ export async function readPrFilesWithRateLimitFallback(input: {
156
196
  const waited = await waitForAppApiRateLimitReset(error.resetAtMs, input.now?.() ?? Date.now(), input.sleep);
157
197
  if (!waited) throw error;
158
198
  try {
159
- return await fromApi();
199
+ return await fromApi(1);
160
200
  } catch (retryError) {
161
201
  if (retryError instanceof AppApiRateLimitError) throw retryError;
162
202
  throw gitError;
@@ -8,6 +8,7 @@
8
8
  // 셸 검사는 `zsh -n`/`bash -n`(구문만·미실행). JSON/TOML 은 인-프로세스 파싱(외부 프로세스 불필요).
9
9
 
10
10
  import { spawnSync } from 'node:child_process';
11
+ import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
11
12
  import { readFileSync } from 'node:fs';
12
13
  import { basename } from 'node:path';
13
14
 
@@ -32,7 +33,7 @@ export function runConfigSyntaxGate(filePath: string): ConfigGateResult {
32
33
  const isBash = /(^|\.)(bashrc|bash_profile|bash_login|profile|bash_aliases)$/.test(name) || name.endsWith('.bash') || name.endsWith('.sh');
33
34
  if (isZsh || isBash) {
34
35
  const shell = isZsh ? 'zsh' : 'bash';
35
- const r = spawnSync(shell, ['-n', filePath], { encoding: 'utf8', timeout: SHELL_TIMEOUT_MS });
36
+ const r = spawnSync(shell, ['-n', filePath], { encoding: 'utf8', timeout: SHELL_TIMEOUT_MS, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
36
37
  // 셸 미설치(status=null·ENOENT) → 검사 불가로 skip(차단 아님·HITL diff 로 검증).
37
38
  if (r.error || r.status === null) return { passed: true, checked: false, label: `${shell} -n (미설치)`, log: String(r.error?.message ?? 'shell 없음') };
38
39
  return { passed: r.status === 0, checked: true, label: `${shell} -n`, log: `${r.stdout ?? ''}${r.stderr ?? ''}`.slice(-2000) };
@@ -13,6 +13,10 @@ import { selfDevRunsDir } from '../self-dev/run-store.js';
13
13
  import { syncTestConfig } from '../cli/config-test-sync.js';
14
14
  import { debug } from '../debug/log.js';
15
15
 
16
+ /** = `PREAMBLE_SYNC_BLOCK_ENV`(dashboard/turn-preamble.ts). 그 모듈을 끌어오지 않으려 이름만 둔다 —
17
+ * 같은 값인지는 elanous-tui-spawn-identity.test.ts 가 잡는다. */
18
+ export const PREAMBLE_SYNC_BLOCK_ENV = 'ELANOUS_TEST_PREAMBLE_SYNC_BLOCK_MS';
19
+
16
20
  export interface ElanousTuiSpawnOptions {
17
21
  readonly repoRoot: string;
18
22
  readonly cwd: string;
@@ -138,6 +142,13 @@ export function elanousTuiSpawnOptions(opts: ElanousTuiSpawnOptions): StartOpts
138
142
  }
139
143
  const { runId } = resolveRunIdentity({ explicit: opts.runId, inherited: opts.space.runId });
140
144
  const debugLevel = process.env.ELANOUS_DEBUG_LEVEL;
145
+ // ⭐ PTY 는 기동 때 잡은 로그인 셸 env 위에 «여기 적은 키만» 얹는다(registry `buildPtyEnv`) —
146
+ // 부모에 건 시험 seam env 는 적어 주지 않으면 자식에 안 닿는다(run-fbe85b7c · 자식 env 실측).
147
+ // 격리 자식에만 넘긴다. 자식도 운영 우주면 무시한다(`preambleSyncBlockMs`).
148
+ const preambleSyncBlock = isolated ? process.env[PREAMBLE_SYNC_BLOCK_ENV]?.trim() : undefined;
149
+ if (preambleSyncBlock) {
150
+ debug.log('self-implement.elanous-tui-spawn', 'test-seam-env', { name: PREAMBLE_SYNC_BLOCK_ENV, value: preambleSyncBlock });
151
+ }
141
152
  const controller = opts.controller ?? deriveChildController(process.env, process.pid);
142
153
  const channels = 'pty,inbox';
143
154
  debug.log('self-implement.elanous-tui-spawn', 'controller', { controller, channels });
@@ -149,6 +160,8 @@ export function elanousTuiSpawnOptions(opts: ElanousTuiSpawnOptions): StartOpts
149
160
  ],
150
161
  accessMode: 'auto',
151
162
  transitionPolicy: 'open',
163
+ // 안 넘길 때는 로그인 셸 캡처본에 그 변수가 있어도 지운다 — 비격리 자식에 seam 이 새지 않게.
164
+ ...(preambleSyncBlock ? {} : { unsetEnv: [PREAMBLE_SYNC_BLOCK_ENV] }),
152
165
  // ⭐ 대표 2026-08-02 — 자식 화면 기본 **160×40**. 가상 PTY라 사람 터미널과 무관하고,
153
166
  // 좁으면 렌더 블록이 화면을 넘어 **관측이 잘린다**(그 실측이 `--cols/--rows` 를 열게 했다).
154
167
  cols: opts.cols ?? 160,
@@ -164,6 +177,7 @@ export function elanousTuiSpawnOptions(opts: ElanousTuiSpawnOptions): StartOpts
164
177
  ELANOUS_CONTROL_CHANNELS: channels,
165
178
  ...observeOnlyFlagEnv(opts.observeOnly),
166
179
  ...(debugLevel === undefined ? {} : { ELANOUS_DEBUG_LEVEL: debugLevel }),
180
+ ...(preambleSyncBlock ? { [PREAMBLE_SYNC_BLOCK_ENV]: preambleSyncBlock } : {}),
167
181
  ...childRunContextEnv('self-build'),
168
182
  ...childNestEnv(),
169
183
  ...harnessSpaceEnv(opts.space.kind, opts.space.id, runId),
@@ -1,4 +1,5 @@
1
1
  import { spawnSync } from 'node:child_process';
2
+ import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
2
3
  import { debug } from '../debug/log.js';
3
4
 
4
5
  type ExposeMode = 'warn' | 'strict';
@@ -15,7 +16,7 @@ export function runExposeGate(
15
16
  changed: readonly string[],
16
17
  mode: ExposeMode,
17
18
  run: (command: string, args: string[], cwd: string) => ProcessResult = (command, args, dir) => {
18
- const result = spawnSync(command, args, { cwd: dir, encoding: 'utf8', timeout: 300_000 });
19
+ const result = spawnSync(command, args, { cwd: dir, encoding: 'utf8', timeout: 300_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
19
20
  return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '', error: result.error };
20
21
  },
21
22
  ): ExposeResult {