elanous 0.2.27 → 0.2.29

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 (700) 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/{Ev2jivDMTSoEc-5rIXdcy → cIpv5nU9AycwYWZI9H589}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{ab4d57c2.e90bc2cb31949045.js → 058a98ba.7eb28d5e6dc03565.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{4565-67e4c620597965c8.js → 1015-9cba22a5a4554797.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +8 -0
  9. package/apps/pwa/out/_next/static/chunks/{1516.83dd2c1b86b4e507.js → 1142.65d002789ab3af7d.js} +2 -2
  10. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +34 -0
  12. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1516.dfaceff3fd2d0e0d.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +286 -0
  16. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +24 -0
  17. package/apps/pwa/out/_next/static/chunks/1782-59db1b5aa06df38a.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{1743.563d3168e95825ef.js → 1852.7f7b53991fcb99ef.js} +2 -2
  19. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +36 -0
  22. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +64 -0
  24. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{65ebff95.081daeff622d238e.js → 285adb1a.5654e605dddf86d2.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +115 -0
  31. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3160-95c96f4d2a21dd26.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +90 -0
  36. package/apps/pwa/out/_next/static/chunks/328bb3ab-6628a1114fe3fb3b.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{9917-9e26abc5f7772735.js → 3396-97b97928c49190c9.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/{6196.34d6b229079e9e28.js → 3403.7199205e65124486.js} +1 -1
  40. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/419.736c0d6f426249a7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{6def8a8e.c81f9ca41028eccf.js → 425cfc4d.fb91158e3971c39f.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/{16e57f67.3ea19e893461e611.js → 46bd8bea.2f4b4099172fcdb7.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{5081.a240b63fad28663a.js → 4759.1f76713aefb87db5.js} +1 -1
  51. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +94 -0
  54. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +62 -0
  60. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +27 -0
  63. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +104 -0
  64. package/apps/pwa/out/_next/static/chunks/{9974.e77b4ff4884557b3.js → 5591.a35e7a217734a8b9.js} +2 -2
  65. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +93 -0
  66. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/{5492-e05e26a033ba80d2.js → 6013-2f769370d8b4c2c6.js} +3 -3
  69. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +24 -0
  70. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +2 -0
  72. package/apps/pwa/out/_next/static/chunks/{5408.377c8c543635b81f.js → 6534.1ab00f370db7b105.js} +1 -1
  73. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +148 -0
  74. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +149 -0
  75. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +79 -0
  77. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/{8578.dff22d988cc2b106.js → 6767.1fcfc9b8be83975f.js} +16 -16
  79. package/apps/pwa/out/_next/static/chunks/6776.06ff1e3b464cc607.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{9311.24c8f5ea793253dd.js → 6853.cc5174a9dee59593.js} +1 -1
  81. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +287 -0
  86. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/{94.4cfed21c0b781a06.js → 7375.050ea0d72968e49f.js} +16 -16
  92. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +77 -0
  94. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +74 -0
  97. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7725-4f83d5541fbdb81b.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8332.6f0f49df772e163b.js +23 -0
  102. package/apps/pwa/out/_next/static/chunks/{7483.ba01c6c209b81bba.js → 8398.73a19b39715eda04.js} +1 -1
  103. package/apps/pwa/out/_next/static/chunks/{2846.d6a433b8663819a5.js → 8471.8d2a8c74f09c36ff.js} +3 -3
  104. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +226 -0
  106. package/apps/pwa/out/_next/static/chunks/{5785-ea8d2c633b6688e3.js → 8767-2f6a634f5abeaa01.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +32 -0
  109. package/apps/pwa/out/_next/static/chunks/8795.32573a185af18c7b.js +41 -0
  110. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{4593.10f5b9bd702d4a6c.js → 9143.ff14585db1d275ff.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{4204.a409ab6250c0f6a8.js → 9907.49be0fcadaf214b5.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{973cbf1b.3bbcf2b41548eca7.js → a435ad95.577add051b4facb2.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-a5635eba0d73b84e.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/{page-ff27902d0b11ef4f.js → page-8aaa6dedc4c10dfb.js} +1 -1
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/{page-25a302273b054fd7.js → page-33bf667a5fb297bf.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-29900ed0011b2c83.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-87b88f551f421d8b.js → page-9eb56166774eb256.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9f92737b8766009a.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{f4dfbfc0.a69fb12f854882aa.js → bc324b7c.02a09dd93f6a399b.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +122 -0
  177. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +1 -0
  183. package/apps/pwa/out/approvals/index.html +1 -1
  184. package/apps/pwa/out/approvals/index.txt +22 -22
  185. package/apps/pwa/out/autopilot/index.html +1 -1
  186. package/apps/pwa/out/autopilot/index.txt +22 -22
  187. package/apps/pwa/out/board/index.html +1 -1
  188. package/apps/pwa/out/board/index.txt +22 -22
  189. package/apps/pwa/out/botlab/index.html +1 -1
  190. package/apps/pwa/out/botlab/index.txt +21 -21
  191. package/apps/pwa/out/bots/index.html +1 -1
  192. package/apps/pwa/out/bots/index.txt +21 -21
  193. package/apps/pwa/out/ceo/index.html +1 -1
  194. package/apps/pwa/out/ceo/index.txt +22 -22
  195. package/apps/pwa/out/chat/index.html +1 -1
  196. package/apps/pwa/out/chat/index.txt +21 -21
  197. package/apps/pwa/out/consult/index.html +1 -1
  198. package/apps/pwa/out/consult/index.txt +22 -22
  199. package/apps/pwa/out/control/index.html +1 -1
  200. package/apps/pwa/out/control/index.txt +22 -22
  201. package/apps/pwa/out/decisions/index.html +1 -1
  202. package/apps/pwa/out/decisions/index.txt +21 -21
  203. package/apps/pwa/out/design-check/index.html +1 -1
  204. package/apps/pwa/out/design-check/index.txt +22 -22
  205. package/apps/pwa/out/editor/index.html +1 -1
  206. package/apps/pwa/out/editor/index.txt +22 -22
  207. package/apps/pwa/out/exec/index.html +1 -1
  208. package/apps/pwa/out/exec/index.txt +22 -22
  209. package/apps/pwa/out/field/index.html +1 -1
  210. package/apps/pwa/out/field/index.txt +22 -22
  211. package/apps/pwa/out/healthz +1 -1
  212. package/apps/pwa/out/index.html +1 -1
  213. package/apps/pwa/out/index.txt +21 -21
  214. package/apps/pwa/out/inside/index.html +1 -1
  215. package/apps/pwa/out/inside/index.txt +21 -21
  216. package/apps/pwa/out/intake/index.html +1 -1
  217. package/apps/pwa/out/intake/index.txt +22 -22
  218. package/apps/pwa/out/live/index.html +1 -1
  219. package/apps/pwa/out/live/index.txt +22 -22
  220. package/apps/pwa/out/live-run/index.html +1 -1
  221. package/apps/pwa/out/live-run/index.txt +22 -22
  222. package/apps/pwa/out/loops/index.html +1 -1
  223. package/apps/pwa/out/loops/index.txt +21 -21
  224. package/apps/pwa/out/market/index.html +1 -1
  225. package/apps/pwa/out/market/index.txt +21 -21
  226. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  227. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  228. package/apps/pwa/out/morning/index.html +1 -1
  229. package/apps/pwa/out/morning/index.txt +22 -22
  230. package/apps/pwa/out/observatory/index.html +1 -1
  231. package/apps/pwa/out/observatory/index.txt +22 -22
  232. package/apps/pwa/out/ops/checklist/index.html +1 -1
  233. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  234. package/apps/pwa/out/ops/release/index.html +1 -1
  235. package/apps/pwa/out/ops/release/index.txt +21 -21
  236. package/apps/pwa/out/ops/seats/index.html +1 -1
  237. package/apps/pwa/out/ops/seats/index.txt +21 -21
  238. package/apps/pwa/out/outputs/index.html +1 -1
  239. package/apps/pwa/out/outputs/index.txt +21 -21
  240. package/apps/pwa/out/reflection/index.html +1 -1
  241. package/apps/pwa/out/reflection/index.txt +22 -22
  242. package/apps/pwa/out/scheduler/index.html +1 -1
  243. package/apps/pwa/out/scheduler/index.txt +22 -22
  244. package/apps/pwa/out/sessions/index.html +1 -1
  245. package/apps/pwa/out/sessions/index.txt +21 -21
  246. package/apps/pwa/out/settings/devices/index.html +1 -1
  247. package/apps/pwa/out/settings/devices/index.txt +22 -22
  248. package/apps/pwa/out/settings/index.html +1 -1
  249. package/apps/pwa/out/settings/index.txt +22 -22
  250. package/apps/pwa/out/setup/done/index.html +1 -1
  251. package/apps/pwa/out/setup/done/index.txt +22 -22
  252. package/apps/pwa/out/setup/index.html +1 -1
  253. package/apps/pwa/out/setup/index.txt +22 -22
  254. package/apps/pwa/out/share/index.html +1 -1
  255. package/apps/pwa/out/share/index.txt +22 -22
  256. package/apps/pwa/out/showroom/index.html +1 -1
  257. package/apps/pwa/out/showroom/index.txt +21 -21
  258. package/apps/pwa/out/tasks/index.html +1 -1
  259. package/apps/pwa/out/tasks/index.txt +22 -22
  260. package/apps/pwa/out/term/index.html +1 -1
  261. package/apps/pwa/out/term/index.txt +22 -22
  262. package/apps/pwa/out/today/index.html +1 -1
  263. package/apps/pwa/out/today/index.txt +22 -22
  264. package/apps/pwa/out/trace/index.html +1 -1
  265. package/apps/pwa/out/trace/index.txt +22 -22
  266. package/apps/pwa/out/vault/index.html +1 -1
  267. package/apps/pwa/out/vault/index.txt +22 -22
  268. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  269. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  270. package/apps/pwa/out/workflows/index.html +1 -1
  271. package/apps/pwa/out/workflows/index.txt +22 -22
  272. package/apps/pwa/out/workspace/index.html +1 -1
  273. package/apps/pwa/out/workspace/index.txt +22 -22
  274. package/apps/pwa/out/worktrees/index.html +1 -1
  275. package/apps/pwa/out/worktrees/index.txt +22 -22
  276. package/graphs/implement-loop.yaml +38 -1
  277. package/graphs/release/release-loop.yaml +6 -2
  278. package/graphs/steward/recipes.yaml +6 -0
  279. package/graphs/steward/release-day.yaml +23 -0
  280. package/graphs/steward/steward.yaml +9 -1
  281. package/graphs/work/code-pr.yaml +23 -0
  282. package/package.json +1 -1
  283. package/plugins/agent-team/agents/research.md +1 -0
  284. package/scripts/browser-observe-cycle.ts +76 -2
  285. package/scripts/ci-typecheck-changed.ts +53 -19
  286. package/scripts/coord-channel-watch.sh +26 -6
  287. package/scripts/coord-role-pack.ts +143 -0
  288. package/scripts/detect-test-interference.ts +31 -1
  289. package/scripts/lib/morning-report-options.ts +41 -0
  290. package/scripts/pr-land-extra-remote-gates.ts +49 -0
  291. package/scripts/release-loop/docs-node.ts +51 -22
  292. package/scripts/release-loop/gate-batch-safe.ts +23 -0
  293. package/scripts/release-loop/gate-history.ts +422 -0
  294. package/scripts/release-loop/gate-node.ts +336 -39
  295. package/scripts/release-loop/gate-triage-node.ts +190 -0
  296. package/scripts/release-loop/node-verdict.ts +3 -1
  297. package/scripts/release-loop/publish-node.ts +3 -0
  298. package/scripts/release-loop/spawn-lane.ts +68 -0
  299. package/scripts/release-loop/tui-node-checks.ts +28 -2
  300. package/scripts/release-loop/version-node.ts +62 -4
  301. package/scripts/skills/public-check.ts +5 -2
  302. package/scripts/test-deterministic.ts +549 -37
  303. package/scripts/usage-rollup.ts +11 -3
  304. package/scripts/ux-sim.ts +7 -1
  305. package/scripts/verify-kpack6-live.ts +230 -0
  306. package/src/acp/codex-plugins.ts +17 -0
  307. package/src/acp/core-turn-bridge.ts +98 -22
  308. package/src/acp/elanous-extensions.ts +2 -0
  309. package/src/acp/server.ts +2 -0
  310. package/src/agent/ref-grounding.ts +18 -0
  311. package/src/agent/task-notification.ts +2 -1
  312. package/src/agent-mission/in-agent-plugin.ts +8 -3
  313. package/src/agent-substrate/pr-reviewer.ts +29 -21
  314. package/src/agent-substrate/self-review-cli.ts +34 -10
  315. package/src/briefing/brief-items.ts +151 -35
  316. package/src/budget/llm-cost.ts +25 -2
  317. package/src/budget/pty-usage-reemit.ts +7 -0
  318. package/src/budget/run-usage-rollup.ts +9 -0
  319. package/src/budget/usage-daily-store.ts +98 -0
  320. package/src/budget/usage-outcomes.ts +32 -0
  321. package/src/capture/tui-self-report.ts +22 -4
  322. package/src/chat/index.ts +31 -10
  323. package/src/chat/pickers/modal-runtime.ts +1 -0
  324. package/src/chat/pickers/modals.ts +3 -1
  325. package/src/chat/turn-typeahead.ts +123 -16
  326. package/src/claims/claims-ledger.ts +23 -0
  327. package/src/claims/claims-render.ts +22 -2
  328. package/src/cli/brief-cli.ts +131 -10
  329. package/src/cli/claims-cli.ts +24 -4
  330. package/src/cli/dashboard-name-flag.ts +48 -0
  331. package/src/cli/doctor-cli.ts +80 -0
  332. package/src/cli/log-event-names.ts +12 -0
  333. package/src/cli/msg-cli.ts +210 -11
  334. package/src/cli/plugin-cli.ts +11 -3
  335. package/src/cli/pr-cli.ts +443 -104
  336. package/src/cli/pr-land-heavy-remote.ts +233 -0
  337. package/src/cli/pr-land-overlap-evidence.ts +104 -5
  338. package/src/cli/pr-land-refusal.ts +20 -0
  339. package/src/cli/pty-takeover-cli.ts +125 -16
  340. package/src/cli/release-cli.ts +46 -2
  341. package/src/cli/remote-resolve.ts +2 -1
  342. package/src/cli/rfc-cli.ts +24 -0
  343. package/src/cli/seat-cli.ts +26 -16
  344. package/src/cli/tailscale-serve.ts +5 -8
  345. package/src/cli/tasks-cli.ts +400 -27
  346. package/src/cli/usage-cli.ts +155 -16
  347. package/src/cli/usage-daily-cli.ts +84 -0
  348. package/src/context-bus/context-now.ts +82 -5
  349. package/src/core-turn/auth-rejected-notice.ts +41 -0
  350. package/src/core-turn/run-core-turn.ts +13 -2
  351. package/src/core-turn/run-goal-loop.ts +17 -1
  352. package/src/core-turn/short-question.ts +45 -12
  353. package/src/core-turn/types.ts +7 -0
  354. package/src/dashboard/acp-active-model.ts +40 -0
  355. package/src/dashboard/auto-compact-runtime.ts +2 -0
  356. package/src/dashboard/boot-banner.ts +80 -0
  357. package/src/dashboard/dashboard-status-lines.ts +11 -0
  358. package/src/dashboard/detail-viewer-runtime.ts +15 -2
  359. package/src/dashboard/event-loop-stall-monitor.ts +4 -0
  360. package/src/dashboard/first-screen-band.ts +63 -13
  361. package/src/dashboard/goal-loop-thinking.ts +16 -0
  362. package/src/dashboard/hitl-boot.ts +9 -4
  363. package/src/dashboard/index.ts +235 -389
  364. package/src/dashboard/input/chat-main-entry-runtime.ts +2 -0
  365. package/src/dashboard/input/chat-main-log-actions.ts +4 -0
  366. package/src/dashboard/input/chat-main-log-command.ts +12 -1
  367. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +172 -3
  368. package/src/dashboard/input/chat-main-session.ts +6 -2
  369. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  370. package/src/dashboard/input/chat-main-turn.ts +2 -1
  371. package/src/dashboard/input/compact-prepass-recovery.ts +97 -0
  372. package/src/dashboard/input/dashboard-chord-actions.ts +10 -1
  373. package/src/dashboard/input/dashboard-chord-runtime.ts +2 -0
  374. package/src/dashboard/input/external-input-host.ts +45 -0
  375. package/src/dashboard/input/log-fold-binding.ts +18 -0
  376. package/src/dashboard/input/mouse-wiring.ts +17 -4
  377. package/src/dashboard/input/turn-steer-bridge.ts +94 -0
  378. package/src/dashboard/log-click-runtime.ts +5 -3
  379. package/src/dashboard/running-build-status.ts +74 -0
  380. package/src/dashboard/seat-boot-preamble.ts +113 -0
  381. package/src/dashboard/seat-local-instructions.ts +305 -0
  382. package/src/dashboard/skill-detection-runtime.ts +24 -4
  383. package/src/dashboard/slash-runtime/dashboard-handlers.ts +100 -28
  384. package/src/dashboard/slash-runtime/model-choices.ts +35 -0
  385. package/src/dashboard/term-slash-runtime.ts +15 -0
  386. package/src/dashboard/turn-preamble.ts +30 -2
  387. package/src/dashboard/turn-session-layers.ts +176 -0
  388. package/src/dashboard/turn-stream-formatter.ts +14 -6
  389. package/src/dashboard/turn-stream-presentation-applier.ts +8 -0
  390. package/src/domains/morning-report.ts +3 -1
  391. package/src/domains/release-tool.ts +8 -9
  392. package/src/domains/surface-events.ts +4 -1
  393. package/src/domains/watch-default-scheduler.ts +8 -9
  394. package/src/fold-stack.ts +24 -1
  395. package/src/git-fs/dirty.ts +32 -4
  396. package/src/git-fs/index.ts +43 -1
  397. package/src/github/pr-labels.ts +10 -4
  398. package/src/graph-runner/runner.ts +102 -14
  399. package/src/harness/harness-clean.ts +21 -3
  400. package/src/harness/harness-cli-command.ts +22 -6
  401. package/src/harness/harness-gc.ts +32 -5
  402. package/src/harness/harness-pod-dispatch.ts +11 -4
  403. package/src/hq/seats.ts +17 -3
  404. package/src/index.ts +48 -6
  405. package/src/input/external-input-queue.ts +219 -0
  406. package/src/intelligence-map/model-bench-scores.ts +102 -0
  407. package/src/interactive-terminal-modal.ts +13 -0
  408. package/src/llm/route-decision.ts +25 -0
  409. package/src/llm-stream-retry-display.ts +59 -0
  410. package/src/llm.ts +253 -55
  411. package/src/log-entry.ts +3 -3
  412. package/src/log-pane/search.ts +29 -4
  413. package/src/loops/agent-reply.ts +256 -0
  414. package/src/loops/budget.ts +37 -7
  415. package/src/loops/loop-cli.ts +3 -2
  416. package/src/loops/msg-address.ts +57 -0
  417. package/src/loops/msg-wake.ts +282 -0
  418. package/src/loops/orchestrator/inbox.ts +130 -0
  419. package/src/loops/orchestrator/resync-shadow.ts +100 -12
  420. package/src/loops/orchestrator/tick.ts +94 -3
  421. package/src/loops/registry.ts +42 -4
  422. package/src/maturity/feature-maturity.ts +1 -1
  423. package/src/memory.ts +20 -5
  424. package/src/msg/msg-sse-server.ts +141 -0
  425. package/src/msg/msg-store.ts +84 -14
  426. package/src/native-tool-catalog.ts +125 -0
  427. package/src/nexus/api/http-server.ts +5 -0
  428. package/src/nexus/api/ops-api.ts +2 -0
  429. package/src/nexus/api/project-autopsy.ts +127 -0
  430. package/src/nexus/api/terminals.ts +3 -0
  431. package/src/nexus/api/workflow-approvals.ts +2 -0
  432. package/src/nexus/onboarding/first-boot-wizard.ts +56 -2
  433. package/src/oauth/codex-account-store.ts +15 -3
  434. package/src/oauth/codex-billing-route.ts +31 -0
  435. package/src/ops/overview-collect.ts +19 -2
  436. package/src/panes/log-pane.ts +67 -8
  437. package/src/patents/ledger.ts +128 -0
  438. package/src/persona/presets.ts +44 -0
  439. package/src/plugins/install/market-fetch.ts +32 -1
  440. package/src/plugins/maker/wizard-generate.ts +6 -4
  441. package/src/pod-lease/admission.ts +116 -41
  442. package/src/preview/terminal.ts +14 -1
  443. package/src/prompt-cache/types.ts +2 -0
  444. package/src/prompt-enhance/enhance.ts +24 -8
  445. package/src/prompt-library/universal-preamble.ts +273 -56
  446. package/src/pty-shell/pty-control-ipc.ts +4 -1
  447. package/src/pty-shell/pty-manifest.ts +77 -5
  448. package/src/pty-shell/registry.ts +19 -2
  449. package/src/pty-shell/tui-run-state.ts +253 -0
  450. package/src/release-loop/checklist.ts +11 -0
  451. package/src/release-loop/light-rc.ts +28 -3
  452. package/src/release-loop/merged-pr-checklist.ts +24 -5
  453. package/src/release-loop/rehearsal.ts +1 -1
  454. package/src/release-loop/rubric.ts +70 -0
  455. package/src/render.ts +5 -1
  456. package/src/rfc-registry/registry.ts +88 -0
  457. package/src/seat-dispatch/seat-request-ledger.ts +4 -0
  458. package/src/seat-loop/knowhow-lint.ts +233 -0
  459. package/src/seat-loop/seat-pack.ts +16 -4
  460. package/src/seat-loop/seat-report.ts +42 -2
  461. package/src/seat-loop/traffic-signal.ts +7 -0
  462. package/src/self-dev/ask-launch-flow.ts +48 -8
  463. package/src/self-dev/ask-path-candidates.ts +69 -14
  464. package/src/self-dev/decompose-proposal.ts +43 -1
  465. package/src/self-dev/graph-journey-nodes.ts +2 -0
  466. package/src/self-dev/launch-preflight-text.ts +5 -1
  467. package/src/self-dev/launch-preflight.ts +143 -10
  468. package/src/self-dev/run-supervisor.ts +71 -5
  469. package/src/self-dev/shard-aggregate.ts +2 -0
  470. package/src/self-dev/shard-run.ts +23 -2
  471. package/src/self-health/signatures.ts +132 -0
  472. package/src/self-implement/doctor-visit.ts +118 -0
  473. package/src/self-implement/gate-cli.ts +17 -4
  474. package/src/self-implement/goal-author-decompose.ts +80 -16
  475. package/src/self-implement/goal-author.ts +116 -73
  476. package/src/self-implement/goal-authoring-grounding.ts +1 -1
  477. package/src/self-implement/goal-file-name.ts +65 -0
  478. package/src/self-implement/goal-new-paths.ts +4 -5
  479. package/src/self-implement/graph-authority.ts +17 -3
  480. package/src/self-implement/graph-yaml.ts +15 -7
  481. package/src/self-implement/ground-goal.ts +2 -1
  482. package/src/self-implement/headless-elanous-driver.ts +16 -1
  483. package/src/self-implement/host-regate.ts +58 -9
  484. package/src/self-implement/orchestrator.ts +3 -10
  485. package/src/self-implement/review-mustfix-class.ts +115 -0
  486. package/src/self-implement/rework-policy.ts +80 -2
  487. package/src/self-implement/run-ledger.ts +111 -7
  488. package/src/self-implement/running-runs.ts +10 -6
  489. package/src/self-implement/self-implement-runtime.ts +32 -0
  490. package/src/self-implement/speed-claims.ts +145 -6
  491. package/src/session/pending-input.ts +62 -11
  492. package/src/session-runtime/index.ts +7 -1
  493. package/src/skills/tools/ops-ledger.ts +707 -0
  494. package/src/skills/tools/persistent-grounding.ts +103 -8
  495. package/src/skills/tools/shell.ts +196 -2
  496. package/src/status/bar.ts +32 -2
  497. package/src/status/status-provider-info.ts +58 -0
  498. package/src/steward/rejudge-tick.ts +12 -1
  499. package/src/steward/release-day.ts +158 -0
  500. package/src/steward/resync-tick.ts +123 -0
  501. package/src/task-agent/actions.ts +1 -0
  502. package/src/task-agent/adopt-pr.ts +140 -0
  503. package/src/task-agent/board.ts +11 -1
  504. package/src/task-agent/card-evidence.ts +37 -5
  505. package/src/task-agent/cover.ts +84 -17
  506. package/src/task-agent/failure-notify.ts +61 -0
  507. package/src/task-agent/green-sweep.ts +170 -0
  508. package/src/task-agent/land-worktree.ts +52 -5
  509. package/src/task-agent/live-move-history.ts +1 -0
  510. package/src/task-agent/live-moves.ts +43 -12
  511. package/src/task-agent/parent-host.ts +1 -1
  512. package/src/task-agent/postland-card.ts +139 -0
  513. package/src/task-agent/rejudge-on-head.ts +109 -7
  514. package/src/task-agent/remote-rejudge-bind.ts +91 -0
  515. package/src/task-agent/repair-branch-cas.ts +182 -0
  516. package/src/task-agent/repair-cycle.ts +288 -0
  517. package/src/task-agent/repair-next-move.ts +31 -0
  518. package/src/task-agent/repair-review.ts +24 -0
  519. package/src/task-agent/repair-worker.ts +87 -0
  520. package/src/task-agent/review-result-capture.ts +2 -1
  521. package/src/task-agent/shadow.ts +13 -7
  522. package/src/task-agent/task-hand.ts +115 -6
  523. package/src/task-orchestrator/surfaces/kubectl-transient-retry.ts +51 -0
  524. package/src/task-orchestrator/surfaces/pod-command-job.ts +63 -7
  525. package/src/task-orchestrator/surfaces/pod-install-slots.ts +6 -11
  526. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +76 -0
  527. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +96 -0
  528. package/src/task-orchestrator/surfaces/self-implement-pod.ts +175 -43
  529. package/src/telegram.ts +30 -1
  530. package/src/terminal/session-registry.ts +6 -0
  531. package/src/thinking-line.ts +12 -3
  532. package/src/tool-runtime/index.ts +4 -0
  533. package/src/tool-runtime/ops-ledger-runtimes.ts +84 -0
  534. package/src/tool-runtime/ref-consult-runtime.ts +17 -2
  535. package/src/tool-runtime/run-shell-runtime.ts +4 -1
  536. package/src/tool-runtime/self-cognition-runtimes.ts +5 -1
  537. package/src/tui.ts +5 -0
  538. package/src/user-config.ts +62 -7
  539. package/src/ux-sim/fake-llm.ts +29 -0
  540. package/src/ux-sim/fault-sqlite-busy.ts +50 -0
  541. package/src/ux-sim/in-process-cli.ts +175 -0
  542. package/src/version/packed-revision.json +1 -1
  543. package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +0 -36
  548. package/apps/pwa/out/_next/static/chunks/1146.80d15ea7c6e6ee95.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/1157.f08bf2b70915e176.js +0 -148
  550. package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/1454-a9c338f5bb556f42.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +0 -27
  557. package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/2528.3868070ef1be69f9.js +0 -24
  562. package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/2697.76ca2ac3efef6f3b.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +0 -32
  565. package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/3143.257997a5f1ed79df.js +0 -34
  567. package/apps/pwa/out/_next/static/chunks/3259-86f3be56e43eaf6a.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/3309.364573ceedbdfd5f.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +0 -287
  572. package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/4084.15ecaf4240bd9e77.js +0 -286
  577. package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +0 -8
  582. package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +0 -104
  584. package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +0 -149
  586. package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/599-a914cc0468f56143.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +0 -23
  596. package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +0 -77
  600. package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +0 -64
  602. package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +0 -2
  604. package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +0 -62
  612. package/apps/pwa/out/_next/static/chunks/7752.5cbdd0b433c54af9.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/8085-1e5fce59500a2cc2.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +0 -226
  621. package/apps/pwa/out/_next/static/chunks/83a80514-b897b64df43ce108.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +0 -93
  623. package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +0 -24
  624. package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +0 -115
  627. package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +0 -41
  629. package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +0 -74
  630. package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +0 -94
  631. package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/949.1e7d45ccb71580aa.js +0 -90
  635. package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/9938.b23e4d4dfa0114cd.js +0 -79
  639. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/approvals/page-a1ce306364f08da9.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-07110da72c45e68f.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/board/page-d2d76d4a7eae91bd.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/botlab/page-30007380f2e2a3c1.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/bots/page-e5a9302c105725a3.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/ceo/page-b93c04b5311c97ec.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/chat/page-718a49e86bf25f9c.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/consult/page-20662900d6b4b455.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/control/page-f707a509515ac50c.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/decisions/page-6a16a48d1aa6e91f.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/design-check/page-fcb06e305f515527.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/editor/page-6acf5ec4e6c6d1af.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/exec/page-39f82acf619cca23.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/field/page-7c2c8f81b185f9c0.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/inside/page-ae7aff07e32676bb.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/intake/page-482c60c1bc540d0a.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/layout-7cb996c1aa08b6f5.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/live/page-623e08fe4477d606.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/live-run/page-db460cd8aecb8490.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/market/page-8397a5c6ca569bf4.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1917ea87ea71ab6b.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/not-found-670510eda8b9443f.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d73c3f1e00d93986.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-65caacf54389081e.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4bb7556e2e97a750.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-77e04b4f8762c666.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/outputs/page-15c0a4095baddfba.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/page-4eb96fc7241c2456.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/reflection/page-63e272a4cd3b6634.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-0d64ff212dc55d03.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/sessions/page-7f096248993fc2d4.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e47fc72049149a38.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/settings/page-f7d808e31e005895.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-5c2b24b5496dad73.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/setup/page-76cdb531668b5191.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/share/page-e2b63345bba1a11f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/showroom/page-d376e0c83edc041a.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d6db55fe2c04d128.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/today/page-dab163b338e3b966.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/trace/page-08019efef111ed2e.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/vault/page-0260ffc7eda50db1.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-980ce6fe36ad95eb.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/workflows/page-99c4e6c7345a9156.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/workspace/page-0ab42e0f05823013.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ad9220422d20ba33.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/e117f801.e92bf10242653497.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/e87d89b9.2e71c0ae475d28a1.js +0 -122
  690. package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +0 -1
  696. package/src/dashboard/bench-slash-runtime.ts +0 -40
  697. package/src/dashboard/input/search-modal-router.ts +0 -9
  698. package/src/dashboard/modals/pane-key-router.ts +0 -27
  699. package/src/dashboard/view-slash-runtime.ts +0 -48
  700. /package/apps/pwa/out/_next/static/{Ev2jivDMTSoEc-5rIXdcy → cIpv5nU9AycwYWZI9H589}/_ssgManifest.js +0 -0
@@ -15,8 +15,8 @@ import { extname, join, relative, resolve } from 'node:path';
15
15
  import { debug } from '../debug/log.js';
16
16
  import { readTaskAgentState, readTaskCard, taskAgentStatePath, TASK_CARD_PREFIX, type CompletionKind, type TaskCard } from './task-hand.js';
17
17
  import type { SupervisorJobResult, SupervisorStopReason } from '../self-dev/run-supervisor.js';
18
- import { executeNextAction, type DeliveryKind, type NextAction } from './actions.js';
19
- import { judgeNextMove, type TaskJudgeInput, type TaskJudgement } from './judge.js';
18
+ import { executeNextAction, type ActionDeps, type DeliveryKind, type NextAction } from './actions.js';
19
+ import { judgeNextMove, LIVE_RETRY_MOVES, type TaskJudgeInput, type TaskJudgement } from './judge.js';
20
20
  import { HARNESS_RUN_ID_ENV } from '../harness/harness-space.js';
21
21
  import { appendRunLedgerEntry, loadRunLedger } from '../self-implement/run-ledger.js';
22
22
  import { collectWiringEvidence, readCardRunSnapshot, type WiringEvidenceDeps, type CardRunEvidenceDeps } from './card-evidence.js';
@@ -57,8 +57,10 @@ export interface TaskAgentShadowMove {
57
57
 
58
58
  export interface TaskAgentShadowDeps {
59
59
  log?: (category: string, event: string, data: Record<string, unknown>) => void;
60
- /** 시험용 — shadow 실행부가 명령을 부르면 여기로 온다(정상이면 0회). */
61
- command?: (args: string[]) => Promise<{ status: number; stdout: string; stderr?: string }>;
60
+ /** 재발사 live 실행부 명령(주입되지 않으면 shadow). */
61
+ command?: ActionDeps['command'];
62
+ /** 재발사 live 부하 관문(주입되지 않으면 shadow). */
63
+ loadGate?: ActionDeps['loadGate'];
62
64
  readCard?: (taskId: string) => TaskCard | undefined;
63
65
  /** Explicit live invocation only; supervisor's default hook always uses shadow. */
64
66
  mode?: 'shadow' | 'live';
@@ -265,6 +267,9 @@ export async function recordTaskAgentShadowMove(input: TaskAgentShadowInput, dep
265
267
  : { move: 'wait', stage: 'waiting', reason: '전달 후보 없음' }
266
268
  : judgeNextMove(judgeInput);
267
269
  if (cardLookupFailed) judgement.reason = `${judgement.reason} · 종결 종류 미확인(카드 조회 실패)`;
270
+ // 판단마다 해석한다 — 허용되지 않은 수를 판단할 때도 모르는 항목 경고가 남게.
271
+ const liveMoves = deps.liveMoves ?? await configuredTaskAgentLiveMoves();
272
+ const retryLaunches = { count: 0 };
268
273
  let executorResult: string | null = null;
269
274
  let wouldDo: string | null = null;
270
275
  if (judgement.executorKind) {
@@ -279,10 +284,13 @@ export async function recordTaskAgentShadowMove(input: TaskAgentShadowInput, dep
279
284
  checklistId: delivery ? card?.checklistId ?? '' : '',
280
285
  ...(delivery ? { delivery } : {}),
281
286
  };
287
+ const liveRetry = !delivery && deps.command !== undefined && deps.loadGate !== undefined
288
+ && (LIVE_RETRY_MOVES as readonly string[]).includes(judgement.move) && liveMoves.has(judgement.move as TaskAgentLiveMove);
282
289
  executorResult = await executeNextAction(action, {
283
- mode: delivery ? (deps.mode ?? 'shadow') : 'shadow',
290
+ mode: delivery ? (deps.mode ?? 'shadow') : liveRetry ? 'live' : 'shadow',
284
291
  command: deps.command ?? (async () => { throw new Error('task-agent shadow path must not run commands'); }),
285
292
  observe: (_event, data) => { wouldDo = data.reason; },
293
+ ...(liveRetry ? { liveMoves, retryLaunches, loadGate: deps.loadGate } : {}),
286
294
  });
287
295
  }
288
296
  const move: TaskAgentShadowMove = {
@@ -305,8 +313,6 @@ export async function recordTaskAgentShadowMove(input: TaskAgentShadowInput, dep
305
313
  move.wouldDo = null;
306
314
  }
307
315
  const liveKind: TaskAgentLiveMove | null = move.move === 'review' || move.move === 'propose-green' || move.move === 'propose-land' || move.move === 'decision-card' ? move.move : null;
308
- // 판단마다 해석한다 — 허용되지 않은 수를 판단할 때도 모르는 항목 경고가 남게.
309
- const liveMoves = deps.liveMoves ?? await configuredTaskAgentLiveMoves();
310
316
  // 카드 id 는 모든 판단 관측에 싣는다(그림자 일치율을 카드로 잇는다) — 읽기 전용 조회.
311
317
  // live 수는 «근거 결과»에 묶는다 — PR 수는 그 PR 을 낸 결과의 카드·작업 트리, 전달은 전달한 카드(다중 결과에서 남의 카드에 쓰지 않게).
312
318
  const prResult = typeof judgeInput.pr === 'number' ? input.results.find((result) => result.prNumber === judgeInput.pr) : undefined;
@@ -11,6 +11,10 @@ import { execFileSync } from 'node:child_process';
11
11
  import { createHash, randomBytes } from 'node:crypto';
12
12
  import { mkdirSync, readFileSync, statSync, writeFileSync, type Stats } from 'node:fs';
13
13
  import { dirname, join, resolve } from 'node:path';
14
+ import { fileURLToPath } from 'node:url';
15
+ import { parse as parseYaml } from 'yaml';
16
+ import { validateUnitCalls } from '../graph-runner/runner.js';
17
+ import { parseGraphTemplateYaml } from '../self-implement/graph-yaml.js';
14
18
  import { resolveDaemonHarnessTarget } from '../intake-plane/harness-target.js';
15
19
  import { HARNESS_RUN_ID_ENV, mintRunId, normalizeRunId } from '../harness/harness-space.js';
16
20
  import { debug } from '../debug/log.js';
@@ -89,6 +93,66 @@ export function taskCardLabelContext(card: Pick<TaskCard, 'id'>): TaskCardLabelC
89
93
  export const COMPLETION_KINDS = ['code-pr', 'artifact', 'research-report', 'ops-action', 'content', 'watch-brief', 'decision-support', 'deliverable'] as const;
90
94
  export type CompletionKind = typeof COMPLETION_KINDS[number];
91
95
 
96
+ export interface TaskComposition {
97
+ file: string;
98
+ /** null = 파일은 있으나 파싱 실패로 판을 확인하지 못했다. */
99
+ version: number | null;
100
+ }
101
+
102
+ export interface CompositionSelection {
103
+ composition?: TaskComposition;
104
+ unitsResolved: boolean;
105
+ missingUnits: string[];
106
+ launcher?: 'harness-say' | 'graph-run';
107
+ error?: string;
108
+ }
109
+
110
+ /** 1판은 조합을 고르고 단위 해석 결과를 기록한다. 단위 실행은 2판의 몫이다. */
111
+ export function selectTaskComposition(completion: CompletionKind, root = join(dirname(fileURLToPath(import.meta.url)), '..', '..')): CompositionSelection {
112
+ const file = `graphs/work/${completion}.yaml`;
113
+ const path = join(root, file);
114
+ let source: string;
115
+ try { source = readFileSync(path, 'utf8'); } catch (error) {
116
+ if ((error as NodeJS.ErrnoException)?.code === 'ENOENT') return { unitsResolved: false, missingUnits: [] };
117
+ return { composition: { file, version: null }, unitsResolved: false, missingUnits: [],
118
+ error: `조합 읽기 오류: ${file}: ${error instanceof Error ? error.message : String(error)}` };
119
+ }
120
+ const parsed = parseGraphTemplateYaml(source, path);
121
+ if (!parsed.template || parsed.errors.length) {
122
+ let version: number | null = null;
123
+ try {
124
+ const raw: unknown = parseYaml(source);
125
+ if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
126
+ const candidate = (raw as Record<string, unknown>).version;
127
+ if (typeof candidate === 'number' && Number.isInteger(candidate)) version = candidate;
128
+ }
129
+ } catch { /* 파싱 실패 자체를 아래 원장에 적는다. */ }
130
+ return { composition: { file, version }, unitsResolved: false, missingUnits: [],
131
+ error: `조합 오류: ${file}: ${parsed.errors.map(e => e.message).join('; ')}` };
132
+ }
133
+ const raw: unknown = parseYaml(source);
134
+ const launcher = raw && typeof raw === 'object' && !Array.isArray(raw) ? (raw as Record<string, unknown>).launcher : undefined;
135
+ if (launcher !== undefined && launcher !== 'harness-say' && launcher !== 'graph-run') {
136
+ return { composition: { file, version: parsed.template.version }, unitsResolved: false, missingUnits: [],
137
+ error: `조합 오류: ${file}: 모르는 launcher` };
138
+ }
139
+ if (completion === 'code-pr' && launcher === undefined) {
140
+ return { composition: { file, version: parsed.template.version }, unitsResolved: false, missingUnits: [],
141
+ error: `조합 오류: ${file}: launcher 없음` };
142
+ }
143
+ const missingUnits: string[] = [];
144
+ let unitError: string | undefined;
145
+ try { validateUnitCalls(parsed.template, path, [], call => missingUnits.push(call)); }
146
+ catch (error) { unitError = error instanceof Error ? error.message : String(error); }
147
+ return {
148
+ composition: { file, version: parsed.template.version },
149
+ unitsResolved: missingUnits.length === 0 && !unitError,
150
+ missingUnits,
151
+ ...(launcher === 'harness-say' || launcher === 'graph-run' ? { launcher } : {}),
152
+ ...(unitError ? { error: `조합 단위 해석 오류: ${file}: ${unitError}` } : {}),
153
+ };
154
+ }
155
+
92
156
  /**
93
157
  * `run-bound`·`goal-bound`·`pr-bound` 은 runId(⊕ pr)를 싣는다 — 옛 카드의 칸은 at·event·detail 뿐이다.
94
158
  * TA-LIVE-MOVE-CARD-HISTORY — `live-move` 줄만 kind·executed·ok·executorResult·head·effect 를 더 싣는다(`live-move-history.ts`).
@@ -104,6 +168,8 @@ export interface TaskCardEvent {
104
168
  resultPath?: string;
105
169
  /** TA-REVIEW-RESULT-CAPTURE — `live-move-result` 줄만: 회수한 `self review --json` 의 칸(못 읽은 칸은 null). */
106
170
  verdict?: string | null; reviewed?: boolean | null; mustFix?: number | null; reviewRoute?: string | null;
171
+ /** Exact bytes of the captured review stdout; repair must read the same resultPath and digest. */
172
+ reviewSha256?: string;
107
173
  }
108
174
  /** 카드 history 의 live-move 줄 이벤트 이름 — 상태 사유(«마지막 칸») 판정에서 뺀다. */
109
175
  export const LIVE_MOVE_HISTORY_EVENT = 'live-move';
@@ -117,8 +183,15 @@ export interface TaskCard {
117
183
  text: string;
118
184
  seat?: TaskSeat;
119
185
  checklistId?: string;
186
+ /** Explicit release version for an adopted PR; post-land still confirms the cell exists there. */
187
+ checklistVersion?: string;
120
188
  /** 종결 종류 — 비면 code-pr. */
121
189
  completion?: CompletionKind;
190
+ /** 선택된 일 조합 파일과 판(1판: 실행은 launcher 에 위임). */
191
+ composition?: TaskComposition;
192
+ graphSelectedBy?: 'completion';
193
+ unitsResolved?: boolean;
194
+ missingUnits?: string[];
122
195
  /** 과제 대상 프로젝트(§A4b②) — target 은 절대 경로(git 이 아닐 수 있다). id 는 `task hand --project` 가 싣는다(옛 카드엔 없을 수 있다). */
123
196
  project?: { id?: string; target: string };
124
197
  /** 보드(§A4b① `board.ts`) 소속 — 목표 id · 이정표 id(`task hand --goal/--milestone`). 조각 카드의 `goalId`(골 sha 16자)와 다른 칸이다. */
@@ -130,7 +203,7 @@ export interface TaskCard {
130
203
  * failed = 발사된 런이 PR·수확 가지 없이 죽었거나 끝내 안 떴다(TA-JUDGE-DEAD-RUN · `card-evidence.ts`) — 사유
131
204
  * (`failed/needs-owner|needs-relaunch — …`)는 history 마지막 칸 · 자동 재발사하지 않는다(사람/판단부 몫).
132
205
  */
133
- status: 'handed' | 'launched' | 'launch-failed' | 'failed';
206
+ status: 'handed' | 'launched' | 'launch-failed' | 'failed' | 'done';
134
207
  history: TaskCardEvent[];
135
208
  /** 미션 카드만 — 조각 카드 id(순서대로) · 쪼갠 출처(`mission.ts` splitMission). */
136
209
  pieces?: string[];
@@ -145,6 +218,12 @@ export interface TaskCard {
145
218
  * 번호는 `cardPrNumber` 로 읽는다(옛 카드의 number 도 그대로 읽힌다).
146
219
  */
147
220
  pr?: number | TaskCardPr;
221
+ /** Host-verified existing OPEN PR adopted without launching a new implementation run. */
222
+ adoptedPr?: { pr: number; url: string; head: string; at: string };
223
+ /** Bound PR observed in a terminal GitHub state. Only applies while the card still binds the same PR and URL. */
224
+ prTerminal?: { pr: number; url: string; head: string; state: 'MERGED' | 'CLOSED'; at: string };
225
+ /** Post-land checklist judgement. A partial slice closes this card while leaving the checklist cell yellow. */
226
+ postLand?: { pr: number; head: string; at: string; outcome: 'complete' | 'partial'; evidence: string[]; remaining: string[] };
148
227
  goalId?: string;
149
228
  /** `manual` = pr/goalId 를 사람이 적었다(`recordPieceRef`) — 런 묶기가 건드리지 않는다. */
150
229
  refSource?: 'manual';
@@ -185,6 +264,10 @@ export interface TaskCard {
185
264
  taLand?: true;
186
265
  /** TASKS-HAND-CHILD-LLM — `tasks hand --child-llm <provider>/<model> [--child-llm-effort <level>]` → 발사 인자 `--child-llm-provider/-model/-effort`. */
187
266
  childLlm?: TaskChildLlm;
267
+ /** Same-PR repair launches; exact source head and worker result are retained for CAS and retry limits. */
268
+ repairs?: Array<{ pr: number; head: string; branch: string; at: string; move: string; runId: string;
269
+ resultPath: string; fromModel: string; toModel: string; status: 'requested' | 'unconfirmed' | 'failed' | 'applied';
270
+ detail?: string; commit?: string; bundleSha256?: string; bundlePath?: string }>;
188
271
  }
189
272
 
190
273
  /** 구현 자식 LLM 선택 — 하니스 `--child-llm-provider/--child-llm-model/--child-llm-effort` 로 그대로 넘긴다(검증 권위는 하니스). */
@@ -215,6 +298,12 @@ export function cardPrNumber(card: Pick<TaskCard, 'pr'>): number | undefined {
215
298
  return typeof card.pr === 'number' ? card.pr : card.pr?.number;
216
299
  }
217
300
 
301
+ /** A stale terminal marker must never close a card after its PR binding changes. */
302
+ export function boundPrTerminal(card: Pick<TaskCard, 'pr' | 'prTerminal'>): TaskCard['prTerminal'] | undefined {
303
+ const marker = card.prTerminal;
304
+ return marker && typeof card.pr === 'object' && card.pr.number === marker.pr && card.pr.url === marker.url ? marker : undefined;
305
+ }
306
+
218
307
  /** A uniquely launched code-PR card may own a draft through its PR or its opening run. */
219
308
  export function draftTaskOwner(cards: readonly TaskCard[], draft: { number: number; runId?: string | null }): TaskCard | undefined {
220
309
  const owners = cards.filter((card) => card.status === 'launched' && (card.completion ?? 'code-pr') === 'code-pr'
@@ -374,6 +463,8 @@ export interface HandTaskOptions {
374
463
  childLlm?: string;
375
464
  childLlmEffort?: string;
376
465
  statePath?: string;
466
+ /** 시험에서만 조합 저장소를 바꿔 해석·거부를 검증한다. */
467
+ compositionRoot?: string;
377
468
  /** `--live` 일 때만 불린다. */
378
469
  launcher?: TaskLauncher;
379
470
  now?: () => Date;
@@ -443,6 +534,11 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
443
534
  }
444
535
  if (opts.childLlmEffort !== undefined && opts.childLlm === undefined) throw new Error('--child-llm-effort 는 --child-llm <provider>/<model> 과 함께 준다');
445
536
  const childLlm = opts.childLlm !== undefined ? parseChildLlm(opts.childLlm, opts.childLlmEffort) : undefined;
537
+ const completion = opts.completion ?? 'code-pr';
538
+ const selected = selectTaskComposition(completion, opts.compositionRoot);
539
+ const selectionFailure = !selected.composition ? `조합 없음: graphs/work/${completion}.yaml`
540
+ : selected.error ?? (completion !== 'code-pr' || selected.launcher !== 'harness-say'
541
+ ? `조합 실행기 없음: ${selected.composition.file} (1판은 code-pr harness-say만 발사)` : undefined);
446
542
  let project: TaskCard['project'];
447
543
  let targetIsGit: boolean | null = null;
448
544
  if (opts.project) {
@@ -467,19 +563,25 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
467
563
  ...(opts.seat ? { seat: opts.seat } : {}),
468
564
  ...(opts.checklistId ? { checklistId: opts.checklistId } : {}),
469
565
  ...(opts.completion ? { completion: opts.completion } : {}),
566
+ ...(selected.composition ? { composition: selected.composition, graphSelectedBy: 'completion' as const } : {}),
567
+ unitsResolved: selected.unitsResolved,
568
+ missingUnits: selected.missingUnits,
470
569
  ...(project ? { project } : {}),
471
570
  ...(opts.goal ? { goal: opts.goal } : {}),
472
571
  ...(opts.milestone ? { milestone: opts.milestone } : {}),
473
572
  ...(opts.taLand === true ? { taLand: true as const } : {}),
474
573
  ...(childLlm ? { childLlm } : {}),
475
574
  createdAt: now.toISOString(),
476
- status: 'handed',
477
- history: [],
575
+ status: selectionFailure ? 'failed' : 'handed',
576
+ history: selectionFailure ? [{ at: now.toISOString(), event: !selected.composition ? 'composition-missing'
577
+ : selected.error ? 'composition-invalid' : 'composition-launcher-unavailable', detail: selectionFailure }] : [],
478
578
  ...(opts.mission ? { mission: opts.mission, after: [...(opts.after ?? [])] } : {}),
479
- ...(opts.cardFields ?? {}),
579
+ ...(opts.cardFields?.pr !== undefined ? { pr: opts.cardFields.pr } : {}),
580
+ ...(opts.cardFields?.goalId !== undefined ? { goalId: opts.cardFields.goalId } : {}),
581
+ ...(opts.cardFields?.handed !== undefined ? { handed: opts.cardFields.handed } : {}),
480
582
  };
481
- const move = nextMoveFor(card, opts.landed);
482
- if (move.kind !== 'launch') throw new Error(`발사할 수 없는 과제다 — ${move.reason}`);
583
+ const move = selectionFailure ? undefined : nextMoveFor(card, opts.landed);
584
+ if (move && move.kind !== 'launch') throw new Error(`발사할 수 없는 과제다 — ${move.reason}`);
483
585
  const guard = opts.writeGuard;
484
586
  const writeCard = (target: string, next: TaskCard): void => {
485
587
  if (!guard) { writeTaskCards(target, [next]); return; }
@@ -495,6 +597,13 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
495
597
  if (!owned.ok) throw new TaskCardSupersededError(next.id);
496
598
  };
497
599
  writeCard(path, card);
600
+ try { debug.log('task-agent.graph-select', !selected.composition ? 'composition-missing' : selected.error ? 'composition-invalid' : 'composition-selected', {
601
+ completion, file: selected.composition?.file ?? `graphs/work/${completion}.yaml`,
602
+ unitsResolved: selected.unitsResolved, missingUnits: selected.missingUnits,
603
+ ...(selected.error ? { error: selected.error } : {}),
604
+ }); } catch { /* fail-soft */ }
605
+ if (selectionFailure) throw new Error(`${selectionFailure} (카드 ${id})`);
606
+ if (!move || move.kind !== 'launch') throw new Error('조합 선택 뒤 발사 수가 없다');
498
607
  try { debug.log('task-agent', 'handed', { taskId: id, seat: card.seat ?? null, checklistId: card.checklistId ?? null, mode, projectId: project?.id ?? null, targetIsGit, taLand: card.taLand === true }); } catch { /* fail-soft */ }
499
608
  if (childLlm) {
500
609
  try { debug.log('task-agent', 'child-llm', { taskId: id, input: opts.childLlm, provider: childLlm.provider, model: childLlm.model, effort: childLlm.effort ?? null, mode }); } catch { /* fail-soft */ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * K3S-SECRET-DB-LOCK-RETRY — kubectl 호출이 «일시 오류»로 거부되면 지수 백오프로 다시 친다.
3
+ *
4
+ * 근거: node-b k3d(k3s · sqlite 저장소)가 Pod Secret 생성 때
5
+ * `Error from server: error when creating "STDIN": rpc error: code = Unknown desc = database is locked`
6
+ * 로 거부했다(10-15 02:11 KST 전후 4건 · TC #4186). sqlite 쓰기 잠금 경합이라 잠시 뒤 같은 apply 는 선다.
7
+ *
8
+ * ⛔ 판정 문구는 «실측 근거가 있는 것»만 둔다 — 짐작으로 늘리면 진짜 거부(권한·스키마)를 백오프 동안 삼킨다.
9
+ * 재시도 소진 시에만 호출부의 기존 실패 경로로 마지막 결과를 그대로 돌려준다.
10
+ */
11
+ import { debug } from '../../debug/log.js';
12
+
13
+ export type KubectlCallResult = { status: number | null; stdout: string; stderr: string };
14
+
15
+ /** 실측된 일시 오류 문구(stderr 만 · 부분 일치 · 대소문자 무시 — stdout 은 apply 결과라 판정에 안 쓴다). */
16
+ export const KUBECTL_TRANSIENT_PATTERNS: readonly RegExp[] = [/database is locked/i];
17
+
18
+ /** 재시도 사이 대기(ms) — 길이가 곧 재시도 상한(4회 · 합 7.5s). */
19
+ export const KUBECTL_TRANSIENT_BACKOFF_MS: readonly number[] = [500, 1_000, 2_000, 4_000];
20
+
21
+ export function kubectlTransientReason(result: KubectlCallResult): string | null {
22
+ if (result.status === 0) return null;
23
+ const hit = KUBECTL_TRANSIENT_PATTERNS.find((pattern) => pattern.test(result.stderr));
24
+ return hit ? hit.source : null;
25
+ }
26
+
27
+ /**
28
+ * 첫 결과 `first` 가 일시 오류일 때만 부른다(성공 경로에 await 를 더하지 않으려고 — 호출부의 마이크로태스크 순서를 지킨다).
29
+ * 다시 친 결과가 성공이거나 일시 오류가 아니면 즉시 돌려주고, 백오프를 다 써도 일시 오류면 마지막 결과를 돌려준다.
30
+ */
31
+ export async function retryKubectlTransient(
32
+ run: () => KubectlCallResult,
33
+ first: KubectlCallResult,
34
+ opts: { sleep: (ms: number) => Promise<void>; category: string; data?: Record<string, unknown>; backoffMs?: readonly number[] },
35
+ ): Promise<KubectlCallResult> {
36
+ const backoff = opts.backoffMs ?? KUBECTL_TRANSIENT_BACKOFF_MS;
37
+ let last = first;
38
+ let reason = kubectlTransientReason(last);
39
+ for (let i = 0; i < backoff.length && reason; i++) {
40
+ debug.log(opts.category, 'retry', { ...opts.data, attempt: i + 1, maxAttempts: backoff.length, delayMs: backoff[i], reason });
41
+ await opts.sleep(backoff[i]!);
42
+ last = run();
43
+ reason = kubectlTransientReason(last);
44
+ if (last.status === 0) {
45
+ debug.log(opts.category, 'retry-recovered', { ...opts.data, attempt: i + 1 });
46
+ return last;
47
+ }
48
+ }
49
+ if (reason) debug.log(opts.category, 'retry-exhausted', { ...opts.data, attempts: backoff.length, reason, stderr: last.stderr.trim().slice(0, 300) }, { level: 'warn' });
50
+ return last;
51
+ }
@@ -16,10 +16,11 @@ import { collectPodArtifacts } from './pod-artifact-return.js';
16
16
  import { getDefaultLogStore, type LogStore } from '../../mss/logging/log-store.js';
17
17
  import { podBunCacheVolume } from './pod-bun-cache.js';
18
18
  import { POD_JOB_TTL_AFTER_FINISHED_SECONDS } from './pod-lease.js';
19
- import { podHostDirsInit, podInstallSlotsVolume } from './pod-install-slots.js';
19
+ import { podHostDirsScript, podInstallSlotsVolume } from './pod-install-slots.js';
20
20
  import { type PodPoolMember, PodPoolScheduler, resolvePodPoolSpec, parsePodPool, checkPodPool, syncPoolImages, type PoolKubectl } from './pod-pool.js';
21
21
  import { podSkillsDigest, readSkillEnvFiles, resolvePodSkills } from './pod-skills.js';
22
22
  import { podSourceScript, type PodSource } from './pod-source-receive.js';
23
+ import { seedMirrorOnce, type MirrorSeedResult } from './pod-mirror-seed.js';
23
24
  import {
24
25
  POD_CHILD_REQUESTS,
25
26
  POD_JOB_DEADLINE_SECONDS,
@@ -132,13 +133,18 @@ export function tailBytes(text: string, maxBytes: number): string {
132
133
  return `…[앞 ${bytes.length - maxBytes}바이트 생략]\n${cut.subarray(start).toString('utf8')}`;
133
134
  }
134
135
 
135
- const GATE = `ok=0
136
+ /** The isolation probe: wait until the NetworkPolicy blocks the host/prod daemons, then run `onPass` (default `exit 0`). */
137
+ function isolationGateScript(onPass = 'exit 0'): string {
138
+ return `ok=0
136
139
  for i in $(seq 1 60); do
137
140
  if curl -s -m 1 -o /dev/null http://host.orb.internal:31415/health || curl -s -m 1 -o /dev/null http://core.elanous-prod:8080/; then ok=0; else ok=$((ok+1)); fi
138
- [ "$ok" -ge 3 ] && { echo "[gate] isolation enforced after \${i} probes"; exit 0; }
141
+ [ "$ok" -ge 3 ] && { echo "[gate] isolation enforced after \${i} probes"; ${onPass}; }
139
142
  sleep 0.5
140
143
  done
141
144
  echo "[gate] ISOLATION NOT ENFORCED within 30s"; exit 1`;
145
+ }
146
+
147
+ const GATE = isolationGateScript();
142
148
 
143
149
  /** Export the command's log store into the existing outbox return channel without changing the command exit status. */
144
150
  const COMMAND_LOG_EXPORT = `if mkdir -p "$HOME/outbox/pod-logs" && elanous --test="$HOME/.elanous-test" logs --instance prod --since 12h --limit 20000 --json --json-data > "$HOME/outbox/pod-logs/logs.jsonl"; then
@@ -244,6 +250,10 @@ export function podCommandJobManifest(o: PodCommandJobInput): Record<string, unk
244
250
  // A command may not end in LF; keep artifact markers on their own line for the existing parser.
245
251
  ...(o.returnLogs ? ["printf '\\n'", COMMAND_LOG_EXPORT] : []),
246
252
  ARTIFACT_EMIT,
253
+ // GATE-POD-RESULT-MARKER: the last line says «the child is done» so the host need not wait for the Job condition
254
+ // (k3d on node-b flips it 90~550s late). Leading LF keeps it on its own line; the host strips exactly this tail.
255
+ // The token is this launch's random id — a command that prints the bare marker word cannot end the wait early.
256
+ `printf '\\n${podResultMarker(o.launch ?? o.name)} rc=%s\\n' "$rc"`,
247
257
  'exit $rc',
248
258
  ].join('\n');
249
259
  const secretKeys = grok || skillNames.length || o.clone === true;
@@ -261,8 +271,12 @@ export function podCommandJobManifest(o: PodCommandJobInput): Record<string, unk
261
271
  restartPolicy: 'Never',
262
272
  securityContext: { runAsUser: 1000, fsGroup: 1000 },
263
273
  initContainers: [
264
- { name: 'isolation-gate', image: o.image, imagePullPolicy: o.imagePullPolicy ?? 'Never', command: ['bash', '-c'], args: [GATE] },
265
- ...(hostDirMounts.length ? [podHostDirsInit(o.image, o.imagePullPolicy ?? 'Never', hostDirMounts)] : []),
274
+ // GATE-WARM-BOOT (10-15): ONE init container. Each extra container cost minutes on a loaded k3d node (the measured
275
+ // gap between a finished init script and the next container start), so the root host-dir hand-over runs inside
276
+ // the isolation init after the probe passes instead of as a second `host-dirs` container.
277
+ hostDirMounts.length
278
+ ? { name: 'isolation-gate', image: o.image, imagePullPolicy: o.imagePullPolicy ?? 'Never', securityContext: { runAsUser: 0 }, command: ['bash', '-c'], args: [isolationGateScript(podHostDirsScript(hostDirMounts))], volumeMounts: hostDirMounts.map((mount) => ({ ...mount })) }
279
+ : { name: 'isolation-gate', image: o.image, imagePullPolicy: o.imagePullPolicy ?? 'Never', command: ['bash', '-c'], args: [GATE] },
266
280
  ],
267
281
  containers: [{
268
282
  name: 'child', image: o.image, imagePullPolicy: o.imagePullPolicy ?? 'Never',
@@ -380,6 +394,10 @@ export interface RunPodCommandOptions {
380
394
  kubectl?: Kubectl;
381
395
  /** A caller-owned scheduler is self-capped: acquires count only its own Jobs, never cluster occupancy (POOLGLOBAL-REG). */
382
396
  poolScheduler?: PodPoolScheduler;
397
+ /** GATE-WARM-BOOT — seeds a commit-pinned clone's commit into the pool host mirror (test seam · default {@link seedMirrorOnce}). */
398
+ seedMirror?: (o: { host: string; commit: string; cwd: string }) => Promise<MirrorSeedResult | undefined>;
399
+ /** GATE-WARM-BOOT — the git tree the seed pushes from (default: the process cwd — the gate runs in the repo tree). */
400
+ mirrorSeedCwd?: string;
383
401
  checkPool?: typeof checkPodPool;
384
402
  syncImages?: typeof syncPoolImages;
385
403
  imageCommit?: string | null;
@@ -396,6 +414,19 @@ export interface RunPodCommandOptions {
396
414
  childLogMaxBytes?: number;
397
415
  }
398
416
 
417
+ /** GATE-POD-RESULT-MARKER — the child script's final line (`\n<marker> <token> rc=<n>\n`), printed after the artifact emit. */
418
+ export const POD_RESULT_MARKER = '__ELANOUS_POD_DONE__';
419
+ /** The marker bound to one launch (`token` = the launch's random id · the Job name when the manifest has no launch). */
420
+ export function podResultMarker(token: string): string { return `${POD_RESULT_MARKER} ${token}`; }
421
+
422
+ /** Split the child's logs into the command output (marker tail removed, bytes otherwise unchanged) and the marker rc (null = no marker for this token). */
423
+ export function splitPodResultMarker(logs: string, token: string): { logs: string; rc: number | null } {
424
+ const escaped = podResultMarker(token).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
425
+ const match = new RegExp(`\\n${escaped} rc=(\\d+)\\n?$`).exec(logs);
426
+ if (!match) return { logs, rc: null };
427
+ return { logs: logs.slice(0, match.index), rc: Number(match[1]) };
428
+ }
429
+
399
430
  function jobFinished(types: string): 'complete' | 'failed' | null {
400
431
  if (/Complete|SuccessCriteriaMet/.test(types)) return 'complete';
401
432
  if (/Failed|FailureTarget/.test(types)) return 'failed';
@@ -522,6 +553,16 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
522
553
  }
523
554
  const imageRef = member?.imageRef;
524
555
  if (!imageRef) log('pod.command-job', 'image-fallback-local', { reason: !member ? 'no-pool-member' : !imageCommit ? 'image-commit-unavailable' : 'registry-tag-unavailable' });
556
+ // GATE-WARM-BOOT (10-15): a commit-pinned clone on a pool host — put that commit into the host's mirror first (once per
557
+ // host·commit in this process), so the Pod's podSourceScript finds it (`cat-file -e`) instead of fetching from GitHub.
558
+ // Best effort: a failed seed only logs; the Pod keeps the old path. Never with an injected kubectl (tests) unless seeded.
559
+ const seedMirror = options.seedMirror ?? (options.kubectl ? undefined : seedMirrorOnce);
560
+ if (seedMirror && options.clone && options.source?.kind === 'commit' && hostMirror && member?.sshHost) {
561
+ // Worst case added to a cold start: the push limit (GATE_MIRROR_SEED_LIMIT_MS), once per host·commit.
562
+ const seed = await seedMirror({ host: member.sshHost, commit: options.source.sha, cwd: options.mirrorSeedCwd ?? process.cwd() })
563
+ .catch((error: unknown) => ({ host: member!.sshHost!, ok: false, ms: 0, detail: String(error).slice(0, 300) }));
564
+ log('pod.command-job', 'mirror-seed', { host: member.sshHost, commit: options.source.sha, ok: seed?.ok ?? false, ms: seed?.ms ?? 0, ...(seed?.detail ? { detail: seed.detail } : {}) });
565
+ }
525
566
  const ghToken = options.clone ? (options.ghToken ?? defaultGhToken)() : undefined;
526
567
  const secret = commandJobSecret({ name, namespace, launch, skills, skillEnvText, ...(grokAuth !== undefined ? { grokAuth } : {}), ...(ghToken !== undefined ? { ghToken } : {}) });
527
568
  if (secret) {
@@ -543,10 +584,24 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
543
584
  }
544
585
  let state: 'complete' | 'failed' = 'failed';
545
586
  let unreadableSince: number | null = null;
587
+ let markerRc: number | null = null;
588
+ const appliedAt = Date.now();
546
589
  for (;;) {
547
590
  const got = kubectl(['-n', namespace, 'get', 'job', name, '-o', 'jsonpath={.status.conditions[*].type}']);
548
591
  const finished = jobFinished(got.stdout);
549
592
  if (finished) { state = finished; break; }
593
+ // GATE-POD-RESULT-MARKER: the condition is not there yet — the child may already be done (k3d condition lag).
594
+ // A tail read that fails (Pod still pending · init container) or lacks the marker changes nothing.
595
+ const tail = kubectl(['-n', namespace, 'logs', `job/${name}`, '-c', 'child', '--tail=2']);
596
+ if (tail.status === 0) {
597
+ const seen = splitPodResultMarker(tail.stdout.startsWith('\n') ? tail.stdout : `\n${tail.stdout}`, launch).rc;
598
+ if (seen !== null) {
599
+ markerRc = seen;
600
+ state = seen === 0 ? 'complete' : 'failed';
601
+ log('pod.command-job', 'result-marker-early', { job: name, waitedMs: Date.now() - appliedAt, rc: seen });
602
+ break;
603
+ }
604
+ }
550
605
  if (got.status !== 0 && options.statusUnreadableMs !== undefined) {
551
606
  unreadableSince ??= Date.now();
552
607
  if (Date.now() - unreadableSince >= options.statusUnreadableMs) {
@@ -558,7 +613,7 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
558
613
  }
559
614
  const logsResult = kubectl(['-n', namespace, 'logs', `job/${name}`, '-c', 'child']);
560
615
  const logsFailed = logsResult.status !== 0;
561
- const logs = logsFailed ? '' : logsResult.stdout;
616
+ const logs = logsFailed ? '' : splitPodResultMarker(logsResult.stdout, launch).logs;
562
617
  const artifactDir = artifactRoot;
563
618
  let artifacts: PodArtifactCollection;
564
619
  if (logsFailed) {
@@ -591,7 +646,8 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
591
646
  const maxBytes = options.childLogMaxBytes ?? podChildLogMaxBytes();
592
647
  const childLog = logsFailed ? `산출 회수 못 함: ${artifacts.error}` : tailBytes(logs, maxBytes);
593
648
  writeFileSync(resolve(artifactsDir, 'child.log'), childLog);
594
- const exitCode = exitCodeFromPod(kubectl, namespace, name, state);
649
+ // Marker path: the rc the child printed (the Pod's terminated state may lag like the condition). Condition path: unchanged.
650
+ const exitCode = markerRc ?? exitCodeFromPod(kubectl, namespace, name, state);
595
651
  cleanupSecret();
596
652
  log('pod.command', 'job-finished', {
597
653
  job: name,
@@ -22,7 +22,7 @@ export const POD_INSTALL_SLOTS_DEFAULT = 4;
22
22
  export const POD_INSTALL_SLOTS_MOUNT = '/gate-install-slots';
23
23
 
24
24
  /** hostPath volume ⊕ mount for the tokens. `DirectoryOrCreate` makes a root-owned 0755 directory, so the Pod also needs
25
- * {@link podHostDirsInit} (the child runs as uid 1000). */
25
+ * {@link podHostDirsScript} (the child runs as uid 1000). */
26
26
  export function podInstallSlotsVolume(hostPath: string = POD_INSTALL_SLOTS_HOST_PATH) {
27
27
  return {
28
28
  volume: { name: 'install-slots', hostPath: { path: hostPath, type: 'DirectoryOrCreate' } },
@@ -31,19 +31,14 @@ export function podInstallSlotsVolume(hostPath: string = POD_INSTALL_SLOTS_HOST_
31
31
  }
32
32
 
33
33
  /**
34
- * A root init container that hands the mounted hostPath directories to the child's uid. Without it a `DirectoryOrCreate`
34
+ * The root shell that hands the mounted hostPath directories to the child's uid. Without it a `DirectoryOrCreate`
35
35
  * hostPath stays root:root 0755 and the child's `[ -w … ]` guard silently skips it (the Bun cache option was a no-op).
36
+ * Never fails the Pod: an unchanged directory only means the child falls back (no cache · no throttle).
37
+ * GATE-WARM-BOOT — it runs inside the Pod's single init container (after the isolation probe), not as a second one.
36
38
  */
37
- export function podHostDirsInit(image: string, imagePullPolicy: string, mounts: ReadonlyArray<{ name: string; mountPath: string; readOnly: boolean }>) {
39
+ export function podHostDirsScript(mounts: ReadonlyArray<{ mountPath: string }>): string {
38
40
  const paths = mounts.map((mount) => `'${mount.mountPath.replace(/'/g, `'\\''`)}'`).join(' ');
39
- return {
40
- name: 'host-dirs', image, imagePullPolicy,
41
- securityContext: { runAsUser: 0 },
42
- command: ['sh', '-c'],
43
- // Never fails the Pod: an unchanged directory only means the child falls back (no cache · no throttle).
44
- args: [`for d in ${paths}; do mkdir -p "$d" && chown 1000:1000 "$d" && chmod 0775 "$d" || echo "[host-dirs] could not prepare $d"; done; exit 0`],
45
- volumeMounts: mounts.map((mount) => ({ ...mount })),
46
- };
41
+ return `for d in ${paths}; do mkdir -p "$d" && chown 1000:1000 "$d" && chmod 0775 "$d" || echo "[host-dirs] could not prepare $d"; done; exit 0`;
47
42
  }
48
43
 
49
44
  const int = (value: number, label: string) => {
@@ -0,0 +1,76 @@
1
+ // GATE-WARM-BOOT (10-15) — put the cut commit into each pool host's git mirror before the shard Pods start.
2
+ //
3
+ // S: 0.2.29 gate Pods spent 750–840 s before the shard shell; the tests took 0–69 s. Every Pod clones from the host
4
+ // mirror (`pod.hostMirror` → `/host-mirror`, podSourceScript), but the cut commit e1783835 was not in the node-b mirror
5
+ // (the mirror's own fetch loop follows `main`; only the `--remote` host executor pushed `refs/elanous/gate/<sha>`).
6
+ // So all 68 Pods fell to `git fetch --depth 1 origin <sha>` from GitHub, under load, one by one.
7
+ // A: push `<sha>:refs/elanous/gate/<sha>` to the placed pool member's mirror once per (host, commit) per process — podSourceScript's commit branch
8
+ // then passes `git cat-file -e` and skips the GitHub fetch. Best effort: a failed push is recorded and the Pod keeps
9
+ // its old path (fetch from GitHub) — never a silent use of another tree.
10
+ import { spawn } from 'node:child_process';
11
+ import { debug } from '../../debug/log.js';
12
+
13
+ /** Host-side mirror path (relative to the ssh user's home) — the k3d node binds `~/mirror` at `/mirror-host`. */
14
+ export const GATE_POOL_MIRROR_PATH = 'mirror/elanous-agent.git';
15
+ export const GATE_MIRROR_SEED_LIMIT_MS = 120_000;
16
+
17
+ export interface MirrorSeedResult { host: string; ok: boolean; ms: number; detail?: string }
18
+
19
+ type Push = (args: string[], cwd: string, limitMs: number) => Promise<{ rc: number; output: string }>;
20
+
21
+ export async function seedPoolMirrors(o: { hosts: readonly (string | undefined)[]; commit: string; tree: string; push: Push; mirrorPath?: string; limitMs?: number }): Promise<MirrorSeedResult[]> {
22
+ if (!/^[0-9a-f]{40}$/.test(o.commit)) throw new Error('invalid gate commit');
23
+ const mirror = o.mirrorPath ?? GATE_POOL_MIRROR_PATH;
24
+ const hosts = [...new Set(o.hosts.filter((host): host is string => !!host && /^[\w.@-]+$/.test(host) && !host.startsWith('-')))];
25
+ const results = await Promise.all(hosts.map(async (host): Promise<MirrorSeedResult> => {
26
+ const start = Date.now();
27
+ try {
28
+ const run = await o.push(['push', '--quiet', '--no-verify', `${host}:${mirror}`, `${o.commit}:refs/elanous/gate/${o.commit}`], o.tree, o.limitMs ?? GATE_MIRROR_SEED_LIMIT_MS);
29
+ const ms = Date.now() - start;
30
+ return run.rc === 0 ? { host, ok: true, ms } : { host, ok: false, ms, detail: run.output.trim().slice(-300) };
31
+ } catch (error) {
32
+ return { host, ok: false, ms: Date.now() - start, detail: String(error).slice(0, 300) };
33
+ }
34
+ }));
35
+ for (const result of results) {
36
+ debug.log('release-loop.gate', result.ok ? 'pod-mirror-seeded' : 'pod-mirror-seed-failed', { ...result, commit: o.commit }, result.ok ? undefined : { level: 'warn' });
37
+ }
38
+ return results;
39
+ }
40
+
41
+ const seeded = new Map<string, Promise<MirrorSeedResult | undefined>>();
42
+
43
+ /** Bounded `git <args>` in `cwd` — killed after `limitMs`; never throws. */
44
+ export function gitWithin(args: string[], cwd: string, limitMs: number): Promise<{ rc: number; output: string }> {
45
+ return new Promise((resolve) => {
46
+ let output = '';
47
+ let child;
48
+ try { child = spawn('git', args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] }); }
49
+ catch (error) { resolve({ rc: 2, output: String(error) }); return; }
50
+ const timer = setTimeout(() => { output += `\n[mirror-seed] timed out after ${limitMs} ms`; child.kill('SIGKILL'); }, limitMs);
51
+ child.stdout?.on('data', (chunk) => { output += String(chunk); });
52
+ child.stderr?.on('data', (chunk) => { output += String(chunk); });
53
+ child.on('error', (error) => { clearTimeout(timer); resolve({ rc: 2, output: `${output}\n${String(error)}` }); });
54
+ child.on('close', (code) => { clearTimeout(timer); resolve({ rc: code ?? 2, output }); });
55
+ });
56
+ }
57
+
58
+ /**
59
+ * Seed once per (host, commit) in this process: every shard Job placed on the same member awaits the same push, so a
60
+ * 28-shard gate pushes once per host. `cwd` must be a git tree that has the commit (the gate runs in the repo tree).
61
+ */
62
+ export function seedMirrorOnce(o: { host: string; commit: string; cwd: string; push?: Push }): Promise<MirrorSeedResult | undefined> {
63
+ const key = `${o.host}\0${o.commit}`;
64
+ let pending = seeded.get(key);
65
+ if (!pending) {
66
+ // A failed seed is not memoized — the next Job on that host tries again (a transient ssh drop must not send the whole gate to GitHub).
67
+ pending = seedPoolMirrors({ hosts: [o.host], commit: o.commit, tree: o.cwd, push: o.push ?? gitWithin })
68
+ .then((results) => { if (!results[0]?.ok) seeded.delete(key); return results[0]; },
69
+ (error: unknown) => { seeded.delete(key); return { host: o.host, ok: false, ms: 0, detail: String(error).slice(0, 300) }; });
70
+ seeded.set(key, pending);
71
+ }
72
+ return pending;
73
+ }
74
+
75
+ /** Test seam — forget the per-process seed memo. */
76
+ export function resetMirrorSeedMemo(): void { seeded.clear(); }