elanous 0.2.29 → 0.2.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (709) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{058a98ba.7eb28d5e6dc03565.js → 0bb0ff36.b8d418980951e5ba.js} +7 -7
  5. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +27 -0
  8. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +287 -0
  9. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +62 -0
  10. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/{6013-2f769370d8b4c2c6.js → 1335-6731f392c35216eb.js} +3 -3
  12. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{8332.6f0f49df772e163b.js → 1654.32de4b324981a188.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1834-50625904996a8fa8.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
  17. package/apps/pwa/out/_next/static/chunks/{8795.32573a185af18c7b.js → 1913.7cc6fb6055b1ed3f.js} +2 -2
  18. package/apps/pwa/out/_next/static/chunks/{419.736c0d6f426249a7.js → 2001.6c7e0fd02190886c.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{6767.1fcfc9b8be83975f.js → 2213.2ccbada92c33ea0f.js} +16 -16
  24. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/{4759.1f76713aefb87db5.js → 2871.0bca6137343b3f76.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/{6776.06ff1e3b464cc607.js → 2898.fd781bc7cf01a7b7.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/{1782-59db1b5aa06df38a.js → 2940-619bfd8ef337c611.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/{8471.8d2a8c74f09c36ff.js → 2985.39ccdecd36848b12.js} +4 -4
  31. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +115 -0
  32. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +64 -0
  33. package/apps/pwa/out/_next/static/chunks/{bc324b7c.02a09dd93f6a399b.js → 3267c0e6.d34854e7b3984a6e.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3278.2e5d15b53a4091c8.js +2 -0
  35. package/apps/pwa/out/_next/static/chunks/{7725-4f83d5541fbdb81b.js → 3541-ce3a5424ed5ad7f1.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +34 -0
  39. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{46bd8bea.2f4b4099172fcdb7.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{1142.65d002789ab3af7d.js → 4174.92ed04922709ac9e.js} +2 -2
  43. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +36 -0
  45. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +286 -0
  49. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +77 -0
  50. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +226 -0
  51. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +79 -0
  53. package/apps/pwa/out/_next/static/chunks/5173-233188df2f42c626.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/5307.60f2209e809bd627.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{3396-97b97928c49190c9.js → 5458-16cd7a2b51b74c8c.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/{3403.7199205e65124486.js → 5525.86debf231e181813.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{9143.ff14585db1d275ff.js → 5543.a438b8ab5a13ea47.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +74 -0
  65. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +94 -0
  67. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{8398.73a19b39715eda04.js → 6092.a7f99e68b188ca66.js} +1 -1
  70. package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/{5591.a35e7a217734a8b9.js → 6157.0c9af021de4fb31b.js} +2 -2
  72. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/{7375.050ea0d72968e49f.js → 6433.fc573af22bbc9ab7.js} +17 -17
  75. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +90 -0
  77. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +32 -0
  78. package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +104 -0
  80. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +24 -0
  85. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
  86. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{1852.7f7b53991fcb99ef.js → 7502.ccd5b8065545edd0.js} +2 -2
  93. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
  94. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{6534.1ab00f370db7b105.js → 7862.30a8d6482bb238eb.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/8097-92f87bd108322f66.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
  109. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.js → 9221.7d22eaf353a2d4e7.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{8767-2f6a634f5abeaa01.js → 9279-d28c5b7754d010ae.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
  121. package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.js → 9989.3694300e5f000b14.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-bf3634a117322df7.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-3535a4a69f1fafaa.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-b9f51447f757fbf2.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-a5635eba0d73b84e.js → page-2ebb8fd59b9461f9.js} +1 -1
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-a2fc4e49a4fa4ba8.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5a503541353e60a8.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-6025101384e361a5.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-f4b630cc8b5273cd.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-a645f00a06483e9a.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-61ac22cbab1ee4ec.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e9bab7413b028b28.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-c992eafe028b642e.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-e547e6ce55f1fb33.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-d27e1b9850fd54bf.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-805ac2e137b7a121.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-0fec29c7ba01894b.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-339a07410cd6f36b.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-349f2752d8cd37ad.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-d5c6dcf31c25cecc.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-2fd93ed8c9f16580.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-9b564dbff0fefc35.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-62f4475d3c38fb9b.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-814ba51385225776.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-397d479626e5a459.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-af1bba4e3251b728.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ad3be5e7d3fdce9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-f219ccdbc0bf27df.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4da93ad35d4a8d28.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-456666766e5ce6fc.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-7404e377e8adb8c5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-14456240ed2a36ad.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-3a658d5fa6d16a25.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-0157de6e85f8bb6b.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-0a07363b130182a1.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-841d73d4ac44ed49.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6f43a3d1146e6377.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/{page-29900ed0011b2c83.js → page-521ee23ac8c0abfa.js} +1 -1
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-a9992ee285efaa83.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-3d48e85fa89ec04f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d2ced71132fac9b2.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-f08358bdf251adb9.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-233c71cd5f68f0d7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-70151d78de2f375e.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-dcac33a3e2cb72c0.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/{page-9f92737b8766009a.js → page-149dc1caba411bb9.js} +1 -1
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0448145ccd5c45c1.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-9cb0c444903da65d.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-17e504c396e0e389.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
  175. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
  183. package/apps/pwa/out/_next/static/css/{72becfd42807b50d.css → 3f5fc6f96e2cf7b2.css} +1 -1
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +23 -23
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +23 -23
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +23 -23
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +22 -22
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +22 -22
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +23 -23
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +22 -22
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +23 -23
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +23 -23
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +22 -22
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +23 -23
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +23 -23
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +23 -23
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +23 -23
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +22 -22
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +22 -22
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +23 -23
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +23 -23
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +23 -23
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +22 -22
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +22 -22
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +23 -23
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +23 -23
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +22 -22
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +22 -22
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +22 -22
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +23 -23
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +23 -23
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +22 -22
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +23 -23
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +23 -23
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +23 -23
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +23 -23
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +23 -23
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +22 -22
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +23 -23
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +23 -23
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +23 -23
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +23 -23
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +23 -23
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +23 -23
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +23 -23
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +23 -23
  277. package/bin/elanous.mjs +7 -3
  278. package/graphs/context/nightly-condense.yaml +1 -0
  279. package/graphs/intake/intake-daily.yaml +8 -1
  280. package/graphs/intake/recipes.yaml +5 -0
  281. package/graphs/lecture/lecture-note.yaml +2 -2
  282. package/graphs/ops/harness-gc.yaml +1 -0
  283. package/graphs/release/recipes.yaml +3 -0
  284. package/graphs/release/release-loop.yaml +9 -5
  285. package/graphs/units/recipes.yaml +3 -0
  286. package/graphs/units/release-gate-recheck.yaml +15 -0
  287. package/package.json +2 -1
  288. package/scripts/check-native-tool-wiring.ts +3 -2
  289. package/scripts/ci-android-unit-tests.ts +16 -0
  290. package/scripts/ci-typecheck-changed.ts +37 -9
  291. package/scripts/coord-channel-watch.sh +22 -16
  292. package/scripts/coord-role-pack.ts +81 -2
  293. package/scripts/cron-run.ts +96 -3
  294. package/scripts/detect-test-interference.ts +38 -5
  295. package/scripts/gate-pr-cache.ts +65 -0
  296. package/scripts/gh-surface/capture.ts +126 -0
  297. package/scripts/gh-surface/gh +40 -0
  298. package/scripts/import-graph-scc.ts +38 -0
  299. package/scripts/install.ps1 +19 -0
  300. package/scripts/intake-social.ts +181 -0
  301. package/scripts/lecture-note/node.ts +71 -4
  302. package/scripts/lib/android-toolchain.ts +32 -0
  303. package/scripts/lib/deterministic-env.ts +62 -0
  304. package/scripts/lib/gate-test-env.ts +19 -0
  305. package/scripts/measure-goal-grounding-corpus.ts +2 -1
  306. package/scripts/ratchets/test-interference-patterns.allowlist.txt +257 -0
  307. package/scripts/ratchets/test-interference-patterns.ts +367 -0
  308. package/scripts/release-loop/cut-branch.ts +4 -3
  309. package/scripts/release-loop/export-check-node.ts +0 -1
  310. package/scripts/release-loop/fixtures/warm-failure-assertion/sample.junit.xml +8 -0
  311. package/scripts/release-loop/fixtures/warm-job-029/sample.json +1 -0
  312. package/scripts/release-loop/fixtures/warm-job-029/sample.junit.xml +10 -0
  313. package/scripts/release-loop/gate-closure.ts +12 -8
  314. package/scripts/release-loop/gate-diff.ts +1 -1
  315. package/scripts/release-loop/gate-host-mirror.ts +66 -0
  316. package/scripts/release-loop/gate-node.ts +523 -75
  317. package/scripts/release-loop/gate-partial.ts +106 -9
  318. package/scripts/release-loop/gate-pr-cache.ts +66 -0
  319. package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
  320. package/scripts/release-loop/gate-r2-verdict.ts +189 -0
  321. package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
  322. package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
  323. package/scripts/release-loop/import-graph-scc-run.ts +54 -0
  324. package/scripts/release-loop/import-graph-scc.ts +215 -0
  325. package/scripts/release-loop/node-verdict.ts +2 -0
  326. package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
  327. package/scripts/release-loop/resume-release.ts +33 -4
  328. package/scripts/release-loop/resume.ts +13 -5
  329. package/scripts/release-loop/spawn-lane.ts +2 -19
  330. package/scripts/release-loop/tui-sim-node.ts +3 -2
  331. package/scripts/release-loop/unattended-release.ts +16 -0
  332. package/scripts/test-deterministic.ts +5 -61
  333. package/scripts/train-reach-grouping.ts +48 -0
  334. package/scripts/tsc-incremental-cache.ts +86 -0
  335. package/scripts/tsc-incremental-diagnostics.ts +76 -0
  336. package/scripts/tsc-main-safety-net.ts +2 -2
  337. package/src/acp/client.ts +4 -1
  338. package/src/acp/core-turn-bridge.ts +50 -5
  339. package/src/ad-pipeline/run.ts +4 -2
  340. package/src/agent/runner.ts +169 -3
  341. package/src/agent/subagent-callable.ts +3 -2
  342. package/src/agent-mission/review-loop.ts +6 -3
  343. package/src/agent-substrate/acp-implementer.ts +14 -2
  344. package/src/agent-substrate/pr-reviewer.ts +12 -0
  345. package/src/agent-substrate/self-review-cli.ts +30 -4
  346. package/src/autopilot/pr-manager.ts +62 -7
  347. package/src/briefing/brief-items.ts +24 -22
  348. package/src/capture/tui-self-report.ts +15 -0
  349. package/src/chat/chat-cli.ts +10 -2
  350. package/src/chat/index.ts +77 -11
  351. package/src/chat/input-control-key.ts +5 -3
  352. package/src/chat/tool-interrupt-behavior.ts +38 -0
  353. package/src/chat/tool-render/dispatch.ts +5 -1
  354. package/src/chat/turn-typeahead.ts +75 -20
  355. package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
  356. package/src/cli/agent-cli.ts +41 -13
  357. package/src/cli/config-audit.ts +123 -0
  358. package/src/cli/decisions-cli.ts +80 -6
  359. package/src/cli/log-event-names.ts +7 -0
  360. package/src/cli/mcp-login.ts +21 -5
  361. package/src/cli/msg-cli.ts +88 -0
  362. package/src/cli/pr-cli.ts +214 -57
  363. package/src/cli/pr-land-heavy-remote.ts +2 -2
  364. package/src/cli/pr-land-overlap-evidence.ts +63 -9
  365. package/src/cli/pr-land-pod-shadow-job.ts +83 -0
  366. package/src/cli/pr-land-pod-shadow.ts +16 -3
  367. package/src/cli/pr-land-virtual-rebase.ts +108 -0
  368. package/src/cli/release-cli.ts +80 -14
  369. package/src/cli/seat-cli.ts +138 -3
  370. package/src/cli/self-update.ts +5 -2
  371. package/src/cli/tasks-cli.ts +97 -19
  372. package/src/context-bus/context-first.ts +13 -0
  373. package/src/context-bus/context-now.ts +13 -2
  374. package/src/context-bus/ops-events.ts +75 -0
  375. package/src/control-plane/lease-holder.ts +12 -8
  376. package/src/control-plane/ledger.ts +163 -4
  377. package/src/control-plane/server.ts +91 -11
  378. package/src/core-turn/run-core-turn.ts +1 -0
  379. package/src/core-turn/run-goal-loop.ts +222 -3
  380. package/src/core-turn/seat-turn-cap.ts +79 -0
  381. package/src/core-turn/short-question.ts +38 -6
  382. package/src/core-turn/types.ts +3 -0
  383. package/src/dashboard/acp-boot.ts +3 -0
  384. package/src/dashboard/index.ts +224 -615
  385. package/src/dashboard/input/chat-main-entry-runtime.ts +1 -1
  386. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
  387. package/src/dashboard/input/chat-main-session.ts +8 -1
  388. package/src/dashboard/input/chat-main-turn.ts +12 -3
  389. package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
  390. package/src/dashboard/input/external-input-host.ts +26 -0
  391. package/src/dashboard/input/internal-turn.ts +261 -0
  392. package/src/dashboard/input/seat-autowake.ts +318 -0
  393. package/src/dashboard/input/turn-steer-bridge.ts +70 -0
  394. package/src/dashboard/loop-scheduler.ts +72 -0
  395. package/src/dashboard/seat-boot-preamble.ts +18 -0
  396. package/src/dashboard/skill-runtime.ts +2 -0
  397. package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
  398. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
  399. package/src/dashboard/slash-runtime/index.ts +13 -0
  400. package/src/dashboard/turn-busy-teardown.ts +50 -0
  401. package/src/decisions/decision-ledger.ts +45 -4
  402. package/src/discord-self-message.ts +4 -4
  403. package/src/domains/release-tool.ts +18 -1
  404. package/src/field-note/transcribe.ts +17 -0
  405. package/src/github/remote-call.ts +81 -0
  406. package/src/goals/registry.ts +46 -6
  407. package/src/goals/types.ts +7 -1
  408. package/src/graph-runner/runner.ts +1 -0
  409. package/src/grok/credential.ts +26 -0
  410. package/src/harness/harness-clean.ts +2 -1
  411. package/src/harness/harness-cli-command.ts +52 -5
  412. package/src/harness/harness-gc.ts +2 -1
  413. package/src/harness/harness-incidents.ts +57 -20
  414. package/src/harness/harness-pod-dispatch.ts +87 -10
  415. package/src/harness/harness-queue.ts +53 -4
  416. package/src/harness/harness-stop.ts +4 -3
  417. package/src/harness/harness-substrate-default.ts +78 -7
  418. package/src/harness/harness-worktree-auto.ts +2 -1
  419. package/src/harness/harness-worktrees.ts +3 -2
  420. package/src/hooks/dispatch.ts +2 -1
  421. package/src/index.ts +152 -25
  422. package/src/input/external-input-queue.ts +33 -1
  423. package/src/intake-plane/slash.ts +14 -3
  424. package/src/keybindings.ts +4 -1
  425. package/src/llm/tool-loop-steered-rejection.ts +33 -0
  426. package/src/llm.ts +138 -19
  427. package/src/loops/consensus.ts +348 -0
  428. package/src/loops/msg-wake.ts +206 -4
  429. package/src/loops/observe.ts +19 -3
  430. package/src/loops/orchestrator/tick.ts +64 -10
  431. package/src/loops/orchestrator/traffic.ts +64 -1
  432. package/src/loops/registry.ts +30 -0
  433. package/src/market/signed-index.ts +14 -0
  434. package/src/mcp/mcp-oauth.ts +54 -5
  435. package/src/models/prompts.ts +28 -0
  436. package/src/msg/msg-sse-client.ts +223 -0
  437. package/src/msg/msg-store.ts +86 -2
  438. package/src/mss/logging/log-store.ts +225 -1
  439. package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
  440. package/src/nexus/api/http-server.ts +54 -15
  441. package/src/nexus/api/loop-resources.ts +19 -3
  442. package/src/nexus/api/ops-api.ts +11 -0
  443. package/src/nexus/daemon-thin-inventory.md +37 -0
  444. package/src/nexus/index.ts +70 -0
  445. package/src/nexus/state/state.ts +1 -0
  446. package/src/oauth/store.ts +32 -7
  447. package/src/onboarding/first-run.ts +28 -3
  448. package/src/ops/overview-cache.ts +16 -4
  449. package/src/ops/resources.ts +82 -0
  450. package/src/plugins/maker/connector-maker.ts +41 -0
  451. package/src/plugins/maker/skill-maker.ts +42 -0
  452. package/src/pr-tool/census.ts +288 -0
  453. package/src/prompt-library/chat-conciseness.ts +13 -0
  454. package/src/prompt-library/universal-preamble.ts +10 -5
  455. package/src/release-loop/gate-host-reservation.ts +97 -0
  456. package/src/release-loop/landing-freeze.ts +5 -0
  457. package/src/release-loop/light-rc.ts +5 -2
  458. package/src/release-loop/placement.ts +92 -1
  459. package/src/release-loop/rehearsal-shard-plan.ts +149 -0
  460. package/src/release-loop/rehearsal.ts +73 -17
  461. package/src/repl/index.ts +20 -2
  462. package/src/seat-loop/seat-knowhow.ts +282 -0
  463. package/src/seat-loop/seat-loop.ts +41 -2
  464. package/src/seat-loop/traffic-signal.ts +3 -0
  465. package/src/self-dev/ask-launch-flow.ts +24 -3
  466. package/src/self-dev/decompose-compose-graph.ts +28 -27
  467. package/src/self-dev/decompose-proposal.ts +53 -38
  468. package/src/self-dev/decompose.ts +17 -0
  469. package/src/self-dev/dev-pipeline.ts +31 -2
  470. package/src/self-dev/draft-residue.ts +24 -9
  471. package/src/self-dev/draft-sweep.ts +59 -4
  472. package/src/self-dev/external-call-zero.ts +77 -0
  473. package/src/self-dev/launch-preflight-text.ts +6 -0
  474. package/src/self-dev/launch-preflight.ts +25 -3
  475. package/src/self-dev/local-supervisor-judge.ts +185 -0
  476. package/src/self-dev/run-supervisor.ts +229 -19
  477. package/src/self-dev/run-types.ts +20 -0
  478. package/src/self-dev/shard-aggregate.ts +13 -2
  479. package/src/self-dev/shard-plan.ts +47 -0
  480. package/src/self-dev/shard-run.ts +112 -10
  481. package/src/self-dev/spawn-lane-files.ts +19 -0
  482. package/src/self-implement/app-api-budget.ts +51 -11
  483. package/src/self-implement/config-gate.ts +2 -1
  484. package/src/self-implement/expose-gate.ts +2 -1
  485. package/src/self-implement/gate-artifacts.ts +405 -0
  486. package/src/self-implement/gate-cli.ts +201 -16
  487. package/src/self-implement/gate-remote.ts +110 -25
  488. package/src/self-implement/gate-scenario.ts +85 -0
  489. package/src/self-implement/goal-author.ts +160 -8
  490. package/src/self-implement/graph-authority.ts +38 -6
  491. package/src/self-implement/graph-overlay-condition.ts +92 -1
  492. package/src/self-implement/heal-triage.ts +79 -0
  493. package/src/self-implement/host-regate.ts +61 -3
  494. package/src/self-implement/orchestrator.ts +14 -123
  495. package/src/self-implement/pr-title.ts +123 -0
  496. package/src/self-implement/run-checkpoint.ts +235 -0
  497. package/src/self-implement/run-ledger.ts +155 -10
  498. package/src/self-implement/run-stop.ts +4 -3
  499. package/src/self-implement/run-ttl.ts +28 -4
  500. package/src/self-implement/seams.ts +2 -0
  501. package/src/self-implement/shadow-stage.ts +7 -6
  502. package/src/self-implement/stop-autoheal.ts +2 -1
  503. package/src/self-implement/train-gate-remote.ts +37 -8
  504. package/src/self-implement/train-reach-grouping.ts +157 -0
  505. package/src/self-implement/train-scenario-layers.ts +133 -0
  506. package/src/self-implement/uncommitted-work.ts +2 -0
  507. package/src/session/pending-input.ts +19 -0
  508. package/src/session/session-start.ts +224 -0
  509. package/src/session-runtime/parallel-dispatch.ts +22 -5
  510. package/src/skills/tools/dev-harness.ts +6 -4
  511. package/src/skills/tools/shell.ts +1 -1
  512. package/src/steward/resync-tick.ts +114 -23
  513. package/src/steward/ta-repair-event-collect.ts +158 -0
  514. package/src/task-agent/card-evidence.ts +25 -1
  515. package/src/task-agent/green-sweep.ts +8 -3
  516. package/src/task-agent/judge.ts +76 -0
  517. package/src/task-agent/land-queue.ts +79 -0
  518. package/src/task-agent/live-moves.ts +30 -9
  519. package/src/task-agent/postland-card.ts +5 -0
  520. package/src/task-agent/prelaunch-already-done.ts +98 -0
  521. package/src/task-agent/real-launch-guard.ts +37 -0
  522. package/src/task-agent/rejudge-on-head.ts +89 -12
  523. package/src/task-agent/remote-rejudge-bind.ts +28 -8
  524. package/src/task-agent/repair-cycle.ts +45 -7
  525. package/src/task-agent/repair-worker.ts +7 -0
  526. package/src/task-agent/run-identity.ts +200 -0
  527. package/src/task-agent/shadow.ts +50 -3
  528. package/src/task-agent/task-hand.ts +158 -5
  529. package/src/task-agent/train-landing.ts +77 -0
  530. package/src/task-agent/work-order.ts +104 -0
  531. package/src/task-orchestrator/surfaces/pod-command-job.ts +88 -28
  532. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
  533. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
  534. package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
  535. package/src/task-orchestrator/surfaces/pod-install-slots.ts +121 -9
  536. package/src/task-orchestrator/surfaces/pod-lease.ts +20 -6
  537. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
  538. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +27 -0
  539. package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
  540. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +63 -0
  541. package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
  542. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
  543. package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
  544. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
  545. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +208 -0
  546. package/src/task-orchestrator/surfaces/self-implement-pod.ts +132 -15
  547. package/src/telegram.ts +2 -4
  548. package/src/tui/input/pickers.ts +732 -0
  549. package/src/tui/slash/mission.ts +492 -0
  550. package/src/tui/slash/term.ts +877 -0
  551. package/src/tui-client/dashboard-session.ts +9 -0
  552. package/src/tui.ts +48 -0
  553. package/src/user-config/gemini-server-tools.ts +9 -0
  554. package/src/user-config.ts +53 -16
  555. package/src/util/spawn-sync-output.ts +7 -0
  556. package/src/ux-sim/fake-bin.ts +154 -0
  557. package/src/ux-sim/fake-clock.ts +36 -0
  558. package/src/ux-sim/headless-tui.ts +72 -0
  559. package/src/ux-sim/in-process-cli.ts +2 -1
  560. package/src/ux-sim/temp-git-remote.ts +82 -0
  561. package/src/version/packed-revision.json +1 -1
  562. package/src/video-pipeline/recipes/vlog.ts +25 -7
  563. package/apps/pwa/out/_next/static/chunks/1015-9cba22a5a4554797.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
  567. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
  569. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
  572. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
  573. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
  576. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
  578. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
  584. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
  588. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
  599. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
  605. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
  608. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
  609. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
  610. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
  613. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
  615. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
  616. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
  617. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
  619. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
  625. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
  632. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
  635. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
  640. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
  642. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
  703. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
  709. /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_ssgManifest.js +0 -0
@@ -91,9 +91,8 @@ export async function runMcpLogin(opts: McpLoginOpts): Promise<McpLoginResult> {
91
91
  const discovered = await discoverMcpOAuth(challenge.resourceMetadata, {
92
92
  resourceUrl: spec.url, ...oauthOpts,
93
93
  });
94
- if ((why || !discovered.metadata.authorizationEndpoint) && discovered.metadata.deviceAuthorizationEndpoint) {
95
- if (early?.server.listening) await closeServer(early.server);
96
- if (why) out.log(why);
94
+ const loginWithDevice = async (): Promise<McpLoginResult> => {
95
+ if (server?.listening) await closeServer(server);
97
96
  const stored = loadStoredRegistration(discovered.metadata.issuer, oauthOpts);
98
97
  const deviceRegistration = await ensureClientRegistration(discovered.metadata, { ...oauthOpts, deviceCode: true });
99
98
  const authorizeDevice = (registration: typeof deviceRegistration) => authorizeMcpDevice(discovered.metadata, registration, {
@@ -119,6 +118,10 @@ export async function runMcpLogin(opts: McpLoginOpts): Promise<McpLoginResult> {
119
118
  out.log(`✓ credentials saved for '${opts.serverId}' (${discovered.metadata.issuer})`);
120
119
  persistLoginDiscovery(opts, discovered.metadata, out);
121
120
  return { exitCode: 0 };
121
+ };
122
+ if ((why || !discovered.metadata.authorizationEndpoint) && discovered.metadata.deviceAuthorizationEndpoint) {
123
+ if (why) out.log(why);
124
+ return await loginWithDevice();
122
125
  }
123
126
  const callbackListener = early ?? await listenForCallback(opts.createListener, 0);
124
127
  server = callbackListener.server;
@@ -170,7 +173,17 @@ export async function runMcpLogin(opts: McpLoginOpts): Promise<McpLoginResult> {
170
173
  }
171
174
  }
172
175
  }
173
- const callback = await callbackPromise;
176
+ let callback: Callback;
177
+ try {
178
+ callback = await callbackPromise;
179
+ } catch (error) {
180
+ // A missing browser callback can use the advertised device flow. An explicit
181
+ // denial, mismatched state, or malformed callback must never silently fall back.
182
+ if (!discovered.metadata.deviceAuthorizationEndpoint ||
183
+ !/^authorization callback timed out after \d+ms$/.test(error instanceof Error ? error.message : '')) throw error;
184
+ out.log(`Browser approval did not complete for '${opts.serverId}'; trying device code.`);
185
+ return await loginWithDevice();
186
+ }
174
187
  await exchangeAuthorizationCode(authorization.metadata, authorization.request, callback, oauthOpts);
175
188
  out.log(`✓ credentials saved for '${opts.serverId}' (${authorization.metadata.issuer})`);
176
189
  persistLoginDiscovery(opts, authorization.metadata, out);
@@ -424,7 +437,10 @@ async function listenForCallback(
424
437
  }
425
438
  settle = resolve;
426
439
  reject = rejectWait;
427
- const timer = setTimeout(() => rejectWait(new Error(`authorization callback timed out after ${timeoutMs}ms`)), timeoutMs);
440
+ const timer = setTimeout(() => {
441
+ completed = true;
442
+ settleCallback(new Error(`authorization callback timed out after ${timeoutMs}ms`));
443
+ }, timeoutMs);
428
444
  (timer as unknown as { unref?: () => void }).unref?.();
429
445
  // ⛔ 성공·실패 어느 쪽으로 끝나든 타이머를 «반드시» 거둔다.
430
446
  clearWaitTimer = () => clearTimeout(timer as unknown as ReturnType<typeof setTimeout>);
@@ -21,6 +21,14 @@ export interface MsgCliDeps {
21
21
  registerLogSink?: () => Promise<unknown>;
22
22
  /** Wake the recipient after a durable post; never changes the post outcome. */
23
23
  wake?: (address: string, msgId: number, message: { from: string; kind?: string }, deps: WakeDeps) => Promise<WakeOutcome>;
24
+ /** Test seams for the existing self-send transport and the selected task-card ledger. */
25
+ readCard?: typeof import('../task-agent/task-hand.js').readTaskCard;
26
+ podFragmentsForRun?: typeof import('../harness/self-send-target.js').listPodFragmentsForRun;
27
+ sendPod?: typeof import('../harness/self-send-target.js').dispatchPodSelfSend;
28
+ runScreen?: typeof import('../self-implement/run-ledger.js').queryRunScreenKey;
29
+ sendMemo?: typeof import('../harness/control-inbox.js').enqueueControlMemo;
30
+ sendStop?: typeof import('../harness/control-inbox.js').enqueueSoftStop;
31
+ screenAlive?: (spaceId: string) => boolean;
24
32
  }
25
33
 
26
34
  type CommonOptions = { json?: boolean };
@@ -59,6 +67,83 @@ export function registerMsgCommands(program: Command, deps: MsgCliDeps = {}): vo
59
67
  const setExitCode = deps.setExitCode ?? ((code: number) => { process.exitCode = code; });
60
68
  const msg = program.command('msg').description('Durable seat-addressed messages');
61
69
 
70
+ // Called by both msg post and msg ask after their durable TA request is written.
71
+ const handleTaMessage = async (request: Message): Promise<void> => {
72
+ if (request.to !== 'TA' || request.from === 'TA' || request.replyTo !== undefined) return;
73
+ const command = /\b(stop|memo|status)\b/i.exec(request.body);
74
+ const cardId = /\bta-[a-zA-Z0-9][a-zA-Z0-9._-]*\b/.exec(request.body)?.[0]?.replace(/[.,!?]+$/, '');
75
+ if (!command || !cardId) return;
76
+ const { readTaskCard } = await import('../task-agent/task-hand.js');
77
+ const { queryRunScreenKey } = await import('../self-implement/run-ledger.js');
78
+ const { listHarnessScreens } = await import('../harness/harness-screen.js');
79
+ const { normalizeRunId } = await import('../harness/harness-space.js');
80
+ const { dispatchPodSelfSend, listPodFragmentsForRun } = await import('../harness/self-send-target.js');
81
+ const { enqueueControlMemo, enqueueSoftStop } = await import('../harness/control-inbox.js');
82
+ withStore(store => {
83
+ // Reserve one linked reply and pending delivery before touching another store or Pod.
84
+ const pending = store.db.transaction(() => {
85
+ // A concurrent sender may have claimed after an earlier read. Keep this
86
+ // check in the same write transaction as any pending reply change.
87
+ if (store.taDeliveryClaimState(request.id) === 'held') return null;
88
+ const reply = store.listReplies(request.id, 1)[0];
89
+ if (reply && store.taDeliveryStatus(request.id) !== 'pending') return null;
90
+ let delivery: (() => void) | undefined;
91
+ let deliveryReply: string | undefined;
92
+ let answer: string;
93
+ try {
94
+ const card = (deps.readCard ?? readTaskCard)(cardId);
95
+ if (!card) throw new Error(`카드 없음: ${cardId}`);
96
+ if (command[1]!.toLowerCase() === 'status') {
97
+ answer = `${card.id}: ${card.status}${card.runId ? ` · run ${card.runId}` : ''}`;
98
+ } else {
99
+ const runId = card.runId;
100
+ if (!runId || normalizeRunId(runId) !== runId) throw new Error(`${cardId}: 연결된 런 없음`);
101
+ const fragments = (deps.podFragmentsForRun ?? listPodFragmentsForRun)(runId);
102
+ const resolved = fragments.length === 0 ? (deps.runScreen ?? queryRunScreenKey)(runId) : null;
103
+ const screen = resolved?.logStoreStatus === 'read' ? resolved.screenKey : null;
104
+ if (fragments.length > 1 || (fragments.length === 0 && (!screen || !(deps.screenAlive ?? ((id: string) => listHarnessScreens().some(row => row.spaceId === id)))(screen)))) {
105
+ throw new Error(`${cardId}: 실행 중인 단일 런 공간을 찾을 수 없음`);
106
+ }
107
+ const space = fragments[0]?.spaceId ?? screen!;
108
+ const stop = command[1]!.toLowerCase() === 'stop';
109
+ const body = stop ? '' : request.body.replace(command[0], '').replace(cardId, '').trim().replace(/^[,.:;\s-]+/, '');
110
+ if (!stop && (!body || /[\r\n]/.test(body))) throw new Error('memo는 비어 있지 않은 한 줄이어야 한다');
111
+ const memo = { version: 1 as const, kind: 'supervisor', urgency: 'normal' as const, body };
112
+ answer = `${cardId}: run ${runId} 전달 여부 미확인 (${space}) — 자동 재시도 중지; 런 인박스를 확인하세요.`;
113
+ delivery = () => {
114
+ if (fragments.length) {
115
+ if (!(deps.sendPod ?? dispatchPodSelfSend)(space, stop ? { stop: true } : { memo })) throw new Error(`${cardId}: Pod 전달 실패`);
116
+ } else if (stop) (deps.sendStop ?? enqueueSoftStop)(space);
117
+ else (deps.sendMemo ?? enqueueControlMemo)(space, memo);
118
+ };
119
+ deliveryReply = stop ? `${cardId}: run ${runId} soft stop 요청 기록 (${space})`
120
+ : `${cardId}: run ${runId} 감독 메모 기록 (${space})`;
121
+ }
122
+ } catch (error) {
123
+ answer = `${cardId}: ${error instanceof Error ? error.message : String(error)}`;
124
+ }
125
+ if (delivery) store.setTaDeliveryStatus(request.id, 'pending');
126
+ if (reply) store.updateTaReply(request.id, answer);
127
+ else store.post({ from: 'TA', to: request.from, kind: 'reply', body: answer, replyTo: request.id });
128
+ return delivery && deliveryReply ? { delivery, reply: deliveryReply } : null;
129
+ }).immediate();
130
+ if (pending) {
131
+ const claim = store.claimTaDelivery(request.id);
132
+ if (!claim) return;
133
+ try {
134
+ pending.delivery();
135
+ store.settleTaDelivery(request.id, claim, pending.reply, true);
136
+ }
137
+ catch (error) {
138
+ // A transport error or failed DB settlement may follow a successful publication.
139
+ // Keep the claim and require inspection rather than send the same memo again.
140
+ store.markTaDeliveryUnknown(request.id, claim,
141
+ `${cardId}: 전달 여부 미확인 — 자동 재시도 중지: ${error instanceof Error ? error.message : String(error)}`);
142
+ }
143
+ }
144
+ });
145
+ };
146
+
62
147
  const run = (action: () => void | Promise<void>) => async () => {
63
148
  try { await action(); }
64
149
  catch (error) {
@@ -94,6 +179,7 @@ export function registerMsgCommands(program: Command, deps: MsgCliDeps = {}): vo
94
179
  ? store.post(envelope)
95
180
  : store.appendWithProvenance(envelope, opts.originKey));
96
181
  emit(posted, opts.json, () => out.log(formatMessage(posted)));
182
+ await handleTaMessage(posted); // msg post: process the durable TA request (including pending retry).
97
183
  const noBody = noReplyBodyNotice(to);
98
184
  if (noBody) out.error(noBody);
99
185
  // 저장 «뒤» 한 번 — 읽는 몸이 없다는 안내가 이미 나갔으면 깨움 경고는 겹쳐 내지 않는다.
@@ -273,6 +359,8 @@ export function registerMsgCommands(program: Command, deps: MsgCliDeps = {}): vo
273
359
  let store: MsgStore | undefined;
274
360
  try {
275
361
  const asked = withStore(ledger => ledger.post({ from, to, body: question }));
362
+ // msg ask uses the same saved-message handler before waiting for its linked reply.
363
+ await handleTaMessage(asked);
276
364
  const deadline = Date.now() + waitSeconds * 1000;
277
365
  let reply: Message | undefined;
278
366
  store = open();
package/src/cli/pr-cli.ts CHANGED
@@ -58,12 +58,16 @@ import { branchLineageSlug, findSiblingPrs } from './pr-lineage.js';
58
58
  import { parseReleaseNoteSection } from '../release-loop/release-note.js';
59
59
  import { landingFreezeMessage } from '../release-loop/landing-freeze.js';
60
60
  import { admitLandingMerge } from '../self-implement/frozen-merges.js';
61
- import { verifyAncestorAutoPass, verifyOverlapEvidence } from './pr-land-overlap-evidence.js';
61
+ import { verifyAllSameHeadReviews, verifyAncestorAutoPass, verifyOverlapEvidence } from './pr-land-overlap-evidence.js';
62
+ import { verifyVirtualRebasePatch } from './pr-land-virtual-rebase.js';
62
63
  import { observePrLandRefusal } from './pr-land-refusal.js';
63
64
  import { ensurePrLandHeavyRemote, type HeavyRemoteInput, type HeavyRemoteResult } from './pr-land-heavy-remote.js';
65
+ import { runHeavyOnPodShadow } from './pr-land-pod-shadow.js';
66
+ import type { LandingPodShadowInput, LandingPodShadowVerdict } from './pr-land-pod-shadow-job.js';
64
67
  import { taskAgentStatePath } from '../task-agent/task-hand.js';
65
68
  import { PR_LABEL_NAMES } from '../github/pr-labels.js';
66
69
  import { enqueueL8ShadowQueue, runL8ShadowQueue, shadowPrNumber, statusL8ShadowQueue, type L8ShadowQueueDeps } from '../self-implement/l8-merge-queue.js';
70
+ import { censusOpenPrs, guardNewPr, parseDiffHunks, readOpenPrs, type Seat } from '../pr-tool/census.js';
67
71
 
68
72
  export { branchLineageSlug, findSiblingPrs };
69
73
 
@@ -93,6 +97,8 @@ export interface PrLandOpts {
93
97
  overlapEvidence?: string;
94
98
  /** Pinned landing opt-in: run the heavy changed-file gate on node-b at the reviewed head and current main tip. */
95
99
  heavyRemote?: boolean;
100
+ /** Opt-in comparison of the heavy remote verdict with a Pod Job; the remote verdict still decides landing. */
101
+ heavyOnPodShadow?: boolean;
96
102
  }
97
103
 
98
104
  export interface PrGranularityOpts {
@@ -146,6 +152,7 @@ export interface PrLandDeps {
146
152
  runIosGate?: (out: { log: (message: string) => void; error: (message: string) => void }, changedFiles: readonly string[]) => boolean;
147
153
  runPwaGate?: (out: { log: (message: string) => void; error: (message: string) => void }, changedFiles: readonly string[]) => boolean;
148
154
  runHeavyRemote?: (input: HeavyRemoteInput) => HeavyRemoteResult;
155
+ runLandingPodShadow?: (input: LandingPodShadowInput) => Promise<LandingPodShadowVerdict>;
149
156
  isInteractive?: () => boolean;
150
157
  /** Clock for the recent-landings window (test seam · default Date.now). */
151
158
  now?: () => number;
@@ -818,13 +825,22 @@ function renderConflictRunIds(runIds: readonly { runId: string; status: string }
818
825
  return runIds.map(({ runId, status }) => `${runId}) status=${status}`).join(', ');
819
826
  }
820
827
 
828
+ function currentChangePaths(
829
+ run: CmdRunner, cwd: string, staged: PorcelainStatusRecord[] | null, base: string,
830
+ out: { log: (message: string) => void }, strict: true,
831
+ ): string[] | null;
832
+ function currentChangePaths(
833
+ run: CmdRunner, cwd: string, staged: PorcelainStatusRecord[] | null, base: string,
834
+ out: { log: (message: string) => void }, strict?: false,
835
+ ): string[];
821
836
  function currentChangePaths(
822
837
  run: CmdRunner,
823
838
  cwd: string,
824
839
  staged: PorcelainStatusRecord[] | null,
825
840
  base: string,
826
841
  out: { log: (message: string) => void },
827
- ): string[] {
842
+ strict = false,
843
+ ): string[] | null {
828
844
  const fromStatus = staged
829
845
  ? staged.flatMap(({ path, originalPath }) => (originalPath ? [path, originalPath] : [path]))
830
846
  : [];
@@ -847,6 +863,7 @@ function currentChangePaths(
847
863
  }
848
864
 
849
865
  const diff = run('git', ['diff', '--name-only', '--no-renames', `${comparisonBase}...HEAD`], { cwd });
866
+ if (strict && !diff.ok) return null;
850
867
  const fromDiff = diff.ok ? parseNameOnlyList(diff.out) : [];
851
868
  return unionPaths(fromStatus, fromDiff);
852
869
  }
@@ -1014,12 +1031,13 @@ function emitLandingOverlapAdvisory(
1014
1031
  currentFiles: readonly string[],
1015
1032
  out: { log: (message: string) => void },
1016
1033
  overlappingLandings: string[] = [],
1034
+ resolvedLandings?: NonNullable<ReturnType<typeof collectResolvedBaseLandings>>,
1017
1035
  ): boolean {
1018
1036
  if (currentFiles.length === 0) {
1019
1037
  record('overlap', true, { outcome: 'no-changed-files' });
1020
1038
  return false;
1021
1039
  }
1022
- const commits = collectResolvedBaseLandings(run, cwd, DEFAULT_GRANULARITY_SINCE, base);
1040
+ const commits = resolvedLandings ?? collectResolvedBaseLandings(run, cwd, DEFAULT_GRANULARITY_SINCE, base);
1023
1041
  if (commits === null) {
1024
1042
  record('overlap', false, { outcome: 'lookup-failed' });
1025
1043
  return false;
@@ -1041,6 +1059,88 @@ function emitLandingOverlapAdvisory(
1041
1059
  return false;
1042
1060
  }
1043
1061
 
1062
+ /** The pinned overlap evidence decision is shared by landing and its read-only preview. */
1063
+ function verifyPinnedOverlapDecision(input: {
1064
+ opts: PrLandOpts;
1065
+ deps: PrLandDeps;
1066
+ run: CmdRunner;
1067
+ cwd: string;
1068
+ base: string;
1069
+ readFile: (path: string) => string;
1070
+ overlappingLandings: readonly string[];
1071
+ decision: OverlapLandingDecisionOutcome | undefined;
1072
+ out: { log: (message: string) => void; error: (message: string) => void };
1073
+ refuse: (message: string) => void;
1074
+ }): boolean {
1075
+ const { opts, deps, run, cwd, base, readFile, overlappingLandings, decision, out, refuse } = input;
1076
+ if (decision === undefined || decision === 'user-merge') return true;
1077
+ let accepted = false;
1078
+ let ancestorResyncNeeded = false;
1079
+ if (decision === 'unavailable' && opts.overlapEvidence !== undefined) {
1080
+ const ref = resolveRemoteBranchRef(run, cwd, base);
1081
+ const verdict = verifyOverlapEvidence({
1082
+ evidencePath: opts.overlapEvidence, pr: Number(opts.pr), expectedHead: opts.expectedHead!,
1083
+ remote: ref.remote, branch: ref.branch, cwd, run, readFile,
1084
+ reviewResultsDir: deps.reviewResultsDir ?? join(dirname(taskAgentStatePath()), 'review-results'),
1085
+ listDir: (dir) => readdirSync(dir), reviewMtime: (path) => statSync(path).mtimeMs,
1086
+ reviewRealPath: (path) => realpathSync(path), overlappingLandings,
1087
+ });
1088
+ accepted = verdict.ok;
1089
+ if (verdict.ok) {
1090
+ out.log(verdict.mode === 'already-ancestor'
1091
+ ? `✓ overlap-evidence: already-ancestor — 겹친 최근 착지 ${overlappingLandings.length}개가 전부 head ${opts.expectedHead!.slice(0, 12)} 의 조상 · review pass must-fix 0 (${verdict.reviewResult})`
1092
+ : verdict.mode === 'base-advanced-disjoint'
1093
+ ? `✓ overlap-evidence: base-advanced-disjoint — gate base ${verdict.gateBase.slice(0, 12)} ⊂ head ${opts.expectedHead!.slice(0, 12)} · ${ref.remote}/${ref.branch} ${verdict.baseTip.slice(0, 12)} 까지 ${verdict.windowCommits}개 커밋이 PR 파일을 안 건드린다 · review pass|warn must-fix 0 (${verdict.reviewResult})`
1094
+ : `✓ overlap-evidence: ${ref.remote}/${ref.branch} ${verdict.baseTip.slice(0, 12)} ⊂ head ${opts.expectedHead!.slice(0, 12)} · gate passed on that base · review pass must-fix 0 (${verdict.reviewResult})`);
1095
+ } else refuse(`✗ overlap-evidence: ${verdict.reason}`);
1096
+ } else if (decision === 'unavailable') {
1097
+ const verdict = verifyAncestorAutoPass({
1098
+ pr: Number(opts.pr), expectedHead: opts.expectedHead!, cwd, run, readFile, overlappingLandings,
1099
+ reviewResultsDir: deps.reviewResultsDir ?? join(dirname(taskAgentStatePath()), 'review-results'),
1100
+ listDir: (dir) => readdirSync(dir),
1101
+ });
1102
+ accepted = verdict.ok;
1103
+ if (verdict.ok) {
1104
+ out.log(`✓ overlap-evidence: already-ancestor-auto — 겹친 최근 착지 ${overlappingLandings.length}개가 전부 head ${opts.expectedHead!.slice(0, 12)} 의 조상 · review pass|warn must-fix 0 (${verdict.reviewResult})`);
1105
+ } else {
1106
+ ancestorResyncNeeded = verdict.reason.startsWith('ancestor-auto-not-ancestor:');
1107
+ if (ancestorResyncNeeded) {
1108
+ const ref = resolveRemoteBranchRef(run, cwd, base);
1109
+ const remote = run('git', ['ls-remote', ref.remote, `refs/heads/${ref.branch}`], { cwd });
1110
+ const baseTip = remote.ok ? remote.out.trim().split(/\s+/u, 1)[0] ?? '' : '';
1111
+ const local = run('git', ['rev-parse', '--verify', `refs/remotes/${ref.remote}/${ref.branch}`], { cwd });
1112
+ const reviews = verifyAllSameHeadReviews({
1113
+ pr: Number(opts.pr), expectedHead: opts.expectedHead!, readFile,
1114
+ reviewResultsDir: deps.reviewResultsDir ?? join(dirname(taskAgentStatePath()), 'review-results'),
1115
+ listDir: (dir) => readdirSync(dir),
1116
+ });
1117
+ const patch = reviews.ok && /^[a-f0-9]{40}$/iu.test(baseTip) && local.ok && local.out.trim() === baseTip
1118
+ ? verifyVirtualRebasePatch({ cwd, baseTip, head: opts.expectedHead! })
1119
+ : { ok: false as const, reason: reviews.ok ? 'base-stale-or-unmeasured' : reviews.reason };
1120
+ accepted = patch.ok;
1121
+ ancestorResyncNeeded = !accepted;
1122
+ record('virtual-rebase', patch.ok, {
1123
+ pr: Number(opts.pr), head: opts.expectedHead, baseTip: baseTip || null,
1124
+ reason: patch.ok ? 'same-patch-id' : patch.reason,
1125
+ reviewResult: reviews.ok ? reviews.reviewResult : null,
1126
+ });
1127
+ if (patch.ok) {
1128
+ out.log(`✓ overlap-evidence: virtual-rebase — ${ref.remote}/${ref.branch} ${baseTip.slice(0, 12)} 와 head ${opts.expectedHead!.slice(0, 12)} 충돌 없음 · patch-id ${patch.patchId.slice(0, 12)} 동일 · review pass|warn must-fix 0 (${reviews.reviewResult})`);
1129
+ } else refuse(`✗ virtual-rebase: ${patch.reason} · ${verdict.reason}`);
1130
+ } else refuse(`✗ ancestor-auto: ${verdict.reason}`);
1131
+ }
1132
+ }
1133
+ if (!accepted) {
1134
+ if (ancestorResyncNeeded && !opts.dryRun) {
1135
+ const marked = run('gh', ['pr', 'edit', String(opts.pr), '--add-label', PR_LABEL_NAMES.needsRebase], { cwd });
1136
+ record('resync-marker', marked.ok, { pr: Number(opts.pr), reason: 'ancestor-auto-not-ancestor' });
1137
+ if (!marked.ok) out.error('⚠ resync-marker: needs-rebase 라벨을 남기지 못했습니다');
1138
+ }
1139
+ out.error('✗ expected-head: overlap merge approval unavailable for the reviewed head');
1140
+ }
1141
+ return accepted;
1142
+ }
1143
+
1044
1144
  const SOURCE_SPLIT_PR_LIST_LIMIT = 200;
1045
1145
  /**
1046
1146
  * merged 조회의 «폭주 방지» 절대 상한 — ⛔ 창을 덮는 값이 «아니라» 그 위의 천장이다.
@@ -1217,6 +1317,10 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1217
1317
  out.error('✗ heavy-remote: --pr ⊕ --expected-head 머리 고정 착지에서만 쓴다.');
1218
1318
  return 1;
1219
1319
  }
1320
+ if (opts.heavyOnPodShadow && !opts.heavyRemote) {
1321
+ out.error('✗ heavy-on-pod-shadow: --heavy-remote 머리 고정 착지에서만 쓴다.');
1322
+ return 1;
1323
+ }
1220
1324
 
1221
1325
  const readFile = deps.readFile ?? ((path: string) => readFileSync(path, 'utf8'));
1222
1326
  let title = opts.title;
@@ -1310,8 +1414,8 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1310
1414
  out.error('✗ dry-run: --hold 는 머리 고정 읽기 전용 예행과 함께 사용할 수 없습니다.');
1311
1415
  return 1;
1312
1416
  }
1313
- if (opts.overlapEvidence !== undefined) {
1314
- out.error('✗ dry-run: --overlap-evidence 는 머리 고정 읽기 전용 예행에서 사용할 수 없습니다.');
1417
+ if (opts.overlapEvidence !== undefined && !opts.overlapEvidence.trim()) {
1418
+ out.error('✗ overlap-evidence: --overlap-evidence <file> 는 비어 있을 수 없습니다.');
1315
1419
  return 1;
1316
1420
  }
1317
1421
  const inspected = inspectPinnedPr(run, cwd, pr, opts.expectedHead!);
@@ -1322,8 +1426,55 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1322
1426
  for (const reason of reasons) out.log(`[dry-run] ✗ preflight: ${reason}`);
1323
1427
  if (reasons.includes('PR is draft')) out.log(`[dry-run] 선행: eln gh pr ready ${pr}`);
1324
1428
  if (reasons.length === 0) out.log('[dry-run] ✓ preflight: PR OPEN non-draft, matching PR/local HEAD and branch, clean worktree');
1325
- out.log('[dry-run] Remaining landing gates, freeze, overlap and merge: UNMEASURED; no PR or git state changed.');
1326
- return reasons.length === 0 ? 0 : 1;
1429
+ if (reasons.length > 0) return 1;
1430
+ // A dry-run may inspect the remote tip but must not update refs, FETCH_HEAD, objects or PR labels.
1431
+ const readOnlyRun: CmdRunner = (command, args, options) => {
1432
+ if ((command === 'git' && /^(fetch|pull|push|merge|commit|checkout|switch|worktree|update-ref|reset|apply|am|rebase)$/u.test(args[0] ?? ''))
1433
+ || (command === 'gh' && args[0] === 'pr' && /^(edit|ready|merge|create|close|reopen)$/u.test(args[1] ?? ''))) {
1434
+ return { ok: false, out: '', err: 'dry-run forbids mutation' };
1435
+ }
1436
+ return run(command, args, options);
1437
+ };
1438
+ const base = (deps.resolveBase ?? resolveDeliverableBase)(readOnlyRun, cwd, opts.base);
1439
+ if (!base) { out.error('✗ base: 비교 base를 선택하지 못했습니다.'); return 1; }
1440
+ const ref = resolveRemoteBranchRef(readOnlyRun, cwd, base);
1441
+ const measuredBase = `refs/remotes/${ref.remote}/${ref.branch}`;
1442
+ const remoteTip = readOnlyRun('git', ['ls-remote', ref.remote, `refs/heads/${ref.branch}`], { cwd });
1443
+ const tip = remoteTip.ok ? remoteTip.out.trim().split(/\s+/u, 1)[0] : undefined;
1444
+ const localTip = readOnlyRun('git', ['rev-parse', '--verify', measuredBase], { cwd });
1445
+ if (!tip || !/^[a-f0-9]{40}$/iu.test(tip) || !localTip.ok || localTip.out.trim() !== tip) {
1446
+ out.error(`✗ overlap-preflight: ${base} 최신 SHA를 로컬에서 읽지 못했다. 읽기 전용 예행은 ref를 갱신하지 않는다.`);
1447
+ return 1;
1448
+ }
1449
+ const staged = stagedPaths(readOnlyRun, cwd);
1450
+ if (staged === null) {
1451
+ out.error('✗ overlap-preflight: PR 변경 파일을 읽지 못했다. 겹침을 미측정 상태로 둔다.');
1452
+ return 1;
1453
+ }
1454
+ const changed = readOnlyRun('git', ['diff', '--name-only', '--no-renames', `${measuredBase}...HEAD`], { cwd });
1455
+ if (!changed.ok) {
1456
+ out.error('✗ overlap-preflight: PR 변경 파일을 읽지 못했다. 겹침을 미측정 상태로 둔다.');
1457
+ return 1;
1458
+ }
1459
+ const changedPaths = unionPaths(staged.flatMap(({ path, originalPath }) => originalPath ? [path, originalPath] : [path]), parseNameOnlyList(changed.out));
1460
+ const landings = collectResolvedBaseLandings(readOnlyRun, cwd, DEFAULT_GRANULARITY_SINCE, measuredBase);
1461
+ if (landings === null) {
1462
+ out.error('✗ overlap-preflight: 최근 착지 조회가 실패했다. 겹침을 미측정 상태로 둔다.');
1463
+ return 1;
1464
+ }
1465
+ const overlappingLandings: string[] = [];
1466
+ const overlapFound = emitLandingOverlapAdvisory(readOnlyRun, cwd, measuredBase, changedPaths, out, overlappingLandings, landings);
1467
+ emitSiblingPrAdvisory(branch!, deps.listOpenPrs ?? (() => lookupOpenPrs(readOnlyRun, cwd)), out);
1468
+ if (overlapFound && !verifyPinnedOverlapDecision({
1469
+ opts, deps, run: readOnlyRun, cwd, base, readFile, overlappingLandings,
1470
+ decision: 'unavailable', out, refuse: out.error,
1471
+ })) {
1472
+ out.log('[dry-run] Remaining landing gates, freeze and merge: UNMEASURED; no PR or git state changed.');
1473
+ return 1;
1474
+ }
1475
+ out.log(`[dry-run] ✓ overlap: ${overlapFound ? 'evidence accepted' : 'no recent overlapping landing'}`);
1476
+ out.log('[dry-run] Remaining landing gates, freeze and merge: UNMEASURED; no PR or git state changed.');
1477
+ return 0;
1327
1478
  }
1328
1479
  if (opts.overlapEvidence !== undefined && (!pinned || !opts.overlapEvidence.trim())) {
1329
1480
  out.error('✗ overlap-evidence: --overlap-evidence <file> 는 --pr ⊕ --expected-head 머리 고정 착지에서만 쓴다.');
@@ -1592,7 +1743,12 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1592
1743
  }
1593
1744
  // Pinned landings reject a known non-ancestor before local or remote heavy gates.
1594
1745
  // Unpinned landings keep their existing gate and advisory order.
1595
- let changedPaths = pinned ? currentChangePaths(run, cwd, staged, base, out) : [];
1746
+ const initialChangedPaths = pinned ? currentChangePaths(run, cwd, staged, base, out, true) : [];
1747
+ if (initialChangedPaths === null) {
1748
+ out.error('✗ overlap-preflight: PR 변경 파일을 읽지 못했다. 겹침을 미측정 상태로 두고 무거운 게이트를 시작하지 않는다.');
1749
+ return 1;
1750
+ }
1751
+ let changedPaths: string[] = initialChangedPaths;
1596
1752
  let hold = !!opts.hold;
1597
1753
  const checkOverlap = async (): Promise<number | undefined> => {
1598
1754
  const overlappingLandings: string[] = [];
@@ -1627,54 +1783,7 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1627
1783
  });
1628
1784
  }
1629
1785
  hold = !!opts.hold || overlapDecision?.outcome === 'user-hold';
1630
- // TA-LAND-OVERLAP — 비대화형 «승인 불가»만 증거로 대신한다(사람의 hold 는 증거로 뒤집지 않는다) · 증거가 없거나 어긋나면 종전 거부 그대로.
1631
- let overlapEvidenceAccepted = false;
1632
- let ancestorResyncNeeded = false;
1633
- if (pinned && overlapDecision?.outcome === 'unavailable' && opts.overlapEvidence !== undefined) {
1634
- const ref = resolveRemoteBranchRef(run, cwd, base);
1635
- const verdict = verifyOverlapEvidence({
1636
- evidencePath: opts.overlapEvidence, pr: Number(opts.pr), expectedHead: opts.expectedHead!,
1637
- remote: ref.remote, branch: ref.branch, cwd, run, readFile,
1638
- reviewResultsDir: deps.reviewResultsDir ?? join(dirname(taskAgentStatePath()), 'review-results'),
1639
- listDir: (dir) => readdirSync(dir), reviewMtime: (path) => statSync(path).mtimeMs,
1640
- reviewRealPath: (path) => realpathSync(path), overlappingLandings,
1641
- });
1642
- overlapEvidenceAccepted = verdict.ok;
1643
- if (verdict.ok) {
1644
- out.log(verdict.mode === 'already-ancestor'
1645
- ? `✓ overlap-evidence: already-ancestor — 겹친 최근 착지 ${overlappingLandings.length}개가 전부 head ${opts.expectedHead!.slice(0, 12)} 의 조상 · review pass must-fix 0 (${verdict.reviewResult})`
1646
- : verdict.mode === 'base-advanced-disjoint'
1647
- ? `✓ overlap-evidence: base-advanced-disjoint — gate base ${verdict.gateBase.slice(0, 12)} ⊂ head ${opts.expectedHead!.slice(0, 12)} · ${ref.remote}/${ref.branch} ${verdict.baseTip.slice(0, 12)} 까지 ${verdict.windowCommits}개 커밋이 PR 파일을 안 건드린다 · review pass|warn must-fix 0 (${verdict.reviewResult})`
1648
- : `✓ overlap-evidence: ${ref.remote}/${ref.branch} ${verdict.baseTip.slice(0, 12)} ⊂ head ${opts.expectedHead!.slice(0, 12)} · gate passed on that base · review pass must-fix 0 (${verdict.reviewResult})`);
1649
- }
1650
- else refuse(`✗ overlap-evidence: ${verdict.reason}`);
1651
- } else if (pinned && overlapDecision?.outcome === 'unavailable') {
1652
- // 증거 파일이 없을 때 — 겹친 착지가 전부 머리의 조상이고 표준 자리의 리뷰가 pass|warn ⊕ must-fix 0 이면 통과(아니면 종전 거부).
1653
- const verdict = verifyAncestorAutoPass({
1654
- pr: Number(opts.pr), expectedHead: opts.expectedHead!, cwd, run, readFile, overlappingLandings,
1655
- reviewResultsDir: deps.reviewResultsDir ?? join(dirname(taskAgentStatePath()), 'review-results'),
1656
- listDir: (dir) => readdirSync(dir),
1657
- });
1658
- overlapEvidenceAccepted = verdict.ok;
1659
- if (verdict.ok) {
1660
- out.log(`✓ overlap-evidence: already-ancestor-auto — 겹친 최근 착지 ${overlappingLandings.length}개가 전부 head ${opts.expectedHead!.slice(0, 12)} 의 조상 · review pass|warn must-fix 0 (${verdict.reviewResult})`);
1661
- }
1662
- else {
1663
- refuse(`✗ ancestor-auto: ${verdict.reason}`);
1664
- ancestorResyncNeeded = verdict.reason.startsWith('ancestor-auto-not-ancestor:');
1665
- }
1666
- }
1667
- if (pinned && overlapDecision && overlapDecision.outcome !== 'user-merge' && !overlapEvidenceAccepted) {
1668
- // A clean GitHub PR can still be behind a recently landed overlapping head. Preserve the cue
1669
- // across hosts; the current steward tick acts only if it can also prove local run ownership.
1670
- if (ancestorResyncNeeded && !opts.dryRun) {
1671
- const marked = run('gh', ['pr', 'edit', String(opts.pr), '--add-label', PR_LABEL_NAMES.needsRebase], { cwd });
1672
- record('resync-marker', marked.ok, { pr: Number(opts.pr), reason: 'ancestor-auto-not-ancestor' });
1673
- if (!marked.ok) out.error('⚠ resync-marker: needs-rebase 라벨을 남기지 못했습니다');
1674
- }
1675
- out.error('✗ expected-head: overlap merge approval unavailable for the reviewed head');
1676
- return 1;
1677
- }
1786
+ if (pinned && !verifyPinnedOverlapDecision({ opts, deps, run, cwd, base, readFile, overlappingLandings, decision: overlapDecision?.outcome, out, refuse })) return 1;
1678
1787
  return undefined;
1679
1788
  };
1680
1789
  if (pinned && (await checkOverlap()) !== undefined) return 1;
@@ -1724,6 +1833,18 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1724
1833
  verifiedHeavyBase = main;
1725
1834
  out.log(`✓ heavy-remote: host=${verdict.host ?? 'unknown'} head=${opts.expectedHead!.slice(0, 12)} main=${main.slice(0, 12)} source=${verdict.source} elapsed=${verdict.elapsedMs}ms`);
1726
1835
  out.log(`✓ typecheck-roots: ${JSON.stringify(verdict.rootPlan ?? { mode: 'not-applicable', roots: null, promoted: false, reason: 'no-root-plan-in-gate-output' })}`);
1836
+ if (opts.heavyOnPodShadow) {
1837
+ await runHeavyOnPodShadow({
1838
+ enabled: true, pr: Number(opts.pr), head: opts.expectedHead!,
1839
+ local: { measured: verdict.rootPlan != null, ok: verdict.ok, rootPlan: verdict.rootPlan ?? null },
1840
+ runPod: async () => {
1841
+ const runPod = deps.runLandingPodShadow ?? (await import('./pr-land-pod-shadow-job.js')).runLandingPodShadowJob;
1842
+ return runPod({ head: opts.expectedHead!, main });
1843
+ },
1844
+ log: (category, event, data) => debug.log(category, event, { ...data, main, phase: 'initial' }),
1845
+ warn: (message) => out.error(`⚠ heavy-on-pod-shadow: ${message}`),
1846
+ });
1847
+ }
1727
1848
  }
1728
1849
  // Call immediately before the first mergePrOutcome and again before every UNKNOWN retry.
1729
1850
  // A move during the wait is the same race as a move during the gate: rerun or fail closed.
@@ -1751,7 +1872,12 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1751
1872
  };
1752
1873
  const recheckOverlapAtBase = async (currentBase: string): Promise<number | undefined> => {
1753
1874
  if (currentBase === overlapCheckedBase) return undefined;
1754
- changedPaths = currentChangePaths(run, cwd, staged, base, out);
1875
+ const refreshedPaths = currentChangePaths(run, cwd, staged, base, out, true);
1876
+ if (refreshedPaths === null) {
1877
+ out.error('✗ overlap-preflight: 움직인 base의 PR 변경 파일을 읽지 못했다. 재게이트하지 않는다.');
1878
+ return 1;
1879
+ }
1880
+ changedPaths = refreshedPaths;
1755
1881
  const refused = await checkOverlap();
1756
1882
  if (refused !== undefined) return refused;
1757
1883
  overlapCheckedBase = currentBase;
@@ -2294,6 +2420,36 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
2294
2420
 
2295
2421
  export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queueDeps: L8ShadowQueueDeps = {}): void {
2296
2422
  const pr = program.command('pr').description('PR landing commands');
2423
+ const prToolRun = deps.run ?? defaultCmdRunner;
2424
+ const prToolOut = deps.out ?? liveOut;
2425
+ const prToolExit = deps.setExitCode ?? ((code: number) => { process.exitCode = code; });
2426
+ pr.command('census')
2427
+ .description('열린 PR 전체·골 문서만·2일 무커밋 draft·미닫힌 superseded 집계')
2428
+ .option('--cwd <path>', '저장소 경로')
2429
+ .action((opts: { cwd?: string }) => {
2430
+ const result = censusOpenPrs(readOpenPrs(prToolRun, { cwd: opts.cwd, includeDraftCommitDates: true }));
2431
+ prToolOut.log(JSON.stringify(result));
2432
+ if (result.status === 'unknown') prToolExit(1);
2433
+ });
2434
+ pr.command('open-guard')
2435
+ .description('새 PR 전에 같은 파일 OPEN PR·골 문서만·자리별 상한 검사')
2436
+ .option('--cwd <path>', '작업 트리 경로')
2437
+ .option('--base <ref>', '비교 base ref', 'origin/main')
2438
+ .option('--seat <seat>', 'PR 소유 자리(OP|TC|MK|UX)')
2439
+ .option('--cell <id>', '릴리스 칸 id (같은 칸 OPEN PR 검사)')
2440
+ .option('--seat-cap <number>', '자리별 열린 PR 경고 상한', '30')
2441
+ .action((opts: { cwd?: string; base: string; seat?: string; cell?: string; seatCap: string }) => {
2442
+ const cwd = opts.cwd ?? process.cwd();
2443
+ const diff = prToolRun('git', ['-C', cwd, 'diff', '--name-only', '-z', `${opts.base}...HEAD`]);
2444
+ const files = diff.ok ? diff.out.split('\0').filter(Boolean) : null;
2445
+ const patch = prToolRun('git', ['-C', cwd, 'diff', '--unified=0', `${opts.base}...HEAD`]);
2446
+ const inventory = readOpenPrs(prToolRun, { cwd, ...(files ? { candidateFiles: files } : {}) });
2447
+ const result = guardNewPr({ files: patch.ok ? files : null, seat: opts.seat as Seat | undefined, seatCap: Number(opts.seatCap), cellId: opts.cell, hunks: patch.ok ? parseDiffHunks(patch.out) : undefined }, inventory);
2448
+ // Inspection never spends the three-creation unmeasured allowance.
2449
+ // Only pr-manager records an actual new-PR attempt in that ledger.
2450
+ prToolOut.log(JSON.stringify(result));
2451
+ if (result.status !== 'allow') prToolExit(1);
2452
+ });
2297
2453
  const queue = pr.command('queue').description('Shadow merge queue (never lands PRs)');
2298
2454
  const queueAction = async (action: () => Promise<unknown>) => {
2299
2455
  try {
@@ -2314,6 +2470,7 @@ export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queu
2314
2470
  .option('--pr <number>', '기존 PR 번호 고정 (--expected-head 와 함께)')
2315
2471
  .option('--expected-head <sha>', '리뷰된 PR 머리 SHA 고정 (--pr 와 함께)')
2316
2472
  .option('--heavy-remote', '머리 고정 착지의 무거운 게이트를 node-b·node-c 중 빈 호스트에서 실행; head⊕main 증거가 없거나 실패하면 거부(로컬 폴백 없음)')
2473
+ .option('--heavy-on-pod-shadow', '--heavy-remote 판정을 유지하고 같은 head/main의 Pod 타입·변경 시험 결과를 비교만 한다')
2317
2474
  .option('--dry-run', '변경 없이 landing 계획만 출력')
2318
2475
  .option('--hold', 'PR을 생성 또는 갱신한 뒤 병합하지 않고 쌓아 둔다')
2319
2476
  .option('--title <title>', 'PR title')
@@ -5,7 +5,7 @@ import { randomBytes } from 'node:crypto';
5
5
  import { effectiveInstanceRoot } from '../instance/resolve.js';
6
6
  import { getUserConfig } from '../user-config.js';
7
7
  import { debug, redactSecretText } from '../debug/log.js';
8
- import { realGateRemoteRunner, resolveGateRemoteSettings, runOnRemote, type GateRemoteRunner, type RemoteRunOutcome } from '../self-implement/gate-remote.js';
8
+ import { gateRemoteHostCap, realGateRemoteRunner, resolveGateRemoteSettings, runOnRemote, type GateRemoteRunner, type RemoteRunOutcome } from '../self-implement/gate-remote.js';
9
9
 
10
10
  const SHA = /^[0-9a-f]{40}$/i;
11
11
  // WSL is excluded until its push permissions and gate environment are proven stable.
@@ -179,7 +179,7 @@ export function ensurePrLandHeavyRemote(input: HeavyRemoteInput, deps: HeavyRemo
179
179
  try {
180
180
  outcome = (deps.runRemote ?? runOnRemote)({
181
181
  repo: input.repo, host, mirror: settings.mirror, commit: input.head,
182
- refs: [input.main], hostCap: settings.hostCap, installPwa: true,
182
+ refs: [input.main], hostCap: gateRemoteHostCap(settings, host), installPwa: true, stableCheckout: true,
183
183
  // Test the tree GitHub will merge: scratch-checkout the reviewed head, merge the pinned main tip there,
184
184
  // then run typecheck and self gate (changed tests and PWA reach/build) at that exact pair.
185
185
  // The detached integration commit stays on the selected host and never changes the PR branch.