elanous 0.2.32 → 0.2.35

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 (753) 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/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.js → 0368f25d-ad84af92fefee68f.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +32 -0
  7. package/apps/pwa/out/_next/static/chunks/{5525.86debf231e181813.js → 1530.0e612369b6fd7ea0.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +41 -0
  9. package/apps/pwa/out/_next/static/chunks/{7391.ebae168025c91b6a.js → 1674.2a65fd5668e1cc5f.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +24 -0
  11. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +74 -0
  12. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{7947-d0759430f8042240.js → 1993-c0007b7ad0c0ef41.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{60fb96c9.360b01d8d4927b7b.js → 1c735de4.f993a30bbd3c57c4.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.js → 2018.a741297bce759490.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +148 -0
  23. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{3902.e1e71aaac850a045.js → 2625.5d870aa999f33db1.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +77 -0
  26. package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +62 -0
  29. package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +90 -0
  31. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{4174.92ed04922709ac9e.js → 3408.21d1570602f4b6c0.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3589.5444a06bcf6e775c.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/359-2250789a2d3499e7.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +36 -0
  37. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{9398-6aed28f0a96d0d6f.js → 3677-4215f826f6aa68e5.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +79 -0
  40. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +122 -0
  42. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{7371.80c05c653b08e907.js → 4346.8601952e73bf5803.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +286 -0
  46. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +24 -0
  49. package/apps/pwa/out/_next/static/chunks/{2940-619bfd8ef337c611.js → 4705-194e64e47ca0fbdb.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.js → 4718-17d2af636796a330.js} +3 -3
  51. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{7502.ccd5b8065545edd0.js → 5101.e32282718f99ed6f.js} +2 -2
  57. package/apps/pwa/out/_next/static/chunks/{2001.6c7e0fd02190886c.js → 5154.a118f3957ed14e36.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +23 -0
  61. package/apps/pwa/out/_next/static/chunks/{5173-233188df2f42c626.js → 5483-dd5d7697f6bdb106.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +94 -0
  63. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{3267c0e6.d34854e7b3984a6e.js → 56d372f2.681ab4ec4c998fae.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +287 -0
  67. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/{6433.fc573af22bbc9ab7.js → 6236.e18cced2d5ba6afb.js} +17 -17
  74. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +8 -0
  75. package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +27 -0
  78. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +93 -0
  80. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/{6544cb48.a87fe20ddf137be2.js → 6b89c8bd.24df687a820500b3.js} +1 -1
  83. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +149 -0
  87. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +104 -0
  88. package/apps/pwa/out/_next/static/chunks/{2871.0bca6137343b3f76.js → 7385.50a308a477bdfc21.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.js → 7644.17e37ba6f1d4226e.js} +4 -4
  90. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/{8018.a32663f04a6fc5f9.js → 8219.baa715d1deee80e2.js} +1 -1
  95. package/apps/pwa/out/_next/static/chunks/{4111.2bfedbb233ad206b.js → 8256.e3ac8421a71f82f4.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 8444.4c26b379ca2b9596.js} +17 -17
  100. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +226 -0
  101. package/apps/pwa/out/_next/static/chunks/8557-e7898769499cd56f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +64 -0
  104. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{6092.a7f99e68b188ca66.js → 8637.47f5b35afcae5e6b.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{3278.2e5d15b53a4091c8.js → 9214.63a510d39178e997.js} +2 -2
  111. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +115 -0
  112. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{9221.7d22eaf353a2d4e7.js → 938.66ad1ef0e5abae1c.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.js → 9512.5a76207a730e0491.js} +2 -2
  115. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{69-0a2c8209c6d4a158.js → 967-2aa39b2d04b4c690.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{7862.30a8d6482bb238eb.js → 9952.5daf5f94063a2b3e.js} +1 -1
  120. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/{page-a27b1e5a0d1b308f.js → page-406b47745b53f269.js} +1 -1
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/{page-32866485913d6a04.js → page-47c5d4db587266bd.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-04d00ae9b0890349.js → page-dc0a532f5b9196ec.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{7a1887c4.f36b88fba31da8fd.js → b2f6ba4d.fb56fdbbf798df33.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/b6705a4f-b9a9047de9eecfd0.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/{b313b242.cb1265eea908db61.js → cbe38a15.5a032598e39970c6.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → da5176c6.6773b6c5994e1d99.js} +7 -7
  178. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +1 -0
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +22 -22
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +22 -22
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +22 -22
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +21 -21
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +21 -21
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +22 -22
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +21 -21
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +22 -22
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +22 -22
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +21 -21
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +22 -22
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +22 -22
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +22 -22
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +22 -22
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +21 -21
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +21 -21
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +22 -22
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +22 -22
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +22 -22
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +21 -21
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +21 -21
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +22 -22
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +22 -22
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +21 -21
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +21 -21
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +21 -21
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +22 -22
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +22 -22
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +21 -21
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +22 -22
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +22 -22
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +22 -22
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +22 -22
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +22 -22
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +21 -21
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +22 -22
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +22 -22
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +22 -22
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +22 -22
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +22 -22
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +22 -22
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +22 -22
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +22 -22
  277. package/bin/elanous.mjs +10 -2
  278. package/catalog/providers/opengateway.yaml +25 -0
  279. package/docs/goal-context/01-goal-authoring-checks.md +8 -0
  280. package/docs/goal-context/03-verification-menu.md +24 -0
  281. package/docs/goal-context/04-mock-scenarios.md +100 -0
  282. package/docs/goal-context/README.md +5 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/default-loop.yaml +76 -5
  285. package/graphs/document-loop.yaml +71 -4
  286. package/graphs/implement-loop.yaml +59 -4
  287. package/graphs/journey/SCENARIOS.md +33 -0
  288. package/graphs/journey/recipes.yaml +1 -0
  289. package/graphs/journey/ta-journey.yaml +94 -0
  290. package/graphs/journey/units/author/author.yaml +20 -0
  291. package/graphs/journey/units/author/recipes.yaml +2 -0
  292. package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
  293. package/graphs/journey/units/author-dialogue/observe.ts +96 -0
  294. package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
  295. package/graphs/journey/units/green/green.yaml +20 -0
  296. package/graphs/journey/units/green/recipes.yaml +2 -0
  297. package/graphs/journey/units/pr/pr.yaml +20 -0
  298. package/graphs/journey/units/pr/recipes.yaml +2 -0
  299. package/graphs/journey/units/remember/recipes.yaml +2 -0
  300. package/graphs/journey/units/remember/remember.yaml +20 -0
  301. package/graphs/operate-loop.yaml +71 -4
  302. package/graphs/overlays/stop-heal-ladder.yaml +1 -1
  303. package/graphs/release-rehearsal/recipes.yaml +1 -1
  304. package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
  305. package/graphs/research-loop.yaml +159 -4
  306. package/graphs/test-diet/test-diet.yaml +3 -0
  307. package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
  308. package/graphs/units/dispatch-pod/recipes.yaml +14 -0
  309. package/graphs/units/entry/entry.yaml +50 -0
  310. package/graphs/units/entry/recipes.yaml +14 -0
  311. package/graphs/units/harvest/harvest.yaml +25 -0
  312. package/graphs/units/harvest/recipes.yaml +4 -0
  313. package/graphs/units/land/land.yaml +45 -0
  314. package/graphs/units/land/recipes.yaml +3 -0
  315. package/graphs/units/recipes.yaml +7 -0
  316. package/graphs/units/recover.yaml +39 -0
  317. package/graphs/units/reflect/recipes.yaml +3 -0
  318. package/graphs/units/reflect/reflect.yaml +15 -0
  319. package/graphs/units/task-agent-recover-review.yaml +17 -0
  320. package/graphs/units/task-agent-recover-wait.yaml +17 -0
  321. package/graphs/units/verbs/make-doc.yaml +34 -0
  322. package/graphs/units/verbs/recipes.yaml +33 -0
  323. package/graphs/units/verbs/verify.yaml +55 -0
  324. package/graphs/work/recipes.yaml +2 -0
  325. package/graphs/work/research-report.yaml +28 -0
  326. package/package.json +1 -1
  327. package/scripts/ci-typecheck-changed.ts +69 -16
  328. package/scripts/coord-role-pack.ts +19 -6
  329. package/scripts/docs/generate-graph-anatomy.ts +19 -2
  330. package/scripts/graph-harvest-unit.ts +22 -0
  331. package/scripts/graph-units/journey-stub.ts +6 -0
  332. package/scripts/graph-units/land-enqueue.ts +78 -0
  333. package/scripts/graph-units/recover-plan.ts +15 -0
  334. package/scripts/graph-units/reflect-node.ts +88 -0
  335. package/scripts/graph-units/ta-journey-observe.ts +109 -0
  336. package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
  337. package/scripts/graph-units/verbs/verify-stage.ts +75 -0
  338. package/scripts/graph-units/verbs-envelope.ts +139 -0
  339. package/scripts/hq/standby-snapshot.ts +30 -0
  340. package/scripts/public-export.ts +43 -1
  341. package/scripts/ratchets/train-side-invariants.sh +45 -0
  342. package/scripts/release-loop/auto-approve-node.ts +30 -16
  343. package/scripts/release-loop/docs-land-node.ts +21 -5
  344. package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
  345. package/scripts/release-loop/gate-closure.ts +5 -1
  346. package/scripts/release-loop/gate-diff.ts +1 -1
  347. package/scripts/release-loop/gate-node.ts +675 -49
  348. package/scripts/release-loop/gate-partial.ts +68 -14
  349. package/scripts/release-loop/gate-radius-live.ts +177 -0
  350. package/scripts/release-loop/gate-radius-shadow.ts +138 -0
  351. package/scripts/release-loop/gate-traffic-mode.ts +128 -0
  352. package/scripts/release-loop/gate-triage-node.ts +5 -2
  353. package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
  354. package/scripts/release-loop/known-issues-node.ts +77 -8
  355. package/scripts/release-loop/node-verdict.ts +12 -1
  356. package/scripts/release-loop/npm-publish-node.ts +66 -12
  357. package/scripts/release-loop/preflight.ts +93 -7
  358. package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
  359. package/scripts/release-loop/publish-node.ts +60 -9
  360. package/scripts/release-loop/pwa-remote.ts +166 -0
  361. package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
  362. package/scripts/release-loop/resume-cap.ts +56 -0
  363. package/scripts/release-loop/resume-release.ts +155 -19
  364. package/scripts/release-loop/resume.ts +24 -1
  365. package/scripts/release-loop/tui-sim-node.ts +8 -2
  366. package/scripts/release-loop/unattended-release.ts +10 -2
  367. package/scripts/test-diet/lib.ts +6 -1
  368. package/scripts/test-diet/node.ts +194 -13
  369. package/scripts/ux-sim.ts +39 -0
  370. package/src/acp/core-turn-bridge.ts +20 -5
  371. package/src/acp/reasoning-thought-buffer.ts +45 -0
  372. package/src/agent/self-ambient-cache.ts +8 -0
  373. package/src/agent-substrate/acp-reviewer.ts +90 -15
  374. package/src/agent-substrate/pr-reviewer.ts +17 -0
  375. package/src/agent-substrate/review-finding-key.ts +53 -0
  376. package/src/agent-substrate/self-review-cli.ts +188 -18
  377. package/src/ask-user-question/pending-questions.ts +1 -1
  378. package/src/autopilot/pr-manager.ts +393 -65
  379. package/src/budget/run-usage-rollup.ts +1 -0
  380. package/src/chat/index.ts +0 -2
  381. package/src/chat/pickers/modal-runtime.ts +10 -27
  382. package/src/chat/tool-render/dispatch.ts +62 -10
  383. package/src/cli/agent-cli.ts +13 -2
  384. package/src/cli/control-cli.ts +24 -7
  385. package/src/cli/doctor-cli.ts +4 -1
  386. package/src/cli/guardian-cli.ts +10 -0
  387. package/src/cli/light-entry-route.ts +75 -0
  388. package/src/cli/llm-detect-cli.ts +23 -1
  389. package/src/cli/pod-cli.ts +77 -3
  390. package/src/cli/pr-cli.ts +81 -14
  391. package/src/cli/pr-land-base-read.ts +2 -0
  392. package/src/cli/pr-land-overlap-evidence.ts +154 -16
  393. package/src/cli/pr-land-pod-shadow-job.ts +3 -0
  394. package/src/cli/pr-land-recovery.ts +64 -0
  395. package/src/cli/pty-takeover-cli.ts +6 -5
  396. package/src/cli/release-checklist-read-cli.ts +79 -0
  397. package/src/cli/release-cli.ts +189 -132
  398. package/src/cli/release-run-if-ready.ts +29 -28
  399. package/src/cli/release-single-flight.ts +178 -0
  400. package/src/cli/remote-resolve.ts +1 -1
  401. package/src/cli/root-tui-entry.ts +48 -0
  402. package/src/cli/seat-cli.ts +37 -0
  403. package/src/cli/setup-cli.ts +40 -1
  404. package/src/cli/sim-cli.ts +22 -0
  405. package/src/cli/tasks-cli.ts +667 -14
  406. package/src/cli/usage-cli.ts +13 -11
  407. package/src/clipboard/history.ts +179 -13
  408. package/src/config.ts +8 -1
  409. package/src/control/control-status.ts +8 -3
  410. package/src/control-plane/ledger.ts +5 -3
  411. package/src/control-plane/server.ts +5 -3
  412. package/src/core-turn/short-question.ts +5 -1
  413. package/src/dashboard/chat/acp-chat.ts +8 -0
  414. package/src/dashboard/index.ts +114 -77
  415. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
  416. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  417. package/src/dashboard/input/seat-autowake.ts +56 -3
  418. package/src/dashboard/render/theme-resolver.ts +33 -4
  419. package/src/dashboard/seat-boot-preamble.ts +1 -1
  420. package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
  421. package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
  422. package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
  423. package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
  424. package/src/dashboard/turn-preamble.ts +47 -1
  425. package/src/dashboard/turn-stream-formatter.ts +34 -1
  426. package/src/dashboard/turn-stream-runtime.ts +2 -0
  427. package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
  428. package/src/domains/guardian-tick.ts +54 -2
  429. package/src/domains/outbound-alert.ts +3 -2
  430. package/src/domains/schedule-registry.ts +16 -2
  431. package/src/extractors.ts +3 -1
  432. package/src/git-fs/idle-refresh.ts +76 -0
  433. package/src/git-fs/index.ts +18 -7
  434. package/src/git-fs/retry.ts +4 -0
  435. package/src/git-fs/runner.ts +2 -0
  436. package/src/git-fs/worktree.ts +42 -4
  437. package/src/graph-kinds/registry.ts +2 -2
  438. package/src/graph-runner/runner.ts +267 -54
  439. package/src/grok/credential.ts +15 -3
  440. package/src/harness/harness-cli-command.ts +151 -38
  441. package/src/harness/harness-incidents.ts +37 -0
  442. package/src/harness/harness-pod-dispatch.ts +38 -1
  443. package/src/harness/harness-salvage-cli.ts +14 -2
  444. package/src/harness/launch-utterance-ledger.ts +208 -0
  445. package/src/impl-discipline/detector.ts +16 -4
  446. package/src/impl-discipline/system-prompt.ts +11 -0
  447. package/src/impl-discipline/types.ts +2 -2
  448. package/src/index.ts +683 -146
  449. package/src/intake-plane/already-built-hint.ts +91 -0
  450. package/src/intake-plane/requirement-funnel.ts +29 -1
  451. package/src/knowhow/pack.ts +199 -0
  452. package/src/light-cli.ts +111 -0
  453. package/src/llm/opengateway-models.ts +11 -0
  454. package/src/llm/provider-credentials.ts +14 -0
  455. package/src/llm/provider-detect.ts +8 -1
  456. package/src/llm/runtime-model-family.ts +2 -1
  457. package/src/llm.ts +268 -65
  458. package/src/loops/budget.ts +95 -0
  459. package/src/loops/msg-wake.ts +8 -2
  460. package/src/loops/orchestrator/traffic.ts +132 -1
  461. package/src/model-tier/llm-tier-map.ts +15 -1
  462. package/src/mss/logging/log-store.ts +4 -5
  463. package/src/native-tool-catalog.ts +15 -1
  464. package/src/nexus/api/graphs-api.ts +22 -3
  465. package/src/nexus/api/http-server.ts +1 -1
  466. package/src/nexus/api/loop-resources.ts +13 -1
  467. package/src/nexus/api/ops-api.ts +12 -0
  468. package/src/oauth/claude-pty-maturity.ts +66 -0
  469. package/src/oauth/codex-access-mirror.ts +55 -0
  470. package/src/oauth/codex.ts +7 -0
  471. package/src/oauth/fallback-chain.ts +1 -1
  472. package/src/onboarding/first-run.ts +5 -3
  473. package/src/onboarding/non-interactive.ts +64 -13
  474. package/src/onboarding.ts +10 -2
  475. package/src/ops/overview-collect.ts +54 -4
  476. package/src/ops/overview.ts +31 -7
  477. package/src/pr-tool/census.ts +282 -30
  478. package/src/pr-tool/inflight-registry.ts +160 -7
  479. package/src/prompt-library/gpt6-family-addendum.ts +14 -1
  480. package/src/pty-shell/herdr-agent-report.ts +442 -0
  481. package/src/pty-shell/pty-control-ipc.ts +5 -5
  482. package/src/pty-shell/pty-manifest.ts +7 -0
  483. package/src/pty-shell/pty-write-outcome.ts +24 -6
  484. package/src/pty-shell/tui-run-state.ts +117 -3
  485. package/src/release-loop/checklist.ts +103 -5
  486. package/src/release-loop/feature-store.ts +19 -2
  487. package/src/release-loop/landed-but-yellow.ts +129 -5
  488. package/src/release-loop/light-rc.ts +1 -0
  489. package/src/release-loop/placement.ts +10 -3
  490. package/src/release-loop/rehearsal.ts +205 -25
  491. package/src/release-loop/rubric.ts +16 -2
  492. package/src/repl/index.ts +174 -17
  493. package/src/repl/ops-msg-bridge.ts +32 -0
  494. package/src/self-dev/ask-launch-flow.ts +44 -5
  495. package/src/self-dev/cli-help-text.ts +17 -0
  496. package/src/self-dev/dev-cli.ts +11 -9
  497. package/src/self-dev/draft-residue.ts +37 -1
  498. package/src/self-dev/draft-sweep.ts +188 -13
  499. package/src/self-dev/draft-triage-rules.ts +107 -0
  500. package/src/self-dev/fleet-reduce.ts +3 -2
  501. package/src/self-dev/graph-front-nodes.ts +112 -0
  502. package/src/self-dev/graph-journey-nodes.ts +11 -6
  503. package/src/self-dev/graph-journey-route.ts +60 -6
  504. package/src/self-dev/harness-run-cli.ts +3 -15
  505. package/src/self-dev/orchestrate-cli-text.ts +10 -0
  506. package/src/self-dev/orchestrate.ts +79 -3
  507. package/src/self-dev/review-provider-fallback.ts +35 -1
  508. package/src/self-dev/run-supervisor.ts +107 -12
  509. package/src/self-dev/run-types.ts +5 -1
  510. package/src/self-dev/self-orchestrate-runtime.ts +1 -11
  511. package/src/self-dev/shard-aggregate.ts +42 -5
  512. package/src/self-dev/shard-run.ts +8 -1
  513. package/src/self-implement/blocked-draft-policy.ts +20 -0
  514. package/src/self-implement/classify-shadow.ts +3 -7
  515. package/src/self-implement/doctor-visit.ts +18 -1
  516. package/src/self-implement/gate-baseline.ts +95 -12
  517. package/src/self-implement/gate-cli.ts +1 -0
  518. package/src/self-implement/gate-remote.ts +40 -25
  519. package/src/self-implement/goal-author-decompose.ts +275 -47
  520. package/src/self-implement/goal-author-identity.ts +66 -0
  521. package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
  522. package/src/self-implement/goal-author.ts +254 -120
  523. package/src/self-implement/goal-elaborate.ts +295 -0
  524. package/src/self-implement/goal-refine.ts +270 -0
  525. package/src/self-implement/graph-overlay-yaml.ts +28 -2
  526. package/src/self-implement/graph-unit-flatten.ts +103 -0
  527. package/src/self-implement/graph-unit-resolver.ts +107 -0
  528. package/src/self-implement/graph-yaml.ts +151 -1
  529. package/src/self-implement/headless-elanous-driver.ts +1 -0
  530. package/src/self-implement/knowhow-pack.ts +103 -0
  531. package/src/self-implement/orchestrator.ts +160 -45
  532. package/src/self-implement/pod-warm-pool-profile.ts +45 -0
  533. package/src/self-implement/review-mustfix-class.ts +203 -0
  534. package/src/self-implement/rework-budget-judgment.ts +5 -8
  535. package/src/self-implement/run-stop.ts +17 -2
  536. package/src/self-implement/running-runs.ts +29 -1
  537. package/src/self-implement/scope-adjacency.ts +113 -0
  538. package/src/self-implement/seams.ts +138 -4
  539. package/src/self-implement/stop-autoheal.ts +112 -2
  540. package/src/session/chat.ts +27 -0
  541. package/src/session-runtime/index.ts +1 -1
  542. package/src/session-runtime/retry-policy.ts +2 -1
  543. package/src/setup/llm-env-detect.ts +5 -0
  544. package/src/skills/tools/agent.ts +140 -14
  545. package/src/skills/tools/msg-ask.ts +100 -0
  546. package/src/skills/tools/ops-ledger.ts +2 -1
  547. package/src/skills/tools/schedule-wakeup.ts +66 -17
  548. package/src/steward/hold-hygiene.ts +24 -6
  549. package/src/steward/release-day.ts +7 -3
  550. package/src/steward/triage-budget.ts +194 -0
  551. package/src/steward/triage.ts +57 -7
  552. package/src/task-agent/actions.ts +69 -1
  553. package/src/task-agent/green-sweep.ts +4 -0
  554. package/src/task-agent/harvest-unit.ts +141 -0
  555. package/src/task-agent/live-moves.ts +257 -15
  556. package/src/task-agent/parent-host.ts +216 -6
  557. package/src/task-agent/postland-card.ts +80 -1
  558. package/src/task-agent/rejudge-on-head.ts +112 -26
  559. package/src/task-agent/repair-branch-cas.ts +4 -1
  560. package/src/task-agent/repair-cycle.ts +16 -3
  561. package/src/task-agent/run-identity.ts +4 -3
  562. package/src/task-agent/shadow.ts +19 -3
  563. package/src/task-agent/task-hand.ts +96 -36
  564. package/src/task-agent/tier-split.ts +127 -0
  565. package/src/task-agent/work-order-build.ts +24 -0
  566. package/src/task-agent/work-order.ts +3 -2
  567. package/src/task-orchestrator/generator-prompt.ts +60 -11
  568. package/src/task-orchestrator/surfaces/pod-account-broker.ts +72 -3
  569. package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
  570. package/src/task-orchestrator/surfaces/pod-command-job.ts +47 -8
  571. package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
  572. package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
  573. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
  574. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +8 -2
  575. package/src/task-orchestrator/surfaces/pod-pool.ts +73 -17
  576. package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -0
  577. package/src/task-orchestrator/surfaces/pod-source-receive.ts +72 -4
  578. package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
  579. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +32 -5
  580. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +3 -0
  581. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +421 -0
  582. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +2 -1
  583. package/src/task-orchestrator/surfaces/self-implement-pod.ts +588 -71
  584. package/src/task-orchestrator/surfaces/self-implement.ts +106 -2
  585. package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
  586. package/src/tool-runtime/truncation-store.ts +4 -0
  587. package/src/tui/README.md +2 -0
  588. package/src/tui/chat/background-job-status.ts +54 -0
  589. package/src/tui/chat/log-view.ts +80 -0
  590. package/src/tui/entry.ts +406 -0
  591. package/src/tui/input/composer.ts +144 -0
  592. package/src/tui/seat-mail-boot.ts +59 -0
  593. package/src/tui/slash/compact.ts +100 -0
  594. package/src/tui/slash/new-session.ts +35 -0
  595. package/src/tui-client/dashboard-session.ts +10 -1
  596. package/src/tui-client/local-chat-turn.ts +239 -0
  597. package/src/tui-client/local-harness-command.ts +63 -0
  598. package/src/tui-client/local-provider-command.ts +184 -0
  599. package/src/user-config/coercion.ts +36 -0
  600. package/src/user-config.ts +22 -43
  601. package/src/ux-sim/event-monkey.ts +378 -0
  602. package/src/ux-sim/fake-bin.ts +42 -7
  603. package/src/ux-sim/fault-nextmove-dispatch.ts +266 -0
  604. package/src/ux-sim/fault-pod-codex-503.ts +211 -0
  605. package/src/ux-sim/fault-scope-escape-lift.ts +189 -0
  606. package/src/ux-sim/scenario.ts +72 -13
  607. package/src/version/packed-revision.json +1 -1
  608. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
  611. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
  612. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
  613. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
  617. package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
  619. package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
  620. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
  629. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
  630. package/apps/pwa/out/_next/static/chunks/3541-ce3a5424ed5ad7f1.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
  636. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
  640. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
  641. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +0 -226
  642. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
  644. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
  647. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/5543.a438b8ab5a13ea47.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
  653. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
  655. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
  661. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
  662. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
  663. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
  668. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
  669. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
  674. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +0 -24
  685. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/9989.3694300e5f000b14.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/setup/page-c219f2ed171131be.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
  744. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
  752. package/src/cli/g6a-registration-probe.ts +0 -16
  753. /package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
@@ -1,3 +1,6 @@
1
+ import { realpathSync } from 'node:fs';
2
+ import { isAbsolute, relative, resolve, sep } from 'node:path';
3
+ import { debug } from '../debug/log.js';
1
4
  import {
2
5
  allowsBaselineOnlyFailure,
3
6
  buildGateBaselineReport,
@@ -21,6 +24,10 @@ export interface GateShardAttempt {
21
24
  /** LIGHT-RC-MEASURE — the shard files that exist in the baseline tree, i.e. what the baseline side actually ran.
22
25
  * Absent = every shard file (the old shape). Empty = the baseline side was not run and contributes zero cases. */
23
26
  baselineFiles?: readonly string[];
27
+ /** SHARD-JUNIT-ABS-PATH — the tree each side ran in. bun writes an absolute JUnit `file` once a test process.chdir()s;
28
+ * such a path under this root is read as the cohort-relative file. Absent = absolute paths stay rejected (old shape). */
29
+ currentRoot?: string;
30
+ baselineRoot?: string;
24
31
  }
25
32
 
26
33
  export interface GateShardAggregate {
@@ -125,7 +132,32 @@ function textOf(element: XmlElement): string {
125
132
  return element.text + element.children.map(textOf).join('');
126
133
  }
127
134
 
128
- function readJUnit(xml: string, files: readonly string[]): JUnitCase[] | undefined {
135
+ const realOrResolved = (path: string): string => {
136
+ try { return realpathSync(path); } catch { return resolve(path); }
137
+ };
138
+
139
+ /** SHARD-JUNIT-ABS-PATH — an absolute JUnit `file` under `root` becomes the cohort-relative path. Both sides are
140
+ * realpath'd (macOS /tmp ↔ /private/tmp). A path outside the root is returned unchanged, so the cohort check rejects it. */
141
+ function junitPathNormalizer(root: string | undefined): (file: string | undefined) => string | undefined {
142
+ if (!root) return (file) => file;
143
+ const realRoot = realOrResolved(root);
144
+ const seen = new Map<string, string>();
145
+ return (file) => {
146
+ if (file === undefined || !isAbsolute(file)) return file;
147
+ const cached = seen.get(file);
148
+ if (cached !== undefined) return cached;
149
+ const rel = relative(realRoot, realOrResolved(file));
150
+ const inside = rel !== '' && !rel.startsWith('..') && !isAbsolute(rel);
151
+ const to = inside ? rel.split(sep).join('/') : file;
152
+ seen.set(file, to);
153
+ if (inside) debug.log('gate.shard', 'junit-path-normalized', { from: file, to });
154
+ else debug.log('gate.shard', 'junit-path-outside-root', { from: file, root: realRoot });
155
+ return to;
156
+ };
157
+ }
158
+
159
+ function readJUnit(xml: string, files: readonly string[], treeRoot?: string): JUnitCase[] | undefined {
160
+ const normalize = junitPathNormalizer(treeRoot);
129
161
  const root = parseXml(xml);
130
162
  if (!root || (root.name !== 'testsuites' && root.name !== 'testsuite')) return undefined;
131
163
  const expected = new Set(files);
@@ -140,7 +172,7 @@ function readJUnit(xml: string, files: readonly string[]): JUnitCase[] | undefin
140
172
  || (/^(0|[1-9]\d*)$/.test(value) && Number(value) === actual);
141
173
  // Each suite's tests attribute covers its descendants too: compare subtree totals.
142
174
  const walkSuite = (suite: XmlElement, parentFile: string | undefined): { tests: number; failures: number; errors: number } | undefined => {
143
- const file = suite.attrs.file ?? parentFile;
175
+ const file = normalize(suite.attrs.file) ?? parentFile;
144
176
  const declared = Number(suite.attrs.tests);
145
177
  if ((file && !expected.has(file)) || !Number.isSafeInteger(declared) || declared < 0) return undefined;
146
178
  const total = { tests: 0, failures: 0, errors: 0 };
@@ -150,7 +182,7 @@ function readJUnit(xml: string, files: readonly string[]): JUnitCase[] | undefin
150
182
  if (!sub) return undefined;
151
183
  total.tests += sub.tests; total.failures += sub.failures; total.errors += sub.errors;
152
184
  } else if (child.name === 'testcase') {
153
- const caseFile = child.attrs.file ?? file;
185
+ const caseFile = normalize(child.attrs.file) ?? file;
154
186
  const leaf = child.attrs.name;
155
187
  if (!caseFile || !expected.has(caseFile) || !leaf || (file && file !== caseFile)) return undefined;
156
188
  total.tests++;
@@ -245,14 +277,16 @@ export function aggregateGateTestShards(shards: readonly GateTestShard[], attemp
245
277
  const retryShardIds: string[] = [];
246
278
  const current: JUnitCase[] = [];
247
279
  const baseline: JUnitCase[] = [];
280
+ // 기준선 JUnit 전체 testcase(통과·실패·스킵 포함). 귀속 일치 확인용이라 판정 재료인 `baseline`(스킵 제외)과 분리한다.
281
+ const baselineTestCases: JUnitCase[] = [];
248
282
  const skippedRegressions: JUnitCase[] = [];
249
283
  for (const shard of shards) {
250
284
  const attempt = selected.get(shard.id);
251
- const head = attempt?.currentJUnit === undefined ? undefined : readJUnit(attempt.currentJUnit, shard.files);
285
+ const head = attempt?.currentJUnit === undefined ? undefined : readJUnit(attempt.currentJUnit, shard.files, attempt.currentRoot);
252
286
  // LIGHT-RC-MEASURE ① — the baseline side reads only the files that exist in the baseline tree; none = not run.
253
287
  const baselineFiles = attempt?.baselineFiles ?? shard.files;
254
288
  const baselineSkipped = baselineFiles.length === 0;
255
- const base = baselineSkipped ? [] : attempt?.baselineJUnit === undefined ? undefined : readJUnit(attempt.baselineJUnit, baselineFiles);
289
+ const base = baselineSkipped ? [] : attempt?.baselineJUnit === undefined ? undefined : readJUnit(attempt.baselineJUnit, baselineFiles, attempt.baselineRoot);
256
290
  if (!attempt || attempt.currentExitCode === null || attempt.currentSignal
257
291
  || ![0, 1].includes(attempt.currentExitCode)
258
292
  || baselineFiles.some((file) => !shard.files.includes(file))
@@ -267,6 +301,7 @@ export function aggregateGateTestShards(shards: readonly GateTestShard[], attemp
267
301
  }
268
302
  current.push(...head.filter((test) => !test.skipped));
269
303
  baseline.push(...base.filter((test) => !test.skipped));
304
+ baselineTestCases.push(...base);
270
305
  const passedAtBase = new Set(base.filter((test) => !test.skipped && test.failure === undefined).map((test) => `${test.file}\u0000${test.name}`));
271
306
  skippedRegressions.push(...head.filter((test) => test.skipped && passedAtBase.has(`${test.file}\u0000${test.name}`)));
272
307
  }
@@ -279,6 +314,8 @@ export function aggregateGateTestShards(shards: readonly GateTestShard[], attemp
279
314
  const passedTestEvidence: GatePassedTestEvidence = {
280
315
  status: 'available',
281
316
  tests: baseline.filter((test) => test.failure === undefined).map(({ file, name }) => ({ file, name: `${file} > ${name}` })),
317
+ // #27844 귀속 불일치 — 비샤드 경로(runBaselineBunTest)와 같은 계약으로 기준선 전체 testcase 를 넘긴다.
318
+ testCases: baselineTestCases.map(({ file, name }) => ({ file, name: `${file} > ${name}` })),
282
319
  };
283
320
  const report = buildGateBaselineReport(asGateLog(current), {
284
321
  status: baselineStatus,
@@ -25,6 +25,8 @@ export interface ShardRunResult {
25
25
  failureEvidence?: ShardFailureEvidence[];
26
26
  /** Latest failed attempt's reason for each incomplete shard; copied into the gate artifact summary. */
27
27
  unmeasuredByShard?: Record<string, string>;
28
+ /** git stderr tail (redacted · ≤2KB · one line) when the baseline worktree could not be added. */
29
+ baselineStderrTail?: string;
28
30
  }
29
31
 
30
32
  /** What a failed shard process leaves behind so «test failure vs runner error» can be told apart after the fact. */
@@ -275,6 +277,7 @@ function runPlannedShards(
275
277
  currentSignal: current.signal, baselineSignal: base.signal,
276
278
  currentDiagnostic: current.diagnostic, baselineDiagnostic: base.diagnostic,
277
279
  baselineFiles,
280
+ currentRoot: cwd, baselineRoot: dir,
278
281
  });
279
282
  }
280
283
  const retry = new Set(aggregateGateTestShards(shards, attempts).retryShardIds);
@@ -288,9 +291,13 @@ function runPlannedShards(
288
291
  ...(baseline.retryShardIds.length ? { unmeasuredByShard: incompleteShardReasons(baseline.retryShardIds, attempts) } : {}),
289
292
  };
290
293
  const retryShardIds = shards.map((shard) => shard.id);
294
+ // The stderr tail has its own budget (≤2KB, already redacted) so the 500-char log cut cannot drop it.
295
+ const stderrTail = baseline.gitStderrTail;
296
+ const stderrPart = stderrTail ? ` · git stderr: ${stderrTail}` : '';
291
297
  return {
292
298
  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)}`])),
299
+ unmeasuredByShard: Object.fromEntries(retryShardIds.map((id) => [id, `baseline worktree: ${redactSecretText(baseline.log).replace(/[\r\n\t\x00-\x1f\x7f]+/g, ' ').slice(0, 500)}${stderrPart}`])),
300
+ ...(stderrTail ? { baselineStderrTail: stderrTail } : {}),
294
301
  };
295
302
  }
296
303
 
@@ -89,3 +89,23 @@ export function salvageBranchForRun(runId: string, branch: string): string {
89
89
  const leaf = branch.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/^[-.]+|[-.]+$/g, '').replace(/\.\.+/g, '.').replace(/\.lock$/i, '-lock') || 'branch';
90
90
  return `salvage/${runShort}/${leaf}`;
91
91
  }
92
+
93
+ /** REPAIR-BLOCKED-DRAFT-LINK-ORIGINAL — commit-only 수리 런의 base 는 합성 로컬 가지 `pr-<N>`(harness-pod-dispatch 가 넘긴다).
94
+ * ⛔ origin 에 없는 가지라 그 base 로 새 draft 를 열면 반드시 실패한다. 이 꼴이면 원 PR 번호를 낸다. */
95
+ export function syntheticRepairBasePr(base: string | undefined): number | undefined {
96
+ const match = /^pr-([1-9]\d*)$/.exec(base ?? '');
97
+ return match ? Number(match[1]) : undefined;
98
+ }
99
+
100
+ export type BlockedDraftTarget = { action: 'open-draft' } | { action: 'link-original'; originalPr: number };
101
+
102
+ /** 중단 산출물을 어디에 남기나 — 합성 base `pr-<N>` 이면 새 draft 대신 «기존 PR #N 에 수확 가지 연결». */
103
+ export function blockedDraftTargetFor(base: string | undefined): BlockedDraftTarget {
104
+ const originalPr = syntheticRepairBasePr(base);
105
+ return originalPr === undefined ? { action: 'open-draft' } : { action: 'link-original', originalPr };
106
+ }
107
+
108
+ /** 원 PR 에 다는 한 줄 — 수확 가지 이름·sha·런. (force push 없음 · 원 PR 가지는 그대로) */
109
+ export function repairSalvageLinkComment(input: { salvageRef: string; sha?: string; runId: string; stage: string }): string {
110
+ return `수리 산출물 salvage ${input.salvageRef}${input.sha ? ` @ ${input.sha.slice(0, 12)}` : ''} — 런 ${input.runId} 이 ${input.stage} 로 멈춰 새 PR 대신 이 PR 에 잇는다(원 PR 가지 무변경)`;
111
+ }
@@ -1,5 +1,5 @@
1
- import { executeClassifyNode } from '../workflow-runtime/nodes/classify.js';
2
- import type { ClassifyNode, NodeExecContext, NodeOutput, WorkflowDeps } from '../workflow-runtime/types.js';
1
+ import { runGraphClassifyNode } from '../graph-runner/runner.js';
2
+ import type { ClassifyNode, NodeExecContext, WorkflowDeps } from '../workflow-runtime/types.js';
3
3
  import { REWORK_BUDGET_VERDICTS, type ReworkBudgetVerdict } from './run-outcome.js';
4
4
 
5
5
  export type ClassifyShadowCallLLM = WorkflowDeps['callLLM'];
@@ -36,11 +36,7 @@ export async function classifyReworkBudgetShadow(
36
36
  resolvedModel: undefined,
37
37
  toolPolicy: {},
38
38
  };
39
- const deps: WorkflowDeps = {
40
- callLLM,
41
- runBash: async () => ({ stdout: '', stderr: '', exitCode: 0 }),
42
- };
43
- const result: NodeOutput = await executeClassifyNode(node, context, deps);
39
+ const result = await runGraphClassifyNode(node, context, callLLM, { caller: 'rework-budget-shadow' });
44
40
  const picked = isReworkBudgetVerdict(result.output) ? result.output : 'unknown';
45
41
  return {
46
42
  picked,
@@ -1,4 +1,6 @@
1
1
  import { debug } from '../debug/log.js';
2
+ import { findIncidentPrecedents, type IncidentPrecedent } from '../harness/harness-incidents.js';
3
+ import { elanousStateRoot } from '../autopilot/state-paths.js';
2
4
  import {
3
5
  appendRunLedgerEntry,
4
6
  listRunLedgers,
@@ -6,6 +8,10 @@ import {
6
8
  lookupRunLedger,
7
9
  type RunLedgerLookupOptions,
8
10
  } from './run-ledger.js';
11
+ /** 사고 원장 루트 기본값 — 운영/시험 우주 상태 디렉터리(없으면 빈 선례 · fail-soft). */
12
+ export function doctorVisitIncidentRoot(): string {
13
+ return elanousStateRoot();
14
+ }
9
15
 
10
16
  /** DOCTOR-VISIT 증상 닫힌 목록 — 이 밖의 값은 기록·조회 모두 거부한다. */
11
17
  export const DOCTOR_SYMPTOMS = [
@@ -49,6 +55,8 @@ export interface RecordDoctorVisitInput {
49
55
  evidence?: string;
50
56
  /** 원장 디렉터리(시험 seam) — 기본 = `runLedgerDir()`. */
51
57
  dir?: string;
58
+ /** 사고 원장 루트(시험 seam) — 기본 = `doctorVisitIncidentRoot()`. `null` 이면 선례 연결을 건너뛴다. */
59
+ incidentRoot?: string | null;
52
60
  }
53
61
 
54
62
  export interface DoctorVisit {
@@ -57,6 +65,8 @@ export interface DoctorVisit {
57
65
  symptom: DoctorSymptom;
58
66
  evidence?: string;
59
67
  timestamp?: string;
68
+ /** 사고 선례 연결 — 같은 reason 으로 이전에 기록된 실제 exit(기록 없으면 빈 배열). */
69
+ incidentPrecedents?: IncidentPrecedent[];
60
70
  }
61
71
 
62
72
  /**
@@ -74,15 +84,22 @@ export function recordDoctorVisit(visit: RecordDoctorVisitInput): DoctorVisit {
74
84
  throw new Error(`없음: 런 원장이 없습니다 (runId=${visit.runId}) — 새 원장을 만들지 않습니다`);
75
85
  }
76
86
  const timestamp = new Date().toISOString();
87
+ // 사고 선례 연결 — 기록된 실제 exit 만(지어내기 금지). 원장이 없으면 빈 배열(fail-soft).
88
+ const incidentRoot = 'incidentRoot' in visit ? visit.incidentRoot ?? null : doctorVisitIncidentRoot();
89
+ const incidentPrecedents = incidentRoot === null
90
+ ? []
91
+ : findIncidentPrecedents({ reason: visit.symptom, at: timestamp, runId: visit.runId }, incidentRoot);
77
92
  const data: Record<string, unknown> = { from: visit.from, symptom: visit.symptom };
78
93
  if (typeof visit.evidence === 'string' && visit.evidence.length > 0) data.evidence = visit.evidence;
94
+ if (incidentPrecedents.length > 0) data.incidentPrecedents = incidentPrecedents;
79
95
  appendRunLedgerEntry({ timestamp, runId: visit.runId, event: 'doctor-visit', data }, visit.dir);
80
- debug.log('run-doctor', 'visit', { runId: visit.runId, from: visit.from, symptom: visit.symptom });
96
+ debug.log('run-doctor', 'visit', { runId: visit.runId, from: visit.from, symptom: visit.symptom, incidentPrecedents: incidentPrecedents.length });
81
97
  return {
82
98
  runId: visit.runId,
83
99
  from: visit.from,
84
100
  symptom: visit.symptom,
85
101
  ...(typeof visit.evidence === 'string' && visit.evidence.length > 0 ? { evidence: visit.evidence } : {}),
102
+ ...(incidentPrecedents.length > 0 ? { incidentPrecedents } : {}),
86
103
  timestamp,
87
104
  };
88
105
  }
@@ -3,9 +3,10 @@ import { copyFileSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSy
3
3
  import { tmpdir } from 'node:os';
4
4
  import { dirname, join } from 'node:path';
5
5
  import { prepareDeterministicChildEnvironment } from '../../scripts/lib/deterministic-env.js';
6
- import { debug } from '../debug/log.js';
6
+ import { debug, redactSecretText } from '../debug/log.js';
7
7
  import { runGitCommand } from '../git-fs/runner.js';
8
- import { linkWorktreeDependencies } from '../git-fs/worktree.js';
8
+ import type { GitRunResult } from '../git-fs/retry.js';
9
+ import { linkWorktreeDependencies, worktreeAddTimeoutForRepo } from '../git-fs/worktree.js';
9
10
  import { reapStaleGateWorktrees } from './gate-baseline-reap.js';
10
11
 
11
12
  export type GateFailureAttribution = 'introduced' | 'preexisting' | 'unknown' | 'precondition-unmet' | 'flaky-timeout' | 'flaky-rerun';
@@ -212,6 +213,8 @@ export interface BaselineProcessResult {
212
213
  childResponsibility?: 'none';
213
214
  output?: string;
214
215
  log: string;
216
+ /** Redacted, single-line tail (≤2KB) of git's stderr when the baseline `worktree add` failed; «(비었음 · signal=… · errorCode=…)» when git wrote none — so «truthy» does NOT mean git wrote stderr. */
217
+ gitStderrTail?: string;
215
218
  missingAtBase?: readonly string[];
216
219
  passedTestEvidence?: GatePassedTestEvidence;
217
220
  }
@@ -787,12 +790,77 @@ function runIsolatedBunTest(cwd: string, args: string[], timeout: number): Proce
787
790
  try {
788
791
  // SIGKILL — a test that traps SIGTERM while blocked in a native wait never runs its handler, so spawnSync
789
792
  // waited forever and its drive grandchildren lived on as ppid=1 orphans (09-30 O1: 19 processes, up to 11h).
790
- return spawnSync('bun', ['test', ...args], { cwd, env: isolated.env, encoding: 'utf8', timeout, killSignal: 'SIGKILL', maxBuffer: 32 * 1024 * 1024 });
793
+ const started = Date.now();
794
+ const result = spawnSync('bun', ['test', ...args], { cwd, env: isolated.env, encoding: 'utf8', timeout, killSignal: 'SIGKILL', maxBuffer: 32 * 1024 * 1024 });
795
+ debug.log('self-implement.gate-baseline', 'test-process-result', {
796
+ status: result.status, signal: result.signal, errorCode: (result.error as NodeJS.ErrnoException | undefined)?.code ?? null,
797
+ elapsedMs: Date.now() - started, timeoutMs: timeout, parentRssBytes: process.memoryUsage().rss,
798
+ cgroupMemoryCurrentBytes: cgroupMemoryBytes('memory.current'), cgroupMemoryLimitBytes: cgroupMemoryBytes('memory.max'),
799
+ });
800
+ return result;
791
801
  } finally {
792
802
  isolated.cleanup();
793
803
  }
794
804
  }
795
805
 
806
+ function cgroupMemoryBytes(name: 'memory.current' | 'memory.max'): number | null {
807
+ try {
808
+ const raw = readFileSync(`/sys/fs/cgroup/${name}`, 'utf8').trim();
809
+ const value = Number(raw);
810
+ return Number.isSafeInteger(value) && value >= 0 ? value : null;
811
+ } catch { return null; }
812
+ }
813
+
814
+ export const BASELINE_GIT_STDERR_TAIL_LIMIT = 2_048;
815
+
816
+ /** git's own messages only, but a token-shaped string is still masked; lines are joined so one gate.log line holds it. */
817
+ export function baselineGitStderrTail(stderr: string): string {
818
+ const lines = String(stderr ?? '').replace(/\r\n?/g, '\n').split('\n').map((line) => line.trimEnd()).filter((line) => line !== '');
819
+ const flat = redactSecretText(lines.join(' ⏎ ')).replace(/[\u0000-\u001F\u007F]/g, '·');
820
+ const bytes = Buffer.from(flat, 'utf8');
821
+ if (bytes.length <= BASELINE_GIT_STDERR_TAIL_LIMIT) return flat;
822
+ // Byte cap (UTF-8): a cut inside a multi-byte character decodes to U+FFFD at the front — drop it.
823
+ return bytes.subarray(bytes.length - BASELINE_GIT_STDERR_TAIL_LIMIT).toString('utf8').replace(/^�+/, '');
824
+ }
825
+
826
+ export interface BaselineWorktreeAddContext {
827
+ dir: string;
828
+ baseRef: string;
829
+ /** Resolved commit of baseRef; absent when it could not be resolved. */
830
+ baseSha?: string;
831
+ }
832
+
833
+ /** A failed checkout never proves that a baseline test ran. Preserve the Git failure's signal, timeout and stderr. */
834
+ export function classifyBaselineWorktreeAddFailure(add: GitRunResult, elapsedMs: number, timeoutMs: number, context?: BaselineWorktreeAddContext): BaselineProcessResult {
835
+ const reason = add.errorCode === 'ETIMEDOUT' ? 'worktree-add-timeout'
836
+ : add.signal ? `worktree-add-signal-${add.signal}` : 'worktree-add-failed';
837
+ const where = context ? `, target ${context.dir}, base ${context.baseRef}@${context.baseSha ? context.baseSha.slice(0, 12) : 'unresolved'}` : '';
838
+ // An empty stderr is a finding (git died without a word), not «nothing to say» — name the signal and errorCode instead.
839
+ const stderrTail = baselineGitStderrTail(add.stderr ?? '')
840
+ || `(비었음 · signal=${add.signal ?? 'none'} · errorCode=${add.errorCode ?? 'none'})`;
841
+ debug.log('self-implement.gate-baseline', 'worktree-add-failed', {
842
+ code: add.status, signal: add.signal ?? null, errorCode: add.errorCode ?? null, elapsedMs, timeoutMs,
843
+ stderrTail, ...(context ? { dir: context.dir, baseRef: context.baseRef, baseSha: context.baseSha ?? null } : {}),
844
+ });
845
+ return {
846
+ status: 'unknown', unknownReason: 'infrastructure-failure', childResponsibility: 'none',
847
+ log: `baseline ${reason} (code ${String(add.status)}, elapsed ${elapsedMs}ms, limit ${timeoutMs}ms${where})`,
848
+ output: `${add.stdout}\n${add.stderr}`,
849
+ gitStderrTail: stderrTail,
850
+ };
851
+ }
852
+
853
+ /** Only on the failure path: one extra rev-parse (5s cap · not counted in the add's elapsedMs) so the reason names the commit. */
854
+ function worktreeAddFailureContext(cwd: string, dir: string, baseRef: string): BaselineWorktreeAddContext {
855
+ try {
856
+ const parsed = runGitCommand(cwd, ['rev-parse', '--verify', '--quiet', `${baseRef}^{commit}`], { encoding: 'utf8', timeout: 5_000 });
857
+ const sha = parsed.status === 0 ? (parsed.stdout ?? '').trim() : '';
858
+ return { dir, baseRef, ...(/^[0-9a-f]{40,64}$/.test(sha) ? { baseSha: sha } : {}) };
859
+ } catch {
860
+ return { dir, baseRef };
861
+ }
862
+ }
863
+
796
864
  function junitReportTemporaryDirectory(): string {
797
865
  return process.env.ELANOUS_GATE_JUNIT_TMPDIR || tmpdir();
798
866
  }
@@ -920,8 +988,17 @@ export function withBaselineWorktree<T>(cwd: string, baseRef: string, run: (base
920
988
  const baselineDir = mkdtempSync(join(tmpdir(), 'elanous-gate-baseline-'));
921
989
  let attached = false;
922
990
  try {
923
- const add = runGitCommand(cwd, gateWorktreeAddArgs(baselineDir, baseRef), { encoding: 'utf8', timeout: 60_000 });
924
- if (add.status !== 0) return classifyBaselineProcess({ status: add.status, stdout: add.stdout, stderr: add.stderr });
991
+ const started = Date.now();
992
+ const addTimeout = worktreeAddTimeoutForRepo(cwd, undefined, baseRef);
993
+ const add = runGitCommand(cwd, gateWorktreeAddArgs(baselineDir, baseRef), { encoding: 'utf8', timeout: addTimeout.ms, killSignal: 'SIGKILL' });
994
+ const elapsedMs = Date.now() - started;
995
+ debug.log('self-implement.gate-baseline', 'worktree-add-result', {
996
+ phase: 'baseline',
997
+ status: add.status, signal: add.signal ?? null, errorCode: add.errorCode ?? null,
998
+ elapsedMs, timeoutMs: addTimeout.ms, trackedFileCount: addTimeout.trackedFileCount, timeoutSource: addTimeout.source, parentRssBytes: process.memoryUsage().rss,
999
+ cgroupMemoryCurrentBytes: cgroupMemoryBytes('memory.current'), cgroupMemoryLimitBytes: cgroupMemoryBytes('memory.max'),
1000
+ });
1001
+ if (add.status !== 0) return classifyBaselineWorktreeAddFailure(add, elapsedMs, addTimeout.ms, worktreeAddFailureContext(cwd, baselineDir, baseRef));
925
1002
  attached = true;
926
1003
  linkDependencies(cwd, baselineDir);
927
1004
  return run(baselineDir);
@@ -953,8 +1030,17 @@ function withVerifyWorktree<T>(cwd: string, baseRef: string, run: (dir: string)
953
1030
  let attached = false;
954
1031
  try {
955
1032
  dir = mkdtempSync(join(tmpdir(), 'elanous-gate-baseline-'));
956
- const add = runGitCommand(cwd, gateWorktreeAddArgs(dir, baseRef), { encoding: 'utf8', timeout: 60_000 });
957
- if (add.status !== 0) return classifyBaselineProcess({ status: add.status, stdout: add.stdout, stderr: add.stderr });
1033
+ const started = Date.now();
1034
+ const addTimeout = worktreeAddTimeoutForRepo(cwd, undefined, baseRef);
1035
+ const add = runGitCommand(cwd, gateWorktreeAddArgs(dir, baseRef), { encoding: 'utf8', timeout: addTimeout.ms, killSignal: 'SIGKILL' });
1036
+ const elapsedMs = Date.now() - started;
1037
+ debug.log('self-implement.gate-baseline', 'worktree-add-result', {
1038
+ phase: 'verify',
1039
+ status: add.status, signal: add.signal ?? null, errorCode: add.errorCode ?? null,
1040
+ elapsedMs, timeoutMs: addTimeout.ms, trackedFileCount: addTimeout.trackedFileCount, timeoutSource: addTimeout.source, parentRssBytes: process.memoryUsage().rss,
1041
+ cgroupMemoryCurrentBytes: cgroupMemoryBytes('memory.current'), cgroupMemoryLimitBytes: cgroupMemoryBytes('memory.max'),
1042
+ });
1043
+ if (add.status !== 0) return classifyBaselineWorktreeAddFailure(add, elapsedMs, addTimeout.ms, worktreeAddFailureContext(cwd, dir, baseRef));
958
1044
  attached = true;
959
1045
  linkDependencies(cwd, dir);
960
1046
  return run(dir);
@@ -979,10 +1065,7 @@ export function runGateBaseline(cwd: string, failedFiles: readonly string[], bas
979
1065
  const files = [...new Set(failedFiles.filter(Boolean))];
980
1066
  if (files.length === 0) return { status: 'unknown', log: 'baseline skipped: failed test files could not be identified' };
981
1067
  const result = withBaselineWorktree(cwd, baseRef, (baselineDir) => {
982
- const missingAtBase = files.filter((f) => {
983
- const probe = runGitCommand(cwd, ['cat-file', '-e', `${baseRef}:${f}`], { encoding: 'utf8', timeout: 15_000 });
984
- return probe.status === 1;
985
- });
1068
+ const missingAtBase = files.filter((f) => probeBaseTestFilePresence(cwd, baseRef, f) === 'missing');
986
1069
  const timeoutMs = baselineTimeoutForFiles(files.length);
987
1070
  const process = runBaselineBunTest(baselineDir, files, timeoutMs);
988
1071
  const baseline = classifyBaselineProcess(process, { timeoutMs, fileCount: files.length });
@@ -1417,7 +1500,7 @@ export function buildGateBaselineReport(
1417
1500
  worktreeFailuresParsed,
1418
1501
  files: [...new Set(failures.flatMap((failure) => failure.file ? [failure.file] : []))],
1419
1502
  baselineStatus: baseline.status,
1420
- log: baseline.log,
1503
+ log: baseline.gitStderrTail ? `${baseline.log}\nbaseline worktree-add git stderr: ${baseline.gitStderrTail}` : baseline.log,
1421
1504
  };
1422
1505
  }
1423
1506
 
@@ -893,6 +893,7 @@ function runSelfGateCliCore(cwd: string, options: SelfGateCliOptions, deps: Self
893
893
  lines.push(`shard unmeasured: ${shardId} · ${sharded.unmeasuredByShard?.[shardId] ?? sharded.reason ?? 'cause unavailable'}`);
894
894
  }
895
895
  lines.push(`shards: unmeasured (${unmeasuredReason})`);
896
+ if (sharded.baselineStderrTail) lines.push(`baseline worktree-add git stderr: ${sharded.baselineStderrTail}`);
896
897
  capture.unmeasuredReason = unmeasuredReason;
897
898
  }
898
899
  else if (aggregate.report) {
@@ -184,8 +184,8 @@ export const PUSH_TIMEOUT_MS = 10 * 60_000;
184
184
 
185
185
  export type RemoteRunOutcome =
186
186
  | { kind: 'ran'; rc: number; stdout: Buffer; stderr: Buffer; commit: string; host: string; ms: number }
187
- | { kind: 'busy'; occupied?: number }
188
- | { kind: 'infra'; reason: string };
187
+ | { kind: 'busy'; occupied?: number; rc?: number }
188
+ | { kind: 'infra'; reason: string; stage?: string; rc?: number | null; stderr?: string };
189
189
 
190
190
  export interface RemoteRunOptions {
191
191
  repo: string;
@@ -331,12 +331,12 @@ export function runOnRemote(opts: RemoteRunOptions, runner: GateRemoteRunner = r
331
331
  } catch (error) { return { kind: 'infra', reason: `argv: ${error instanceof Error ? error.message : String(error)}` }; }
332
332
  const shas = [...new Set([commit, mainSha, ...extra])];
333
333
  const pushTarget = `${opts.host}:${opts.mirror.startsWith('~/') ? opts.mirror.slice(2) : opts.mirror}`;
334
- // Non-interactive and time-bounded: a stuck connection or auth prompt must end in a local fallback, not a hang.
334
+ // Non-interactive and time-bounded: a stuck connection or auth prompt must end without hanging.
335
335
  const push = runner.local('git', ['push', '--quiet', pushTarget, ...shas.map((sha) => `${sha}:refs/elanous/gate/${sha}`)], opts.repo, {
336
336
  timeoutMs: PUSH_TIMEOUT_MS,
337
337
  env: { ...process.env, GIT_SSH_COMMAND: 'ssh -o BatchMode=yes -o ConnectTimeout=10', GIT_TERMINAL_PROMPT: '0' },
338
338
  });
339
- if (push.rc !== 0 || push.error) return { kind: 'infra', reason: `push-failed rc=${push.rc}: ${(push.stderr || push.error || '').trim().split('\n').slice(-2).join(' | ')}` };
339
+ if (push.rc !== 0 || push.error) return { kind: 'infra', stage: 'push', rc: push.rc, stderr: push.stderr || push.error || '', reason: `push-failed rc=${push.rc}: ${(push.stderr || push.error || '').trim().split('\n').slice(-2).join(' | ')}` };
340
340
  const script = remoteScript({ mirror: opts.mirror, commit, fetchShas: shas, mainSha, argv, installPwa: opts.installPwa ?? false, stableCheckout: opts.stableCheckout, payloadFiles: opts.payloadFiles, hostCap: opts.hostCap, slotDir: opts.slotDir });
341
341
  const run = runner.ssh(opts.host, script, opts.timeoutMs ?? 120 * 60_000);
342
342
  // The script prints "\n<marker><rc>\n": everything before that leading newline is the tool's own stderr, byte for byte.
@@ -350,17 +350,17 @@ export function runOnRemote(opts: RemoteRunOptions, runner: GateRemoteRunner = r
350
350
  const last = stderrText.trimEnd().split('\n').at(-1) ?? '';
351
351
  if (run.rc === 98) {
352
352
  const busy = /^__GATE_REMOTE_BUSY(?:=(\d+))?$/.exec(last);
353
- if (busy) return { kind: 'busy', ...(busy[1] !== undefined ? { occupied: Number(busy[1]) } : {}) };
353
+ if (busy) return { kind: 'busy', rc: run.rc, ...(busy[1] !== undefined ? { occupied: Number(busy[1]) } : {}) };
354
354
  }
355
- if (run.rc === 97 && last.startsWith(INFRA)) return { kind: 'infra', reason: `remote-${last.slice(INFRA.length).trim()}` };
355
+ if (run.rc === 97 && last.startsWith(INFRA)) return { kind: 'infra', stage: last.slice(INFRA.length).trim(), rc: run.rc, stderr: stderrText, reason: `remote-${last.slice(INFRA.length).trim()}` };
356
356
  }
357
357
  // No marker, or ssh did not end cleanly after it (the script always exits 0 once the marker is written): output may be cut.
358
- if (marker < 0) return { kind: 'infra', reason: `ssh rc=${run.rc}${run.error ? ` ${run.error}` : ''}: ${stderrText.trim().split('\n').slice(-2).join(' | ')}` };
359
- if (run.rc !== 0 || run.error) return { kind: 'infra', reason: `ssh-incomplete rc=${run.rc}${run.error ? ` ${run.error}` : ''}` };
358
+ if (marker < 0) return { kind: 'infra', stage: 'ssh', rc: run.rc, stderr: stderrText, reason: `ssh rc=${run.rc}${run.error ? ` ${run.error}` : ''}: ${stderrText.trim().split('\n').slice(-2).join(' | ')}` };
359
+ if (run.rc !== 0 || run.error) return { kind: 'infra', stage: 'ssh-incomplete', rc: run.rc, stderr: stderrText, reason: `ssh-incomplete rc=${run.rc}${run.error ? ` ${run.error}` : ''}` };
360
360
  // The marker is the last thing the script writes: exactly "\n<marker><digits>\n". Anything else (empty, cut) is infra.
361
361
  const tail = /^\n__GATE_REMOTE_RC=(\d{1,3})\n$/.exec(stderrBytes.subarray(marker).toString('utf8'));
362
362
  const rc = tail ? Number(tail[1]) : NaN;
363
- if (!(rc >= 0 && rc <= 255)) return { kind: 'infra', reason: 'rc-unparsed' };
363
+ if (!(rc >= 0 && rc <= 255)) return { kind: 'infra', stage: 'rc-unparsed', rc: run.rc, stderr: stderrText, reason: 'rc-unparsed' };
364
364
  // The tool's stderr is exactly what came before the marker line.
365
365
  return { kind: 'ran', rc, stdout: stdoutBytes, stderr: stderrBytes.subarray(0, marker), commit, host: opts.host, ms: Date.now() - started };
366
366
  }
@@ -437,11 +437,13 @@ export interface DispatchOptions {
437
437
  /** Set when this invocation cannot be reproduced remotely (e.g. self gate without --base): automatic placement
438
438
  * falls back with this reason; an explicit self gate --remote reports an unmeasured check instead. */
439
439
  localOnlyReason?: string;
440
- /** Self gate CLI only: explicit --remote must never be measured by a local fallback. */
440
+ /** Explicit or caller-required remote measurement must never become a local fallback. */
441
441
  explicitRemoteOnly?: boolean;
442
+ /** Keep the remote checkout and TypeScript cache per host slot across repeated checks. */
443
+ stableCheckout?: boolean;
442
444
  /** Self gate CLI only: name the host for both automatic and explicit remote execution. */
443
445
  reportRemoteHost?: boolean;
444
- /** Self gate's state universe; omitted by other callers and injected tests. */
446
+ /** Release gate host reservations shared by self gate and changed typecheck. */
445
447
  reservationRoot?: string;
446
448
  runLocal: () => number | Promise<number>;
447
449
  /** Called once with the final remote outcome (never on a local decision), before its output passes through or the
@@ -467,14 +469,21 @@ async function loadSettings(): Promise<GateRemoteSettings> {
467
469
  } catch { return resolveGateRemoteSettings(undefined); }
468
470
  }
469
471
 
470
- /** Decide local/remote, run, and return the tool's exit code. Automatic infra failure ⇒ visible local fallback. */
472
+ /** Decide local/remote, run, and return the tool's exit code. Self gate remote failures are never local measurements. */
471
473
  export async function dispatchHeavyCheck(opts: DispatchOptions, deps: DispatchDeps = {}): Promise<number> {
472
474
  const settings = deps.settings ?? await loadSettings();
473
475
  const env = deps.env ?? process.env;
474
476
  const write = deps.write ?? { out: (d: string | Uint8Array) => process.stdout.write(d), err: (d: string | Uint8Array) => process.stderr.write(d) };
475
- const decision = decideGateDispatch({ flags: opts.flags, settings, load1: deps.load1 ?? loadavg()[0]!, env });
477
+ const flags = opts.tool === 'self-gate' && !opts.flags.local ? { ...opts.flags, remote: opts.flags.remote ?? true } : opts.flags;
478
+ const decision = decideGateDispatch({ flags, settings, load1: deps.load1 ?? loadavg()[0]!, env });
476
479
  debug.log('gate.remote', 'decision', { tool: opts.tool, mode: decision.mode, host: decision.host, reason: decision.reason, load1: decision.load1 });
477
480
  if (decision.mode === 'local') {
481
+ if (opts.tool === 'self-gate' && !opts.flags.local) {
482
+ const host = typeof flags.remote === 'string' ? flags.remote : settings.host;
483
+ debug.log('gate.remote', 'remote-unmeasured', { tool: opts.tool, host, reason: decision.reason, stage: 'placement', rc: null });
484
+ write.err(`[gate.remote] remote unmeasured on ${host} (stage=placement, rc=unknown) — ${decision.reason}\n`);
485
+ return 1;
486
+ }
478
487
  if (opts.explicitRemoteOnly && opts.flags.remote !== undefined && decision.reason !== 'flag-local') {
479
488
  write.err(`[gate.remote] remote unmeasured — ${decision.reason}\n`);
480
489
  return 1;
@@ -482,12 +491,14 @@ export async function dispatchHeavyCheck(opts: DispatchOptions, deps: DispatchDe
482
491
  return opts.runLocal();
483
492
  }
484
493
  let host = decision.host!;
485
- const reservationRoot = opts.tool === 'self-gate' ? opts.reservationRoot ?? (deps.runner ? undefined : gateHostReservationRoot()) : undefined;
494
+ const reservationRoot = opts.tool === 'self-gate' || opts.tool === 'ci-typecheck-changed'
495
+ ? opts.reservationRoot ?? (deps.runner ? undefined : gateHostReservationRoot()) : undefined;
486
496
  if (reservationRoot) {
487
497
  const reservationHost = host.split('@').at(-1)!;
488
498
  const first = inspectReleaseGateHost(reservationRoot, reservationHost);
489
499
  if (first.status !== 'free') {
490
- const alternate = reservationHost === 'node-b' ? 'node-c' : null;
500
+ // Changed typecheck has a fixed node-b placement; a release reservation makes it unmeasured.
501
+ const alternate = opts.tool === 'self-gate' && reservationHost === 'node-b' ? 'node-c' : null;
491
502
  const other = alternate ? inspectReleaseGateHost(reservationRoot, alternate) : null;
492
503
  if (alternate && other?.status === 'free') {
493
504
  debug.log('gate.remote', 'host-reserved-reroute', { from: host, to: alternate, reason: first.reason, status: first.status });
@@ -496,22 +507,26 @@ export async function dispatchHeavyCheck(opts: DispatchOptions, deps: DispatchDe
496
507
  } else {
497
508
  const reason = `host-reserved: ${host} (${first.reason}); alternate ${alternate ?? '(none)'} ${other?.status ?? 'unavailable'}`;
498
509
  debug.log('gate.remote', 'host-reserved-unmeasured', { host, reason });
499
- write.err(`[gate.remote] remote unmeasured — ${reason}\n`);
510
+ write.err(opts.tool === 'self-gate'
511
+ ? `[gate.remote] remote unmeasured on ${host} (stage=host-reserved, rc=unknown) — ${reason}\n`
512
+ : `[gate.remote] remote unmeasured — ${reason}\n`);
500
513
  return 1;
501
514
  }
502
515
  }
503
516
  }
504
- const fallback = (reason: string) => {
505
- if (opts.explicitRemoteOnly && opts.flags.remote !== undefined) {
506
- debug.log('gate.remote', 'remote-unmeasured', { tool: opts.tool, host, reason });
507
- write.err(`[gate.remote] remote unmeasured on ${host} — ${reason.replace(/\s+/g, ' ').trim()}\n`);
517
+ const fallback = (reason: string, failure?: { stage?: string; rc?: number | null; stderr?: string }) => {
518
+ const selfGateInfrastructureFailure = opts.tool === 'self-gate' && failure?.stage !== 'reproducibility';
519
+ if (selfGateInfrastructureFailure || (opts.explicitRemoteOnly && opts.flags.remote !== undefined)) {
520
+ debug.log('gate.remote', 'remote-unmeasured', { tool: opts.tool, host, reason, ...(opts.tool === 'self-gate' ? { stage: failure?.stage, rc: failure?.rc, stderr: failure?.stderr } : {}) });
521
+ write.err(`[gate.remote] remote unmeasured on ${host}${opts.tool === 'self-gate' && failure?.stage ? ` (stage=${failure.stage}, rc=${failure.rc ?? 'unknown'})` : ''} — ${reason.replace(/\s+/g, ' ').trim()}\n`);
522
+ if (opts.tool === 'self-gate' && failure?.stderr) write.err(failure.stderr.endsWith('\n') ? failure.stderr : `${failure.stderr}\n`);
508
523
  return 1;
509
524
  }
510
525
  debug.log('gate.remote', 'fallback', { tool: opts.tool, host, reason });
511
526
  write.err(`[gate.remote] fallback to local — ${reason}\n`);
512
527
  return opts.runLocal();
513
528
  };
514
- if (opts.localOnlyReason) return fallback(opts.localOnlyReason);
529
+ if (opts.localOnlyReason) return fallback(opts.localOnlyReason, { stage: 'reproducibility', rc: null });
515
530
  const hostCap = gateRemoteHostCap(settings, host);
516
531
  const sleep = deps.sleep ?? ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)));
517
532
  const now = deps.now ?? Date.now;
@@ -520,13 +535,13 @@ export async function dispatchHeavyCheck(opts: DispatchOptions, deps: DispatchDe
520
535
  let outcome: RemoteRunOutcome;
521
536
  for (;;) {
522
537
  try {
523
- outcome = runOnRemote({ repo: opts.repo, host, mirror: settings.mirror, argv: opts.remoteArgv, refs: opts.refs, ...(opts.commit !== undefined ? { commit: opts.commit } : {}), installPwa: opts.installPwa, payloadFiles: opts.payloadFiles, hostCap }, deps.runner);
538
+ outcome = runOnRemote({ repo: opts.repo, host, mirror: settings.mirror, argv: opts.remoteArgv, refs: opts.refs, ...(opts.commit !== undefined ? { commit: opts.commit } : {}), installPwa: opts.installPwa, payloadFiles: opts.payloadFiles, stableCheckout: opts.stableCheckout, hostCap }, deps.runner);
524
539
  } catch (error) {
525
540
  outcome = { kind: 'infra', reason: `exception: ${error instanceof Error ? error.message : String(error)}` };
526
541
  }
527
542
  if (outcome.kind !== 'busy') break;
528
543
  debug.log('gate.remote', 'host-busy', { tool: opts.tool, host, cap: hostCap, occupied: outcome.occupied ?? null });
529
- // Never start an attempt past the deadline: an expired wait falls back only for automatic placement.
544
+ // Never start an attempt past the deadline: an expired self gate wait remains unmeasured.
530
545
  const left = deadline - now();
531
546
  if (left <= 0) break;
532
547
  await sleep(Math.min(15_000, left));
@@ -536,8 +551,8 @@ export async function dispatchHeavyCheck(opts: DispatchOptions, deps: DispatchDe
536
551
  try { opts.onRemoteOutcome(outcome, host, deps.runner ?? realGateRemoteRunner); }
537
552
  catch (error) { debug.log('gate.remote', 'outcome-hook-failed', { tool: opts.tool, host, error: error instanceof Error ? error.message : String(error) }); }
538
553
  }
539
- if (outcome.kind === 'busy') return fallback(`host-busy (occupied ${outcome.occupied ?? 'unknown'}/${hostCap}, held for ${settings.slotWaitSeconds}s)`);
540
- if (outcome.kind === 'infra') return fallback(outcome.reason);
554
+ if (outcome.kind === 'busy') return fallback(`host-busy (occupied ${outcome.occupied ?? 'unknown'}/${hostCap}, held for ${settings.slotWaitSeconds}s)`, { stage: 'host-busy', rc: outcome.rc });
555
+ if (outcome.kind === 'infra') return fallback(outcome.reason, { ...outcome, stage: outcome.stage ?? 'preflight', rc: outcome.rc ?? null });
541
556
  // Parity: the tool's own stdout/stderr/rc pass through unchanged; JSON gains host · remote:true,
542
557
  // and the self gate CLI appends a host diagnostic to human-readable stderr.
543
558
  debug.log('gate.remote', 'result', { tool: opts.tool, host: outcome.host, commit: outcome.commit, rc: outcome.rc, ms: outcome.ms });