elanous 0.2.34 → 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 (611) 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/{L04y73dlwKeTW-GetaTF3 → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{5014f970-22bef0b5210f7d60.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/{2124.ed5bf480cea7f85b.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/1674.2a65fd5668e1cc5f.js +1 -0
  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/1993-c0007b7ad0c0ef41.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{8368.014caa8de2f5af34.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/2625.5d870aa999f33db1.js +34 -0
  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/{1644.35dd25240ae24e4b.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/{3121.779fafe3e44612c5.js → 3589.5444a06bcf6e775c.js} +1 -1
  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/{9131-fce7256c4180c4a5.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/4346.8601952e73bf5803.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/{6053-d893974de92e6198.js → 4441-875b97f5821ed58a.js} +1 -1
  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/{1895-60ed0e341c658bd4.js → 4705-194e64e47ca0fbdb.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{5576-82d3703636d5c4b9.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/{7431.3051e9b8a4372d2d.js → 5101.e32282718f99ed6f.js} +2 -2
  57. package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +1 -0
  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/{2987-30cf9c2eb7b8bdd5.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/56d372f2.681ab4ec4c998fae.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/{7386.5d8e7e42e818dfb6.js → 5852.db1f7449f4f74612.js} +2 -2
  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/{3110.0a7065f25c841818.js → 6236.e18cced2d5ba6afb.js} +3 -3
  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/6b89c8bd.24df687a820500b3.js +1 -0
  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/{7005.1623d2aea78eb85f.js → 7385.50a308a477bdfc21.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{6086.913a69e6fa3e4a8b.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/8219.baa715d1deee80e2.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +1 -0
  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/{7193-cf355cca5ba6c5d5.js → 8437-8d5492094b166cfa.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/{2554.3b5e200f5f5cfcd6.js → 8444.4c26b379ca2b9596.js} +4 -4
  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/{2547.dd27303624cb4da8.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/{9550.d5f76828f972058c.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/{8548.036c344973968847.js → 938.66ad1ef0e5abae1c.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/{3414.172ad4ca2d9b08e8.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/967-2aa39b2d04b4c690.js +1 -0
  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/{6740.43de73fc427c9fe2.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-406b47745b53f269.js +1 -0
  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-d7bff0f0905a662c.js → page-26e6c18a1a750cf6.js} +1 -1
  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-47c5d4db587266bd.js +1 -0
  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-df3445b207ceceab.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/{9a8cb466.cc9fc9e6e46038aa.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/{4fa33ebd.21c1bd5b294496e6.js → cbe38a15.5a032598e39970c6.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{abb4b98b.163e0f56e84ae35d.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{9b48c871.204d5d13e7809bd0.js → da5176c6.6773b6c5994e1d99.js} +1 -1
  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 +3 -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 +4 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/default-loop.yaml +57 -3
  285. package/graphs/document-loop.yaml +51 -3
  286. package/graphs/implement-loop.yaml +53 -4
  287. package/graphs/journey/ta-journey.yaml +11 -1
  288. package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
  289. package/graphs/journey/units/author-dialogue/observe.ts +96 -0
  290. package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
  291. package/graphs/operate-loop.yaml +51 -3
  292. package/graphs/research-loop.yaml +137 -3
  293. package/graphs/test-diet/test-diet.yaml +3 -0
  294. package/package.json +1 -1
  295. package/scripts/coord-role-pack.ts +19 -6
  296. package/scripts/hq/standby-snapshot.ts +17 -12
  297. package/scripts/release-loop/docs-land-node.ts +21 -5
  298. package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
  299. package/scripts/release-loop/gate-node.ts +181 -22
  300. package/scripts/release-loop/gate-partial.ts +65 -11
  301. package/scripts/release-loop/gate-radius-live.ts +177 -0
  302. package/scripts/release-loop/gate-radius-shadow.ts +1 -1
  303. package/scripts/release-loop/node-verdict.ts +12 -1
  304. package/scripts/release-loop/npm-publish-node.ts +66 -12
  305. package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
  306. package/scripts/release-loop/pwa-remote.ts +166 -0
  307. package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
  308. package/scripts/release-loop/resume-release.ts +41 -4
  309. package/scripts/release-loop/unattended-release.ts +2 -0
  310. package/scripts/test-diet/lib.ts +6 -1
  311. package/scripts/test-diet/node.ts +194 -13
  312. package/scripts/ux-sim.ts +39 -0
  313. package/src/agent/self-ambient-cache.ts +8 -0
  314. package/src/agent-substrate/acp-reviewer.ts +39 -4
  315. package/src/agent-substrate/pr-reviewer.ts +17 -0
  316. package/src/agent-substrate/self-review-cli.ts +62 -13
  317. package/src/autopilot/pr-manager.ts +215 -36
  318. package/src/budget/run-usage-rollup.ts +1 -0
  319. package/src/chat/index.ts +0 -2
  320. package/src/chat/pickers/modal-runtime.ts +10 -27
  321. package/src/cli/agent-cli.ts +13 -2
  322. package/src/cli/doctor-cli.ts +4 -1
  323. package/src/cli/light-entry-route.ts +46 -6
  324. package/src/cli/pod-cli.ts +77 -3
  325. package/src/cli/pr-cli.ts +5 -2
  326. package/src/cli/pr-land-pod-shadow-job.ts +3 -0
  327. package/src/cli/release-checklist-read-cli.ts +79 -0
  328. package/src/cli/release-cli.ts +72 -102
  329. package/src/cli/remote-resolve.ts +1 -1
  330. package/src/cli/root-tui-entry.ts +48 -0
  331. package/src/cli/sim-cli.ts +22 -0
  332. package/src/cli/tasks-cli.ts +540 -31
  333. package/src/cli/usage-cli.ts +13 -11
  334. package/src/clipboard/history.ts +179 -13
  335. package/src/config.ts +8 -1
  336. package/src/dashboard/chat/acp-chat.ts +8 -0
  337. package/src/dashboard/index.ts +78 -10
  338. package/src/dashboard/render/theme-resolver.ts +33 -4
  339. package/src/domains/schedule-registry.ts +16 -2
  340. package/src/git-fs/idle-refresh.ts +76 -0
  341. package/src/git-fs/index.ts +18 -7
  342. package/src/git-fs/worktree.ts +42 -4
  343. package/src/graph-kinds/registry.ts +2 -2
  344. package/src/graph-runner/runner.ts +153 -10
  345. package/src/grok/credential.ts +10 -3
  346. package/src/harness/harness-cli-command.ts +112 -28
  347. package/src/harness/harness-incidents.ts +33 -0
  348. package/src/harness/launch-utterance-ledger.ts +208 -0
  349. package/src/impl-discipline/detector.ts +16 -4
  350. package/src/impl-discipline/system-prompt.ts +11 -0
  351. package/src/impl-discipline/types.ts +2 -2
  352. package/src/index.ts +496 -143
  353. package/src/intake-plane/already-built-hint.ts +4 -2
  354. package/src/intake-plane/requirement-funnel.ts +29 -1
  355. package/src/light-cli.ts +27 -11
  356. package/src/llm/opengateway-models.ts +11 -0
  357. package/src/llm/provider-credentials.ts +14 -0
  358. package/src/llm/provider-detect.ts +8 -1
  359. package/src/llm/runtime-model-family.ts +2 -1
  360. package/src/llm.ts +213 -56
  361. package/src/model-tier/llm-tier-map.ts +15 -1
  362. package/src/native-tool-catalog.ts +15 -1
  363. package/src/nexus/api/loop-resources.ts +13 -1
  364. package/src/oauth/codex.ts +7 -0
  365. package/src/ops/overview-collect.ts +18 -3
  366. package/src/ops/overview.ts +20 -7
  367. package/src/pr-tool/census.ts +261 -27
  368. package/src/pty-shell/pty-manifest.ts +7 -0
  369. package/src/release-loop/checklist.ts +24 -0
  370. package/src/release-loop/landed-but-yellow.ts +129 -5
  371. package/src/release-loop/light-rc.ts +1 -0
  372. package/src/release-loop/rehearsal.ts +2 -2
  373. package/src/repl/index.ts +174 -17
  374. package/src/repl/ops-msg-bridge.ts +32 -0
  375. package/src/self-dev/ask-launch-flow.ts +44 -5
  376. package/src/self-dev/cli-help-text.ts +17 -0
  377. package/src/self-dev/dev-cli.ts +11 -9
  378. package/src/self-dev/draft-residue.ts +37 -1
  379. package/src/self-dev/draft-sweep.ts +137 -11
  380. package/src/self-dev/draft-triage-rules.ts +107 -0
  381. package/src/self-dev/fleet-reduce.ts +3 -2
  382. package/src/self-dev/graph-front-nodes.ts +112 -0
  383. package/src/self-dev/graph-journey-nodes.ts +1 -0
  384. package/src/self-dev/harness-run-cli.ts +3 -15
  385. package/src/self-dev/orchestrate-cli-text.ts +10 -0
  386. package/src/self-dev/review-provider-fallback.ts +35 -1
  387. package/src/self-dev/self-orchestrate-runtime.ts +1 -11
  388. package/src/self-dev/shard-aggregate.ts +42 -5
  389. package/src/self-dev/shard-run.ts +8 -1
  390. package/src/self-implement/blocked-draft-policy.ts +20 -0
  391. package/src/self-implement/classify-shadow.ts +3 -7
  392. package/src/self-implement/doctor-visit.ts +18 -1
  393. package/src/self-implement/gate-baseline.ts +56 -17
  394. package/src/self-implement/gate-cli.ts +1 -0
  395. package/src/self-implement/gate-remote.ts +31 -20
  396. package/src/self-implement/goal-author-decompose.ts +275 -47
  397. package/src/self-implement/goal-author.ts +250 -0
  398. package/src/self-implement/goal-elaborate.ts +295 -0
  399. package/src/self-implement/goal-refine.ts +270 -0
  400. package/src/self-implement/graph-overlay-yaml.ts +14 -3
  401. package/src/self-implement/orchestrator.ts +152 -45
  402. package/src/self-implement/rework-budget-judgment.ts +5 -8
  403. package/src/self-implement/run-stop.ts +10 -1
  404. package/src/self-implement/running-runs.ts +29 -1
  405. package/src/self-implement/scope-adjacency.ts +113 -0
  406. package/src/self-implement/seams.ts +127 -24
  407. package/src/self-implement/stop-autoheal.ts +87 -1
  408. package/src/session-runtime/index.ts +1 -1
  409. package/src/setup/llm-env-detect.ts +5 -0
  410. package/src/skills/tools/agent.ts +140 -14
  411. package/src/skills/tools/msg-ask.ts +100 -0
  412. package/src/skills/tools/ops-ledger.ts +2 -1
  413. package/src/steward/hold-hygiene.ts +24 -6
  414. package/src/steward/triage-budget.ts +194 -0
  415. package/src/steward/triage.ts +20 -3
  416. package/src/task-agent/actions.ts +69 -1
  417. package/src/task-agent/green-sweep.ts +4 -0
  418. package/src/task-agent/live-moves.ts +160 -4
  419. package/src/task-agent/parent-host.ts +123 -3
  420. package/src/task-agent/shadow.ts +7 -1
  421. package/src/task-agent/task-hand.ts +54 -41
  422. package/src/task-agent/tier-split.ts +127 -0
  423. package/src/task-agent/work-order-build.ts +2 -0
  424. package/src/task-agent/work-order.ts +3 -2
  425. package/src/task-orchestrator/generator-prompt.ts +60 -11
  426. package/src/task-orchestrator/surfaces/pod-account-broker.ts +33 -0
  427. package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
  428. package/src/task-orchestrator/surfaces/pod-command-job.ts +45 -7
  429. package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
  430. package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
  431. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +8 -2
  432. package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -0
  433. package/src/task-orchestrator/surfaces/pod-source-receive.ts +18 -0
  434. package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
  435. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +6 -2
  436. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +3 -0
  437. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +37 -5
  438. package/src/task-orchestrator/surfaces/self-implement-pod.ts +368 -36
  439. package/src/task-orchestrator/surfaces/self-implement.ts +23 -0
  440. package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
  441. package/src/tui/README.md +2 -0
  442. package/src/tui/chat/background-job-status.ts +54 -0
  443. package/src/tui/chat/log-view.ts +80 -0
  444. package/src/tui/entry.ts +406 -0
  445. package/src/tui/input/composer.ts +144 -0
  446. package/src/tui/seat-mail-boot.ts +59 -0
  447. package/src/tui/slash/compact.ts +100 -0
  448. package/src/tui/slash/new-session.ts +35 -0
  449. package/src/tui-client/local-chat-turn.ts +239 -0
  450. package/src/tui-client/local-harness-command.ts +63 -0
  451. package/src/tui-client/local-provider-command.ts +184 -0
  452. package/src/user-config.ts +4 -2
  453. package/src/ux-sim/event-monkey.ts +378 -0
  454. package/src/ux-sim/fake-bin.ts +42 -7
  455. package/src/ux-sim/fault-nextmove-dispatch.ts +266 -0
  456. package/src/ux-sim/fault-pod-codex-503.ts +211 -0
  457. package/src/ux-sim/fault-scope-escape-lift.ts +189 -0
  458. package/src/version/packed-revision.json +1 -1
  459. package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +0 -79
  460. package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +0 -94
  463. package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +0 -23
  465. package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +0 -115
  467. package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +0 -8
  468. package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/3001-5a52788c813b6113.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/3103.84470c8445962f04.js +0 -34
  479. package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/3411-f87314c6c66ebc73.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/3498.cf2a15a8a9e5b926.js +0 -226
  485. package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/3819.163d4777f0a597f6.js +0 -32
  487. package/apps/pwa/out/_next/static/chunks/3837.722e053fb9f321ad.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +0 -104
  490. package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +0 -286
  491. package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +0 -149
  492. package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +0 -148
  493. package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +0 -64
  494. package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +0 -74
  497. package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/5028-f0722e6114c313e7.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/5249.96a848656b582a93.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +0 -62
  504. package/apps/pwa/out/_next/static/chunks/5446.edf141cff9ef647d.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/5489.ec2dd1b5272a19dc.js +0 -24
  506. package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +0 -1
  510. package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +0 -77
  517. package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +0 -90
  520. package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/7448.478958ffbbba0ac0.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/7562.948255cbc3e79d33.js +0 -41
  527. package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +0 -27
  530. package/apps/pwa/out/_next/static/chunks/7952.b192c31b6a0e00cc.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +0 -36
  533. package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/8817.61bb7ffbba502ecb.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +0 -93
  547. package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +0 -24
  549. package/apps/pwa/out/_next/static/chunks/9739.8d5f36ac67a3b236.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/field/page-4fb31eb476dcbad3.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-398c0faa173203f7.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +0 -122
  603. package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/ffdc3a04.b9c23c1b28dd4a96.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +0 -1
  611. /package/apps/pwa/out/_next/static/{L04y73dlwKeTW-GetaTF3 → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
@@ -1,8 +1,41 @@
1
1
  export type LightCliRoute = 'msg' | 'release' | 'tasks' | 'pty' | 'logs' | 'config';
2
2
 
3
3
  const VALUE_FLAGS = new Set(['--config-dir', '--test-state-dir']);
4
+ const HOT_ROOTS = new Set(['msg', 'pty', 'logs', 'tasks']);
5
+ const ROOT_GLOBAL_FLAGS = new Set(['--test', '--config-dir', '--test-state-dir', '--state-dir', '--remote', '-r', '--name', '--help-all', '--version', '-V']);
6
+ const LOG_SUBCOMMANDS = new Set([
7
+ 'instances', 'level', 'timeline', 'durations', 'model-input', 'degenerate', 'fields', 'unclosed', 'abandoned-draft-prs',
8
+ ]);
9
+ const LOG_VALUE_FLAGS = new Set([
10
+ '--level', '--surface', '--space', '--category', '--exact-category', '--axis', '--event', '--grep',
11
+ '--rework-recurrence-disagreement', '--since', '--until', '--before', '--session', '--limit', '--threshold', '--instance',
12
+ ]);
13
+ const LOG_BOOLEAN_FLAGS = new Set([
14
+ '-h', '--help', '-f', '--follow', '--list-categories', '--list-events', '--explain', '--top-failures', '--json', '--json-data', '--test', '--all', '--include-test',
15
+ ]);
4
16
 
5
- /** Select only read-heavy command paths whose CLI module can stand alone. */
17
+ function isRootGlobalFlag(arg: string): boolean {
18
+ return [...ROOT_GLOBAL_FLAGS].some(flag => arg === flag || arg.startsWith(`${flag}=`))
19
+ || (arg.startsWith('-') && !arg.startsWith('--') && (arg.startsWith('-r') && arg.length > 2 || arg.slice(1).includes('V')));
20
+ }
21
+
22
+ function isSupportedLogsShape(args: readonly string[]): boolean {
23
+ for (let index = 1; index < args.length; index += 1) {
24
+ const token = args[index]!;
25
+ if (token.startsWith('-')) {
26
+ const equals = token.indexOf('=');
27
+ const flag = equals < 0 ? token : token.slice(0, equals);
28
+ if (LOG_BOOLEAN_FLAGS.has(flag)) continue;
29
+ if (!LOG_VALUE_FLAGS.has(flag)) return false;
30
+ if (equals < 0) index += 1;
31
+ continue;
32
+ }
33
+ return LOG_SUBCOMMANDS.has(token);
34
+ }
35
+ return true;
36
+ }
37
+
38
+ /** Select lightweight operational paths whose CLI modules can stand alone. */
6
39
  export function selectLightCliRoute(args: readonly string[]): LightCliRoute | undefined {
7
40
  const command: string[] = [];
8
41
  let index = 0;
@@ -24,12 +57,19 @@ export function selectLightCliRoute(args: readonly string[]): LightCliRoute | un
24
57
  command.push(token);
25
58
  }
26
59
 
27
- if (command[0] === 'msg' && (command[1] === 'list' || command[1] === 'ack' || command[1] === 'watch')) return 'msg';
60
+ // These four operational roots are the hot router. Keep all root flags and
61
+ // every leading-option form on the full entry so its isolation/bootstrap
62
+ // parser remains the sole owner of those semantics.
63
+ if (HOT_ROOTS.has(command[0] ?? '') && (args[0] !== command[0] || args.some(isRootGlobalFlag))) return undefined;
64
+
65
+ if (command[0] === 'msg' && ['list', 'post', 'ack', 'watch'].includes(command[1] ?? '')) return 'msg';
28
66
  // --reveal has an audit-log contract owned by the full CLI.
29
67
  if (command[0] === 'config' && command[1] === 'get' && !args.some(arg => arg === '--reveal' || arg.startsWith('--reveal='))) return 'config';
30
- if (command[0] === 'release' && command[1] === 'checklist' && command[2] === 'status') return 'release';
31
- if (command[0] === 'tasks' && command[1] === 'show') return 'tasks';
32
- if (command[0] === 'pty' && (command[1] === 'list' || command[1] === 'state')) return 'pty';
33
- if (command[0] === 'logs') return 'logs';
68
+ if (command[0] === 'release' && command[1] === 'checklist'
69
+ && (command[2] === 'status' || command[2] === 'list')) return 'release';
70
+ if (command[0] === 'tasks' && (command[1] === 'list' || command[1] === 'show'
71
+ || (command[1] === 'hand' && args.includes('--help')))) return 'tasks';
72
+ if (command[0] === 'pty' && ['list', 'snapshot', 'text', 'state'].includes(command[1] ?? '')) return 'pty';
73
+ if (command[0] === 'logs' && isSupportedLogsShape(args)) return 'logs';
34
74
  return undefined;
35
75
  }
@@ -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,
@@ -71,7 +72,7 @@ import { readTaskAgentState, taskAgentStatePath, type TaskCard } from '../task-a
71
72
  import { INFLIGHT_REGISTRY_FILE, removeInflightForPr } from '../pr-tool/inflight-registry.js';
72
73
  import { PR_LABEL_NAMES } from '../github/pr-labels.js';
73
74
  import { enqueueL8ShadowQueue, runL8ShadowQueue, shadowPrNumber, statusL8ShadowQueue, type L8ShadowQueueDeps } from '../self-implement/l8-merge-queue.js';
74
- 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';
75
76
 
76
77
  export { branchLineageSlug, findSiblingPrs };
77
78
 
@@ -2542,7 +2543,9 @@ export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queu
2542
2543
  const diff = prToolRun('git', ['-C', cwd, 'diff', '--name-only', '-z', `${opts.base}...HEAD`]);
2543
2544
  const files = diff.ok ? diff.out.split('\0').filter(Boolean) : null;
2544
2545
  const patch = prToolRun('git', ['-C', cwd, 'diff', '--unified=0', `${opts.base}...HEAD`]);
2545
- 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 }) });
2546
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);
2547
2550
  // Inspection never spends the three-creation unmeasured allowance.
2548
2551
  // Only pr-manager records an actual new-PR attempt in that ledger.
@@ -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,79 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import type { Command } from 'commander';
4
+ import { debug } from '../debug/log.js';
5
+ import { getElanousConfigDirOverride } from '../elanous-config-dir.js';
6
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
7
+ import { devVersion, listChecklist, ownerMatches, parseOwner, parityGap, summarizeChecklist } from '../release-loop/checklist.js';
8
+ import { userConfigPath } from '../user-config.js';
9
+ import { CliUserError } from './cli-user-error.js';
10
+ import { writeStdoutJson } from './stdout-json.js';
11
+
12
+ const SEMVER = /^\d+\.\d+\.\d+(?:-(?:rc|alpha|beta)\.\d+)?$/;
13
+ export function isReleaseVersion(version: string): boolean { return SEMVER.test(version); }
14
+
15
+ export function checklistCodenames(): Record<string, string> {
16
+ const path = getElanousConfigDirOverride() ? join(effectiveInstanceRoot(), 'config.json') : userConfigPath();
17
+ if (!existsSync(path)) return {};
18
+ const raw = JSON.parse(readFileSync(path, 'utf8')) as { release?: { codenames?: Record<string, string> } };
19
+ return raw.release?.codenames ?? {};
20
+ }
21
+
22
+ export function checklistVersion(input: string | undefined, codenames: Record<string, string>): string {
23
+ const v = input ?? devVersion().replace(/-dev\.\d+$/, '');
24
+ const resolved = isReleaseVersion(v) ? v : Object.entries(codenames).find(([, name]) => name === v)?.[0] ?? v;
25
+ if (!isReleaseVersion(resolved)) throw new CliUserError(`체크리스트 판 또는 별칭이 아니다: ${v}`);
26
+ return resolved;
27
+ }
28
+
29
+ export function readChecklistContext(cmd: Command): { version: string; codenames: Record<string, string>; json?: boolean } {
30
+ const opts = { ...(cmd.parent?.parent?.opts() as { version?: string; json?: boolean }), ...(cmd.parent?.opts() as { version?: string; json?: boolean }), ...(cmd.opts() as { version?: string; json?: boolean }) };
31
+ const codenames = checklistCodenames();
32
+ return { version: checklistVersion(opts.version, codenames), codenames, json: opts.json };
33
+ }
34
+
35
+ export async function checklistOutput(v: string, codenames: Record<string, string>, mode: 'list' | 'status', json?: boolean, owner?: string): Promise<void> {
36
+ if (owner !== undefined) parseOwner(owner);
37
+ const snapshot = listChecklist(v);
38
+ const data = owner === undefined ? snapshot : { ...snapshot, items: snapshot.items.filter((item) => ownerMatches(item.owner, owner)) };
39
+ const summary = summarizeChecklist(data);
40
+ const parity = data.items.flatMap((item) => {
41
+ const why = item.kind === 'screen' ? parityGap(item.evidence) : null;
42
+ return why ? [{ id: item.id, why }] : [];
43
+ });
44
+ const result = { ...data, codename: codenames[v] ?? '', ...summary, parity };
45
+ for (const { id, why } of parity) debug.log('release.checklist', 'parity-warning', { version: v, id, why });
46
+ if (json) { await writeStdoutJson(`${JSON.stringify(result)}\n`); return; }
47
+ console.log(`⚠ 짝 경고 ${parity.length}: ${parity.map(({ id }) => id).join(', ') || '없음'}`);
48
+ console.log(`${v}${result.codename ? ` (${result.codename})` : ''} · 공개 ${data.released || '없음'} · 개발 ${data.dev}`);
49
+ if (mode === 'list') {
50
+ for (const item of data.items) console.log(`${({ green: '🟢', yellow: '🟡', red: '🔴', done: '✅' } as const)[item.status]} ${item.id} ${item.title}${item.owner ? ` · ${item.owner}` : ''}${item.ceoMinutes !== undefined ? ` · 대표 손 ${item.ceoMinutes}분${item.ceoDate ? ` (${item.ceoDate})` : ''}` : ''}`);
51
+ } else {
52
+ console.log(`🟢 ${summary.green} · 🟡 ${summary.yellow} · 🔴 ${summary.red} · ✅ ${summary.done}`);
53
+ console.log(`🔴 칸: ${summary.blocked.join(', ') || '없음'}`);
54
+ console.log(`담당별: ${Object.entries(summary.byOwner).map(([owner, count]) => `${owner} ${count}`).join(' · ') || '없음'}`);
55
+ }
56
+ }
57
+
58
+ /** Register the same read commands on the full and lightweight release roots. */
59
+ export function registerChecklistReadCommands(checklist: Command): void {
60
+ const withContext = (cmd: Command) => cmd.option('--version <v>', '판 또는 별칭').option('--json', '결과 JSON').option('--hq-override', '본부 임대 거부를 관측하며 수동 우회');
61
+ withContext(checklist.command('list').description('모든 칸')).option('--owner <owner>', '자리 또는 하위 자리로 거르기').action(async (opts: { owner?: string }, cmd: Command) => {
62
+ const { version, codenames, json } = readChecklistContext(cmd);
63
+ await checklistOutput(version, codenames, 'list', json, opts.owner);
64
+ });
65
+ withContext(checklist.command('status').description('상태 요약')).option('--owner <owner>', '자리 또는 하위 자리로 거르기').action(async (opts: { owner?: string }, cmd: Command) => {
66
+ const { version, codenames, json } = readChecklistContext(cmd);
67
+ await checklistOutput(version, codenames, 'status', json, opts.owner);
68
+ });
69
+ }
70
+
71
+ /** The light router enters only list/status, so no publishing modules are loaded. */
72
+ export function registerReleaseChecklistReadCommands(program: Command): void {
73
+ const release = program.command('release').description('공개 배포 한 판 — prepare(로컬) → publish(--yes) → verify (docs/manual/MANUAL-versioning-and-release-2026-09-25.md)');
74
+ const checklist = release.command('checklist').description('판별 확인표 조회·갱신')
75
+ .option('--version <v>', '판 또는 별칭(기본: package.json 의 개발판에서 -dev.N 제거)')
76
+ .option('--json', '결과 JSON')
77
+ .option('--hq-override', '본부 임대 거부를 관측하며 수동 우회');
78
+ registerChecklistReadCommands(checklist);
79
+ }
@@ -8,7 +8,7 @@
8
8
  // elanous release run --version <x.y.z> [--prerelease rc] [--main-cut | --cut-commit <sha>] [--publish-at <iso>] [--gate-executor <pod|host> [--gate-host <ssh-host>]] [--dry-run] [--json] [--if-ready] [--force-new]
9
9
  // elanous release resume --run <runId> --from <node> [--waive <node> --reason <text>] [--accepted-regressions <json>] [--gate-executor <pod|host> [--gate-host <ssh-host>]] [--gate-pod-pool <pool>] [--json]
10
10
  // elanous release auto-start [--window-minutes <n>] [--apply] [--json]
11
- // elanous release rehearsal tick [--apply] [--checkout <dir>] [--shards <n>] [--remote <host>] [--json]
11
+ // elanous release rehearsal tick [--apply] [--checkout <dir>] [--shards <n>] [--remote <host>] [--recovery-run <id>] [--json]
12
12
  // elanous release preflight --version <x.y.z> [--publish-at <iso>] [--json] (컷 − 60분 main export 포함 사전 점검 · 읽기 전용 · ⛔ 있으면 exit 1)
13
13
  // elanous release cut-branch --version <x.y.z> --base <sha> --pick <sha>... [--dry-run]
14
14
  //
@@ -17,7 +17,7 @@
17
17
  // ⛔ prepare 는 «네트워크에 아무것도 쓰지 않는다»(공개 저장소를 «읽기»로 clone 만 한다) — 쓰는 것은 publish 뿐이고 `--yes` 가 있어야 한다.
18
18
  // 공개는 되돌릴 수 없다(그 판은 영구히 공개 라이선스).
19
19
  // ⛔ 공개본은 «원본 매니페스트»(`release/public-export.yaml`)대로만 만든다 — 매매 실행 코드는 그 매니페스트가 이미 뺀다(🅢 #20529).
20
- import { spawnSync } from 'node:child_process';
20
+ import { spawn, spawnSync } from 'node:child_process';
21
21
  import { createHash } from 'node:crypto';
22
22
  import { chmodSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync } from 'node:fs';
23
23
  import { tmpdir } from 'node:os';
@@ -27,10 +27,10 @@ import { debug } from '../debug/log.js';
27
27
  import { effectiveInstanceRoot, releaseLedgerRoot } from '../instance/resolve.js';
28
28
  import { getElanousConfigDirOverride } from '../elanous-config-dir.js';
29
29
  import { envLiteral } from '../platform/env-literal.js';
30
- import { getUserConfig, userConfigPath } from '../user-config.js';
31
- import { addItem, cellsReferencingDoc, claimItem, decodeClaimHistoryEntry, devVersion, inspectChecklistTargetPaths, lintDocRefs, listChecklist, normalizeRefs, noteDispatchSkip, ownerMatches, parseOwner, parityGap, refRoots, removeItem, renderRefsStatus, seedFromRoadmap, setItem, summarizeChecklist, type ChecklistStatus, type ChecklistDisposition, type ChecklistKind, type ChecklistDispatchKind } from '../release-loop/checklist.js';
30
+ import { getUserConfig } from '../user-config.js';
31
+ import { addItem, cellsReferencingDoc, claimItem, decodeClaimHistoryEntry, inspectChecklistTargetPaths, lintDocRefs, listChecklist, normalizeRefs, noteDispatchSkip, ownerMatches, parseOwner, parityGap, refRoots, removeItem, renderRefsStatus, seedFromRoadmap, setItem, type ChecklistStatus, type ChecklistDisposition, type ChecklistKind, type ChecklistDispatchKind } from '../release-loop/checklist.js';
32
32
  import * as features from '../release-loop/feature-store.js';
33
- import { evidencePlan, landedButYellow, type MergedChecklistPr } from '../release-loop/landed-but-yellow.js';
33
+ import { evidencePlan, fetchMergedChecklistPrs, landedButYellow, type MergedPrRunner } from '../release-loop/landed-but-yellow.js';
34
34
  import { formatSchedule, getSchedule, listSchedules, setSchedule } from '../release-loop/release-schedule.js';
35
35
  import { mergedPrsLast24h, placeCell, planPullForward, pullForwardPlacementConfig, rebalance, seatMove, type PlacementPriority } from '../release-loop/placement.js';
36
36
  import { readTrafficSignal } from '../seat-loop/traffic-signal.js';
@@ -43,7 +43,7 @@ import { isIsolatedLedgerWriteRoot } from '../hq/ledger-write-target.js';
43
43
  import { runUnattendedRelease, type UnattendedReleaseDeps } from '../../scripts/release-loop/unattended-release.js';
44
44
  import { publishAtError } from '../../scripts/release-loop/publish-at.js';
45
45
  import { cutReleaseBranch } from '../../scripts/release-loop/cut-branch.js';
46
- import { planResumeReleaseRun, resumeReleaseRun } from '../../scripts/release-loop/resume-release.js';
46
+ import { planResumeReleaseRun, resumeReleaseRun, type ResumeReleaseDeps } from '../../scripts/release-loop/resume-release.js';
47
47
  import type { AcceptedRegression } from '../../scripts/release-loop/resume.js';
48
48
  import type { PrereleaseKind } from '../../scripts/release-loop/release-version.js';
49
49
  import { releaseReadiness } from '../../scripts/release-loop/release-readiness.js';
@@ -57,9 +57,11 @@ import { landingFreezeMessage, LandingFrozenError, readLandingFreeze } from '../
57
57
  import { formatLightRc, runLightRc, type LightRcDeps } from '../release-loop/light-rc.js';
58
58
  import { applyWatchList, formatGateHistory, gateHistory, ghMergedPrs } from '../../scripts/release-loop/gate-history.js';
59
59
  import { registerRfcCommands } from './rfc-cli.js';
60
+ import { checklistCodenames, checklistVersion, isReleaseVersion, readChecklistContext, registerChecklistReadCommands } from './release-checklist-read-cli.js';
61
+
62
+ export { isReleaseVersion } from './release-checklist-read-cli.js';
60
63
 
61
64
  export const DEFAULT_PUBLIC_REPO = 'ElanvitalAI/elanous';
62
- const SEMVER = /^\d+\.\d+\.\d+(?:-(?:rc|alpha|beta)\.\d+)?$/;
63
65
 
64
66
  export interface RunResult { status: number | null; stdout: string; stderr: string }
65
67
  export type Runner = (command: string, args: readonly string[], cwd: string, opts?: { env?: NodeJS.ProcessEnv; input?: string }) => RunResult;
@@ -69,7 +71,6 @@ export const defaultRunner: Runner = (command, args, cwd, opts = {}) => {
69
71
  return { status: r.status, stdout: r.stdout ?? '', stderr: r.error ? String(r.error) : (r.stderr ?? '') };
70
72
  };
71
73
 
72
- export function isReleaseVersion(version: string): boolean { return SEMVER.test(version); }
73
74
  export function isPrerelease(version: string): boolean { return version.includes('-'); }
74
75
 
75
76
  export interface ReleaseManifest {
@@ -535,45 +536,12 @@ function warnChecklistTargetPaths(input: { title: string; evidence?: string; ref
535
536
  }
536
537
  }
537
538
 
538
- function checklistCodenames(): Record<string, string> {
539
- const path = getElanousConfigDirOverride() ? join(effectiveInstanceRoot(), 'config.json') : userConfigPath();
540
- if (!existsSync(path)) return {};
541
- const raw = JSON.parse(readFileSync(path, 'utf8')) as { release?: { codenames?: Record<string, string> } };
542
- return raw.release?.codenames ?? {};
543
- }
544
-
545
- function checklistVersion(input: string | undefined, codenames: Record<string, string>): string {
546
- const v = input ?? devVersion().replace(/-dev\.\d+$/, '');
547
- const resolved = isReleaseVersion(v) ? v : Object.entries(codenames).find(([, name]) => name === v)?.[0] ?? v;
548
- if (!isReleaseVersion(resolved)) throw new CliUserError(`체크리스트 판 또는 별칭이 아니다: ${v}`);
549
- return resolved;
550
- }
551
-
552
- async function checklistOutput(v: string, codenames: Record<string, string>, mode: 'list' | 'status', json?: boolean, owner?: string): Promise<void> {
553
- if (owner !== undefined) parseOwner(owner);
554
- const snapshot = listChecklist(v);
555
- const data = owner === undefined ? snapshot : { ...snapshot, items: snapshot.items.filter((item) => ownerMatches(item.owner, owner)) };
556
- const summary = summarizeChecklist(data);
557
- const parity = data.items.flatMap((item) => {
558
- const why = item.kind === 'screen' ? parityGap(item.evidence) : null;
559
- return why ? [{ id: item.id, why }] : [];
560
- });
561
- const result = { ...data, codename: codenames[v] ?? '', ...summary, parity };
562
- for (const { id, why } of parity) debug.log('release.checklist', 'parity-warning', { version: v, id, why });
563
- if (json) { await writeStdoutJson(`${JSON.stringify(result)}\n`); return; }
564
- console.log(`⚠ 짝 경고 ${parity.length}: ${parity.map(({ id }) => id).join(', ') || '없음'}`);
565
- console.log(`${v}${result.codename ? ` (${result.codename})` : ''} · 공개 ${data.released || '없음'} · 개발 ${data.dev}`);
566
- if (mode === 'list') {
567
- for (const item of data.items) console.log(`${({ green: '🟢', yellow: '🟡', red: '🔴', done: '✅' } as const)[item.status]} ${item.id} ${item.title}${item.owner ? ` · ${item.owner}` : ''}${item.ceoMinutes !== undefined ? ` · 대표 손 ${item.ceoMinutes}분${item.ceoDate ? ` (${item.ceoDate})` : ''}` : ''}`);
568
- } else {
569
- console.log(`🟢 ${summary.green} · 🟡 ${summary.yellow} · 🔴 ${summary.red} · ✅ ${summary.done}`);
570
- console.log(`🔴 칸: ${summary.blocked.join(', ') || '없음'}`);
571
- console.log(`담당별: ${Object.entries(summary.byOwner).map(([owner, count]) => `${owner} ${count}`).join(' · ') || '없음'}`);
572
- }
573
- }
574
-
575
539
  export interface LandedButYellowDeps {
576
540
  run?: Runner;
541
+ /** Async gh for the merged-PR windows; wins over `run` (tests inject delay). */
542
+ runAsync?: MergedPrRunner;
543
+ /** logs.db sink for the stage timings; the default registers only on the real (uninjected) gh path. */
544
+ registerLogSink?: () => Promise<unknown>;
577
545
  checklist?: typeof listChecklist;
578
546
  now?: () => Date;
579
547
  evidenceAdd?: typeof features.evidenceAdd;
@@ -581,45 +549,18 @@ export interface LandedButYellowDeps {
581
549
  released?: typeof features.releasedVersion;
582
550
  }
583
551
 
584
- const MERGED_PR_LIMIT = 400;
585
-
586
- function mergedChecklistPrs(since: string, now: Date, run: Runner): { prs: MergedChecklistPr[]; truncated: boolean } {
587
- const cwd = process.cwd();
588
- const fetch = (lower: string, upper?: string, limit = MERGED_PR_LIMIT): MergedChecklistPr[] => {
589
- const search = `merged:>=${lower}${upper ? ` merged:<${upper}` : ''}`;
590
- const raw = must(run('gh', ['pr', 'list', '--state', 'merged', '--search', search, '--limit', String(limit), '--json', 'number,title,body,mergedAt'], cwd), '병합 PR 조회(gh)');
591
- const page = JSON.parse(raw) as MergedChecklistPr[];
592
- if (!Array.isArray(page)) throw new Error('병합 PR 조회(gh): 배열이 아니다');
593
- return page;
594
- };
595
- const unique = new Map<number, MergedChecklistPr>();
596
- let truncated = false;
597
- const collect = (page: MergedChecklistPr[]) => {
598
- for (const pr of page) if (!unique.has(pr.number)) unique.set(pr.number, pr);
599
- };
600
- const first = fetch(since);
601
- if (first.length < MERGED_PR_LIMIT) return { prs: first, truncated: false };
602
- const lower = Date.parse(`${since}T00:00:00Z`);
603
- const upper = Math.max(lower + 1000, Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1));
604
- const visit = (start: number, end: number): void => {
605
- const from = new Date(start).toISOString();
606
- const to = new Date(end).toISOString();
607
- const page = fetch(from, to);
608
- if (page.length < MERGED_PR_LIMIT) { collect(page); return; }
609
- if (end - start <= 1000) {
610
- // The second-precision search cannot be subdivided; probe one extra row to distinguish exactly 400 from a real truncation.
611
- const probe = fetch(from, to, MERGED_PR_LIMIT + 1);
612
- collect(probe.slice(0, MERGED_PR_LIMIT));
613
- if (probe.length > MERGED_PR_LIMIT) truncated = true;
614
- return;
615
- }
616
- const middle = start + Math.floor((end - start) / 2000) * 1000;
617
- visit(start, middle);
618
- visit(middle, end);
619
- };
620
- visit(lower, upper);
621
- return { prs: [...unique.values()], truncated };
622
- }
552
+ /** A spawn failure (gh missing from PATH) resolves `status: null` with the error text — the shape the sync runner gave. */
553
+ const defaultMergedPrRunner: MergedPrRunner = (command, args, cwd) => new Promise((resolve) => {
554
+ const out: Buffer[] = [], err: Buffer[] = [];
555
+ const failed = (error: unknown) => resolve({ status: null, stdout: Buffer.concat(out).toString('utf8'), stderr: String(error) });
556
+ let child: ReturnType<typeof spawn>;
557
+ try { child = spawn(command, [...args], { cwd, env: process.env, stdio: ['ignore', 'pipe', 'pipe'] }); }
558
+ catch (error) { failed(error); return; }
559
+ child.stdout?.on('data', (chunk: Buffer) => out.push(chunk));
560
+ child.stderr?.on('data', (chunk: Buffer) => err.push(chunk));
561
+ child.on('error', failed);
562
+ child.on('close', (code) => resolve({ status: code, stdout: Buffer.concat(out).toString('utf8'), stderr: Buffer.concat(err).toString('utf8') }));
563
+ });
623
564
 
624
565
  function printLandedRows(rows: ReturnType<typeof landedButYellow>, items: ReturnType<typeof listChecklist>['items']): void {
625
566
  const updatedAtById = new Map(items.map((item) => [item.id, item.updatedAt]));
@@ -647,7 +588,7 @@ function compareReleaseVersions(a: string, b: string): number {
647
588
  return 0;
648
589
  }
649
590
 
650
- export function registerReleaseCommands(program: Command, releaseRunDeps: UnattendedReleaseDeps = {}, landedDeps: LandedButYellowDeps = {}, hqDeps: HqDeps = {}, lightRcDeps: LightRcDeps = {}, rehearsalDeps: RehearsalDeps = {}): void {
591
+ export function registerReleaseCommands(program: Command, releaseRunDeps: UnattendedReleaseDeps = {}, landedDeps: LandedButYellowDeps = {}, hqDeps: HqDeps = {}, lightRcDeps: LightRcDeps = {}, rehearsalDeps: RehearsalDeps = {}, resumeDeps: ResumeReleaseDeps = {}): void {
651
592
  registerRfcCommands(program);
652
593
  const release = program.command('release').description('공개 배포 한 판 — prepare(로컬) → publish(--yes) → verify (docs/manual/MANUAL-versioning-and-release-2026-09-25.md)');
653
594
  const schedule = release.command('schedule').description('판별 컷·착지 마감 조회·갱신');
@@ -789,11 +730,7 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
789
730
  .option('--json', '결과 JSON')
790
731
  .option('--hq-override', '본부 임대 거부를 관측하며 수동 우회');
791
732
  const mayWrite = (cmd: Command) => mayWriteLedger(`release checklist ${cmd.name()}`, Boolean(cmd.optsWithGlobals().hqOverride), releaseLedgerRoot());
792
- const context = (cmd: Command) => {
793
- const opts = { ...(cmd.parent?.parent?.opts() as { version?: string; json?: boolean }), ...(cmd.parent?.opts() as { version?: string; json?: boolean }), ...(cmd.opts() as { version?: string; json?: boolean }) };
794
- const codenames = checklistCodenames();
795
- return { version: checklistVersion(opts.version, codenames), codenames, json: opts.json };
796
- };
733
+ const context = readChecklistContext;
797
734
  const withContext = (cmd: Command) => cmd.option('--version <v>', '판 또는 별칭').option('--json', '결과 JSON').option('--hq-override', '본부 임대 거부를 관측하며 수동 우회');
798
735
  const actor = () => process.env.ELANOUS_TRACK || 'cli';
799
736
  withContext(checklist.command('rubric').description('루브릭 채점(읽기 전용)'))
@@ -843,20 +780,30 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
843
780
  console.log(renderRefsStatus(rows));
844
781
  console.log(`칸 ${rows.length} · 🟢 ${byStatus.green} · 🟡 ${byStatus.yellow} · 🔴 ${byStatus.red} · ✅ ${byStatus.done}`);
845
782
  });
846
- withContext(checklist.command('list').description('모든 칸')).option('--owner <owner>', '자리 또는 하위 자리로 거르기').action(async (opts: { owner?: string }, cmd: Command) => {
847
- const { version, codenames, json } = context(cmd);
848
- await checklistOutput(version, codenames, 'list', json, opts.owner);
849
- });
850
- withContext(checklist.command('status').description('상태 요약')).option('--owner <owner>', '자리 또는 하위 자리로 거르기').action(async (opts: { owner?: string }, cmd: Command) => {
851
- const { version, codenames, json } = context(cmd);
852
- await checklistOutput(version, codenames, 'status', json, opts.owner);
853
- });
783
+ registerChecklistReadCommands(checklist);
854
784
  withContext(checklist.command('landed-but-yellow').description('병합 PR 이 있지만 노랑·빨강인 칸(기본 읽기 전용)'))
855
785
  .option('--owner <owner>', '자리 또는 하위 자리로 거르기')
856
786
  .option('--open', '미발행 일정 판 중 칸이 있는 판 전부')
857
787
  .option('--apply-evidence', '확실한 PR 짝의 근거를 붙인다(상태는 그대로)')
858
788
  .option('--dry-run', '근거 추가 없이 계획만 출력')
859
789
  .action(async (opts: { owner?: string; open?: boolean; applyEvidence?: boolean; dryRun?: boolean }, cmd: Command) => {
790
+ // Stage timings (LANDED-YELLOW-FAST): which step ate the time — `elanous logs --category release.landed-yellow`.
791
+ let stageAt = performance.now();
792
+ const stage = (name: string, data: Record<string, unknown>) => {
793
+ const at = performance.now();
794
+ debug.log('release.landed-yellow', 'stage', { stage: name, ms: Math.round(at - stageAt), ...data });
795
+ stageAt = at;
796
+ };
797
+ // A standalone CLI's debug.log reaches logs.db only through a registered sink (pr land #6701 lesson). Fail-open, 1s cap.
798
+ const registerLogSink = landedDeps.registerLogSink ?? (landedDeps.run || landedDeps.runAsync ? undefined
799
+ : async () => (await import('../domains/standalone-log-sink.js')).registerStandaloneLogSink('release-landed-yellow'));
800
+ if (registerLogSink) {
801
+ let sinkTimer: ReturnType<typeof setTimeout> | undefined;
802
+ try {
803
+ await Promise.race([registerLogSink(), new Promise<void>((resolve) => { sinkTimer = setTimeout(resolve, 1000); })]);
804
+ } catch { /* observability is fail-open */ } finally { clearTimeout(sinkTimer); }
805
+ }
806
+ stageAt = performance.now();
860
807
  try {
861
808
  const inherited = cmd.parent?.opts() as { version?: string; json?: boolean } | undefined;
862
809
  const local = cmd.opts() as { version?: string; json?: boolean };
@@ -873,6 +820,7 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
873
820
  .filter(({ version }) => isReleaseVersion(version) && (!released || compareReleaseVersions(version, released) > 0))
874
821
  .sort((a, b) => compareReleaseVersions(a.version, b.version))
875
822
  .map(({ version }) => (landedDeps.checklist ?? listChecklist)(version)).filter((snapshot) => snapshot.items.length > 0);
823
+ stage('snapshots', { n: openSnapshots.length, schedules: schedules.length });
876
824
  if (opts.open && !openSnapshots.length) {
877
825
  if (json) await writeStdoutJson('[]\n'); else console.log('열린 판 없음');
878
826
  return;
@@ -887,7 +835,10 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
887
835
  .map((item) => Date.parse(item.updatedAt)).filter((at) => Number.isFinite(at)));
888
836
  const since = updated.length ? new Date(updated.reduce((earliest, at) => Math.min(earliest, at))).toISOString().slice(0, 10)
889
837
  : new Date(now.getTime() - 7 * 86_400_000).toISOString().slice(0, 10);
890
- const { prs, truncated } = mergedChecklistPrs(since, now, landedDeps.run ?? defaultRunner);
838
+ const syncRun = landedDeps.run;
839
+ const runAsync: MergedPrRunner = landedDeps.runAsync ?? (syncRun ? async (command, args, cwd) => syncRun(command, args, cwd) : defaultMergedPrRunner);
840
+ const { prs, truncated, calls } = await fetchMergedChecklistPrs(since, now, runAsync, process.cwd());
841
+ stage('merged-prs', { n: prs.length, calls, since, truncated });
891
842
  const results: Array<{ version: string; rows?: ReturnType<typeof landedButYellow>; plan?: ReturnType<typeof evidencePlan> }> = [];
892
843
  let totalAdded = 0, totalSkipped = 0;
893
844
  for (const snapshot of snapshots) {
@@ -914,6 +865,7 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
914
865
  results.push({ version, rows });
915
866
  }
916
867
  }
868
+ stage('match', { n: results.reduce((sum, result) => sum + (result.rows?.length ?? result.plan?.length ?? 0), 0), versions: snapshots.length, prs: prs.length });
917
869
  if (opts.open) {
918
870
  if (opts.applyEvidence && !opts.dryRun) debug.log('release.checklist', 'evidence-synced', { versions: snapshots.map(({ version }) => version), added: totalAdded, skippedMention: totalSkipped });
919
871
  if (!json) console.log(`판 ${snapshots.length} · 붙임 합 ${totalAdded} · 건너뜀(언급만) 합 ${totalSkipped}`);
@@ -1389,16 +1341,34 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
1389
1341
  .option('--checkout <dir>', '깨끗한 git 체크아웃(기본 ELANOUS_REHEARSAL_GIT_CWD)')
1390
1342
  .option('--shards <n>', '시험 분할 수')
1391
1343
  .option('--remote <host>', '게이트 호스트')
1344
+ .option('--recovery-run <id>', '기존 실패 release-loop 런을 gate에서 명시적으로 재개(기본 예약 틱과 분리)')
1392
1345
  .option('--json', '결과 한 줄 JSON(stdout)')
1393
- .action(async (o: { apply?: boolean; checkout?: string; shards?: string; remote?: string; json?: boolean }) => {
1346
+ .action(async (o: { apply?: boolean; checkout?: string; shards?: string; remote?: string; recoveryRun?: string; json?: boolean }) => {
1394
1347
  await jsonAction(o.json, async (log) => {
1395
1348
  const ledgerRoot = scheduleLedgerRoot();
1349
+ if (o.recoveryRun !== undefined) {
1350
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/.test(o.recoveryRun)) throw new Error('release rehearsal recovery: invalid run id');
1351
+ if (o.shards !== undefined || o.remote !== undefined) throw new Error('release rehearsal recovery: --shards and --remote are unsupported; use the saved gate settings');
1352
+ const resumeOptions = { runId: o.recoveryRun, from: 'gate', commandRoot: o.checkout ?? process.cwd() };
1353
+ if (!o.apply) {
1354
+ const plan = await planResumeReleaseRun(resumeOptions, resumeDeps);
1355
+ log(`· 리허설 복구 사전점검 ${plan.preflight} · run ${plan.runId} · ${plan.version} · from ${plan.fromNode} · gate ${plan.gatePlan.mode}`);
1356
+ return { recovery: 'planned', ...plan };
1357
+ }
1358
+ if (!mayWriteLedger('release rehearsal recovery', false, ledgerRoot)) throw new Error('release rehearsal recovery: ledger write denied');
1359
+ const result = await resumeReleaseRun(resumeOptions, resumeDeps);
1360
+ log(`· 리허설 복구 완료 · run ${o.recoveryRun} · ${result.state.status} · gate에서 재개`);
1361
+ return { recovery: 'resumed', runId: o.recoveryRun, status: result.state.status, ...result };
1362
+ }
1396
1363
  if (o.apply && !mayWriteLedger('release rehearsal tick', false, ledgerRoot)) throw new Error('release rehearsal tick: ledger write denied');
1397
- // The tick reports a preflight shard shortage as an unmeasured attempt; its released stage can be claimed on the next CLI tick.
1398
1364
  const result = await runRehearsalTick({ apply: o.apply, checkout: o.checkout, shards: o.shards === undefined ? undefined : Number(o.shards), remote: o.remote, ledgerRoot }, rehearsalDeps);
1399
1365
  log(`· 리허설 ${result.status}${'version' in result ? ` ${result.version}` : ''}${result.status === 'due' ? ` · 실행 ${result.run ?? '-'} · 건너뜀 ${result.supersede.join(', ') || '-'}` : ''}`);
1366
+ for (const stamp of result.stamps ?? []) {
1367
+ if (stamp.outcome === 'unmeasured' && !stamp.result && stamp.shardPlan && (stamp.shardPlan.testFiles === 0 || stamp.shardPlan.gatePlanShards === null))
1368
+ log(`· 리허설 ${stamp.version} ${stamp.step} · ${stamp.summary} · stage claim 해제 · 다음 tick 재시도`);
1369
+ }
1400
1370
  return result;
1401
- }, (result) => !result.notificationFailures && !result.stamps?.some((stamp) => !['ok', 'superseded'].includes(stamp.outcome)));
1371
+ }, (result) => result.status !== 'failed' && !result.notificationFailures && !result.stamps?.some((stamp) => !['ok', 'superseded'].includes(stamp.outcome)));
1402
1372
  });
1403
1373
  release.command('auto-start')
1404
1374
  .description('판 일정의 컷 창에서 릴리스 시작을 미리 본다 · --apply 로 release run --if-ready 실행')
@@ -203,7 +203,7 @@ function hasFlag(args: readonly string[], name: string): boolean {
203
203
  * 읽어 `<값>` 을 받는 것이 전부 여기 있는지 확인한다(`root value-taking flags are enumerated`).
204
204
  * ⇒ 루트에 값 받는 플래그를 더하면 그 시험이 «먼저» 깨진다. */
205
205
  // ⭐ `--name <name>` = 대시보드 TUI 별명(dashboard-name-flag.ts) — 값이 다음 토큰이라 `elanous --name op -r` 의 `-r` 이 루트로 남게 센다.
206
- export const ROOT_FLAGS_TAKING_VALUE = new Set(['--remote', '--config-dir', '--name']);
206
+ export const ROOT_FLAGS_TAKING_VALUE = new Set(['--remote', '--config-dir', '--name', '--tui']);
207
207
 
208
208
  /** 이 토큰이 루트 «선행 플래그 구간» 안에 있나 — 즉 전역 선처리가 소유하나.
209
209
  * ⛔ 없으면 다른 명령의 `-r` 을 «탈취»한다(`autopilot link … -r friend`).