elanous 0.2.32 → 0.2.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (753) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.js → 0368f25d-ad84af92fefee68f.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +32 -0
  7. package/apps/pwa/out/_next/static/chunks/{5525.86debf231e181813.js → 1530.0e612369b6fd7ea0.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +41 -0
  9. package/apps/pwa/out/_next/static/chunks/{7391.ebae168025c91b6a.js → 1674.2a65fd5668e1cc5f.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +24 -0
  11. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +74 -0
  12. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{7947-d0759430f8042240.js → 1993-c0007b7ad0c0ef41.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{60fb96c9.360b01d8d4927b7b.js → 1c735de4.f993a30bbd3c57c4.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.js → 2018.a741297bce759490.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +148 -0
  23. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{3902.e1e71aaac850a045.js → 2625.5d870aa999f33db1.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +77 -0
  26. package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +62 -0
  29. package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +90 -0
  31. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{4174.92ed04922709ac9e.js → 3408.21d1570602f4b6c0.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3589.5444a06bcf6e775c.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/359-2250789a2d3499e7.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +36 -0
  37. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{9398-6aed28f0a96d0d6f.js → 3677-4215f826f6aa68e5.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +79 -0
  40. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +122 -0
  42. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{7371.80c05c653b08e907.js → 4346.8601952e73bf5803.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +286 -0
  46. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +24 -0
  49. package/apps/pwa/out/_next/static/chunks/{2940-619bfd8ef337c611.js → 4705-194e64e47ca0fbdb.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.js → 4718-17d2af636796a330.js} +3 -3
  51. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{7502.ccd5b8065545edd0.js → 5101.e32282718f99ed6f.js} +2 -2
  57. package/apps/pwa/out/_next/static/chunks/{2001.6c7e0fd02190886c.js → 5154.a118f3957ed14e36.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +23 -0
  61. package/apps/pwa/out/_next/static/chunks/{5173-233188df2f42c626.js → 5483-dd5d7697f6bdb106.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +94 -0
  63. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{3267c0e6.d34854e7b3984a6e.js → 56d372f2.681ab4ec4c998fae.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +287 -0
  67. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/{6433.fc573af22bbc9ab7.js → 6236.e18cced2d5ba6afb.js} +17 -17
  74. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +8 -0
  75. package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +27 -0
  78. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +93 -0
  80. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/{6544cb48.a87fe20ddf137be2.js → 6b89c8bd.24df687a820500b3.js} +1 -1
  83. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +149 -0
  87. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +104 -0
  88. package/apps/pwa/out/_next/static/chunks/{2871.0bca6137343b3f76.js → 7385.50a308a477bdfc21.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.js → 7644.17e37ba6f1d4226e.js} +4 -4
  90. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/{8018.a32663f04a6fc5f9.js → 8219.baa715d1deee80e2.js} +1 -1
  95. package/apps/pwa/out/_next/static/chunks/{4111.2bfedbb233ad206b.js → 8256.e3ac8421a71f82f4.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 8444.4c26b379ca2b9596.js} +17 -17
  100. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +226 -0
  101. package/apps/pwa/out/_next/static/chunks/8557-e7898769499cd56f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +64 -0
  104. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{6092.a7f99e68b188ca66.js → 8637.47f5b35afcae5e6b.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{3278.2e5d15b53a4091c8.js → 9214.63a510d39178e997.js} +2 -2
  111. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +115 -0
  112. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{9221.7d22eaf353a2d4e7.js → 938.66ad1ef0e5abae1c.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.js → 9512.5a76207a730e0491.js} +2 -2
  115. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{69-0a2c8209c6d4a158.js → 967-2aa39b2d04b4c690.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{7862.30a8d6482bb238eb.js → 9952.5daf5f94063a2b3e.js} +1 -1
  120. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/{page-a27b1e5a0d1b308f.js → page-406b47745b53f269.js} +1 -1
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/{page-32866485913d6a04.js → page-47c5d4db587266bd.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-04d00ae9b0890349.js → page-dc0a532f5b9196ec.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{7a1887c4.f36b88fba31da8fd.js → b2f6ba4d.fb56fdbbf798df33.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/b6705a4f-b9a9047de9eecfd0.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/{b313b242.cb1265eea908db61.js → cbe38a15.5a032598e39970c6.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → da5176c6.6773b6c5994e1d99.js} +7 -7
  178. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +1 -0
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +22 -22
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +22 -22
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +22 -22
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +21 -21
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +21 -21
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +22 -22
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +21 -21
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +22 -22
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +22 -22
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +21 -21
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +22 -22
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +22 -22
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +22 -22
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +22 -22
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +21 -21
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +21 -21
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +22 -22
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +22 -22
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +22 -22
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +21 -21
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +21 -21
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +22 -22
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +22 -22
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +21 -21
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +21 -21
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +21 -21
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +22 -22
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +22 -22
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +21 -21
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +22 -22
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +22 -22
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +22 -22
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +22 -22
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +22 -22
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +21 -21
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +22 -22
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +22 -22
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +22 -22
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +22 -22
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +22 -22
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +22 -22
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +22 -22
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +22 -22
  277. package/bin/elanous.mjs +10 -2
  278. package/catalog/providers/opengateway.yaml +25 -0
  279. package/docs/goal-context/01-goal-authoring-checks.md +8 -0
  280. package/docs/goal-context/03-verification-menu.md +24 -0
  281. package/docs/goal-context/04-mock-scenarios.md +100 -0
  282. package/docs/goal-context/README.md +5 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/default-loop.yaml +76 -5
  285. package/graphs/document-loop.yaml +71 -4
  286. package/graphs/implement-loop.yaml +59 -4
  287. package/graphs/journey/SCENARIOS.md +33 -0
  288. package/graphs/journey/recipes.yaml +1 -0
  289. package/graphs/journey/ta-journey.yaml +94 -0
  290. package/graphs/journey/units/author/author.yaml +20 -0
  291. package/graphs/journey/units/author/recipes.yaml +2 -0
  292. package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
  293. package/graphs/journey/units/author-dialogue/observe.ts +96 -0
  294. package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
  295. package/graphs/journey/units/green/green.yaml +20 -0
  296. package/graphs/journey/units/green/recipes.yaml +2 -0
  297. package/graphs/journey/units/pr/pr.yaml +20 -0
  298. package/graphs/journey/units/pr/recipes.yaml +2 -0
  299. package/graphs/journey/units/remember/recipes.yaml +2 -0
  300. package/graphs/journey/units/remember/remember.yaml +20 -0
  301. package/graphs/operate-loop.yaml +71 -4
  302. package/graphs/overlays/stop-heal-ladder.yaml +1 -1
  303. package/graphs/release-rehearsal/recipes.yaml +1 -1
  304. package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
  305. package/graphs/research-loop.yaml +159 -4
  306. package/graphs/test-diet/test-diet.yaml +3 -0
  307. package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
  308. package/graphs/units/dispatch-pod/recipes.yaml +14 -0
  309. package/graphs/units/entry/entry.yaml +50 -0
  310. package/graphs/units/entry/recipes.yaml +14 -0
  311. package/graphs/units/harvest/harvest.yaml +25 -0
  312. package/graphs/units/harvest/recipes.yaml +4 -0
  313. package/graphs/units/land/land.yaml +45 -0
  314. package/graphs/units/land/recipes.yaml +3 -0
  315. package/graphs/units/recipes.yaml +7 -0
  316. package/graphs/units/recover.yaml +39 -0
  317. package/graphs/units/reflect/recipes.yaml +3 -0
  318. package/graphs/units/reflect/reflect.yaml +15 -0
  319. package/graphs/units/task-agent-recover-review.yaml +17 -0
  320. package/graphs/units/task-agent-recover-wait.yaml +17 -0
  321. package/graphs/units/verbs/make-doc.yaml +34 -0
  322. package/graphs/units/verbs/recipes.yaml +33 -0
  323. package/graphs/units/verbs/verify.yaml +55 -0
  324. package/graphs/work/recipes.yaml +2 -0
  325. package/graphs/work/research-report.yaml +28 -0
  326. package/package.json +1 -1
  327. package/scripts/ci-typecheck-changed.ts +69 -16
  328. package/scripts/coord-role-pack.ts +19 -6
  329. package/scripts/docs/generate-graph-anatomy.ts +19 -2
  330. package/scripts/graph-harvest-unit.ts +22 -0
  331. package/scripts/graph-units/journey-stub.ts +6 -0
  332. package/scripts/graph-units/land-enqueue.ts +78 -0
  333. package/scripts/graph-units/recover-plan.ts +15 -0
  334. package/scripts/graph-units/reflect-node.ts +88 -0
  335. package/scripts/graph-units/ta-journey-observe.ts +109 -0
  336. package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
  337. package/scripts/graph-units/verbs/verify-stage.ts +75 -0
  338. package/scripts/graph-units/verbs-envelope.ts +139 -0
  339. package/scripts/hq/standby-snapshot.ts +30 -0
  340. package/scripts/public-export.ts +43 -1
  341. package/scripts/ratchets/train-side-invariants.sh +45 -0
  342. package/scripts/release-loop/auto-approve-node.ts +30 -16
  343. package/scripts/release-loop/docs-land-node.ts +21 -5
  344. package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
  345. package/scripts/release-loop/gate-closure.ts +5 -1
  346. package/scripts/release-loop/gate-diff.ts +1 -1
  347. package/scripts/release-loop/gate-node.ts +675 -49
  348. package/scripts/release-loop/gate-partial.ts +68 -14
  349. package/scripts/release-loop/gate-radius-live.ts +177 -0
  350. package/scripts/release-loop/gate-radius-shadow.ts +138 -0
  351. package/scripts/release-loop/gate-traffic-mode.ts +128 -0
  352. package/scripts/release-loop/gate-triage-node.ts +5 -2
  353. package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
  354. package/scripts/release-loop/known-issues-node.ts +77 -8
  355. package/scripts/release-loop/node-verdict.ts +12 -1
  356. package/scripts/release-loop/npm-publish-node.ts +66 -12
  357. package/scripts/release-loop/preflight.ts +93 -7
  358. package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
  359. package/scripts/release-loop/publish-node.ts +60 -9
  360. package/scripts/release-loop/pwa-remote.ts +166 -0
  361. package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
  362. package/scripts/release-loop/resume-cap.ts +56 -0
  363. package/scripts/release-loop/resume-release.ts +155 -19
  364. package/scripts/release-loop/resume.ts +24 -1
  365. package/scripts/release-loop/tui-sim-node.ts +8 -2
  366. package/scripts/release-loop/unattended-release.ts +10 -2
  367. package/scripts/test-diet/lib.ts +6 -1
  368. package/scripts/test-diet/node.ts +194 -13
  369. package/scripts/ux-sim.ts +39 -0
  370. package/src/acp/core-turn-bridge.ts +20 -5
  371. package/src/acp/reasoning-thought-buffer.ts +45 -0
  372. package/src/agent/self-ambient-cache.ts +8 -0
  373. package/src/agent-substrate/acp-reviewer.ts +90 -15
  374. package/src/agent-substrate/pr-reviewer.ts +17 -0
  375. package/src/agent-substrate/review-finding-key.ts +53 -0
  376. package/src/agent-substrate/self-review-cli.ts +188 -18
  377. package/src/ask-user-question/pending-questions.ts +1 -1
  378. package/src/autopilot/pr-manager.ts +393 -65
  379. package/src/budget/run-usage-rollup.ts +1 -0
  380. package/src/chat/index.ts +0 -2
  381. package/src/chat/pickers/modal-runtime.ts +10 -27
  382. package/src/chat/tool-render/dispatch.ts +62 -10
  383. package/src/cli/agent-cli.ts +13 -2
  384. package/src/cli/control-cli.ts +24 -7
  385. package/src/cli/doctor-cli.ts +4 -1
  386. package/src/cli/guardian-cli.ts +10 -0
  387. package/src/cli/light-entry-route.ts +75 -0
  388. package/src/cli/llm-detect-cli.ts +23 -1
  389. package/src/cli/pod-cli.ts +77 -3
  390. package/src/cli/pr-cli.ts +81 -14
  391. package/src/cli/pr-land-base-read.ts +2 -0
  392. package/src/cli/pr-land-overlap-evidence.ts +154 -16
  393. package/src/cli/pr-land-pod-shadow-job.ts +3 -0
  394. package/src/cli/pr-land-recovery.ts +64 -0
  395. package/src/cli/pty-takeover-cli.ts +6 -5
  396. package/src/cli/release-checklist-read-cli.ts +79 -0
  397. package/src/cli/release-cli.ts +189 -132
  398. package/src/cli/release-run-if-ready.ts +29 -28
  399. package/src/cli/release-single-flight.ts +178 -0
  400. package/src/cli/remote-resolve.ts +1 -1
  401. package/src/cli/root-tui-entry.ts +48 -0
  402. package/src/cli/seat-cli.ts +37 -0
  403. package/src/cli/setup-cli.ts +40 -1
  404. package/src/cli/sim-cli.ts +22 -0
  405. package/src/cli/tasks-cli.ts +667 -14
  406. package/src/cli/usage-cli.ts +13 -11
  407. package/src/clipboard/history.ts +179 -13
  408. package/src/config.ts +8 -1
  409. package/src/control/control-status.ts +8 -3
  410. package/src/control-plane/ledger.ts +5 -3
  411. package/src/control-plane/server.ts +5 -3
  412. package/src/core-turn/short-question.ts +5 -1
  413. package/src/dashboard/chat/acp-chat.ts +8 -0
  414. package/src/dashboard/index.ts +114 -77
  415. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
  416. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  417. package/src/dashboard/input/seat-autowake.ts +56 -3
  418. package/src/dashboard/render/theme-resolver.ts +33 -4
  419. package/src/dashboard/seat-boot-preamble.ts +1 -1
  420. package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
  421. package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
  422. package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
  423. package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
  424. package/src/dashboard/turn-preamble.ts +47 -1
  425. package/src/dashboard/turn-stream-formatter.ts +34 -1
  426. package/src/dashboard/turn-stream-runtime.ts +2 -0
  427. package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
  428. package/src/domains/guardian-tick.ts +54 -2
  429. package/src/domains/outbound-alert.ts +3 -2
  430. package/src/domains/schedule-registry.ts +16 -2
  431. package/src/extractors.ts +3 -1
  432. package/src/git-fs/idle-refresh.ts +76 -0
  433. package/src/git-fs/index.ts +18 -7
  434. package/src/git-fs/retry.ts +4 -0
  435. package/src/git-fs/runner.ts +2 -0
  436. package/src/git-fs/worktree.ts +42 -4
  437. package/src/graph-kinds/registry.ts +2 -2
  438. package/src/graph-runner/runner.ts +267 -54
  439. package/src/grok/credential.ts +15 -3
  440. package/src/harness/harness-cli-command.ts +151 -38
  441. package/src/harness/harness-incidents.ts +37 -0
  442. package/src/harness/harness-pod-dispatch.ts +38 -1
  443. package/src/harness/harness-salvage-cli.ts +14 -2
  444. package/src/harness/launch-utterance-ledger.ts +208 -0
  445. package/src/impl-discipline/detector.ts +16 -4
  446. package/src/impl-discipline/system-prompt.ts +11 -0
  447. package/src/impl-discipline/types.ts +2 -2
  448. package/src/index.ts +683 -146
  449. package/src/intake-plane/already-built-hint.ts +91 -0
  450. package/src/intake-plane/requirement-funnel.ts +29 -1
  451. package/src/knowhow/pack.ts +199 -0
  452. package/src/light-cli.ts +111 -0
  453. package/src/llm/opengateway-models.ts +11 -0
  454. package/src/llm/provider-credentials.ts +14 -0
  455. package/src/llm/provider-detect.ts +8 -1
  456. package/src/llm/runtime-model-family.ts +2 -1
  457. package/src/llm.ts +268 -65
  458. package/src/loops/budget.ts +95 -0
  459. package/src/loops/msg-wake.ts +8 -2
  460. package/src/loops/orchestrator/traffic.ts +132 -1
  461. package/src/model-tier/llm-tier-map.ts +15 -1
  462. package/src/mss/logging/log-store.ts +4 -5
  463. package/src/native-tool-catalog.ts +15 -1
  464. package/src/nexus/api/graphs-api.ts +22 -3
  465. package/src/nexus/api/http-server.ts +1 -1
  466. package/src/nexus/api/loop-resources.ts +13 -1
  467. package/src/nexus/api/ops-api.ts +12 -0
  468. package/src/oauth/claude-pty-maturity.ts +66 -0
  469. package/src/oauth/codex-access-mirror.ts +55 -0
  470. package/src/oauth/codex.ts +7 -0
  471. package/src/oauth/fallback-chain.ts +1 -1
  472. package/src/onboarding/first-run.ts +5 -3
  473. package/src/onboarding/non-interactive.ts +64 -13
  474. package/src/onboarding.ts +10 -2
  475. package/src/ops/overview-collect.ts +54 -4
  476. package/src/ops/overview.ts +31 -7
  477. package/src/pr-tool/census.ts +282 -30
  478. package/src/pr-tool/inflight-registry.ts +160 -7
  479. package/src/prompt-library/gpt6-family-addendum.ts +14 -1
  480. package/src/pty-shell/herdr-agent-report.ts +442 -0
  481. package/src/pty-shell/pty-control-ipc.ts +5 -5
  482. package/src/pty-shell/pty-manifest.ts +7 -0
  483. package/src/pty-shell/pty-write-outcome.ts +24 -6
  484. package/src/pty-shell/tui-run-state.ts +117 -3
  485. package/src/release-loop/checklist.ts +103 -5
  486. package/src/release-loop/feature-store.ts +19 -2
  487. package/src/release-loop/landed-but-yellow.ts +129 -5
  488. package/src/release-loop/light-rc.ts +1 -0
  489. package/src/release-loop/placement.ts +10 -3
  490. package/src/release-loop/rehearsal.ts +205 -25
  491. package/src/release-loop/rubric.ts +16 -2
  492. package/src/repl/index.ts +174 -17
  493. package/src/repl/ops-msg-bridge.ts +32 -0
  494. package/src/self-dev/ask-launch-flow.ts +44 -5
  495. package/src/self-dev/cli-help-text.ts +17 -0
  496. package/src/self-dev/dev-cli.ts +11 -9
  497. package/src/self-dev/draft-residue.ts +37 -1
  498. package/src/self-dev/draft-sweep.ts +188 -13
  499. package/src/self-dev/draft-triage-rules.ts +107 -0
  500. package/src/self-dev/fleet-reduce.ts +3 -2
  501. package/src/self-dev/graph-front-nodes.ts +112 -0
  502. package/src/self-dev/graph-journey-nodes.ts +11 -6
  503. package/src/self-dev/graph-journey-route.ts +60 -6
  504. package/src/self-dev/harness-run-cli.ts +3 -15
  505. package/src/self-dev/orchestrate-cli-text.ts +10 -0
  506. package/src/self-dev/orchestrate.ts +79 -3
  507. package/src/self-dev/review-provider-fallback.ts +35 -1
  508. package/src/self-dev/run-supervisor.ts +107 -12
  509. package/src/self-dev/run-types.ts +5 -1
  510. package/src/self-dev/self-orchestrate-runtime.ts +1 -11
  511. package/src/self-dev/shard-aggregate.ts +42 -5
  512. package/src/self-dev/shard-run.ts +8 -1
  513. package/src/self-implement/blocked-draft-policy.ts +20 -0
  514. package/src/self-implement/classify-shadow.ts +3 -7
  515. package/src/self-implement/doctor-visit.ts +18 -1
  516. package/src/self-implement/gate-baseline.ts +95 -12
  517. package/src/self-implement/gate-cli.ts +1 -0
  518. package/src/self-implement/gate-remote.ts +40 -25
  519. package/src/self-implement/goal-author-decompose.ts +275 -47
  520. package/src/self-implement/goal-author-identity.ts +66 -0
  521. package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
  522. package/src/self-implement/goal-author.ts +254 -120
  523. package/src/self-implement/goal-elaborate.ts +295 -0
  524. package/src/self-implement/goal-refine.ts +270 -0
  525. package/src/self-implement/graph-overlay-yaml.ts +28 -2
  526. package/src/self-implement/graph-unit-flatten.ts +103 -0
  527. package/src/self-implement/graph-unit-resolver.ts +107 -0
  528. package/src/self-implement/graph-yaml.ts +151 -1
  529. package/src/self-implement/headless-elanous-driver.ts +1 -0
  530. package/src/self-implement/knowhow-pack.ts +103 -0
  531. package/src/self-implement/orchestrator.ts +160 -45
  532. package/src/self-implement/pod-warm-pool-profile.ts +45 -0
  533. package/src/self-implement/review-mustfix-class.ts +203 -0
  534. package/src/self-implement/rework-budget-judgment.ts +5 -8
  535. package/src/self-implement/run-stop.ts +17 -2
  536. package/src/self-implement/running-runs.ts +29 -1
  537. package/src/self-implement/scope-adjacency.ts +113 -0
  538. package/src/self-implement/seams.ts +138 -4
  539. package/src/self-implement/stop-autoheal.ts +112 -2
  540. package/src/session/chat.ts +27 -0
  541. package/src/session-runtime/index.ts +1 -1
  542. package/src/session-runtime/retry-policy.ts +2 -1
  543. package/src/setup/llm-env-detect.ts +5 -0
  544. package/src/skills/tools/agent.ts +140 -14
  545. package/src/skills/tools/msg-ask.ts +100 -0
  546. package/src/skills/tools/ops-ledger.ts +2 -1
  547. package/src/skills/tools/schedule-wakeup.ts +66 -17
  548. package/src/steward/hold-hygiene.ts +24 -6
  549. package/src/steward/release-day.ts +7 -3
  550. package/src/steward/triage-budget.ts +194 -0
  551. package/src/steward/triage.ts +57 -7
  552. package/src/task-agent/actions.ts +69 -1
  553. package/src/task-agent/green-sweep.ts +4 -0
  554. package/src/task-agent/harvest-unit.ts +141 -0
  555. package/src/task-agent/live-moves.ts +257 -15
  556. package/src/task-agent/parent-host.ts +216 -6
  557. package/src/task-agent/postland-card.ts +80 -1
  558. package/src/task-agent/rejudge-on-head.ts +112 -26
  559. package/src/task-agent/repair-branch-cas.ts +4 -1
  560. package/src/task-agent/repair-cycle.ts +16 -3
  561. package/src/task-agent/run-identity.ts +4 -3
  562. package/src/task-agent/shadow.ts +19 -3
  563. package/src/task-agent/task-hand.ts +96 -36
  564. package/src/task-agent/tier-split.ts +127 -0
  565. package/src/task-agent/work-order-build.ts +24 -0
  566. package/src/task-agent/work-order.ts +3 -2
  567. package/src/task-orchestrator/generator-prompt.ts +60 -11
  568. package/src/task-orchestrator/surfaces/pod-account-broker.ts +72 -3
  569. package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
  570. package/src/task-orchestrator/surfaces/pod-command-job.ts +47 -8
  571. package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
  572. package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
  573. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
  574. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +8 -2
  575. package/src/task-orchestrator/surfaces/pod-pool.ts +73 -17
  576. package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -0
  577. package/src/task-orchestrator/surfaces/pod-source-receive.ts +72 -4
  578. package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
  579. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +32 -5
  580. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +3 -0
  581. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +421 -0
  582. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +2 -1
  583. package/src/task-orchestrator/surfaces/self-implement-pod.ts +588 -71
  584. package/src/task-orchestrator/surfaces/self-implement.ts +106 -2
  585. package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
  586. package/src/tool-runtime/truncation-store.ts +4 -0
  587. package/src/tui/README.md +2 -0
  588. package/src/tui/chat/background-job-status.ts +54 -0
  589. package/src/tui/chat/log-view.ts +80 -0
  590. package/src/tui/entry.ts +406 -0
  591. package/src/tui/input/composer.ts +144 -0
  592. package/src/tui/seat-mail-boot.ts +59 -0
  593. package/src/tui/slash/compact.ts +100 -0
  594. package/src/tui/slash/new-session.ts +35 -0
  595. package/src/tui-client/dashboard-session.ts +10 -1
  596. package/src/tui-client/local-chat-turn.ts +239 -0
  597. package/src/tui-client/local-harness-command.ts +63 -0
  598. package/src/tui-client/local-provider-command.ts +184 -0
  599. package/src/user-config/coercion.ts +36 -0
  600. package/src/user-config.ts +22 -43
  601. package/src/ux-sim/event-monkey.ts +378 -0
  602. package/src/ux-sim/fake-bin.ts +42 -7
  603. package/src/ux-sim/fault-nextmove-dispatch.ts +266 -0
  604. package/src/ux-sim/fault-pod-codex-503.ts +211 -0
  605. package/src/ux-sim/fault-scope-escape-lift.ts +189 -0
  606. package/src/ux-sim/scenario.ts +72 -13
  607. package/src/version/packed-revision.json +1 -1
  608. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
  611. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
  612. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
  613. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
  617. package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
  619. package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
  620. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
  629. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
  630. package/apps/pwa/out/_next/static/chunks/3541-ce3a5424ed5ad7f1.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
  636. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
  640. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
  641. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +0 -226
  642. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
  644. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
  647. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/5543.a438b8ab5a13ea47.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
  653. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
  655. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
  661. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
  662. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
  663. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
  668. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
  669. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
  674. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +0 -24
  685. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/9989.3694300e5f000b14.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/setup/page-c219f2ed171131be.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
  744. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
  752. package/src/cli/g6a-registration-probe.ts +0 -16
  753. /package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
@@ -2,6 +2,12 @@
2
2
  // 산출 경로를 한 줄로 알리고 명령의 종료 코드로 끝난다. `--deadline` 생략 시 기존 Pod Job 상한.
3
3
 
4
4
  import type { Command } from 'commander';
5
+ import { randomUUID } from 'node:crypto';
6
+ import { hostname } from 'node:os';
7
+ import { basename, join } from 'node:path';
8
+ import { readFileSync } from 'node:fs';
9
+ import { putPodShelfImage, listPodShelfImages, type PodShelfImage } from '../task-orchestrator/surfaces/pod-image-source.js';
10
+ import { defaultRemoteRun } from '../task-orchestrator/surfaces/pod-pool.js';
5
11
  import { debug } from '../debug/log.js';
6
12
  import { readPodMemoryAdvice } from './pod-memory-advice.js';
7
13
  import { getUserConfig } from '../user-config.js';
@@ -28,6 +34,10 @@ export interface PodCliDeps {
28
34
  poolSpec?: (explicit?: string) => string | null;
29
35
  harnessPool?: () => string | undefined;
30
36
  memoryAdvice?: (logsDb?: string) => ReturnType<typeof readPodMemoryAdvice>;
37
+ shelfConfig?: () => { harness?: { imageCommit?: unknown } };
38
+ shelfPut?: (ref: string, pool: string) => Promise<PodShelfImage>;
39
+ shelfList?: (pool: string) => Promise<string[]> | string[];
40
+ shelfTail?: (artifactsDir: string) => string;
31
41
  }
32
42
 
33
43
  const HELP = `elanous pod run [--pool <스펙>] [--skill <이름,…>] [--llm grok] [--clone] [--deadline <초>] -- <명령…>
@@ -63,6 +73,57 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
63
73
  };
64
74
  const run = deps.run ?? ((options: RunPodCommandOptions) => runPodCommand(options));
65
75
  const pod = program.command('pod').description('Pod 명령 Job — 하니스 없이 명령 하나를 돌리고 산출을 돌려받는다');
76
+ const shelf = pod.command('shelf').description('임의 PR·SHA·가지의 격리 하니스 이미지와 명령 Job');
77
+ const shelfPool = (explicit?: string) => {
78
+ const config = (deps.shelfConfig ?? getUserConfig)();
79
+ const spec = explicit || process.env.ELANOUS_POD_POOL || ('podPool' in (config.harness ?? {}) ? (config.harness as { podPool?: string }).podPool : undefined) || (config as { pod?: { pool?: string } }).pod?.pool;
80
+ if (!spec) throw new Error('pod shelf: remote pool is not configured');
81
+ return spec;
82
+ };
83
+ shelf.command('put <ref>').description('ref head 이미지를 빌드하거나 레지스트리 태그 재사용')
84
+ .option('--pool <spec>', '단일 원격 레지스트리 풀 멤버')
85
+ .action(async (ref: string, opts: { pool?: string }) => {
86
+ try {
87
+ const image = await (deps.shelfPut ?? putPodShelfImage)(ref, shelfPool(opts.pool));
88
+ io.log(`${image.image} (${image.action})`); io.exit(0);
89
+ } catch (err) { io.error(err instanceof Error ? err.message : String(err)); io.exit(1); }
90
+ });
91
+ shelf.command('ls').description('레지스트리의 커밋 이미지 태그 목록')
92
+ .option('--pool <spec>', '단일 원격 레지스트리 풀 멤버')
93
+ .action(async (opts: { pool?: string }) => {
94
+ try {
95
+ const images = await (deps.shelfList ?? ((pool) => listPodShelfImages(pool, defaultRemoteRun)))(shelfPool(opts.pool));
96
+ for (const image of images) io.log(image);
97
+ io.exit(0);
98
+ } catch (err) { io.error(err instanceof Error ? err.message : String(err)); io.exit(1); }
99
+ });
100
+ shelf.command('run <ref>').description('ref 이미지로 명령 Job 실행 · rc 와 출력 꼬리 반환')
101
+ .option('--pool <spec>', '단일 원격 레지스트리 풀 멤버')
102
+ .allowUnknownOption(true).allowExcessArguments(true)
103
+ .action(async (ref: string, opts: { pool?: string }) => {
104
+ const argv = process.argv.slice(2);
105
+ const sep = argv.indexOf('--');
106
+ const args = sep < 0 ? [] : argv.slice(sep + 1);
107
+ if (!args.length) { io.error('pod shelf run: `--` 뒤에 명령이 없다'); io.exit(2); return; }
108
+ try {
109
+ const pool = shelfPool(opts.pool);
110
+ const image = await (deps.shelfPut ?? putPodShelfImage)(ref, pool);
111
+ const seat = process.env.ELANOUS_SEAT?.trim();
112
+ const actor = seat || process.env.USER?.trim() || process.env.LOGNAME?.trim();
113
+ if (!actor) throw new Error('pod provenance actor missing: ELANOUS_SEAT or USER/LOGNAME required');
114
+ const runId = randomUUID();
115
+ const result = await run({ pool, image: image.image, shelfImage: image.image, imageCommit: image.commit,
116
+ clone: true, source: { kind: 'commit', sha: image.commit }, command: args, runId, returnLogs: true,
117
+ provenance: { actorKind: seat ? 'seat' : 'human', actor, character: 'command-runner', launchHost: hostname(),
118
+ entrance: 'pod-shelf-run', kind: 'command', run: runId, phase: 'exec', requestedAt: new Date().toISOString(), reason: 'unknown', argv: basename(args[0]!) },
119
+ });
120
+ io.error(`[pod shelf] image ${result.image ?? image.image} · rc ${result.exitCode} · job ${result.job}`);
121
+ io.log(result.artifactsDir);
122
+ const tail = (deps.shelfTail ?? ((dir) => readFileSync(join(dir, 'child.log'), 'utf8')))(result.artifactsDir);
123
+ io.log(tail.slice(-4096));
124
+ io.exit(result.exitCode);
125
+ } catch (err) { io.error(err instanceof Error ? err.message : String(err)); io.exit(1); }
126
+ });
66
127
  pod.command('memory').description('실측 기반 Pod 메모리 권고 (읽기 전용)')
67
128
  .command('advise').description('골 종류별 standard 16Gi / high 32Gi 권고와 근거')
68
129
  .option('--json', '권고와 측정 근거를 JSON 으로')
@@ -110,7 +171,9 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
110
171
  // This explicit observation runs after the admission calculation. A slow or failed external
111
172
  // probe can never change recommended/limitedBy or slow the ordinary lease status path.
112
173
  const externalGitHub = opts.githubEgress ? Object.fromEntries(members.map((member) => {
113
- try { return [member.context, (deps.externalGitHub ?? probePoolGitHub)(member.context, kubectl)]; }
174
+ try {
175
+ return [member.context, (deps.externalGitHub ?? probePoolGitHub)(member.context, kubectl)];
176
+ }
114
177
  catch { return [member.context, { externalDns: null, githubHttps: null, measuredAt: null, reason: 'probe failed' }]; }
115
178
  })) : undefined;
116
179
  const result = { pool: spec, ...measure, accounts, perAccount, ...decision, reserved: host.reserved, waitingJobs,
@@ -132,8 +195,10 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
132
195
  }
133
196
  io.log(`예약(저작 중) ${host.reserved} · 대기 Job ${waitingJobs ?? '?'} · 실행 ${decision.running ?? '?'}`);
134
197
  io.log(`임대 없는 실행 ${decision.unleasedRunning ?? '?'}`);
135
- if (externalGitHub) for (const [context, probe] of Object.entries(externalGitHub))
136
- io.log(`GitHub 외부망 ${context}: DNS=${probe.externalDns ?? '?'} HTTPS=${probe.githubHttps ?? '?'} 측정=${probe.measuredAt ?? '?'}${probe.reason ? ` · ${probe.reason}` : ''}`);
198
+ if (externalGitHub) for (const [context, probe] of Object.entries(externalGitHub)) {
199
+ io.log(`GitHub 외부망 ${context}: DNS=${probe.externalDns ?? '?'} HTTPS=${probe.githubHttps ?? '?'} 측정=${probe.measuredAt ?? '?'}${probe.reason ? ` · ${probe.reason}` : ''}${probe.podName ? ` · Pod=${probe.podName}` : ''}`);
200
+ if (probe.podLog !== undefined) io.log(`GitHub 탐침 로그 ${probe.podName ?? context}: ${JSON.stringify(probe.podLog)}`);
201
+ }
137
202
  io.log(`capacity: ${decision.capacitySlots ?? '?'} 칸 (상한 ${members.reduce((sum, m) => sum + m.capacity, 0)} − Running ${decision.running ?? '?'} − Pending ${decision.pending ?? '?'}; 권장 수에서 건강한 멤버의 임대 없는 실행 차감)`);
138
203
  io.log(`memory: ${decision.memorySlots ?? '?'} 칸 (할당 가능 − Running 하니스 상한 합; 골당 16Gi · 모든 네임스페이스의 노드별 기존 예약을 반영해 배치 가능 ${decision.placeableSlots ?? '?'} 칸)`);
139
204
  io.log(`lite: ${decision.liteMemorySlots ?? '?'} 칸 (같은 여유를 lite 골 2Gi 로 센 값 · 관측만 — 권장 수는 위 standard 기준)`);
@@ -186,8 +251,17 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
186
251
  debug.log('pod.run', 'clone-without-install', { argv0: commandArgs[0], argv1: commandArgs[1] });
187
252
  }
188
253
  try {
254
+ const seat = process.env.ELANOUS_SEAT?.trim();
255
+ const user = process.env.USER?.trim() || process.env.LOGNAME?.trim();
256
+ const actor = seat || user;
257
+ if (!actor) throw new Error('pod provenance actor missing: ELANOUS_SEAT or USER/LOGNAME required');
258
+ const runId = randomUUID();
189
259
  const result = await run({
190
260
  command: commandArgs,
261
+ runId,
262
+ provenance: { actorKind: seat ? 'seat' : 'human', actor,
263
+ character: 'command-runner', launchHost: hostname(), entrance: 'pod-run', kind: 'command', run: runId,
264
+ phase: 'exec', requestedAt: new Date().toISOString(), reason: 'unknown', argv: basename(commandArgs[0] || '') },
191
265
  returnLogs: true,
192
266
  ...(opts.pool ? { pool: opts.pool } : {}),
193
267
  ...(skills.length ? { skills } : {}),
package/src/cli/pr-cli.ts CHANGED
@@ -30,6 +30,7 @@ import { queryRunningRuns, type RunningRunsResult } from '../self-implement/runn
30
30
  import { debug } from '../debug/log.js';
31
31
  import { runGitCommand } from '../git-fs/runner.js';
32
32
  import {
33
+ defaultCensusParallelRunner,
33
34
  defaultCmdRunner,
34
35
  makePrManager,
35
36
  resolveDeliverableBase,
@@ -58,10 +59,11 @@ import { branchLineageSlug, findSiblingPrs } from './pr-lineage.js';
58
59
  import { parseReleaseNoteSection } from '../release-loop/release-note.js';
59
60
  import { landingFreezeMessage } from '../release-loop/landing-freeze.js';
60
61
  import { admitLandingMerge } from '../self-implement/frozen-merges.js';
61
- import { verifyAllSameHeadReviews, verifyAncestorAutoPass, verifyOverlapEvidence, verifyOverlapEvidenceVirtualRebase } from './pr-land-overlap-evidence.js';
62
+ import { resolveOverlapEvidencePath, verifyAllSameHeadReviews, verifyAncestorAutoPass, verifyOverlapEvidence, verifyOverlapEvidenceVirtualRebase } from './pr-land-overlap-evidence.js';
62
63
  import type { VerifyOverlapEvidenceInput } from './pr-land-overlap-evidence.js';
63
64
  import { verifyVirtualRebasePatch } from './pr-land-virtual-rebase.js';
64
65
  import { observeDirectPrLandRefusal, observePrLandRefusal } from './pr-land-refusal.js';
66
+ import { planPrLandRecovery } from './pr-land-recovery.js';
65
67
  import { ensurePrLandHeavyRemote, type HeavyRemoteInput, type HeavyRemoteResult } from './pr-land-heavy-remote.js';
66
68
  import { readPrBaseNameWithRetry } from './pr-land-base-read.js';
67
69
  import { runHeavyOnPodShadow } from './pr-land-pod-shadow.js';
@@ -70,7 +72,7 @@ import { readTaskAgentState, taskAgentStatePath, type TaskCard } from '../task-a
70
72
  import { INFLIGHT_REGISTRY_FILE, removeInflightForPr } from '../pr-tool/inflight-registry.js';
71
73
  import { PR_LABEL_NAMES } from '../github/pr-labels.js';
72
74
  import { enqueueL8ShadowQueue, runL8ShadowQueue, shadowPrNumber, statusL8ShadowQueue, type L8ShadowQueueDeps } from '../self-implement/l8-merge-queue.js';
73
- import { censusOpenPrs, guardNewPr, parseDiffHunks, readOpenPrs, type Seat } from '../pr-tool/census.js';
75
+ import { censusOpenPrs, guardNewPr, parseDiffHunks, readOpenPrs, sharedCensusDiffCache, type Seat } from '../pr-tool/census.js';
74
76
 
75
77
  export { branchLineageSlug, findSiblingPrs };
76
78
 
@@ -117,6 +119,8 @@ export const PR_LAND_MERGEABLE_UNKNOWN_WAIT_MS = 5_000;
117
119
 
118
120
  export interface PrLandDeps {
119
121
  manager?: PrManager;
122
+ /** Confirmed merge cleanup; failures are observed and never undo the merge. */
123
+ onMergedSupersede?: (number: number, cwd: string) => Promise<void>;
120
124
  /** 병합 재시도 사이 대기(시험 주입용 · 기본 실제 대기). */
121
125
  sleep?: (ms: number) => Promise<void>;
122
126
  run?: CmdRunner;
@@ -271,14 +275,14 @@ export async function decideOverlapLanding(input: {
271
275
 
272
276
  const liveOut = { log: (message: string) => console.log(message), error: (message: string) => console.error(message) };
273
277
 
274
- function runPrLandTypecheckGate(out: { log: (message: string) => void; error: (message: string) => void }, cwd: string = process.cwd()): boolean {
278
+ function runPrLandTypecheckGate(out: { log: (message: string) => void; error: (message: string) => void }, cwd: string): boolean {
275
279
  let failed = false;
276
280
  const exit = ((code: number): never => {
277
281
  failed = code !== 0;
278
282
  throw new Error(`ci-typecheck-changed exited ${code}`);
279
283
  });
280
284
  try {
281
- runChangedTypecheckGate({ log: out.log, warn: out.error, error: out.error, exit, cwd });
285
+ runChangedTypecheckGate({ log: out.log, warn: out.error, error: out.error, exit, cwd: resolve(cwd), allowMissingCheckoutDependencies: true });
282
286
  } catch (error) {
283
287
  if (!failed) throw error;
284
288
  }
@@ -1087,7 +1091,7 @@ export function verifyPinnedOverlapDecision(input: {
1087
1091
  if (decision === 'unavailable' && opts.overlapEvidence !== undefined) {
1088
1092
  const ref = resolveRemoteBranchRef(run, cwd, base);
1089
1093
  const evidenceInput: VerifyOverlapEvidenceInput = {
1090
- evidencePath: opts.overlapEvidence, pr: Number(opts.pr), expectedHead: opts.expectedHead!,
1094
+ evidencePath: resolveOverlapEvidencePath(opts.overlapEvidence, cwd), pr: Number(opts.pr), expectedHead: opts.expectedHead!,
1091
1095
  remote: ref.remote, branch: ref.branch, cwd, run, readFile,
1092
1096
  reviewResultsDir: deps.reviewResultsDir ?? join(dirname(taskAgentStatePath()), 'review-results'),
1093
1097
  listDir: (dir) => readdirSync(dir), reviewMtime: (path) => statSync(path).mtimeMs,
@@ -1318,6 +1322,19 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1318
1322
  const refuse = (message: string, context: { isDraft?: boolean } = {}): void => {
1319
1323
  out.error(message);
1320
1324
  observePrLandRefusal(message, context);
1325
+ const pr = Number(opts.pr);
1326
+ if (Number.isSafeInteger(pr) && pr > 0 && opts.expectedHead) {
1327
+ try {
1328
+ const plan = planPrLandRecovery({ refusal: message, pr, head: opts.expectedHead, isDraft: context.isDraft });
1329
+ debug.log('pr.land', 'recover-shadow', {
1330
+ pr, head: opts.expectedHead, label: plan.evidence.label, route: plan.evidence.route,
1331
+ outcome: plan.outcome, action: plan.result.action, reason: plan.result.reason,
1332
+ delayMs: plan.result.delayMs ?? null, execution: 'none',
1333
+ });
1334
+ } catch {
1335
+ // Recovery observation must never replace the original landing refusal.
1336
+ }
1337
+ }
1321
1338
  };
1322
1339
  const refuseDirect = (message: string): void => {
1323
1340
  out.error(message);
@@ -1885,14 +1902,22 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1885
1902
  const baseRead = await readPrBaseNameWithRetry({
1886
1903
  pr: String(opts.pr), cwd, run,
1887
1904
  sleep: deps.sleep ?? ((ms) => new Promise<void>((resolve) => setTimeout(resolve, ms))),
1905
+ onUnreadable: (attempt, stderr) => {
1906
+ if (stderr?.trim()) out.error(`⚠ heavy-remote: gh pr view base read attempt ${attempt}/3 stderr: ${stderr.trim()}`);
1907
+ },
1888
1908
  });
1889
1909
  const baseName = baseRead.baseRefName;
1890
1910
  record('heavy-remote-pr-base-read', baseName !== null, {
1891
1911
  pr: Number(opts.pr), baseRefName: baseName, attempts: baseRead.attempts,
1892
1912
  });
1913
+ if (baseName === null) {
1914
+ record('heavy-remote-pr-base', false, { pr: Number(opts.pr), baseRefName: null, attempts: baseRead.attempts, reason: 'unreadable' });
1915
+ refuseDirect(`✗ heavy-remote: PR base 조회 불가 (${baseRead.attempts}회) — 통과한 head/main 쌍을 확인하지 못했다. 병합하지 않는다.`);
1916
+ return 1;
1917
+ }
1893
1918
  if (baseName !== 'main') {
1894
- record('heavy-remote-pr-base', false, { pr: Number(opts.pr), baseRefName: baseName, attempts: baseRead.attempts });
1895
- refuseDirect(`✗ heavy-remote: PR base=${baseName ?? 'unreadable'} ≠ main — 재타기팅된 PR은 통과한 head/main 쌍이 아니다. 병합하지 않는다.`);
1919
+ record('heavy-remote-pr-base', false, { pr: Number(opts.pr), baseRefName: baseName, attempts: baseRead.attempts, reason: 'non-main' });
1920
+ refuseDirect(`✗ heavy-remote: PR base=${baseName} ≠ main — 재타기팅된 PR은 통과한 head/main 쌍이 아니다. 병합하지 않는다.`);
1896
1921
  return 1;
1897
1922
  }
1898
1923
  return undefined;
@@ -1951,7 +1976,8 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1951
1976
  }
1952
1977
  return recheckOverlapAtBase(currentBase);
1953
1978
  };
1954
- const typecheckOk = opts.heavyRemote || (deps.runTypecheckGate ?? ((o) => runPrLandTypecheckGate(o, cwd)))(out);
1979
+ // The production gate must receive this land invocation's --cwd, never the launching shell's cwd.
1980
+ const typecheckOk = opts.heavyRemote || (deps.runTypecheckGate ? deps.runTypecheckGate(out) : runPrLandTypecheckGate(out, cwd));
1955
1981
  record('typecheck', typecheckOk);
1956
1982
  if (!typecheckOk) {
1957
1983
  // ⛔⭐ 「왜 막혔나」를 «단정하지 않는다» — 이 게이트는 불리언만 돌려주므로 여기서는 이유를 모른다.
@@ -2374,6 +2400,13 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
2374
2400
  }
2375
2401
  if (opts.forceFreeze) debug.log('release-loop.freeze', 'force-merge', { pr: prNumber, reason: opts.forceFreeze.trim() });
2376
2402
  record('merge', true, { result: merged.kind, ...(merged.remoteBranchDeletion ? { remoteBranchDeletion: merged.remoteBranchDeletion.detail } : {}) });
2403
+ if (Number.isSafeInteger(prNumber) && prNumber > 0 && deps.onMergedSupersede) {
2404
+ try { await deps.onMergedSupersede(prNumber, cwd); }
2405
+ catch (error) {
2406
+ try { debug.log('drafts.cleanup', 'same-cell-hook-failed', { merged: prNumber, error: String(error) }, { level: 'warn' }); }
2407
+ catch { /* a cleanup observation cannot undo a confirmed merge */ }
2408
+ }
2409
+ }
2377
2410
  // INFLIGHT-REGISTRY — 착지하면 비행 중 등록부의 그 런 줄을 지운다(색인 실패는 착지를 막지 않는다).
2378
2411
  try {
2379
2412
  const statePath = deps.taskStatePath ?? taskAgentStatePath();
@@ -2437,12 +2470,30 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
2437
2470
  out.log(`✓ heavy-remote: post-merge host=${post.host ?? 'unknown'} head=${opts.expectedHead!.slice(0, 12)} main=${firstParent.slice(0, 12)} source=${post.source}`);
2438
2471
  }
2439
2472
  }
2440
- const baseRef = upsert.reused
2473
+ const finalBaseRead = upsert.reused && opts.heavyRemote
2474
+ ? await readPrBaseNameWithRetry({
2475
+ pr: upsert.url, cwd, run,
2476
+ sleep: deps.sleep ?? ((ms) => new Promise<void>((resolve) => setTimeout(resolve, ms))),
2477
+ onUnreadable: (attempt, stderr) => {
2478
+ if (stderr?.trim()) out.error(`⚠ heavy-remote: final gh pr view base read attempt ${attempt}/3 stderr: ${stderr.trim()}`);
2479
+ },
2480
+ })
2481
+ : undefined;
2482
+ const baseRef = upsert.reused && !opts.heavyRemote
2441
2483
  ? run('gh', ['pr', 'view', upsert.url, '--json', 'baseRefName', '--jq', '.baseRefName'], { cwd })
2442
2484
  : undefined;
2443
- const landingBase = baseRef
2444
- ? (baseRef.ok && baseRef.out.trim() ? baseRef.out.trim() : '<base unavailable>')
2445
- : base;
2485
+ const landingBase = finalBaseRead
2486
+ ? finalBaseRead.baseRefName ?? '<base unavailable>'
2487
+ : baseRef
2488
+ ? (baseRef.ok && baseRef.out.trim() ? baseRef.out.trim() : '<base unavailable>')
2489
+ : base;
2490
+ if (finalBaseRead?.baseRefName && finalBaseRead.baseRefName !== 'main') {
2491
+ out.error(`✗ heavy-remote: PR base=${finalBaseRead.baseRefName} ≠ main — 병합된 base를 확인했습니다.`);
2492
+ return 1;
2493
+ }
2494
+ if (finalBaseRead?.baseRefName === null) {
2495
+ out.log(`⚠ heavy-remote: final PR base 조회 불가 (${finalBaseRead.attempts}회) — 병합 결과를 실패 처리하지 않습니다.`);
2496
+ }
2446
2497
  out.log(`✓ merge: squash ${upsert.url} → ${landingBase}`);
2447
2498
  if (landingBase === '<base unavailable>') {
2448
2499
  out.log('⚠ local HEAD does not contain the landed result; the landed base is unavailable, so no branch command can be provided.');
@@ -2458,6 +2509,20 @@ export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queu
2458
2509
  const prToolRun = deps.run ?? defaultCmdRunner;
2459
2510
  const prToolOut = deps.out ?? liveOut;
2460
2511
  const prToolExit = deps.setExitCode ?? ((code: number) => { process.exitCode = code; });
2512
+ const supersedeMerged = deps.onMergedSupersede ?? (async (number: number, cwd: string): Promise<void> => {
2513
+ const { supersedeMergedGoalDrafts } = await import('../harness/harness-cli-command.js');
2514
+ await supersedeMergedGoalDrafts(number, cwd, undefined, undefined, { onlyExplicitSameCell: true });
2515
+ });
2516
+ pr.command('supersede-drafts')
2517
+ .description('확인된 병합 PR의 명시 Supersedes 같은 칸 draft만 정리')
2518
+ .requiredOption('--pr <number>', '병합 PR 번호')
2519
+ .option('--cwd <path>', '저장소 경로')
2520
+ .action(async (opts: { pr: string; cwd?: string }) => {
2521
+ const number = Number(opts.pr);
2522
+ if (!Number.isSafeInteger(number) || number < 1) { prToolOut.error('✗ supersede-drafts: 올바른 --pr 번호 필요'); prToolExit(1); return; }
2523
+ try { await supersedeMerged(number, opts.cwd ?? process.cwd()); }
2524
+ catch (error) { prToolOut.error(`✗ supersede-drafts: ${String(error)}`); prToolExit(1); }
2525
+ });
2461
2526
  pr.command('census')
2462
2527
  .description('열린 PR 전체·골 문서만·2일 무커밋 draft·미닫힌 superseded 집계')
2463
2528
  .option('--cwd <path>', '저장소 경로')
@@ -2478,7 +2543,9 @@ export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queu
2478
2543
  const diff = prToolRun('git', ['-C', cwd, 'diff', '--name-only', '-z', `${opts.base}...HEAD`]);
2479
2544
  const files = diff.ok ? diff.out.split('\0').filter(Boolean) : null;
2480
2545
  const patch = prToolRun('git', ['-C', cwd, 'diff', '--unified=0', `${opts.base}...HEAD`]);
2481
- const inventory = readOpenPrs(prToolRun, { cwd, ...(files ? { candidateFiles: files } : {}) });
2546
+ // PR-CENSUS-PARALLEL: the real runner fans `gh pr diff` out (cap 6); an injected runner stays one by one.
2547
+ const inventory = readOpenPrs(prToolRun, { cwd, ...(files ? { candidateFiles: files } : {}),
2548
+ ...(deps.run ? {} : { runParallel: defaultCensusParallelRunner, diffCache: sharedCensusDiffCache }) });
2482
2549
  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);
2483
2550
  // Inspection never spends the three-creation unmeasured allowance.
2484
2551
  // Only pr-manager records an actual new-PR attempt in that ledger.
@@ -2532,7 +2599,7 @@ export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queu
2532
2599
  const { registerStandaloneLogSink } = await import('../domains/standalone-log-sink.js');
2533
2600
  await registerStandaloneLogSink('pr-land');
2534
2601
  } catch { /* fail-open */ }
2535
- const code = await runPrLand(opts, deps);
2602
+ const code = await runPrLand(opts, { ...deps, onMergedSupersede: supersedeMerged });
2536
2603
  if (code !== 0) (deps.setExitCode ?? ((exitCode: number) => { process.exitCode = exitCode; }))(code);
2537
2604
  });
2538
2605
  pr.command('granularity')
@@ -14,6 +14,7 @@ export async function readPrBaseNameWithRetry(input: {
14
14
  cwd: string;
15
15
  run: CmdRunner;
16
16
  sleep: (ms: number) => Promise<void>;
17
+ onUnreadable?: (attempt: number, stderr: string | undefined) => void;
17
18
  }): Promise<PrBaseReadResult> {
18
19
  for (let attempt = 1; attempt <= PR_LAND_BASE_READ_RETRIES + 1; attempt += 1) {
19
20
  const viewed = input.run('gh', ['pr', 'view', input.pr, '--json', 'baseRefName,url'], { cwd: input.cwd });
@@ -28,6 +29,7 @@ export async function readPrBaseNameWithRetry(input: {
28
29
  } catch { /* Retry unreadable responses; do not treat them as main. */ }
29
30
 
30
31
  if (baseRefName !== null) return { baseRefName, attempts: attempt };
32
+ input.onUnreadable?.(attempt, viewed.err);
31
33
  if (attempt <= PR_LAND_BASE_READ_RETRIES) await input.sleep(PR_LAND_BASE_READ_RETRY_DELAY_MS);
32
34
  }
33
35
  return { baseRefName: null, attempts: PR_LAND_BASE_READ_RETRIES + 1 };
@@ -36,7 +36,7 @@ interface OverlapEvidenceFile {
36
36
  gate?: { head: string; baseCommit: string; passed: boolean };
37
37
  /** `self review --json` stdout 을 받은 파일(TA: `<state>/review-results/<card>-<pr>-<head접두 10~40>.json`); 내용의 전체 head도 확인한다. */
38
38
  reviewResult: string;
39
- /** Explicitly replaced failed reviews. Each reason is the verifier's original refusal reason. */
39
+ /** Evidence-file override for explicitly replaced failed reviews. Each reason is the verifier's refusal reason. */
40
40
  supersedes?: { reviewResult: string; reason: string }[];
41
41
  /** OPEN follow-up PR that owns the findings intentionally split from this landing. */
42
42
  followupPr?: number;
@@ -48,6 +48,11 @@ export type OverlapEvidenceVerdict =
48
48
  | { ok: true; mode: 'base-advanced-disjoint'; baseTip: string; gateBase: string; windowCommits: number; reviewResult: string }
49
49
  | { ok: false; reason: string; baseTip?: string };
50
50
 
51
+ /** Resolve CLI-supplied evidence against the selected repository, not the caller's shell cwd. */
52
+ export function resolveOverlapEvidencePath(evidencePath: string, cwd: string): string {
53
+ return resolve(cwd, evidencePath);
54
+ }
55
+
51
56
  export interface VerifyOverlapEvidenceInput {
52
57
  evidencePath: string;
53
58
  pr: number;
@@ -99,8 +104,12 @@ function checkSelectedReviewAttempts(input: VerifyOverlapEvidenceInput, e: Parti
99
104
  const entries = e.supersedes;
100
105
  if (entries !== undefined && (!Array.isArray(entries) || entries.length === 0)) return { ok: false, reason: 'review-supersedes-invalid' };
101
106
  const superseded = new Map<string, string>();
107
+ const resolvedPriorAccepted: string[] = [];
102
108
  let selectedTime: number | undefined;
103
- if (entries?.length) {
109
+ let selectedRecord: Record<string, unknown> | undefined;
110
+ try { selectedRecord = lastReviewRecord(input.readFile(selected)); } catch { return { ok: false, reason: 'review-unreadable' }; }
111
+ const hasResolvedPrior = hasResolvedPriorDeclaration(selectedRecord);
112
+ if (entries?.length || hasResolvedPrior) {
104
113
  try { selectedTime = input.reviewMtime(selected); } catch { return { ok: false, reason: 'review-attempt-time-unmeasured' }; }
105
114
  if (!Number.isFinite(selectedTime)) return { ok: false, reason: 'review-attempt-time-unmeasured' };
106
115
  }
@@ -123,9 +132,22 @@ function checkSelectedReviewAttempts(input: VerifyOverlapEvidenceInput, e: Parti
123
132
  if (superseded.has(path)) return { ok: false, reason: 'review-supersedes-passing' };
124
133
  continue;
125
134
  }
126
- if (superseded.get(path) !== review.reason) return { ok: false, reason: `review-attempt-not-superseded: ${basename(path)} (${review.reason})` };
127
- if (!/^review-(verdict-fail|must-fix-[1-9][0-9]*)$/.test(review.reason)) {
128
- return { ok: false, reason: `review-supersedes-not-failed: ${basename(path)} (${review.reason})` };
135
+ if (superseded.has(path)) {
136
+ if (superseded.get(path) !== review.reason) return { ok: false, reason: `review-attempt-not-superseded: ${basename(path)} (${review.reason})` };
137
+ if (!/^review-(verdict-fail|must-fix-[1-9][0-9]*)$/.test(review.reason)) {
138
+ return { ok: false, reason: `review-supersedes-not-failed: ${basename(path)} (${review.reason})` };
139
+ }
140
+ continue;
141
+ }
142
+ if (!/^review-(verdict-fail|must-fix-[1-9][0-9]*)$/.test(review.reason)
143
+ || !selectedRecord || !reviewAttemptExplicitlyResolved(input, selectedRecord, path, head)) {
144
+ return { ok: false, reason: `review-attempt-not-superseded: ${basename(path)} (${review.reason})` };
145
+ }
146
+ resolvedPriorAccepted.push(path);
147
+ let failedTime: number;
148
+ try { failedTime = input.reviewMtime(path); } catch { return { ok: false, reason: 'review-attempt-time-unmeasured' }; }
149
+ if (!Number.isFinite(failedTime) || selectedTime === undefined || failedTime >= selectedTime) {
150
+ return { ok: false, reason: 'review-selected-not-later-than-failure' };
129
151
  }
130
152
  }
131
153
  if (entries?.length) {
@@ -145,11 +167,137 @@ function checkSelectedReviewAttempts(input: VerifyOverlapEvidenceInput, e: Parti
145
167
  head,
146
168
  selected,
147
169
  superseded: [...superseded.entries()].map(([reviewResult, reason]) => ({ reviewResult, reason })),
170
+ resolvedPriorAccepted,
148
171
  followupPr: e.followupPr ?? null,
149
172
  });
150
173
  return { ok: true };
151
174
  }
152
175
 
176
+ function lastReviewRecord(text: string): Record<string, unknown> | undefined {
177
+ const lines = text.split('\n').reverse();
178
+ for (const line of lines) {
179
+ if (!line.trim().startsWith('{')) continue;
180
+ let value: unknown;
181
+ try { value = JSON.parse(line); } catch { continue; }
182
+ if (!value || typeof value !== 'object' || Array.isArray(value)) continue;
183
+ const result = value as Record<string, unknown>;
184
+ if (result.pr !== undefined && (('verdict' in result && Array.isArray(result.mustFix)) || typeof result.error === 'string')) return result;
185
+ }
186
+ return undefined;
187
+ }
188
+
189
+ function hasResolvedPriorDeclaration(review: Record<string, unknown> | undefined): boolean {
190
+ if (!review) return false;
191
+ const value = review.resolvedPrior;
192
+ if (Array.isArray(value) && value.length > 0) return true;
193
+ if (value && typeof value === 'object' && Object.keys(value).length > 0) return true;
194
+ return [review.intent, review.intentBlock, review.reviewIntent, review.reviewIntentBlock]
195
+ .some((intent) => typeof intent === 'string' && /resolved prior|prior review findings resolved/i.test(intent));
196
+ }
197
+
198
+ function normalizedFinding(value: string): string {
199
+ return value.trim().replace(/\s+/g, ' ').toLowerCase();
200
+ }
201
+
202
+ function containsUnresolvedClaim(value: string): boolean {
203
+ return /\b(?:unresolved|not(?:\s+yet)?[\s-]+resolved|not(?:\s+yet)?[\s-]+fixed|not(?:\s+yet)?[\s-]+addressed|still[\s-]+open|remains?[\s-]+open|still[\s-]+present|status\s*[:=]\s*(?:open|unresolved|pending|in[- ]progress))\b/i.test(value);
204
+ }
205
+
206
+ function containsUnresolvedDeclaration(value: unknown): boolean {
207
+ if (typeof value === 'string') return containsUnresolvedClaim(value);
208
+ if (Array.isArray(value)) return value.some(containsUnresolvedDeclaration);
209
+ if (!value || typeof value !== 'object') return false;
210
+ const record = value as Record<string, unknown>;
211
+ if (record.resolved === false || (typeof record.status === 'string' && /^(?:open|unresolved|pending|in[- ]progress)$/i.test(record.status))) return true;
212
+ return Object.values(record).some(containsUnresolvedDeclaration);
213
+ }
214
+
215
+ function referencesReview(value: unknown, path: string): boolean {
216
+ return typeof value === 'string' && (value === path || value === basename(path));
217
+ }
218
+
219
+ function findingList(value: unknown): string[] {
220
+ const values = Array.isArray(value) ? value : typeof value === 'string' ? [value] : [];
221
+ return values.filter((entry): entry is string => typeof entry === 'string' && entry.trim().length > 0);
222
+ }
223
+
224
+ /** A later same-head pass/mf0 review may resolve prior attempts only when it names every finding explicitly. */
225
+ function reviewAttemptExplicitlyResolved(input: VerifyOverlapEvidenceInput, selected: Record<string, unknown>, failedPath: string, head: string): boolean {
226
+ let failed: Record<string, unknown> | undefined;
227
+ try { failed = lastReviewRecord(input.readFile(failedPath)); } catch { return false; }
228
+ if (!failed || failed.pr === undefined || String(failed.pr) !== String(input.pr)
229
+ || (typeof failed.headCommit === 'string' && failed.headCommit.toLowerCase() !== head)
230
+ || (typeof failed.currentHeadCommit === 'string' && failed.currentHeadCommit.toLowerCase() !== head)) return false;
231
+ const rawFindings = findingList(failed.mustFix).map((finding) => finding.trim());
232
+ const findings = rawFindings.map(normalizedFinding);
233
+ if (findings.length === 0) return false;
234
+
235
+ const declared = selected.resolvedPrior;
236
+ if (declared !== undefined && containsUnresolvedDeclaration(declared)) return false;
237
+ const intentBlocks = [selected.intent, selected.intentBlock, selected.reviewIntent, selected.reviewIntentBlock]
238
+ .filter((value): value is string => typeof value === 'string');
239
+ // A resolution in one field cannot override an OPEN/PENDING declaration in another.
240
+ if (intentBlocks.some(containsUnresolvedClaim)) return false;
241
+
242
+ let resolved: string[] = [];
243
+ if (Array.isArray(declared)) {
244
+ for (const entry of declared) {
245
+ if (typeof entry === 'string') {
246
+ if (containsUnresolvedClaim(entry)) continue;
247
+ // A string can be an exact finding axis or an explicit "filename: finding" row.
248
+ const line = entry.trim();
249
+ if (rawFindings.includes(line)) resolved.push(line);
250
+ const prefix = `${basename(failedPath)}: `;
251
+ if (line.startsWith(prefix)) {
252
+ const declaredFinding = line.slice(prefix.length).trim();
253
+ const index = rawFindings.indexOf(declaredFinding);
254
+ if (index >= 0) resolved.push(findings[index]!);
255
+ }
256
+ continue;
257
+ }
258
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) continue;
259
+ const item = entry as Record<string, unknown>;
260
+ const ref = item.reviewResult ?? item.review ?? item.path;
261
+ if (ref !== undefined && !referencesReview(ref, failedPath)) continue;
262
+ if (item.head !== undefined && (typeof item.head !== 'string' || item.head.toLowerCase() !== head)) continue;
263
+ if (item.headCommit !== undefined && (typeof item.headCommit !== 'string' || item.headCommit.toLowerCase() !== head)) continue;
264
+ if (item.resolved === false || item.status === 'unresolved'
265
+ || Object.values(item).some((value) => typeof value === 'string' && containsUnresolvedClaim(value))) continue;
266
+ const listed = findingList(item.mustFix ?? item.resolvedMustFix ?? item.findings ?? item.axes ?? item.finding ?? item.axis);
267
+ if (listed.some(containsUnresolvedClaim)) continue;
268
+ if (ref === undefined && listed.every((finding) => rawFindings.includes(finding.trim()))) {
269
+ resolved.push(...listed.filter((finding) => rawFindings.includes(finding.trim())));
270
+ } else if (ref !== undefined) {
271
+ resolved.push(...listed.filter((finding) => rawFindings.includes(finding.trim())));
272
+ }
273
+ }
274
+ } else if (declared && typeof declared === 'object') {
275
+ const record = declared as Record<string, unknown>;
276
+ const value = record[failedPath] ?? record[basename(failedPath)];
277
+ resolved.push(...findingList(value).filter((finding) => !containsUnresolvedClaim(finding) && rawFindings.includes(finding.trim())));
278
+ }
279
+
280
+ for (const intent of intentBlocks) {
281
+ const lines = intent.split(/\r?\n/);
282
+ const header = lines.findIndex((line) => /^resolved prior review findings:\s*$/i.test(line.trim()));
283
+ if (header < 0) continue;
284
+ // Only explicit rows under the resolution header count. A finding quoted in
285
+ // background prose is evidence of context, not a declaration of repair.
286
+ const prefix = `- ${basename(failedPath)}:`;
287
+ for (const raw of lines.slice(header + 1)) {
288
+ const line = raw.trim();
289
+ if (!line) continue;
290
+ if (!line.startsWith('- ')) break;
291
+ if (!line.startsWith(prefix)) continue;
292
+ const declaredFinding = line.slice(prefix.length).trim();
293
+ const index = rawFindings.indexOf(declaredFinding);
294
+ if (index >= 0) resolved.push(findings[index]!);
295
+ }
296
+ }
297
+ const resolvedSet = new Set(resolved.map(normalizedFinding));
298
+ return findings.every((finding) => resolvedSet.has(finding));
299
+ }
300
+
153
301
  type Checked = { ok: false; reason: string; baseTip?: string; gateBase?: string; windowCommits?: number }
154
302
  | (OverlapEvidenceVerdict & { ok: true; baseTip?: string });
155
303
 
@@ -176,17 +324,7 @@ function checkReview(input: Pick<VerifyOverlapEvidenceInput, 'pr' | 'readFile'>,
176
324
  if (review.pr !== input.pr) return { ok: false, reason: 'review-pr-mismatch', baseTip };
177
325
  if (!review.head || review.head.toLowerCase() !== head) return { ok: false, reason: 'review-head-mismatch', baseTip };
178
326
  // The capture parser projects away model provenance; inspect the same last result-shaped line here.
179
- let raw: Record<string, unknown> | undefined;
180
- for (const line of text.split('\n').reverse()) {
181
- if (!line.trim().startsWith('{')) continue;
182
- let value: unknown;
183
- try { value = JSON.parse(line); } catch { continue; }
184
- if (!value || typeof value !== 'object' || Array.isArray(value)) continue;
185
- const result = value as Record<string, unknown>;
186
- if (result.pr === undefined || !(('verdict' in result && Array.isArray(result.mustFix)) || typeof result.error === 'string')) continue;
187
- raw = result;
188
- break;
189
- }
327
+ const raw = lastReviewRecord(text);
190
328
  if (raw) {
191
329
  const actualBackend = typeof raw.actualBackend === 'string' ? raw.actualBackend.trim().toLowerCase() : '';
192
330
  const model = typeof raw.model === 'string' ? raw.model.trim().toLowerCase() : '';
@@ -63,6 +63,9 @@ export async function runLandingPodShadowJob(input: LandingPodShadowInput, deps:
63
63
  // Wait for the runner to observe abort and finish Job/Secret/lease cleanup before landing continues.
64
64
  job = await (deps.runPod ?? runPodCommand)({
65
65
  command: ['bash', '-lc', script], clone: true, source: { kind: 'commit', sha: input.head },
66
+ provenance: { actorKind: 'loop', actor: 'pr-land-shadow', kind: 'land-shadow',
67
+ run: input.head, phase: 'land-shadow', requestedAt: new Date().toISOString(),
68
+ entrance: 'pr-land', commit: input.head, reason: 'landing typecheck and changed gate shadow' },
66
69
  returnLogs: true, deadlineSeconds: 45 * 60,
67
70
  statusUnreadableMs: LANDING_POD_SHADOW_STATUS_UNREADABLE_MS,
68
71
  hostDeadlineAtMs: Date.now() + LANDING_POD_SHADOW_HOST_TIMEOUT_MS,
@@ -0,0 +1,64 @@
1
+ import { classifyPrLandRefusal } from './pr-land-refusal.js';
2
+ import { readJourneyEdge } from '../self-dev/graph-journey-route.js';
3
+
4
+ /** A recover unit selects a next action. The train or TA still owns every effect. */
5
+ export interface PrLandRecoveryContext {
6
+ refusal: string;
7
+ pr?: number;
8
+ head?: string;
9
+ isDraft?: boolean;
10
+ }
11
+
12
+ export interface PrLandRecoveryPlan {
13
+ outcome: 'rework' | 'needs-human' | 'failed';
14
+ result: { action: 'wait-retry' | 'request-review' | 'needs-human' | 'none'; pr?: number; head?: string; delayMs?: number; reason: string };
15
+ evidence: { refusal: string; label: string; route: string | null; source: string };
16
+ }
17
+
18
+ export function planPrLandRecovery(context: PrLandRecoveryContext): PrLandRecoveryPlan {
19
+ const raw = typeof context.refusal === 'string' ? context.refusal : '';
20
+ const lines = raw.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
21
+ // Callers must extract exactly one refusal line. A second diagnostic may be
22
+ // unmarked (for example `error: review-missing`), so never select a line
23
+ // from a larger transcript and mistake it for the whole verdict.
24
+ const refusal = lines.length === 1 ? lines[0]! : raw.trim();
25
+ const label = classifyPrLandRefusal(refusal, { isDraft: context.isDraft });
26
+ const route = readJourneyEdge('merge', label);
27
+ const evidence = { refusal: refusal.slice(0, 500), label, route: route.to, source: route.source };
28
+ const pr = Number.isSafeInteger(context.pr) && context.pr! > 0 ? context.pr : undefined;
29
+ const head = typeof context.head === 'string' && /^[0-9a-f]{40}$/i.test(context.head) ? context.head.toLowerCase() : undefined;
30
+ if (!refusal || !pr || !head) return { outcome: 'failed', result: { action: 'none', reason: 'pinned PR, head and refusal are required' }, evidence };
31
+ if (lines.length !== 1 || !refusal.startsWith('✗')) return { outcome: 'needs-human', result: { action: 'needs-human', pr, head, reason: `expected one marked refusal line, observed ${lines.length} nonempty lines` }, evidence };
32
+ if (route.source !== 'graph') return { outcome: 'needs-human', result: { action: 'needs-human', pr, head, reason: 'refusal has no declared graph route' }, evidence };
33
+ if (label === 'gate-host-busy' && route.to === 'next-move') {
34
+ return { outcome: 'rework', result: { action: 'wait-retry', pr, head, delayMs: 30_000, reason: 'remote gate host busy; retry through existing admission after delay' }, evidence };
35
+ }
36
+ if (label === 'review-missing' && route.to === 'review') {
37
+ return { outcome: 'rework', result: { action: 'request-review', pr, head, reason: 'request exact-head review through existing review gate' }, evidence };
38
+ }
39
+ return { outcome: 'needs-human', result: { action: 'needs-human', pr, head, reason: `${label} requires the existing ${route.to ?? 'unknown'} admission before another landing` }, evidence };
40
+ }
41
+
42
+ /** A graph call_entry cannot turn one refusal into another action. */
43
+ export function planPrLandRecoveryForEntry(context: PrLandRecoveryContext, entry: string): PrLandRecoveryPlan {
44
+ const plan = planPrLandRecovery(context);
45
+ // The default entry keeps the original read-only planner contract.
46
+ if (entry === 'plan') return plan;
47
+ if (entry === 'human-review') {
48
+ if (plan.outcome === 'needs-human' && plan.result.action === 'needs-human') return plan;
49
+ return { outcome: 'failed', result: { action: 'none', reason: `recover entry ${entry} does not match ${plan.result.action}` }, evidence: plan.evidence };
50
+ }
51
+ if (entry === 'request-review' || entry === 'wait-retry') {
52
+ if (plan.outcome === 'rework' && plan.result.action === entry) return plan;
53
+ return {
54
+ outcome: 'failed',
55
+ result: { action: 'none', reason: `recover entry ${entry} does not match ${plan.result.action}` },
56
+ evidence: plan.evidence,
57
+ };
58
+ }
59
+ return {
60
+ outcome: 'failed',
61
+ result: { action: 'none', reason: `unknown recover entry: ${entry}` },
62
+ evidence: plan.evidence,
63
+ };
64
+ }