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,7 +15,7 @@
15
15
  * - 관측: 실행한 수마다 `debug.log('task-agent', 'live-move', {kind, card, ok, detail, live:true})`.
16
16
  */
17
17
  import { spawn, spawnSync } from 'node:child_process';
18
- import { createHash } from 'node:crypto';
18
+ import { createHash, randomUUID } from 'node:crypto';
19
19
  import { closeSync, mkdirSync, openSync, readFileSync, statSync } from 'node:fs';
20
20
  import { dirname, isAbsolute, resolve } from 'node:path';
21
21
  import { debug } from '../debug/log.js';
@@ -25,9 +25,9 @@ import type { DetachedSpawn } from '../cli/tasks-cli.js';
25
25
  import { LIVE_MOVE_HISTORY_EVENT, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
26
26
  import { LIVE_RETRY_MOVES } from './judge.js';
27
27
  import { decisionCardGrounds, decisionRaiseArgs, type DecisionCardEvidence, type NextAction } from './actions.js';
28
- import { reviewResultPath, TA_REVIEW_COMPLETION_CARD_ENV, TA_REVIEW_COMPLETION_RESULT_ENV, TA_REVIEW_COMPLETION_STATE_ENV } from './review-result-capture.js';
28
+ import { pendingReviewResults, reviewResultPath, TA_REVIEW_COMPLETION_CARD_ENV, TA_REVIEW_COMPLETION_RESULT_ENV, TA_REVIEW_COMPLETION_STATE_ENV } from './review-result-capture.js';
29
29
  import { buildPriorFixContext, PRIOR_FIX_SCOPE_LINE, priorFixBlock, priorFixObservation, type PriorDiffReader, type PriorFixContext } from './review-prior-fix.js';
30
- import { createLandWorktree, localHead, observeLandWorktree, type LandWorktree, type LandWorktreeFailure, type LandWorktreeInput, type LandWorktreeRemoval } from './land-worktree.js';
30
+ import { createLandWorktree, localBranch, localHead, observeLandWorktree, type LandWorktree, type LandWorktreeFailure, type LandWorktreeInput, type LandWorktreeRemoval } from './land-worktree.js';
31
31
 
32
32
  export const TASK_AGENT_LIVE_MOVES = ['review', 'propose-green', 'propose-land', 'decision-card', ...LIVE_RETRY_MOVES] as const;
33
33
  export type TaskAgentLiveMove = typeof TASK_AGENT_LIVE_MOVES[number];
@@ -89,7 +89,7 @@ export interface LiveMoveDeps {
89
89
  raiseDecision?: (args: string[]) => Promise<{ status: number; stdout: string; stderr?: string }>;
90
90
  log?: (category: string, event: string, data: Record<string, unknown>) => void;
91
91
  /** TA-LAND-WORKTREE — cwd HEAD 읽기 · PR 머리 임시 워크트리 만들기(시험 주입 · 기본 = git). */
92
- landWorktree?: { localHead?: (cwd: string) => string | null; create?: (input: LandWorktreeInput) => Promise<LandWorktree | LandWorktreeFailure> };
92
+ landWorktree?: { localHead?: (cwd: string) => string | null; localBranch?: (cwd: string) => string | null; create?: (input: LandWorktreeInput) => Promise<LandWorktree | LandWorktreeFailure> };
93
93
  }
94
94
 
95
95
  /** `executed` = 부작용을 실제로 냈다(리뷰를 띄웠다 · 제안을 적었다). ok 이지만 이미 한 수(같은 머리·이미 제안)면 false. */
@@ -317,7 +317,7 @@ function observe(deps: LiveMoveDeps, result: LiveMoveResult): LiveMoveResult {
317
317
  /** `review` — PR 머리마다 한 번. 카드에 먼저 적고(잠금 안) 그다음 띄운다 · 띄우기 실패는 카드에 오류로 남기고 같은 머리는 다시 안 띄운다. */
318
318
  export async function executeLiveReview(
319
319
  card: TaskCard | undefined, pr: number | undefined,
320
- ctx: { runId: string | null; stopReason: string; cwd?: string; produced?: { headCommit?: string; branch?: string; prUrl?: string } },
320
+ ctx: { runId: string | null; stopReason: string; cwd?: string; forceNewReview?: boolean; produced?: { headCommit?: string; branch?: string; prUrl?: string } },
321
321
  deps: LiveMoveDeps = {},
322
322
  ): Promise<LiveMoveResult> {
323
323
  const kind = 'review' as const;
@@ -345,12 +345,16 @@ export async function executeLiveReview(
345
345
  const path = deps.statePath ?? taskAgentStatePath();
346
346
  const at = (deps.now ?? (() => new Date()))().toISOString();
347
347
  // TA-REVIEW-RESULT-CAPTURE — 머리마다 한 번이라 경로도 머리마다 하나다. 요청 칸에 먼저 적는다(회수가 이 칸을 본다).
348
- const resultPath = reviewResultPath(path, card.id, pr, head.head);
348
+ const resultPath = ctx.forceNewReview
349
+ ? reviewResultPath(path, card.id, pr, head.head).replace(/\.json$/, `-${randomUUID()}.json`)
350
+ : reviewResultPath(path, card.id, pr, head.head);
349
351
  const claim: { claimed: boolean; missing: boolean; before?: TaskCard } = { claimed: false, missing: false };
350
352
  updateTaskCard(path, card.id, (current) => {
351
353
  if (!current) { claim.missing = true; return undefined; }
352
354
  // 머리 «이력»으로 본다 — A→B→A 로 돌아와도 A 는 다시 요청하지 않는다.
353
- if ((current.reviewRequests ?? []).some((entry) => entry.pr === pr && entry.head === head!.head)) return undefined;
355
+ if (ctx.forceNewReview) {
356
+ if (pendingReviewResults(current).some((entry) => entry.pr === pr && entry.head === head!.head)) return undefined;
357
+ } else if ((current.reviewRequests ?? []).some((entry) => entry.pr === pr && entry.head === head!.head)) return undefined;
354
358
  claim.claimed = true;
355
359
  claim.before = current;
356
360
  return { ...current, reviewRequests: [...(current.reviewRequests ?? []), { pr, head: head!.head, at, resultPath }] };
@@ -416,6 +420,12 @@ const LAND_BASE_STALE_LINE = /^✗ overlap-evidence: (base-stale-overlap: .*)$/;
416
420
  const LAND_BASE_STALE_CONSEQUENCE_LINES: readonly RegExp[] = [/^✗ expected-head: overlap merge approval unavailable for the reviewed head$/];
417
421
  /** 실패가 아닌 ✗ 줄 — `pr land` 가 «계속합니다»로 넘어간다(판정에 쓰지 않는다). */
418
422
  const LAND_NON_FATAL_LINES: readonly RegExp[] = [/^✗ active-run-files: .*계속합니다\.?$/];
423
+ const TSC_RUNTIME_MISSING = /(?:^|\n)(?:sh: )?(?:env: )?(?:[^\s]*\/)?(?:node|bun|tsc): (?:No such file or directory|command not found)/m;
424
+ const TSC_NOT_RUN = /(?:tsc 종료코드 127|tsc 실행 실패 \([^\n]*code=ENOENT)/;
425
+ const TSC_GATE_REFUSED = '✗ typecheck: scripts/ci-typecheck-changed.ts blocked pr land.';
426
+ function missingTscRuntime(text: string): boolean {
427
+ return TSC_NOT_RUN.test(text) && TSC_RUNTIME_MISSING.test(text);
428
+ }
419
429
  /** executeLiveLand 쪽 인프라 사유(출력 줄이 아니라 실행 사실). */
420
430
  export const LAND_INFRA_EXECUTOR_REASONS = ['land-process-error', 'land-no-result-line'] as const;
421
431
  const [LAND_PROCESS_ERROR, LAND_NO_RESULT_LINE] = LAND_INFRA_EXECUTOR_REASONS;
@@ -435,6 +445,12 @@ export function classifyLandFailure(outcome: { status: number; stdout?: string;
435
445
  // 결과 줄이 «하나도» 없이 0 아닌 코드로 끝났다 — 관문까지 못 간 채 죽었다(크래시 · 신호).
436
446
  if (!marked.length) return outcome.status !== 0 ? { class: 'infra', reason: LAND_NO_RESULT_LINE } : { class: 'judgement', reason: 'no-failure-line' };
437
447
  const failures = marked.map((line) => line.replace(/^\[dry-run\] /, '')).filter((line) => line.startsWith('✗') && !LAND_NON_FATAL_LINES.some((re) => re.test(line)));
448
+ // The gate did not measure TypeScript when its interpreter was absent. The
449
+ // exact typecheck refusal alone remains judgement; require rc127/ENOENT and
450
+ // the missing runtime line, with no second failing gate.
451
+ if (failures.length === 1 && failures[0] === TSC_GATE_REFUSED && missingTscRuntime(lines.join('\n'))) {
452
+ return { class: 'infra', reason: 'tsc-runtime-missing' };
453
+ }
438
454
  const infra = new Set<string>();
439
455
  const unlisted: string[] = [];
440
456
  for (const line of failures) {
@@ -497,7 +513,15 @@ function observeLandWorktreeCreateCapped(deps: LiveMoveDeps, data: { card: strin
497
513
 
498
514
  /** 같은 머리에 한 번 더 시도해도 되나 — 앞 시도가 «전부» 끝났고(ok:false) «전부» infra 이고 상한 밑일 때만. */
499
515
  function landRetryAllowed(prior: readonly LandAttempt[]): boolean {
500
- return prior.length > 0 && prior.length < LAND_ATTEMPTS_PER_HEAD_ON_INFRA && prior.every((entry) => entry.ok === false && entry.class === 'infra');
516
+ return prior.length > 0 && prior.length < LAND_ATTEMPTS_PER_HEAD_ON_INFRA
517
+ && prior.every((entry) => entry.ok === false && (entry.class === 'infra' || legacyMissingTscRuntime(entry)));
518
+ }
519
+
520
+ /** A previous release classified a missing node interpreter as judgement; only that exact recorded shape may be reopened. */
521
+ function legacyMissingTscRuntime(entry: LandAttempt): boolean {
522
+ return entry.ok === false && entry.class === 'judgement' && entry.reason === TSC_GATE_REFUSED
523
+ && typeof entry.detail === 'string'
524
+ && classifyLandFailure({ status: 1, stderr: entry.detail }).reason === 'tsc-runtime-missing';
501
525
  }
502
526
 
503
527
  /**
@@ -566,7 +590,8 @@ export async function executeLiveLand(
566
590
  const at = (deps.now ?? (() => new Date()))().toISOString();
567
591
  const local = (deps.landWorktree?.localHead ?? localHead)(cwd);
568
592
  const landKey = `land:${card.id}:${view.head.slice(0, 12)}`;
569
- const needsLandWorktree = !!local && local.toLowerCase() !== view.head.toLowerCase();
593
+ const branch = local?.toLowerCase() === view.head.toLowerCase() ? (deps.landWorktree?.localBranch ?? localBranch)(cwd) : null;
594
+ const needsLandWorktree = !!local && (local.toLowerCase() !== view.head.toLowerCase() || branch !== view.branch);
570
595
  const createCap = landWorktreeCreateCap();
571
596
  let claimed = false;
572
597
  let missing = false;
@@ -603,7 +628,8 @@ export async function executeLiveLand(
603
628
  const attempt = prior.length + 1;
604
629
  if (attempt > 1) {
605
630
  const last = prior.at(-1)!;
606
- try { (deps.log ?? ((c, e, d) => debug.log(c, e, d)))('task-agent', LAND_RETRY_ON_INFRA_EVENT, { card: card.id, pr, head: view.head, attempt, reason: last.reason ?? 'unknown', class: 'infra', decision: 'retrying' }); } catch { /* fail-soft */ }
631
+ const legacy = legacyMissingTscRuntime(last);
632
+ try { (deps.log ?? ((c, e, d) => debug.log(c, e, d)))('task-agent', LAND_RETRY_ON_INFRA_EVENT, { card: card.id, pr, head: view.head, attempt, reason: legacy ? 'tsc-runtime-missing-legacy' : last.reason ?? 'unknown', class: 'infra', decision: legacy ? 'legacy-reclassified-retrying' : 'retrying' }); } catch { /* fail-soft */ }
607
633
  }
608
634
  if (cycle) landedCycles.add(cycle);
609
635
  // TA-LAND-WORKTREE — `pr land --expected-head` 는 «로컬 HEAD = 고정 머리»를 요구한다. cwd 가 다른 머리면(Pod 런 PR · 호스트 checkout)
@@ -618,6 +644,11 @@ export async function executeLiveLand(
618
644
  if ('reason' in made) {
619
645
  const reason = made.reason;
620
646
  observeLandWorktree({ card: card.id, pr, head: view.head, created: made.created, removed: made.removed, reason }, deps.log);
647
+ if (made.kind === 'worktree-conflict') {
648
+ try { (deps.log ?? ((c, e, d) => debug.log(c, e, d)))('task-agent', 'worktree-conflict', {
649
+ card: card.id, pr, head: view.head, branch: view.branch ?? null, ownerPath: made.ownerPath ?? 'unknown', reason,
650
+ }); } catch { /* fail-soft */ }
651
+ }
621
652
  let failures: LandWorktreeCreateFailure[] = [];
622
653
  let recordFailureError: unknown;
623
654
  try {
@@ -655,7 +686,7 @@ export async function executeLiveLand(
655
686
  } catch (error) {
656
687
  try { (deps.log ?? ((c, e, d) => debug.log(c, e, d, { level: 'warn' })))('task-agent', 'land-worktree-create-failures-clear-failed', { card: card.id, pr, head: view.head, error: String(error).slice(-200) }); } catch { /* fail-soft */ }
657
688
  }
658
- observeLandWorktree({ card: card.id, pr, head: view.head, created: true, removed: false, reason: `cwd HEAD ${local.slice(0, 12)} ≠ PR head ${view.head.slice(0, 12)}` }, deps.log);
689
+ observeLandWorktree({ card: card.id, pr, head: view.head, created: made.created ?? null, removed: false, reason: `cwd HEAD ${local.slice(0, 12)} · branch ${branch ?? 'unknown'} differs from PR ${view.head.slice(0, 12)} · ${view.branch ?? 'unknown'}` }, deps.log);
659
690
  }
660
691
  // 증거 경로는 «원래» cwd 기준으로 고정한다 — 임시 트리로 cwd 를 바꿔도 상대경로가 다른 파일을 가리키지 않게(같은 cwd 면 그대로).
661
692
  const overlapEvidence = ctx.overlapEvidence && worktree ? resolve(cwd, ctx.overlapEvidence) : ctx.overlapEvidence;
@@ -681,7 +712,7 @@ export async function executeLiveLand(
681
712
  // 성공이든 실패든 걷는다.
682
713
  let removal: LandWorktreeRemoval;
683
714
  try { removal = worktree.cleanup(); } catch (error) { removal = { removed: false, reason: String(error).slice(-200) }; }
684
- observeLandWorktree({ card: card.id, pr, head: view.head, created: true, removed: removal.removed, ...(removal.branchRemoved !== undefined ? { branchRemoved: removal.branchRemoved } : {}),
715
+ observeLandWorktree({ card: card.id, pr, head: view.head, created: worktree.created ?? null, removed: removal.removed, ...(removal.branchRemoved !== undefined ? { branchRemoved: removal.branchRemoved } : {}),
685
716
  reason: removal.reason ?? `land ${ok ? 'ok' : 'failed'} — removed` }, deps.log);
686
717
  }
687
718
  const landAttempt: LiveMoveResult['landAttempt'] = failure
@@ -159,7 +159,7 @@ export function remoteLaunchScript(target: ParentHostConfig, args: readonly stri
159
159
  const elanous = target.elanous ?? DEFAULT_REMOTE_ELANOUS;
160
160
  const configDir = target.configDir ?? DEFAULT_REMOTE_CONFIG_DIR;
161
161
  const log = remoteParentLogPath(target, env.ELANOUS_RUN_ID ?? 'unknown');
162
- const envPart = Object.entries(env).filter(([key]) => /^[A-Z_][A-Z0-9_]*$/.test(key)).map(([key, value]) => `${key}=${shellQuote(value)}`).join(' ');
162
+ const envPart = [...Object.entries(env).filter(([key]) => key !== 'ELANOUS_STATE_DIR' && /^[A-Z_][A-Z0-9_]*$/.test(key)).map(([key, value]) => `${key}=${shellQuote(value)}`), `ELANOUS_STATE_DIR=${remotePath(configDir)}`].join(' ');
163
163
  const argv = [remotePath(elanous), '--config-dir', remotePath(configDir), ...remoteParentArgs(args, target.podPool).map(shellQuote)].join(' ');
164
164
  // 준비가 실패하면 «확실히 안 띄웠다»(not-launched=…)를 찍고 끝낸다 — 그때만 호출부가 로컬로 돌아간다.
165
165
  // 띄운 뒤에는 짧게 살아 있는지 보고 pid 를 찍는다(조기 종료면 early-exit — 역시 «안 돈다»가 확실).
@@ -0,0 +1,139 @@
1
+ import { debug } from '../debug/log.js';
2
+ import { listChecklist, setItemIfSnapshot, type Checklist } from '../release-loop/checklist.js';
3
+ import { judgeLandedCell, parseJudgeSignals, type GreenVerdict } from '../release-loop/landed-to-green.js';
4
+ import { cardPrNumber, readTaskAgentState, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
5
+
6
+ export interface LandedTaskPr { number: number; url: string; headRefOid: string; state: string; baseRefName: string; mergedAt: string; files?: Array<{ path: string }> }
7
+ export interface PostlandDeps {
8
+ statePath?: string;
9
+ versions: readonly string[];
10
+ checklist?: (version: string) => Checklist;
11
+ setStatus?: typeof setItemIfSnapshot;
12
+ updateCard?: typeof updateTaskCard;
13
+ judge?: typeof judgeLandedCell;
14
+ log?: typeof debug.log;
15
+ }
16
+
17
+ /** Read-only PR binding for the legacy completion guard, including when judgment or ledger I/O fails. */
18
+ export function boundMergedTaskCells(pr: Pick<LandedTaskPr, 'number' | 'url'>, statePath = taskAgentStatePath()): string[] {
19
+ const tasks = readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(statePath).tasks ?? {};
20
+ const cards = Object.values(tasks).filter((card) => card.taLand && card.checklistId && cardPrNumber(card) === pr.number
21
+ && typeof card.pr === 'object' && card.pr.url?.replace(/\/+$/, '') === pr.url.replace(/\/+$/, ''));
22
+ return [...new Set(cards.map((card) => card.checklistId!))];
23
+ }
24
+
25
+ /** When the PR API omits URL/head, keep candidate TA cells out of the prose-only green path. */
26
+ export function candidateMergedTaskCells(number: number, statePath = taskAgentStatePath()): string[] {
27
+ const tasks = readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(statePath).tasks ?? {};
28
+ return [...new Set(Object.values(tasks).filter((card) => card.taLand && card.checklistId && cardPrNumber(card) === number).map((card) => card.checklistId!))];
29
+ }
30
+
31
+ /** A bound TA card closes only after its exact PR and a unique release cell are confirmed. */
32
+ export function closeMergedTaskCard(pr: LandedTaskPr, cwd: string, deps: PostlandDeps): string | null {
33
+ const log = deps.log ?? debug.log.bind(debug);
34
+ if (pr.state !== 'MERGED' || pr.baseRefName !== 'main' || !/^[a-f0-9]{40}$/i.test(pr.headRefOid) || !pr.url) return null;
35
+ const path = deps.statePath ?? taskAgentStatePath();
36
+ const tasks = readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(path).tasks ?? {};
37
+ const cards = Object.values(tasks).filter((card) => card.taLand && card.checklistId && cardPrNumber(card) === pr.number
38
+ && typeof card.pr === 'object' && card.pr.url?.replace(/\/+$/, '') === pr.url.replace(/\/+$/, ''));
39
+ if (cards.length !== 1) {
40
+ log('task-agent', 'postland-card-skipped', { pr: pr.number, reason: cards.length ? 'ambiguous-card' : 'no-bound-card' });
41
+ return null;
42
+ }
43
+ const card = cards[0]!;
44
+ if (!(card.landAttempts ?? []).some((attempt) => attempt.pr === pr.number && attempt.head.toLowerCase() === pr.headRefOid.toLowerCase())) {
45
+ log('task-agent', 'postland-card-skipped', { pr: pr.number, card: card.id, reason: 'land-head-not-bound' });
46
+ return null;
47
+ }
48
+ const candidateVersions = card.checklistVersion ? [card.checklistVersion] : deps.versions;
49
+ const cells = candidateVersions.flatMap((version) => {
50
+ const snapshot = (deps.checklist ?? listChecklist)(version);
51
+ const item = snapshot.items.find((row) => row.id === card.checklistId);
52
+ return item ? [{ version, snapshot, item }] : [];
53
+ });
54
+ if (cells.length !== 1) {
55
+ log('task-agent', 'postland-card-skipped', { pr: pr.number, card: card.id, reason: cells.length ? 'ambiguous-cell-version' : 'cell-not-found' });
56
+ return null;
57
+ }
58
+ const { version, item } = cells[0]!;
59
+ const expected = { title: item.title, status: item.status, evidence: item.evidence };
60
+ const expectedTitle = expected.title;
61
+ const prior = (card as TaskCard & { postLand?: { pr: number; head: string; outcome: 'complete' | 'partial'; evidence: string[] } }).postLand;
62
+ const marker = `TA postland #${pr.number}/${pr.headRefOid.slice(0, 12)}:`;
63
+ const currentEvidenceLine = item.evidence?.split('\n').find((line) => line.startsWith(marker));
64
+ const terminalBound = card.status === 'done' && card.prTerminal?.pr === pr.number
65
+ && card.prTerminal.head.toLowerCase() === pr.headRefOid.toLowerCase()
66
+ && card.prTerminal.url.replace(/\/+$/, '') === pr.url.replace(/\/+$/, '');
67
+ if (prior?.pr === pr.number && prior.head.toLowerCase() === pr.headRefOid.toLowerCase()
68
+ && prior.outcome === 'complete' && terminalBound && item.status === 'green' && currentEvidenceLine
69
+ && prior.evidence?.length && prior.evidence.every((part) => currentEvidenceLine.includes(part))) return item.id;
70
+ const alreadyGreen = item.status === 'green';
71
+ let verdict: GreenVerdict | undefined = alreadyGreen ? 'proposed' : undefined;
72
+ let judgeError: string | undefined;
73
+ if (!alreadyGreen) {
74
+ try { verdict = (deps.judge ?? judgeLandedCell)({ version, id: item.id, title: expectedTitle, pr: pr.number }, { cwd }); }
75
+ catch (error) { judgeError = String(error).slice(0, 240); }
76
+ }
77
+ const complete = verdict === 'proposed';
78
+ const criterion = expectedTitle.split(/\r?\n/).filter((line) => /^\s*판정(?: 신호)?:/.test(line)).map((line) => line.trim());
79
+ const remaining = complete ? [] : criterion.length ? criterion : ['판정 줄 없음 — 칸 주인의 판정 필요'];
80
+ const allPaths = (pr.files ?? []).map((file) => file.path).filter(Boolean);
81
+ const paths = allPaths.slice(0, 20);
82
+ const omitted = allPaths.length - paths.length;
83
+ const observations = parseJudgeSignals(expectedTitle).map((signal) => signal.observe).filter((value): value is string => !!value);
84
+ const judgeEvidence = alreadyGreen ? '기존 green 상태 확인(새 측정 0)' : judgeError
85
+ ? `판정 실행 오류: ${judgeError}`
86
+ : `판정 ${verdict ?? 'error'}: ${observations.length ? observations.join(' · ') : '측정 명령 없음'}${verdict === 'proposed' ? ' → exit 0' : ''}`;
87
+ const changed = paths.length ? `changed: ${paths.join(' · ')}${omitted ? ` · 외 ${omitted}개(${pr.url}에서 전체 확인)` : ''}`
88
+ : `changed: 경로 목록 미제공(${pr.url} 참조)`;
89
+ const filled = [`PR #${pr.number} merged, head ${pr.headRefOid}`, `카드 land head 대조 일치`, changed, judgeEvidence];
90
+ const note = complete
91
+ ? `${marker} ${filled.join(' | ')}; ${alreadyGreen ? '기존 green 유지' : '판정 신호 통과 → green'}.`
92
+ : `${marker} 이 조각이 채운 것: ${filled.join(' | ')}; 남은 것: ${remaining.join(' | ')}; 다음 조각 retitle 후보: ${remaining[0]}`;
93
+ const priorLines = item.evidence?.split('\n').filter((line) => !line.startsWith(marker)) ?? [];
94
+ const evidence = [...priorLines, note].join('\n');
95
+ const desiredStatus = complete ? 'green' : item.status === 'red' ? 'red' : 'yellow';
96
+ if (prior?.pr === pr.number && prior.head.toLowerCase() === pr.headRefOid.toLowerCase()
97
+ && prior.outcome === (complete ? 'complete' : 'partial') && terminalBound
98
+ && item.status === desiredStatus && item.evidence === evidence) return item.id;
99
+ const at = new Date().toISOString();
100
+ let wrote = false;
101
+ // The card lock protects the binding through the ledger write. A failed ledger write
102
+ // throws before the card changes, so the next pass can retry both records.
103
+ (deps.updateCard ?? updateTaskCard)(path, card.id, (current, currentTasks) => {
104
+ const matching = Object.values(currentTasks).filter((candidate) => candidate.taLand && cardPrNumber(candidate) === pr.number
105
+ && typeof candidate.pr === 'object' && candidate.pr.url?.replace(/\/+$/, '') === pr.url.replace(/\/+$/, ''));
106
+ if (matching.length !== 1 || matching[0]?.id !== card.id) return undefined;
107
+ if (!current || cardPrNumber(current) !== pr.number || current.checklistId !== item.id
108
+ || current.checklistVersion !== card.checklistVersion || typeof current.pr !== 'object'
109
+ || current.pr.url?.replace(/\/+$/, '') !== pr.url.replace(/\/+$/, '')
110
+ || !(current.landAttempts ?? []).some((attempt) => attempt.pr === pr.number && attempt.head.toLowerCase() === pr.headRefOid.toLowerCase())) return undefined;
111
+ const existing = (current as TaskCard & { postLand?: { pr: number; head: string; outcome: 'complete' | 'partial' } }).postLand;
112
+ const currentTerminalBound = current.status === 'done' && current.prTerminal?.pr === pr.number
113
+ && current.prTerminal.head.toLowerCase() === pr.headRefOid.toLowerCase()
114
+ && current.prTerminal.url.replace(/\/+$/, '') === pr.url.replace(/\/+$/, '');
115
+ if (existing?.pr === pr.number && existing.head.toLowerCase() === pr.headRefOid.toLowerCase()
116
+ && existing.outcome === (complete ? 'complete' : 'partial') && currentTerminalBound
117
+ && item.status === desiredStatus && item.evidence === evidence) return undefined;
118
+ const currentVersions = current.checklistVersion ? [current.checklistVersion] : deps.versions;
119
+ const currentCells = currentVersions.flatMap((candidateVersion) =>
120
+ (deps.checklist ?? listChecklist)(candidateVersion).items.some((row) => row.id === item.id) ? [candidateVersion] : []);
121
+ if (currentCells.length !== 1 || currentCells[0] !== version) return undefined;
122
+ (deps.setStatus ?? setItemIfSnapshot)(version, item.id, { evidence, status: desiredStatus }, 'task-agent', expected);
123
+ wrote = true;
124
+ const sameOutcome = existing?.pr === pr.number && existing.head.toLowerCase() === pr.headRefOid.toLowerCase()
125
+ && existing.outcome === (complete ? 'complete' : 'partial');
126
+ return { ...current,
127
+ status: 'done' as const,
128
+ prTerminal: { pr: pr.number, url: pr.url, head: pr.headRefOid, state: 'MERGED' as const, at },
129
+ postLand: { pr: pr.number, head: pr.headRefOid, at, outcome: complete ? 'complete' as const : 'partial' as const, evidence: filled, remaining },
130
+ history: sameOutcome ? current.history : [...current.history, { at, event: 'postland-card', pr: pr.number, head: pr.headRefOid, detail: complete ? `green ${version}/${item.id}` : `${desiredStatus} ${version}/${item.id}; ${remaining.join(' | ')}` }],
131
+ };
132
+ });
133
+ if (!wrote) {
134
+ log('task-agent', 'postland-card-pending', { pr: pr.number, card: card.id, version, id: item.id, reason: 'card-binding-changed-before-write' });
135
+ return item.id;
136
+ }
137
+ log('task-agent', 'postland-card-closed', { pr: pr.number, card: card.id, version, id: item.id, outcome: complete ? 'complete' : 'partial', verdict });
138
+ return item.id;
139
+ }
@@ -40,9 +40,12 @@ import type { DetachedSpawn } from '../cli/tasks-cli.js';
40
40
  import { remoteLedgerMirrorDir } from './parent-host.js';
41
41
  import { appendLandOrderRow, joinLandOrderRow } from './land-order-ledger.js';
42
42
  import { recordLiveMoveHistory } from './live-move-history.js';
43
+ import { runRepairCycle, type RepairLaunchRequest } from './repair-cycle.js';
44
+ import { repairMustFixFromReview, repairReviewDigest } from './repair-review.js';
45
+ import type { RepairCasOutcome, RepairCasRequest } from './repair-branch-cas.js';
43
46
  import { defaultLandPrHead, defaultPrHead, defaultReviewRepoCandidates, executeLiveLand, executeLiveReview, landRetryPending, type LiveMoveDeps, type LiveMoveResult, type PrHeadView, type ReviewRepoCandidate, type TaskAgentLiveMove } from './live-moves.js';
44
- import { capturedLandReview, captureReviewResults, parseReviewResultOutput, pendingReviewResults, type ParsedReviewResult } from './review-result-capture.js';
45
- import { cardPrNumber, readTaskCard, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
47
+ import { capturedLandReview, captureReviewResults, parseReviewResultOutput, pendingReviewResults, reviewResultPath, type ParsedReviewResult } from './review-result-capture.js';
48
+ import { boundPrTerminal, cardPrNumber, LIVE_MOVE_RESULT_EVENT, readTaskCard, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
46
49
 
47
50
  export const REJUDGE_ON_HEAD_EVENT = 'rejudge-on-head';
48
51
  /** 카드·PR 당 재게이트하는 머리 수 상한(머리가 바뀔 때마다 하나) — 넘으면 멈추고 사람에게 넘긴다. */
@@ -52,7 +55,7 @@ export const CATCH_UP_CAP = 2;
52
55
  /** 떼어 띄운 재게이트 결과를 기다리는 상한 — 지나도 파일이 없으면 «결과 없음»으로 적는다(같은 머리는 다시 안 돌린다). */
53
56
  export const REGATE_RESULT_WAIT_MS = 90 * 60_000;
54
57
 
55
- export type RejudgeStep = 'regate' | 'review' | 'ready' | 'land' | 'target' | 'catch-up';
58
+ export type RejudgeStep = 'regate' | 'review' | 'ready' | 'land' | 'target' | 'catch-up' | 'repair';
56
59
  export type CatchUpDecision = 'pushed' | 'conflict' | 'cap-reached' | 'failed';
57
60
  export interface RejudgeOutcome {
58
61
  card: string; pr: number | null; fromHead: string | null; toHead: string | null; step: RejudgeStep; decision: string; reason: string;
@@ -82,6 +85,12 @@ export interface RejudgeDeps {
82
85
  readyPr?: (pr: number, cwd: string) => Promise<{ ok: boolean; reason: string }>;
83
86
  /** 재게이트를 떼어 띄운다 — 시험은 주입한다. 기본은 `tasks regate-run` 자식(stdio ignore · 결과는 파일). */
84
87
  requestRegate?: (request: RegateRequest) => Promise<void>;
88
+ /** Source PR/head repair worker; absent uses the detached HQ local parent. */
89
+ requestRepair?: (request: RepairLaunchRequest) => Promise<void>;
90
+ applyRepair?: (request: RepairCasRequest) => RepairCasOutcome;
91
+ notifyRepair?: (seat: string, body: string) => void;
92
+ /** Shared new-launch budget for this `tasks rejudge --all` call. */
93
+ repairBudget?: import('./repair-cycle.js').RepairTickBudget;
85
94
  /** TA-REJUDGE-REBASE-LOOP — origin/main 을 PR 가지에 3-way merge 하고 일반 push. 시험은 주입한다. */
86
95
  catchUpMain?: (request: CatchUpRequest) => Promise<CatchUpResult>;
87
96
  log?: (category: string, event: string, data: Record<string, unknown>) => void;
@@ -405,7 +414,9 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
405
414
  if (!card || pr === undefined) return target('no-pr', 'card has no bound PR');
406
415
  const reviews = (card.reviewRequests ?? []).filter((entry) => entry.pr === pr);
407
416
  // 원격 부모는 node-b 의 liveMoves 가 꺼져 리뷰 이력이 0일 수 있다. HQ 거울의 종결 증거가 있을 때만 시작한다.
408
- if (!reviews.length && (!card.parentHost || !(deps.remoteRunTerminal ?? remoteBoundRunTerminal)(card)))
417
+ const adopted = card.adoptedPr?.pr === pr && typeof card.pr === 'object'
418
+ && !!card.pr.url && sameUrl(card.adoptedPr.url, card.pr.url) && /^[a-f0-9]{40}$/i.test(card.adoptedPr.head);
419
+ if (!reviews.length && !adopted && (!card.parentHost || !(deps.remoteRunTerminal ?? remoteBoundRunTerminal)(card)))
409
420
  return target('not-started', 'no task-agent review on this PR yet (remote terminal unproven or run not stopped/judged)', pr);
410
421
  // 떼어 띄운 재게이트 결과를 «머리와 무관하게» 먼저 회수한다 — 결과가 나오기 전에 머리가 또 바뀌어도 그 머리의 결과는 카드에 남는다.
411
422
  for (const pending of (card.regates ?? []).filter((entry) => entry.pr === pr && entry.passed === undefined && entry.resultPath)) {
@@ -442,10 +453,100 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
442
453
  if ('reason' in found) return target('pr-unreadable', found.reason, pr, fromHead);
443
454
  const { cwd, view } = found;
444
455
  const toHead = view.head;
456
+ if (view.state === 'MERGED' || view.state === 'CLOSED') {
457
+ const at = now().toISOString();
458
+ updateTaskCard(statePath, card.id, (current) => {
459
+ if (!current || cardPrNumber(current) !== pr || typeof current.pr !== 'object' || current.pr.url !== url) return undefined;
460
+ const previous = boundPrTerminal(current);
461
+ if (previous?.state === view.state && previous.head === toHead) return undefined;
462
+ return { ...current, prTerminal: { pr, url, head: toHead, state: view.state as 'MERGED' | 'CLOSED', at } };
463
+ });
464
+ return target('pr-not-open', `PR #${pr} is ${view.state}`, pr, fromHead, toHead);
465
+ }
445
466
  if (view.state !== 'OPEN') return target('pr-not-open', `PR #${pr} is ${view.state}`, pr, fromHead, toHead);
467
+ // An explicitly rejudged PR can be reopened. Clear the old marker before normal head judgement.
468
+ if (boundPrTerminal(card)) {
469
+ updateTaskCard(statePath, card.id, (current) => current && cardPrNumber(current) === pr && typeof current.pr === 'object' && current.pr.url === url
470
+ ? { ...current, prTerminal: undefined } : undefined);
471
+ card = readTaskCard(card.id, statePath) ?? card;
472
+ }
446
473
  const step = (s: RejudgeStep, decision: string, reason: string, record: boolean, extra: Partial<RejudgeOutcome> = {}) =>
447
474
  emit({ card: card!.id, pr, fromHead, toHead, step: s, decision, reason, ...extra }, record);
448
475
 
476
+ // Adoption is a first judgement for the current head, even when the implementation run
477
+ // already asked for a review. A captured failure needs repair; an accepted result must
478
+ // reach the host regate instead of stopping at the old same-head shortcut below.
479
+ const adoptedReview = adopted ? (card.history ?? []).filter((item) => item.event === LIVE_MOVE_RESULT_EVENT
480
+ && item.kind === 'review' && item.pr === pr && item.head && sameHead(item.head, toHead)
481
+ && item.reviewed === true && ['pass', 'warn', 'fail'].includes(item.verdict ?? '')).at(-1) : undefined;
482
+ if (adopted && !adoptedReview) {
483
+ if (reviews.some((entry) => sameHead(entry.head, toHead))) {
484
+ step('review', 'review-pending', `PR #${pr} head ${toHead.slice(0, 12)} already has a review request; await its result`, false);
485
+ } else if (!deps.liveMoves.has('review')) {
486
+ step('review', 'would-review', 'adopted PR first judgement · review not enabled in HQ taskAgent.liveMoves — shadow', false);
487
+ } else {
488
+ const before = { reviewRequests: card.reviewRequests, landAttempts: card.landAttempts };
489
+ const result = await executeLiveReview(card, pr, { runId: card.runId ?? null, stopReason: 'adopted-pr-first-judgement', cwd }, { ...live, ...(deps.log ? { log: deps.log } : {}) });
490
+ recordMove(statePath, card.id, card.runId, 'review', result, pr, before, now, deps.log);
491
+ step('review', result.executed ? 'review-requested' : 'review-request-failed', result.detail, true);
492
+ }
493
+ return outcomes;
494
+ }
495
+ const capturedForHead = (card.history ?? []).filter((item) => item.event === LIVE_MOVE_RESULT_EVENT
496
+ && item.kind === 'review' && item.pr === pr && item.head && sameHead(item.head, toHead)
497
+ && item.reviewed === true && ['pass', 'warn', 'fail'].includes(item.verdict ?? '')).at(-1);
498
+ if (capturedForHead && (capturedForHead.verdict === 'fail' || (capturedForHead.mustFix ?? 0) > 0)) {
499
+ const capturedPath = capturedForHead.resultPath;
500
+ const requestMatches = !!capturedPath && (card.reviewRequests ?? []).some((entry) => entry.pr === pr
501
+ && sameHead(entry.head, toHead) && entry.resultPath === capturedPath);
502
+ let mustFix: string[] | null = null;
503
+ try {
504
+ if (requestMatches && /^[0-9a-f]{64}$/.test(capturedForHead.reviewSha256 ?? '')) {
505
+ const text = read(capturedPath!);
506
+ if (repairReviewDigest(text) === capturedForHead.reviewSha256) mustFix = repairMustFixFromReview(text, pr, toHead);
507
+ }
508
+ } catch { /* fail closed below */ }
509
+ if (!mustFix && (deps.liveMoves.has('narrow-relaunch') || deps.liveMoves.has('salvage-relaunch') || deps.liveMoves.has('alternative'))
510
+ && !(card.repairs ?? []).some((entry) => entry.pr === pr && (entry.status === 'requested' || entry.status === 'unconfirmed'))) {
511
+ if (pendingReviewResults(card).some((entry) => entry.pr === pr && sameHead(entry.head, toHead))) {
512
+ step('review', 'review-pending', 'replacement exact-head review pending before repair', false);
513
+ return outcomes;
514
+ }
515
+ const originalPath = reviewResultPath(statePath, card.id, pr, toHead);
516
+ const retried = (card.reviewRequests ?? []).some((entry) => entry.pr === pr && sameHead(entry.head, toHead)
517
+ && entry.resultPath && entry.resultPath !== originalPath);
518
+ if (deps.liveMoves.has('review') && !retried) {
519
+ const before = { reviewRequests: card.reviewRequests, landAttempts: card.landAttempts };
520
+ const result = await executeLiveReview(card, pr, { runId: card.runId ?? null, stopReason: 'captured-review-identity-unavailable', cwd, forceNewReview: true },
521
+ { ...live, ...(deps.log ? { log: deps.log } : {}) });
522
+ recordMove(statePath, card.id, card.runId, 'review', result, pr, before, now, deps.log);
523
+ step('review', result.executed ? 'review-requested' : 'review-request-failed', result.detail, true);
524
+ return outcomes;
525
+ }
526
+ step('repair', 'repair-stopped', 'captured review result identity missing or changed; request a new review', true);
527
+ return outcomes;
528
+ }
529
+ if (mustFix?.length || (card.repairs ?? []).some((entry) => entry.pr === pr && (entry.status === 'requested' || entry.status === 'unconfirmed'))) {
530
+ if (!view.branch) {
531
+ step('repair', 'repair-stopped', 'PR branch name unavailable', true);
532
+ return outcomes;
533
+ }
534
+ const result = await runRepairCycle({ card, statePath, repo: cwd, pr, head: toHead, branch: view.branch,
535
+ mustFix: mustFix ?? [], liveMoves: deps.liveMoves, now: now(), readFile: read,
536
+ ...(deps.requestRepair ? { request: deps.requestRepair } : {}),
537
+ ...(deps.applyRepair ? { apply: deps.applyRepair } : {}),
538
+ ...(deps.notifyRepair ? { notify: deps.notifyRepair } : {}),
539
+ ...(deps.repairBudget ? { repairBudget: deps.repairBudget } : {}) });
540
+ step('repair', result.decision, result.reason, true);
541
+ return outcomes;
542
+ }
543
+ }
544
+ if (adopted && (adoptedReview?.verdict === 'fail' || !capturedLandReview(card, pr, toHead)
545
+ || capturedLandReview(card, pr, toHead)?.mustFixCount !== 0)) {
546
+ step('review', 'repair-needed', `PR #${pr} head ${toHead.slice(0, 12)} review ${adoptedReview?.verdict ?? 'unknown'} · must-fix ${adoptedReview?.mustFix ?? 'unknown'} — owner repair`, true);
547
+ return outcomes;
548
+ }
549
+
449
550
  // A remote --ta-land parent leaves its PR draft. Only a captured review for this exact
450
551
  // head may let HQ make it ready; the regate runner deliberately rejects draft PRs.
451
552
  let readyConfirmed = false;
@@ -527,7 +628,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
527
628
  };
528
629
 
529
630
  // 기존 live 경로의 같은 머리 조기 반환은 유지한다. 완료 훅의 그림자 판단만 통과 리뷰를 다시 본다.
530
- if (!regates.length && judgedHead && sameHead(toHead, judgedHead) && !landRetryPending(card, pr, toHead)) {
631
+ if (!adopted && !regates.length && judgedHead && sameHead(toHead, judgedHead) && !landRetryPending(card, pr, toHead)) {
531
632
  const unchangedReview = capturedLandReview(card, pr, toHead);
532
633
  if (!deps.shadowSameHead || deps.liveMoves.size !== 0 || !unchangedReview || !['pass', 'warn'].includes(unchangedReview.verdict) || unchangedReview.mustFixCount !== 0) {
533
634
  return target('head-unchanged', `PR #${pr} head is still the judged head`, pr, fromHead, toHead);
@@ -687,7 +788,8 @@ function recordMove(statePath: string, cardId: string, runId: string | undefined
687
788
  export function rejudgeCandidates(tasks: Readonly<Record<string, TaskCard>>): string[] {
688
789
  return Object.values(tasks).filter((card) => {
689
790
  const pr = cardPrNumber(card);
690
- return pr !== undefined && ((card.reviewRequests ?? []).some((entry) => entry.pr === pr)
691
- || (card.status === 'launched' && card.taLand === true && !!card.parentHost && !!card.runId && !!card.runChildId));
791
+ return pr !== undefined && !boundPrTerminal(card) && ((card.reviewRequests ?? []).some((entry) => entry.pr === pr)
792
+ || (card.status === 'launched' && card.taLand === true && ((!!card.parentHost && !!card.runId && !!card.runChildId)
793
+ || (card.adoptedPr?.pr === pr && typeof card.pr === 'object' && !!card.pr.url && sameUrl(card.adoptedPr.url, card.pr.url)))));
692
794
  }).map((card) => card.id);
693
795
  }
@@ -0,0 +1,91 @@
1
+ /** Bind remote TA parents from the HQ ledger mirror before `rejudge --all` selects PR cards. */
2
+ import { dirname } from 'node:path';
3
+ import { debug } from '../debug/log.js';
4
+ import { loadRunLedger } from '../self-implement/run-ledger.js';
5
+ import { bindCardEvidence, podChildRunIds, readCardRunSnapshot, refreshCardRunBinding } from './card-evidence.js';
6
+ import { mirrorRemoteRunLedgers, remoteLedgerMirrorDir } from './parent-host.js';
7
+ import { cardPrNumber, type TaskCard } from './task-hand.js';
8
+
9
+ const RECENT_LAUNCH_MS = 24 * 60 * 60 * 1000;
10
+
11
+ type BindDeps = {
12
+ now?: () => number;
13
+ mirror?: typeof mirrorRemoteRunLedgers;
14
+ onFailure?: (failure: { card: string; runId: string; host: string; reason: string }) => void;
15
+ };
16
+
17
+ function recentlyLaunched(card: TaskCard, now: number): boolean {
18
+ const launch = [...card.history].reverse().find(event => event.event === 'launch');
19
+ const at = Date.parse(launch?.at ?? card.createdAt);
20
+ return Number.isFinite(at) && at <= now && now - at < RECENT_LAUNCH_MS;
21
+ }
22
+
23
+ /**
24
+ * A remote child PR can appear after the last HQ card refresh. A card without a PR is otherwise absent from
25
+ * `rejudgeCandidates`, so the normal rejudge tick never reaches `mirrorRemoteCardLedger` or the binding replay.
26
+ * Only an existing, launched TA-owned parent with a parent→child edge in its own host mirror is admitted. The
27
+ * launch registry (including foreign/test universes) and child-only ledgers are never scanned or adopted here.
28
+ */
29
+ export async function bindMirroredRemoteRejudgeCards(
30
+ tasks: Readonly<Record<string, TaskCard>>, statePath: string,
31
+ deps: BindDeps = {},
32
+ ): Promise<{ scanned: number; bound: number; skipped: number }> {
33
+ const root = dirname(statePath);
34
+ const now = (deps.now ?? Date.now)();
35
+ const mirror = deps.mirror ?? mirrorRemoteRunLedgers;
36
+ const reportFailure = (card: TaskCard, reason: string): void => {
37
+ const failure = { card: card.id, runId: card.runId!, host: card.parentHost!.host, reason: reason.slice(0, 300) };
38
+ try { (deps.onFailure ?? ((data) => debug.log('task-agent', 'remote-rejudge-bind-failed', data)))(failure); }
39
+ catch { /* observation must not stop the other cards */ }
40
+ };
41
+ let scanned = 0;
42
+ let bound = 0;
43
+ let skipped = 0;
44
+ for (const card of Object.values(tasks)) {
45
+ if (card.status !== 'launched' || card.taLand !== true || !card.parentHost || !card.runId
46
+ || cardPrNumber(card) !== undefined || card.refSource === 'manual') continue;
47
+ scanned++;
48
+ const dir = remoteLedgerMirrorDir(root, card.parentHost.host);
49
+ try {
50
+ // This prepass runs before PR-based candidate selection. Pulling here breaks the otherwise circular
51
+ // dependency: cards with a remote PR cannot be selected while their parent/child ledgers are absent locally.
52
+ // Limit fresh remote pulls to recent launches, but keep binding older ledgers already mirrored at HQ.
53
+ if (recentlyLaunched(card, now)) mirror(card.parentHost, card.runId, root);
54
+ const snapshot = await readCardRunSnapshot(card, {
55
+ loadLedger: (id) => loadRunLedger(id, dir),
56
+ podFinishes: () => [],
57
+ });
58
+ const parent = snapshot.host;
59
+ const evidence = bindCardEvidence(card, snapshot);
60
+ const childRunId = evidence.childRunId;
61
+ const pr = evidence.pr;
62
+ const child = childRunId ? snapshot.children[childRunId] : null;
63
+ if (snapshot.readErrors?.length) {
64
+ reportFailure(card, snapshot.readErrors.join('; '));
65
+ skipped++;
66
+ continue;
67
+ }
68
+ // A PR event alone is not a completed remote run. The rejudge candidate must have the same exact
69
+ // child PR and terminal status that remoteBoundRunTerminal will later require.
70
+ if (!parent || !childRunId || !pr?.url || !child
71
+ || !podChildRunIds(parent, card.runId).includes(childRunId)
72
+ || !child.some((entry) => entry.event === 'pr-opened' && entry.data?.number === pr.number
73
+ && entry.data?.url === pr.url)
74
+ || !child.some((entry) => entry.event === 'run-status'
75
+ && ['completed', 'failed', 'cancelled'].includes(String(entry.data?.runStatus)))) { skipped++; continue; }
76
+ const result = await refreshCardRunBinding(card.id, statePath, {
77
+ // Reuse the verified snapshot so a second mirror read cannot silently change the selected PR.
78
+ loadLedger: (id) => id === card.runId ? [...parent] : snapshot.children[id] ? [...snapshot.children[id]!] : null,
79
+ // The remote mirror is the sole evidence for this prepass. Host logs can contain unrelated child receipts.
80
+ podFinishes: () => [],
81
+ });
82
+ if (result.card?.runId === card.runId && cardPrNumber(result.card) !== undefined
83
+ && result.card.runChildId && podChildRunIds(parent, card.runId).includes(result.card.runChildId)) bound++;
84
+ else skipped++;
85
+ } catch (error) {
86
+ skipped++;
87
+ reportFailure(card, error instanceof Error ? error.message : String(error));
88
+ }
89
+ }
90
+ return { scanned, bound, skipped };
91
+ }