elanous 0.2.35 → 0.2.36

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 (686) 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/chunks/{d06f9160.a3d9062f95de8ad7.js → 053a429e.9a63436527cc751c.js} +1 -1
  4. package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +287 -0
  5. package/apps/pwa/out/_next/static/chunks/{4346.8601952e73bf5803.js → 1201.afbfc5b1c5e5cbe4.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/190.285c832bd9626f8c.js +64 -0
  11. package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +36 -0
  12. package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +149 -0
  15. package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{3103.0df8da390948bb84.js → 2500.cbc1257b774aae52.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/{7644.17e37ba6f1d4226e.js → 2683.c9773a0c589b031b.js} +3 -3
  20. package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +24 -0
  21. package/apps/pwa/out/_next/static/chunks/{4718-17d2af636796a330.js → 275-02ea4c2a33980422.js} +3 -3
  22. package/apps/pwa/out/_next/static/chunks/2812ca6a.3b9f4a7a08885744.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{8714.ff0b7ce3ec3e3ae2.js → 2941.3c3546f96bc6efa7.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +24 -0
  26. package/apps/pwa/out/_next/static/chunks/{9214.63a510d39178e997.js → 2986.45d7652e4f13557e.js} +2 -2
  27. package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/3136.30aaaa5fa03662a3.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{3677-4215f826f6aa68e5.js → 3148-98efd4869d660a87.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +226 -0
  31. package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3324.a09703033abcbd2f.js +34 -0
  34. package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +8 -0
  36. package/apps/pwa/out/_next/static/chunks/3410.7f9af5ab77cbe65f.js +115 -0
  37. package/apps/pwa/out/_next/static/chunks/3538.a445e50bb359d068.js +32 -0
  38. package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +286 -0
  40. package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/{9512.5a76207a730e0491.js → 3727.7949ccaacaa71242.js} +2 -2
  42. package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{8557-e7898769499cd56f.js → 3757-180308bc61021b05.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +74 -0
  45. package/apps/pwa/out/_next/static/chunks/{359-2250789a2d3499e7.js → 3840-5825d56d46976a92.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{da5176c6.6773b6c5994e1d99.js → 3a3d9966.cc4d4585a2708e7c.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +104 -0
  51. package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/{9952.5daf5f94063a2b3e.js → 4286.b70c4520306817e8.js} +1 -1
  53. package/apps/pwa/out/_next/static/chunks/4304.e9b2512834a9e23e.js +23 -0
  54. package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{938.66ad1ef0e5abae1c.js → 4615.8525eb0add35eba6.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/5085-bce4904931767ca6.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +93 -0
  59. package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/{6236.e18cced2d5ba6afb.js → 528.38ce20ef8aa251ff.js} +16 -16
  61. package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +122 -0
  62. package/apps/pwa/out/_next/static/chunks/{3408.21d1570602f4b6c0.js → 552.b7d061ad91eeac51.js} +2 -2
  63. package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5711.957b095705c12560.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/{1530.0e612369b6fd7ea0.js → 575.d929793a53f27c4b.js} +1 -1
  66. package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/599.c39c571b6733f2a2.js +41 -0
  70. package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +79 -0
  71. package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6466-92e65a48490b68a9.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +27 -0
  84. package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/6925.562d532110879886.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/{7385.50a308a477bdfc21.js → 6943.c6b24124853a47b2.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/{630.fe5a46428d63b013.js → 727.7deb87749b0a343a.js} +1 -1
  88. package/apps/pwa/out/_next/static/chunks/{2018.a741297bce759490.js → 7481.39f7a4654907bf6e.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/{8444.4c26b379ca2b9596.js → 771.c3cdb6c1f7f47c02.js} +17 -17
  92. package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{3589.5444a06bcf6e775c.js → 7891.03f910124a737985.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +62 -0
  100. package/apps/pwa/out/_next/static/chunks/{b2f6ba4d.fb56fdbbf798df33.js → 873d6c12.09bd499f57171543.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/{5101.e32282718f99ed6f.js → 8904.7d51af2dc033965c.js} +2 -2
  102. package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +90 -0
  104. package/apps/pwa/out/_next/static/chunks/{5637.281e5dec4ea6ecf1.js → 914.8abefd48d579547b.js} +2 -2
  105. package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/{4705-194e64e47ca0fbdb.js → 9250-072df22eaadaa6b5.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +77 -0
  111. package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{8637.47f5b35afcae5e6b.js → 9514.131c52cc75fe6439.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{1674.2a65fd5668e1cc5f.js → 9789.60f723d18097ec30.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9f31e478.fefcbcd3c388ebc5.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-083747f1d4518f61.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-e2de2e59111c9aad.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f2b2e4bf6e981450.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2af16e62c12f22df.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{0368f25d-ad84af92fefee68f.js → ccae1c4b-0cf414f5eff1b10d.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{cbe38a15.5a032598e39970c6.js → ceba0382.650712b56b85b582.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/{b6705a4f-b9a9047de9eecfd0.js → da5ecc5c-b005ad8cac737d57.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{56d372f2.681ab4ec4c998fae.js → f9a61e4d.1fc2c1dbdd49fe46.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +1 -0
  183. package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → uC-N0emedeNOFuaBQFv-I}/_buildManifest.js +1 -1
  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/docs/goal-context/05-authoring-lessons.jsonl +47 -0
  278. package/docs/goal-context/README.md +3 -0
  279. package/graphs/default-loop.yaml +6 -1
  280. package/graphs/implement-loop.yaml +24 -0
  281. package/graphs/release/recipes.yaml +6 -0
  282. package/graphs/release/release-loop.yaml +17 -4
  283. package/graphs/wizard/recipes.yaml +44 -0
  284. package/graphs/wizard/wizard-loop.yaml +44 -0
  285. package/graphs/work/research-report.yaml +2 -0
  286. package/package.json +1 -1
  287. package/scripts/ci-typecheck-changed.ts +139 -5
  288. package/scripts/coord-role-pack.ts +1 -1
  289. package/scripts/first10-gate.ts +416 -0
  290. package/scripts/fleet/wsl-node-setup.sh +432 -0
  291. package/scripts/release-loop/docs-node.ts +204 -8
  292. package/scripts/release-loop/gate-node.ts +249 -53
  293. package/scripts/release-loop/node-verdict.ts +2 -0
  294. package/scripts/release-loop/resume-cap.ts +14 -34
  295. package/scripts/release-loop/resume-release.ts +37 -11
  296. package/scripts/release-loop/traffic-node.ts +59 -0
  297. package/scripts/release-loop/traffic-transition.ts +159 -0
  298. package/scripts/rhythm/daily.ts +137 -3
  299. package/scripts/ux-sim.ts +53 -0
  300. package/skills/README.md +1 -0
  301. package/src/acp/core-turn-bridge.ts +48 -6
  302. package/src/agent/delegate-hint.ts +16 -0
  303. package/src/agent/runner.ts +82 -2
  304. package/src/agent/task-notification.ts +56 -10
  305. package/src/agent/types.ts +4 -0
  306. package/src/agent-substrate/pr-reviewer.ts +55 -3
  307. package/src/agent-substrate/review-intent.ts +29 -2
  308. package/src/agent-substrate/review-observation.ts +3 -0
  309. package/src/agent-substrate/self-review-cli.ts +168 -16
  310. package/src/autopilot/mission-codebase-gate.ts +141 -12
  311. package/src/autopilot/pr-manager.ts +25 -5
  312. package/src/boot/daemon-tools/self-implement.ts +1 -0
  313. package/src/budget/usage-outcomes.ts +8 -4
  314. package/src/capture/tui-self-report.ts +102 -0
  315. package/src/chat/goal-continue-verdict.ts +41 -0
  316. package/src/chat/index.ts +30 -4
  317. package/src/chat/internal-turn-origin.ts +1 -0
  318. package/src/chat/paste-fold.ts +86 -0
  319. package/src/chat/tool-render/block.ts +32 -0
  320. package/src/chat/tool-render/dispatch.ts +2 -20
  321. package/src/chat/tool-render/result-text.ts +98 -0
  322. package/src/chat/turn-typeahead.ts +70 -7
  323. package/src/cli/config-audit.ts +119 -0
  324. package/src/cli/doctor-cli.ts +22 -0
  325. package/src/cli/guardian-cli.ts +10 -0
  326. package/src/cli/herdr-cli.ts +34 -0
  327. package/src/cli/light-entry-route.ts +6 -3
  328. package/src/cli/log-event-names.ts +2 -0
  329. package/src/cli/make-cli.ts +247 -11
  330. package/src/cli/msg-cli.ts +117 -3
  331. package/src/cli/pr-cli.ts +29 -16
  332. package/src/cli/pr-land-base-read.ts +11 -2
  333. package/src/cli/pr-land-heavy-remote.ts +6 -3
  334. package/src/cli/pr-land-overlap-evidence.ts +23 -4
  335. package/src/cli/pr-land-recovery.ts +117 -1
  336. package/src/cli/pty-takeover-cli.ts +8 -7
  337. package/src/cli/release-cli.ts +21 -5
  338. package/src/cli/release-single-flight.ts +1 -1
  339. package/src/cli/tasks-card-show.ts +162 -0
  340. package/src/cli/tasks-cli.ts +574 -356
  341. package/src/cli/tasks-read-cli.ts +197 -0
  342. package/src/core-turn/run-core-turn.ts +4 -2
  343. package/src/core-turn/run-goal-loop.ts +73 -16
  344. package/src/core-turn/types.ts +6 -1
  345. package/src/dashboard/context/keys.ts +8 -31
  346. package/src/dashboard/index.ts +202 -49
  347. package/src/dashboard/input/agent-wake.ts +7 -1
  348. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
  349. package/src/dashboard/input/chat-main-slash-command.ts +4 -2
  350. package/src/dashboard/input/goal-continue.ts +210 -0
  351. package/src/dashboard/input/goal-interim.ts +2 -0
  352. package/src/dashboard/input/internal-turn.ts +2 -8
  353. package/src/dashboard/input/seat-autowake.ts +9 -7
  354. package/src/dashboard/input/turn-autoheal.ts +52 -0
  355. package/src/dashboard/seat-boot-preamble.ts +132 -5
  356. package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
  357. package/src/dashboard/slash-runtime/dashboard-handlers.ts +3 -2
  358. package/src/dashboard/slash-runtime/model-choices.ts +15 -0
  359. package/src/dashboard/stale-install-check.ts +3 -99
  360. package/src/debug/batch-queue.ts +119 -0
  361. package/src/debug/tui-log-tag.ts +67 -0
  362. package/src/display/agent-surface.ts +7 -0
  363. package/src/domains/standalone-log-sink.ts +15 -2
  364. package/src/esc-abort-gate.ts +69 -0
  365. package/src/git-fs/worktree.ts +95 -1
  366. package/src/graph-runner/graph-cli.ts +18 -0
  367. package/src/graph-runner/runner.ts +20 -11
  368. package/src/graph-wizard/generate.ts +108 -4
  369. package/src/graph-wizard/steps.ts +15 -0
  370. package/src/grounding/proactive-ground.ts +86 -0
  371. package/src/harness/control-inbox.ts +49 -1
  372. package/src/harness/harness-cli-command.ts +51 -7
  373. package/src/harness/harness-incidents.ts +52 -1
  374. package/src/harness/pod-control-send.ts +33 -5
  375. package/src/harness/self-send-remote.ts +69 -0
  376. package/src/harness/self-send-routing-guard.ts +6 -0
  377. package/src/harness/self-send-target.ts +4 -3
  378. package/src/index.ts +327 -12
  379. package/src/input-core/context-key-runtime.ts +21 -0
  380. package/src/light-cli.ts +6 -1
  381. package/src/llm-wellformed.ts +70 -0
  382. package/src/llm.ts +35 -4
  383. package/src/loops/msg-wake.ts +35 -39
  384. package/src/loops/orchestrator/inbox.ts +59 -11
  385. package/src/loops/orchestrator/knowhow-pack.ts +364 -0
  386. package/src/loops/orchestrator/tick.ts +5 -1
  387. package/src/maturity/feature-maturity.ts +1 -1
  388. package/src/models/prompts.ts +17 -2
  389. package/src/msg/msg-post-office.ts +116 -0
  390. package/src/mss/logging/log-store.ts +79 -22
  391. package/src/nexus/api/decisions-route.ts +38 -18
  392. package/src/nexus/api/graph-wizard-api.ts +20 -2
  393. package/src/nexus/boot/register-mcp-clients.ts +263 -38
  394. package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
  395. package/src/onboarding/first-run.ts +37 -6
  396. package/src/onboarding/web-first.ts +43 -11
  397. package/src/ops/overview-collect.ts +12 -6
  398. package/src/ops/overview.ts +3 -3
  399. package/src/persona/loader.ts +11 -0
  400. package/src/persona/types.ts +8 -0
  401. package/src/prompt-library/session-guidance.ts +14 -0
  402. package/src/provider-summary.ts +8 -0
  403. package/src/pty-shell/herdr-agent-report.ts +118 -9
  404. package/src/pty-shell/herdr-prompt.ts +266 -0
  405. package/src/pty-shell/pty-control-ipc.ts +151 -8
  406. package/src/pty-shell/pty-special-keys.ts +42 -2
  407. package/src/pty-shell/stale-install-check.ts +99 -0
  408. package/src/pty-shell/tui-run-state.ts +14 -2
  409. package/src/release-loop/auto-start.ts +20 -2
  410. package/src/release-loop/checklist.ts +76 -4
  411. package/src/release-loop/rehearsal.ts +36 -20
  412. package/src/repl/index.ts +19 -1
  413. package/src/seat-loop/knowhow-lint.ts +1 -1
  414. package/src/self-dev/decompose-proposal.ts +172 -20
  415. package/src/self-dev/decompose.ts +61 -0
  416. package/src/self-dev/dev-cli.ts +37 -3
  417. package/src/self-dev/dev-pipeline.ts +8 -2
  418. package/src/self-dev/draft-triage-rules.ts +31 -0
  419. package/src/self-dev/glm-credential-guard.ts +77 -0
  420. package/src/self-dev/graph-journey-nodes.ts +1 -0
  421. package/src/self-dev/graph-journey-route.ts +12 -2
  422. package/src/self-dev/orchestrate-cli.ts +68 -3
  423. package/src/self-dev/orchestrate.ts +116 -17
  424. package/src/self-dev/run-supervisor.ts +55 -2
  425. package/src/self-dev/run-types.ts +1 -1
  426. package/src/self-health/autoheal.ts +153 -0
  427. package/src/self-health/signatures.ts +6 -0
  428. package/src/self-implement/device-first.ts +116 -0
  429. package/src/self-implement/doctor-visit.ts +239 -1
  430. package/src/self-implement/evidence-command-budget.ts +80 -0
  431. package/src/self-implement/goal-author-cli.ts +1 -0
  432. package/src/self-implement/goal-author-decompose.ts +265 -4
  433. package/src/self-implement/goal-author.ts +33 -8
  434. package/src/self-implement/goal-elaborate.ts +176 -22
  435. package/src/self-implement/goal-refine.ts +3 -0
  436. package/src/self-implement/graph-variant.ts +40 -6
  437. package/src/self-implement/headless-elanous-driver.ts +19 -3
  438. package/src/self-implement/off-diff-evidence.ts +58 -6
  439. package/src/self-implement/orchestrator.ts +222 -21
  440. package/src/self-implement/pod-warm-pool-profile.ts +1 -0
  441. package/src/self-implement/pwa-import-graph.ts +1 -1
  442. package/src/self-implement/rework-policy.ts +30 -0
  443. package/src/self-implement/run-ledger.ts +108 -0
  444. package/src/self-implement/run-ttl.ts +38 -24
  445. package/src/self-implement/scope-adjacency.ts +3 -1
  446. package/src/self-implement/seams.ts +60 -4
  447. package/src/self-implement/wiring-check.ts +358 -0
  448. package/src/shell-env-bootstrap.ts +11 -4
  449. package/src/skills/runner.ts +4 -2
  450. package/src/skills/tools/agent.ts +290 -48
  451. package/src/skills/tools/schedule-wakeup.ts +23 -4
  452. package/src/skills/tools/shell.ts +61 -6
  453. package/src/skills/tools/terminal-modal-inject.ts +1 -2
  454. package/src/skills/tools/terminal-modal.ts +10 -8
  455. package/src/skills/url-router.ts +41 -1
  456. package/src/smart-wizard/run.ts +66 -0
  457. package/src/status/bar.ts +34 -6
  458. package/src/status/status-provider-info.ts +37 -6
  459. package/src/steward/rejudge-tick.ts +10 -2
  460. package/src/steward/ta-repair-event-collect.ts +17 -6
  461. package/src/task-agent/actions.ts +3 -1
  462. package/src/task-agent/land-queue.ts +21 -8
  463. package/src/task-agent/live-moves.ts +22 -6
  464. package/src/task-agent/mission.ts +30 -0
  465. package/src/task-agent/rejudge-on-head.ts +15 -0
  466. package/src/task-agent/repair-cycle.ts +138 -32
  467. package/src/task-agent/repair-next-move.ts +31 -3
  468. package/src/task-agent/repair-outcomes.ts +29 -0
  469. package/src/task-agent/repair-worker.ts +14 -4
  470. package/src/task-agent/shadow.ts +41 -3
  471. package/src/task-agent/task-card-prefix.ts +2 -0
  472. package/src/task-agent/task-hand.ts +477 -22
  473. package/src/task-agent/task-parent-role-llm.ts +36 -0
  474. package/src/task-agent/tier-split.ts +78 -9
  475. package/src/task-orchestrator/surfaces/pod-account-broker.ts +9 -0
  476. package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
  477. package/src/task-orchestrator/surfaces/pod-command-job.ts +86 -5
  478. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
  479. package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
  480. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +11 -0
  481. package/src/task-orchestrator/surfaces/pod-pool.ts +76 -4
  482. package/src/task-orchestrator/surfaces/pod-provenance.ts +8 -2
  483. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
  484. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
  485. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
  486. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
  487. package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
  488. package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
  489. package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
  490. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +4 -0
  491. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +485 -36
  492. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
  493. package/src/task-orchestrator/surfaces/self-implement-pod.ts +396 -19
  494. package/src/task-orchestrator/surfaces/self-implement.ts +42 -2
  495. package/src/tool-runtime/index.ts +15 -2
  496. package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
  497. package/src/tty-foreground.ts +155 -0
  498. package/src/tui/chat/goal-interim.ts +173 -0
  499. package/src/tui/chat/log-view.ts +205 -18
  500. package/src/tui/chat/self-health-status.ts +232 -0
  501. package/src/tui/entry.ts +370 -81
  502. package/src/tui/input/composer.ts +8 -1
  503. package/src/tui/slash/compact-command.ts +7 -0
  504. package/src/tui/slash/compact.ts +1 -7
  505. package/src/tui/slash/resume.ts +75 -0
  506. package/src/tui-client/local-chat-turn.ts +45 -2
  507. package/src/tui-client/next-dashboard-runtime.ts +8 -0
  508. package/src/tui-client/next-loop-command.ts +70 -0
  509. package/src/tui-client/next-wakeup.ts +191 -0
  510. package/src/tui.ts +37 -0
  511. package/src/ui/modal-adapter.ts +2 -2
  512. package/src/ux-sim/classic-tui-seat-scenarios.ts +516 -0
  513. package/src/ux-sim/cli-config-audit-device.ts +121 -0
  514. package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
  515. package/src/ux-sim/event-monkey.ts +3 -2
  516. package/src/ux-sim/fake-bin.ts +45 -0
  517. package/src/ux-sim/fake-herdr.ts +238 -0
  518. package/src/ux-sim/fake-llm.ts +111 -6
  519. package/src/ux-sim/fault-glm-no-credential.ts +116 -0
  520. package/src/ux-sim/fault-nextmove-dispatch.ts +102 -1
  521. package/src/ux-sim/fault-scope-escape-lift.ts +33 -6
  522. package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
  523. package/src/ux-sim/goal-device.ts +619 -0
  524. package/src/ux-sim/in-process-cli.ts +22 -5
  525. package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
  526. package/src/ux-sim/mock-authoring-first-run.ts +97 -0
  527. package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
  528. package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
  529. package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
  530. package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
  531. package/src/ux-sim/next-tui-seat-scenarios.ts +631 -0
  532. package/src/ux-sim/onboarding-first-run-device.ts +269 -0
  533. package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
  534. package/src/ux-sim/subagent-tools-device.ts +81 -0
  535. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
  536. package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
  537. package/src/version/packed-revision.json +1 -1
  538. package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +0 -32
  540. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +0 -41
  541. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +0 -24
  542. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +0 -74
  543. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +0 -148
  553. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +0 -34
  555. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +0 -77
  556. package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +0 -62
  559. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +0 -90
  560. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +0 -36
  563. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +0 -79
  565. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +0 -122
  567. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +0 -286
  570. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +0 -24
  573. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +0 -23
  582. package/apps/pwa/out/_next/static/chunks/5483-dd5d7697f6bdb106.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +0 -287
  586. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +0 -8
  593. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +0 -27
  595. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +0 -93
  597. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +0 -149
  604. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +0 -104
  605. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +0 -226
  615. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +0 -64
  617. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +0 -115
  622. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/morning/page-47c5d4db587266bd.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/term/page-dc0a532f5b9196ec.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +0 -1
  686. /package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → uC-N0emedeNOFuaBQFv-I}/_ssgManifest.js +0 -0
@@ -14,11 +14,13 @@
14
14
  import type { LLMToolSpec } from '../../llm.js';
15
15
  import { truncateOutput } from '../../output-truncation.js';
16
16
  import { getSessionCwd } from '../../session/working-dir.js';
17
- import {
18
- getDashboardTerminalSessions,
19
- } from '../../dashboard/terminal/session.js';
20
17
  import type { TerminalSession, TerminalSessionRegistry } from '../../terminal/session-registry.js';
21
18
 
19
+ async function getDashboardTerminalSessions(): Promise<TerminalSessionRegistry> {
20
+ const { getDashboardTerminalSessions: getSessions } = await import('../../dashboard/terminal/session.js');
21
+ return getSessions() as TerminalSessionRegistry;
22
+ }
23
+
22
24
  const DEFAULT_MAX_BYTES = 64 * 1024;
23
25
 
24
26
  // ─── terminal_modal_list ────────────────────────────────────────
@@ -43,7 +45,7 @@ export async function dispatchTerminalModalList(
43
45
  rawArgs: Record<string, unknown>,
44
46
  deps?: { registry?: TerminalSessionRegistry },
45
47
  ): Promise<{ output: string }> {
46
- const registry = deps?.registry ?? getDashboardTerminalSessions();
48
+ const registry = deps?.registry ?? await getDashboardTerminalSessions();
47
49
  const includeExited = rawArgs.include_exited === true;
48
50
  const sessions = registry.list().filter(s => includeExited || s.state !== 'exited');
49
51
  if (sessions.length === 0) {
@@ -92,7 +94,7 @@ export async function dispatchTerminalModalObserve(
92
94
  rawArgs: Record<string, unknown>,
93
95
  deps?: { registry?: TerminalSessionRegistry },
94
96
  ): Promise<{ output: string }> {
95
- const registry = deps?.registry ?? getDashboardTerminalSessions();
97
+ const registry = deps?.registry ?? await getDashboardTerminalSessions();
96
98
  const id = String(rawArgs.id ?? '').trim();
97
99
  if (!id) throw new Error(`'id' is required`);
98
100
  const session = registry.get(id);
@@ -155,7 +157,7 @@ export async function dispatchTerminalModalFocus(
155
157
  termRows?: number;
156
158
  },
157
159
  ): Promise<{ output: string }> {
158
- const registry = deps?.registry ?? getDashboardTerminalSessions();
160
+ const registry = deps?.registry ?? await getDashboardTerminalSessions();
159
161
  const id = String(rawArgs.id ?? '').trim();
160
162
  if (!id) throw new Error(`'id' is required`);
161
163
  const prior = registry.foreground()?.id ?? null;
@@ -191,7 +193,7 @@ export async function dispatchTerminalModalDetach(
191
193
  rawArgs: Record<string, unknown>,
192
194
  deps?: { registry?: TerminalSessionRegistry },
193
195
  ): Promise<{ output: string }> {
194
- const registry = deps?.registry ?? getDashboardTerminalSessions();
196
+ const registry = deps?.registry ?? await getDashboardTerminalSessions();
195
197
  const id = typeof rawArgs.id === 'string' && rawArgs.id.length > 0
196
198
  ? rawArgs.id
197
199
  : registry.foreground()?.id;
@@ -227,7 +229,7 @@ export async function dispatchTerminalModalKill(
227
229
  rawArgs: Record<string, unknown>,
228
230
  deps?: { registry?: TerminalSessionRegistry },
229
231
  ): Promise<{ output: string }> {
230
- const registry = deps?.registry ?? getDashboardTerminalSessions();
232
+ const registry = deps?.registry ?? await getDashboardTerminalSessions();
231
233
  const id = String(rawArgs.id ?? '').trim();
232
234
  if (!id) throw new Error(`'id' is required`);
233
235
  const session = registry.kill(id);
@@ -108,11 +108,50 @@ function containsAny(haystack: string, needles: string[]): string | null {
108
108
  return null;
109
109
  }
110
110
 
111
+ // ── Work-context guard (URL-ROUTE-WORK-CONTEXT-GUARD · 10-22) ──
112
+ // Observed: a long n8n work instruction carrying «RSS URL https://hnrss.org/frontpage
113
+ // · Limit 5 …» (a value to type into a node) was rewritten into an omni-digest run.
114
+ // The config guardKeywords did not stop it, and a user config replaces that list
115
+ // wholesale — so this guard lives in code and always applies.
116
+
117
+ /** «Put this value into a field» phrasing — the URL is data, not a digest target. */
118
+ const FIELD_INPUT_WORDS = [
119
+ '입력', '넣어', '넣고', '넣기', '붙여넣', '칸에', '노드에', '필드에', '란에',
120
+ '로 설정', '으로 설정', '에 설정', '설정해',
121
+ 'paste into', 'type into', 'fill in', 'into the field', 'enter it',
122
+ ];
123
+ /** Text outside the URLs longer than this is a work instruction, not «summarize this». */
124
+ export const WORK_INSTRUCTION_MIN_CHARS = 160;
125
+ /** Step separators (`·` `→` `->`, numbered/bulleted lines) that mark a multi-step task. */
126
+ const STEP_MARKER_RE = /·|→|->|^\s*(?:\d+[.)]|[-*•])\s+/gmu;
127
+
128
+ /** A URL written as a labelled value — «RSS URL https://…», «Webhook URL: https://…», «endpoint=https://…».
129
+ * Matched against the text with each URL replaced by a marker, so a label inside a URL
130
+ * (`https://a.com/?url=https://b.com`) is never read as one. */
131
+ const URL_MARK = '\u0000';
132
+ /** Words that ask for a digest of the URL — they exempt the labelled-URL check (not the other guards). */
133
+ const DIGEST_REQUEST_WORDS = ['요약', '정리', '분석', 'summar', 'digest', 'tl;dr', 'tldr'];
134
+ const LABELLED_URL_RE = /(?:^|[^\p{L}\p{N}])(?:url|uri|endpoint)\s*[:=]?\s*\u0000/iu;
135
+
136
+ /** Why this URL-bearing text must stay on the LLM path, or null when it may route. */
137
+ export function workContextGuardReason(text: string): string | null {
138
+ const rest = text.replace(URL_RE, ' ').replace(/\s+/g, ' ').trim();
139
+ const field = containsAny(rest.toLowerCase(), FIELD_INPUT_WORDS);
140
+ if (field) return `field-input("${field}")`;
141
+ // An explicit digest request («URL https://… 요약해줘») names the URL to summarize, so the label alone does not hold it back.
142
+ if (LABELLED_URL_RE.test(text.replace(URL_RE, URL_MARK)) && !containsAny(rest.toLowerCase(), DIGEST_REQUEST_WORDS)) return 'labelled-url-value';
143
+ if (rest.length > WORK_INSTRUCTION_MIN_CHARS) return `long-instruction(${rest.length})`;
144
+ const steps = text.replace(URL_RE, ' ').match(STEP_MARKER_RE)?.length ?? 0;
145
+ if (steps >= 2) return `multi-step(${steps})`;
146
+ return null;
147
+ }
148
+
111
149
  /** Main entry. Returns a routing decision when the text contains a URL
112
150
  * that should be auto-processed, or null when:
113
151
  * - routing disabled,
114
152
  * - no URL present,
115
- * - a guard keyword is present (defer to the LLM — R5/R8).
153
+ * - a guard keyword is present (defer to the LLM — R5/R8),
154
+ * - the URL sits inside a work instruction (`workContextGuardReason`).
116
155
  *
117
156
  * Callers (TUI dashboard / Telegram agent) then decide auto-fire vs
118
157
  * suggest, and run the mapped skill (two-stage per P4). */
@@ -132,6 +171,7 @@ export function detectUrlRoute(
132
171
  // "반박해봐", "구현해줘") is NOT a digest request — defer to the LLM.
133
172
  const guardHit = containsAny(haystack, cfg.guardKeywords);
134
173
  if (guardHit) return null;
174
+ if (workContextGuardReason(text)) return null;
135
175
 
136
176
  const url = urls[0]!;
137
177
  const kind = classifyUrl(url);
@@ -0,0 +1,66 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { randomUUID } from 'node:crypto';
4
+ import { runGraph, type GraphRunState } from '../graph-runner/runner.js';
5
+ import type { WorkflowDeps } from '../workflow-runtime/types.js';
6
+
7
+ const WIZARD_GRAPH = resolve(import.meta.dir, '../../graphs/wizard/wizard-loop.yaml');
8
+ const FIRST_RESEARCH_PATH = ['intake', 'classify', 'ground'] as const;
9
+
10
+ export interface WizardRequestRunOptions {
11
+ /** Stable caller-supplied identity, or generated for this request. */
12
+ runId?: string;
13
+ /** Isolated graph-run ledger root. */
14
+ stateRoot?: string;
15
+ /** Injected for controlled runs; omitted to use the graph runner's production LLM. */
16
+ callLLM?: (prompt: string) => Promise<string>;
17
+ /** Injected command runner for isolated execution and deterministic verification. */
18
+ runBash?: WorkflowDeps['runBash'];
19
+ log?: (event: string, data: Record<string, unknown>) => void;
20
+ }
21
+
22
+ export interface WizardRequestRun {
23
+ runId: string;
24
+ status: GraphRunState['status'];
25
+ path: string[];
26
+ /** Observed graph edges; every record is stamped with the enclosing run identity. */
27
+ transitions: Array<{ from: string; to: string; runId: string }>;
28
+ state: GraphRunState;
29
+ }
30
+
31
+ /** Run one request through the wizard graph and expose its first research transition. */
32
+ export async function runWizardRequest(
33
+ request: string,
34
+ options: WizardRequestRunOptions = {},
35
+ ): Promise<WizardRequestRun> {
36
+ const normalizedRequest = request.trim();
37
+ if (!normalizedRequest) throw new TypeError('wizard request must not be empty');
38
+ if (!existsSync(WIZARD_GRAPH)) throw new Error(`wizard-loop graph is missing: ${WIZARD_GRAPH}`);
39
+
40
+ const runId = options.runId ?? randomUUID();
41
+ const state = await runGraph(WIZARD_GRAPH, {
42
+ runId,
43
+ input: { request: normalizedRequest },
44
+ quiet: true,
45
+ deps: {
46
+ ...(options.stateRoot ? { root: options.stateRoot } : {}),
47
+ ...(options.callLLM ? { callLLM: options.callLLM } : {}),
48
+ ...(options.runBash ? { runBash: options.runBash } : {}),
49
+ ...(options.log ? { log: options.log } : {}),
50
+ },
51
+ });
52
+
53
+ if (state.runId !== runId) throw new Error(`wizard run identity changed: expected ${runId}, got ${state.runId}`);
54
+ const transitions = state.path.slice(1).map((to, index) => ({
55
+ from: state.path[index]!,
56
+ to,
57
+ runId: state.runId,
58
+ }));
59
+ const firstResearchPath = state.path.slice(0, Math.min(state.path.length, FIRST_RESEARCH_PATH.length));
60
+ if (!firstResearchPath.every((nodeId, index) => nodeId === FIRST_RESEARCH_PATH[index]) ||
61
+ (state.status === 'awaiting-approval' && firstResearchPath.length !== FIRST_RESEARCH_PATH.length)) {
62
+ throw new Error(`wizard request did not reach the first research steps: ${firstResearchPath.join(' → ')}`);
63
+ }
64
+
65
+ return { runId: state.runId, status: state.status, path: [...state.path], transitions, state };
66
+ }
package/src/status/bar.ts CHANGED
@@ -290,6 +290,25 @@ export function runningBuildSegment(state: RunningBuildState | null | undefined,
290
290
  return strongText(`${label} ⟳ 재기동 필요${target}`, 'yellow', opts);
291
291
  }
292
292
 
293
+ /** 이번 턴 «실제로» 응답한 공급자·모델 (TUI-MODEL-BADGE-ACTUAL · 10-16 · #24·#66).
294
+ *
295
+ * 턴 «시작»에 고른 결정(`RouteDecision`)과 실제 응답은 다를 수 있다 — 폴백 체인이
296
+ * 다른 공급자로 넘기면(예 codex → grok) 배지가 «지금» 으로 보여야 하는 것은 이쪽이다.
297
+ * 완료 배지(`src/tui/chat/execution-badge.ts`)와 같은 원천(`src/llm/route-decision.ts`)을 쓴다. */
298
+ export interface ModelExecutionActual {
299
+ provider?: string;
300
+ /** 실제로 응답한 모델 id — 있으면 배지의 «지금» 은 이 값이다. */
301
+ model: string;
302
+ /** 폴백이면 턴이 «고른» 모델 — 배지가 `고른 → 실제` 로 드러낸다(폴백 아니면 없음/null). */
303
+ fallbackFrom?: string | null;
304
+ }
305
+
306
+ /** 상태줄 배지 입력 — 설정/런타임 값 ⊕ (있으면) 이번 턴 실제 실행.
307
+ * `actual` 이 없는 호출자는 종전과 완전히 같은 배지를 얻는다(추가 필드는 선택). */
308
+ export interface StatusModelInfo extends Pick<ActiveProviderInfo, 'provider' | 'model'> {
309
+ actual?: ModelExecutionActual | null;
310
+ }
311
+
293
312
  /** Truncate a model id at the first parameter-size marker (e.g.
294
313
  * `qwen3.6-35b-a3b-ud-mlx` → `qwen3.6-35b`). The marker pattern
295
314
  * matches one or more digits followed by `b`/`B` (e.g. `7b`, `35b`,
@@ -319,19 +338,22 @@ function truncateAtParamSize(model: string): string {
319
338
  * - `local:qwen3.6-35b-a3b-ud-mlx` → `local:qwen3.6-35b`
320
339
  * - `node-b:qwen2.5-72b-instruct` → `node-b:qwen2.5-72b`
321
340
  * - `claude-opus-4-6` → unchanged (no `\d+b` marker) */
322
- export function modelSegment(info: Pick<ActiveProviderInfo, 'provider' | 'model'>, opts: StatusBarRenderOptions = {}): string {
323
- if (!info.model || info.model === '(none)') {
324
- return strongText(info.provider, 'pink', opts);
341
+ export function modelSegment(info: StatusModelInfo, opts: StatusBarRenderOptions = {}): string {
342
+ // 이번 턴 실제 실행이 있으면 그 값이 «지금» 이다 — 설정/런타임 값은 실행 전 기본값일 뿐.
343
+ const actual = info.actual?.model && info.actual.model !== '(none)' ? info.actual : null;
344
+ const provider = actual?.provider?.trim() || info.provider;
345
+ const model = actual?.model ?? info.model;
346
+ if (!model || model === '(none)') {
347
+ return strongText(provider, 'pink', opts);
325
348
  }
326
349
  // Step 1 — derive the display string with node prefix when local.
327
350
  let display: string;
328
- let model = info.model;
329
351
  if (model.startsWith('local-llm:')) {
330
352
  const rest = model.slice('local-llm:'.length);
331
353
  display = rest.includes(':') ? rest : `local:${rest}`;
332
354
  } else if (model.startsWith('local:')) {
333
355
  display = model;
334
- } else if (info.provider === 'local') {
356
+ } else if (provider === 'local') {
335
357
  display = `local:${model}`;
336
358
  } else {
337
359
  display = model;
@@ -349,6 +371,11 @@ export function modelSegment(info: Pick<ActiveProviderInfo, 'provider' | 'model'
349
371
  display = truncateAtParamSize(display);
350
372
  }
351
373
  }
374
+ // Step 3 — 폴백이면 «처음 → 실제». 고른 값과 실제가 같으면 화살표를 꾸미지 않는다.
375
+ const from = actual?.fallbackFrom?.trim();
376
+ if (from && from !== model) {
377
+ display = `${opts.compact ? truncateAtParamSize(from) : from} → ${display}`;
378
+ }
352
379
  return strongText(display, 'pink', opts);
353
380
  }
354
381
 
@@ -798,7 +825,8 @@ function dockStripDetail(dockedCount: number, dormantCount: number): string {
798
825
 
799
826
  export interface StatusBarState {
800
827
  cwd: string;
801
- providerInfo: ActiveProviderInfo;
828
+ /** 설정/런타임 공급자·모델 ⊕ (있으면) 이번 턴 실제 실행 — 배지는 실제를 «지금» 으로 쓴다. */
829
+ providerInfo: StatusModelInfo;
802
830
  gitBranch?: string;
803
831
  contextUsedTokens?: number;
804
832
  tmuxLabel?: string | null;
@@ -10,8 +10,29 @@
10
10
 
11
11
  import { inspectActiveProvider, type ActiveProviderInfo } from '../provider-summary.js';
12
12
  import { getUserConfig, type UserConfig } from '../user-config.js';
13
+ import { currentRouteDecision, currentRouteExecution } from '../llm/route-decision.js';
14
+ import type { ModelExecutionActual } from './bar.js';
13
15
 
14
- export type StatusProviderInfo = Pick<ActiveProviderInfo, 'provider' | 'model'>;
16
+ export type StatusProviderInfo = Pick<ActiveProviderInfo, 'provider' | 'model'> & {
17
+ /** TUI-MODEL-BADGE-ACTUAL (10-16) — 이번 턴 «실제» 실행. 있으면 배지는 이 값을 «지금» 으로 쓴다. */
18
+ actual?: ModelExecutionActual | null;
19
+ };
20
+
21
+ /** 표면의 이번 턴 «실제» 실행을 배지 입력 꼴로 옮긴다 — 결정(턴 시작에 고른 값)과 다르면
22
+ * `fallbackFrom` 이 채워져 배지가 `고른 → 실제` 를 보인다. 실행 기록이 없으면 null(꾸미지 않는다).
23
+ * 원천은 완료 배지와 «같은» 맵(`src/llm/route-decision.ts`)이다 — 두 표면이 다른 말을 하지 않게. */
24
+ export function statusModelActual(surface = 'dashboard'): ModelExecutionActual | null {
25
+ const execution = currentRouteExecution(surface);
26
+ const model = execution?.model?.trim();
27
+ if (!model) return null;
28
+ const provider = execution?.provider?.trim();
29
+ const planned = currentRouteDecision(surface)?.model?.trim();
30
+ return {
31
+ model,
32
+ ...(provider ? { provider } : {}),
33
+ ...(planned && planned !== model ? { fallbackFrom: planned } : {}),
34
+ };
35
+ }
15
36
 
16
37
  export interface StatusProviderInfoReaderDeps {
17
38
  readConfig?: () => UserConfig;
@@ -23,9 +44,15 @@ export interface StatusProviderInfoReaderDeps {
23
44
  maxAgeMs?: number;
24
45
  }
25
46
 
47
+ /** 상태줄이 매 렌더 부르는 리더 — `actual`(이번 턴 실제 실행)은 선택이라 종전 호출 그대로도 된다. */
48
+ export type StatusProviderInfoReader = (
49
+ runtimeModel?: string,
50
+ actual?: ModelExecutionActual | null,
51
+ ) => StatusProviderInfo;
52
+
26
53
  export function createStatusProviderInfoReader(
27
54
  deps: StatusProviderInfoReaderDeps = {},
28
- ): (runtimeModel?: string) => StatusProviderInfo {
55
+ ): StatusProviderInfoReader {
29
56
  const readConfig = deps.readConfig ?? (() => getUserConfig());
30
57
  const inspect = deps.inspect ?? ((cfg, runtimeModel) => inspectActiveProvider(cfg, runtimeModel));
31
58
  const now = deps.now ?? Date.now;
@@ -39,20 +66,24 @@ export function createStatusProviderInfoReader(
39
66
  inspectedAt: number;
40
67
  } | null = null;
41
68
 
42
- return (runtimeModel?: string): StatusProviderInfo => {
69
+ /** `actual` — 이번 턴 실제 실행(있으면). 기억은 설정/런타임 값만 하고, 실행은 «매 렌더»
70
+ * 달라지므로 기억 밖에서 덧씌운다(낡은 실행이 굳지 않게). */
71
+ return (runtimeModel?: string, actual?: ModelExecutionActual | null): StatusProviderInfo => {
43
72
  const t = now();
44
73
  // ⛔ 조기 반환에도 최대 수명을 건다 — TTL 만 보면 «29초에 설정 확인 → 30.001초 렌더»가 재판정 없이 지나간다.
45
74
  const fresh = memo !== null && t - memo.inspectedAt < maxAgeMs;
46
- if (memo && fresh && memo.runtimeModel === runtimeModel && t - memo.checkedAt < ttlMs) return memo.info;
75
+ if (memo && fresh && memo.runtimeModel === runtimeModel && t - memo.checkedAt < ttlMs) {
76
+ return actual ? { ...memo.info, actual } : memo.info;
77
+ }
47
78
  // getUserConfig() 는 파일 mtime 이 같으면 «같은 객체»를, 바뀌면 새 객체를 돌려준다(user-config.ts getUserConfig).
48
79
  const cfg = readConfig();
49
80
  if (memo && fresh && memo.cfg === cfg && memo.runtimeModel === runtimeModel) {
50
81
  memo.checkedAt = t;
51
- return memo.info;
82
+ return actual ? { ...memo.info, actual } : memo.info;
52
83
  }
53
84
  const full = inspect(cfg, runtimeModel);
54
85
  const info: StatusProviderInfo = { provider: full.provider, model: full.model };
55
86
  memo = { info, cfg, runtimeModel, checkedAt: t, inspectedAt: t };
56
- return info;
87
+ return actual ? { ...info, actual } : info;
57
88
  };
58
89
  }
@@ -63,8 +63,16 @@ function defaultStampPath(): string {
63
63
  function readStamp(path: string): string | null {
64
64
  try {
65
65
  const value = (JSON.parse(readFileSync(path, 'utf8')) as { startedAt?: unknown }).startedAt;
66
- return typeof value === 'string' && Number.isFinite(Date.parse(value)) ? value : null;
67
- } catch { return null; }
66
+ if (typeof value !== 'string' || !Number.isFinite(Date.parse(value))) {
67
+ throw new Error(`invalid steward stamp startedAt: ${path}`);
68
+ }
69
+ return value;
70
+ } catch (error) {
71
+ // A missing stamp is the first tick. A corrupt or unreadable existing stamp is not:
72
+ // claiming it would overwrite the evidence and could launch an overlapping rejudge.
73
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') return null;
74
+ throw error;
75
+ }
68
76
  }
69
77
 
70
78
  /** Same universe as this process (env inherited) · same installed version (entry next to this module). */
@@ -7,6 +7,7 @@ import { acquireLockSync } from '../storage/file-lock.js';
7
7
  import { subscribeInsideEvent, type InsideLiveEvent } from '../nexus/api/inside-events.js';
8
8
  import type { NexusEventBus } from '../nexus/api/event-bus.js';
9
9
  import { parseRepairWorkerResult } from '../task-agent/repair-worker.js';
10
+ import { pairMoveId } from '../task-agent/repair-next-move.js';
10
11
  import { readTaskCard, taskAgentStatePath } from '../task-agent/task-hand.js';
11
12
 
12
13
  const SHA40 = /^[0-9a-f]{40}$/i;
@@ -17,6 +18,8 @@ const OUTPUT_LIMIT = 1024 * 1024;
17
18
  export interface TaRepairCompleted {
18
19
  kind: 'ta.repair.completed'; schema: 1; card: string; pr: number; head: string;
19
20
  runId: string; resultPath: string; completedAt: string;
21
+ /** HARNESS-FULL-GRAPH-NEXTMOVE — worker 가 받은 수 id(옛 worker 는 없다 · 꼴이 틀려도 사건을 버리지 않고 짝짓기에서 «못 짝지음»으로 남긴다). */
22
+ moveId?: string;
20
23
  }
21
24
 
22
25
  export function parseTaRepairCompleted(value: unknown): TaRepairCompleted | null {
@@ -102,14 +105,22 @@ export async function collectTaRepairCompleted(input: unknown, deps: TaRepairCol
102
105
  let card;
103
106
  try { card = readTaskCard(event.card, statePath); } catch { emit('deferred', { reason: 'card unreadable' }); return 'deferred'; }
104
107
  const repair = Array.isArray(card?.repairs) ? card.repairs.find(entry => entry && typeof entry === 'object' && entry.runId === event.runId) : undefined;
108
+ // NEXTMOVE-GENERAL-RELAUNCH-MOVEID — 사건의 수 id 를 카드(발사 순간 적은 값)와 짝짓는다. 결과는 관측 칸에만 싣는다(fail-soft · 수거 판단은 그대로).
109
+ const observedMoveId: unknown = (event as { moveId?: unknown }).moveId;
110
+ const pairing = pairMoveId(repair?.moveId, observedMoveId);
111
+ const moveFields: Record<string, unknown> = pairing.kind === 'legacy' ? {}
112
+ : { moveId: pairing.kind === 'paired' ? pairing.moveId : typeof observedMoveId === 'string' ? observedMoveId : null,
113
+ moveIdPaired: pairing.kind === 'paired', ...(pairing.kind === 'unpaired' ? { expectedMoveId: pairing.expected } : {}) };
114
+ const emitPaired = (outcome: string, extra: Record<string, unknown> = {}) => emit(outcome, { ...moveFields, ...extra });
105
115
  if (!repair || repair.pr !== event.pr || typeof repair.head !== 'string' || repair.head.toLowerCase() !== event.head.toLowerCase()
106
116
  || typeof repair.resultPath !== 'string' || !repair.resultPath.startsWith('/')
117
+ // 카드 귀속이 안 맞는 사건엔 짝짓기 칸을 싣지 않는다 — 남의 수리와 대조한 값이 관측에 섞이지 않게(r1 should-fix).
107
118
  || resolve(repair.resultPath) !== resolve(event.resultPath)) { emit('invalid', { reason: 'event differs from card binding' }); return 'invalid'; }
108
- if (repair.status !== 'requested') { emit('duplicate', { reason: `repair ${repair.status}` }); return 'duplicate'; }
119
+ if (repair.status !== 'requested') { emitPaired('duplicate', { reason: `repair ${repair.status}` }); return 'duplicate'; }
109
120
  let result;
110
121
  try { result = parseRepairWorkerResult((deps.read ?? ((path) => readFileSync(path, 'utf8')))(repair.resultPath), event.pr, event.head, event.runId); }
111
122
  catch { /* periodic tick can recover a missing result */ }
112
- if (!result) { emit('deferred', { reason: 'worker result missing or invalid' }); return 'deferred'; }
123
+ if (!result) { emitPaired('deferred', { reason: 'worker result missing or invalid' }); return 'deferred'; }
113
124
 
114
125
  // Existing PID-aware lock recovers a dead daemon without making later events wait forever.
115
126
  // A live holder keeps the lock through the child process; the card CAS covers periodic-tick races.
@@ -119,25 +130,25 @@ export async function collectTaRepairCompleted(input: unknown, deps: TaRepairCol
119
130
  mkdirSync(dirname(lock), { recursive: true });
120
131
  release = acquireLockSync(lock, { breakDeadHolder: true, staleMs: TIMEOUT_MS + 60_000, maxTries: 2 });
121
132
  }
122
- catch { emit('deferred', { reason: 'collector busy; periodic fallback remains' }); return 'deferred'; }
133
+ catch { emitPaired('deferred', { reason: 'collector busy; periodic fallback remains' }); return 'deferred'; }
123
134
  try {
124
135
  // Recheck after claiming: another collector or the periodic tick may have consumed the file.
125
136
  const current = readTaskCard(event.card, statePath);
126
137
  const latest = Array.isArray(current?.repairs) ? current.repairs.find(entry => entry && typeof entry === 'object' && entry.runId === event.runId) : undefined;
127
138
  if (!latest || latest.status !== 'requested' || latest.pr !== event.pr || typeof latest.head !== 'string'
128
139
  || latest.head.toLowerCase() !== event.head.toLowerCase() || typeof latest.resultPath !== 'string'
129
- || !latest.resultPath.startsWith('/') || resolve(latest.resultPath) !== resolve(event.resultPath)) { emit('duplicate'); return 'duplicate'; }
140
+ || !latest.resultPath.startsWith('/') || resolve(latest.resultPath) !== resolve(event.resultPath)) { emitPaired('duplicate'); return 'duplicate'; }
130
141
  const child = await (deps.run ?? ((card) => defaultRun(card, statePath, deps.cliBin)))(event.card);
131
142
  const after = readTaskCard(event.card, statePath)?.repairs?.find(entry => entry.runId === event.runId);
132
143
  const consumed = child.code === 0 && !child.truncated && after?.status !== 'requested' && after !== undefined
133
144
  && childConsumedRepair(child.output, event);
134
145
  const outcome = consumed ? 'collected' : child.truncated ? 'deferred' : after && after.status !== 'requested' ? 'duplicate' : 'deferred';
135
- emit(outcome, { rc: child.code, repairStatus: after?.status,
146
+ emitPaired(outcome, { rc: child.code, repairStatus: after?.status,
136
147
  ...(child.truncated ? { reason: 'rejudge output exceeded 1 MiB; event attribution unmeasured' } : {}),
137
148
  detail: child.output.slice(-300) });
138
149
  return consumed ? 'collected' : outcome === 'duplicate' ? 'duplicate' : 'deferred';
139
150
  } catch (error) {
140
- emit('deferred', { reason: String(error).slice(-300) });
151
+ emitPaired('deferred', { reason: String(error).slice(-300) });
141
152
  return 'deferred';
142
153
  } finally { release(); }
143
154
  }
@@ -48,6 +48,8 @@ export interface NextAction {
48
48
  cwd?: string;
49
49
  risk?: 'money' | 'security' | 'irreversible-publication';
50
50
  delivery?: { kind: DeliveryKind; worktreePath: string; projectTarget: string; files: string[] };
51
+ /** NEXTMOVE-GENERAL-RELAUNCH-MOVEID — 이 재발사를 고른 next-move 결정의 수 id(결정 순간 한 번 · 다시 만들지 않는다). 있으면 `harness say --move-id` 로 싣는다. */
52
+ moveId?: string;
51
53
  }
52
54
  export interface ActionDeps {
53
55
  command(args: string[]): Promise<{ status: number; stdout: string; stderr?: string }>;
@@ -273,7 +275,7 @@ export async function executeNextAction(action: NextAction, deps: ActionDeps): P
273
275
  return card('review verdict or must-fix unavailable');
274
276
  }
275
277
  // 여기 닿는 종류는 land · retry 둘뿐이다(green·decision·review 는 위에서 끝난다).
276
- const args = action.kind === 'land' ? ['pr', 'land', '--cwd', action.cwd!] : ['harness', 'say', retryText(action)];
278
+ const args = action.kind === 'land' ? ['pr', 'land', '--cwd', action.cwd!] : ['harness', 'say', retryText(action), ...(action.moveId ? ['--move-id', action.moveId] : [])];
277
279
  const day = deps.landingDay ?? new Date().toLocaleDateString('en-CA', { timeZone: 'Asia/Seoul' });
278
280
  if (action.kind === 'retry' && deps.retryLaunches) deps.retryLaunches.count++;
279
281
  const outcome = await deps.command(args);
@@ -4,6 +4,7 @@ import { mkdirSync, readFileSync } from 'node:fs';
4
4
  import { dirname, isAbsolute, join } from 'node:path';
5
5
  import { randomUUID } from 'node:crypto';
6
6
  import { parseReviewResultOutput } from './review-result-capture.js';
7
+ import { executeBoundPrLandRecover, PR_LAND_CARD_ID_ENV } from '../cli/pr-land-recovery.js';
7
8
 
8
9
  type CommandResult = { status: number; stdout: string; stderr: string };
9
10
  export interface QueueLandingInput {
@@ -13,6 +14,8 @@ export interface QueueLandingInput {
13
14
  export interface QueueLandingDeps {
14
15
  run?: (command: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv) => Promise<CommandResult>;
15
16
  read?: (path: string) => string;
17
+ /** LAND-REFUSAL-EXEC — observe a refusal on the recover@1 edge and run that unit once (never an effect). */
18
+ recover?: typeof executeBoundPrLandRecover;
16
19
  }
17
20
 
18
21
  async function run(command: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv): Promise<CommandResult> {
@@ -31,14 +34,24 @@ export async function runQueuedLanding(input: QueueLandingInput, deps: QueueLand
31
34
  const invoke = deps.run ?? run;
32
35
  const read = deps.read ?? ((path: string) => readFileSync(path, 'utf8'));
33
36
  const fail = (stage: string, reason: string): CommandResult => ({ status: 1, stdout: '', stderr: `${stage}: ${reason.slice(-500)}` });
37
+ // LAND-REFUSAL-EXEC — a judged refusal (not an unmeasured prerequisite) is bound to recover@1 with this card
38
+ // and that unit runs once. The returned refusal is unchanged; recovery observation never replaces it.
39
+ const refuse = async (stage: string, reason: string): Promise<CommandResult> => {
40
+ const refused = fail(stage, reason);
41
+ try { await (deps.recover ?? executeBoundPrLandRecover)({ refusal: refused.stderr, pr: input.pr, head: input.head, cardId: input.card }, { root: dirname(input.statePath) }); }
42
+ catch { /* fail-soft */ }
43
+ return refused;
44
+ };
45
+ // The card rides along to every child that may land or record this PR (same env as TA defaultLand).
46
+ const cardEnv = (extra: Record<string, string> = {}): NodeJS.ProcessEnv => ({ ...process.env, ...extra, [PR_LAND_CARD_ID_ENV]: input.card });
34
47
  if (!/^[a-f0-9]{40}$/i.test(input.head) || !Number.isSafeInteger(input.pr) || input.pr < 1) return fail('input', 'invalid PR/head');
35
48
  if (!isAbsolute(input.command) || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(input.remote)) return fail('config', 'land queue command/remote invalid');
36
49
  let review: ReturnType<typeof parseReviewResultOutput>;
37
50
  try { review = parseReviewResultOutput(read(input.reviewResult)); }
38
- catch (error) { return fail('review', String(error)); }
51
+ catch (error) { return refuse('review', String(error)); }
39
52
  if (!review || review.pr !== input.pr || review.head?.toLowerCase() !== input.head.toLowerCase()
40
53
  || review.reviewed !== true || !['pass', 'warn'].includes(review.verdict ?? '') || review.mustFix !== 0 || review.error) {
41
- return fail('review', `exact head #${input.pr} ${input.head.slice(0, 12)} PASS/WARN mf0 not proven`);
54
+ return refuse('review', `exact head #${input.pr} ${input.head.slice(0, 12)} PASS/WARN mf0 not proven`);
42
55
  }
43
56
  const git = async (args: string[]) => invoke(process.execPath, [input.entry, '--config-dir', input.configDir, 'git', ...args], input.cwd);
44
57
  const fetched = await git(['fetch', '--quiet', 'origin', 'main']);
@@ -52,15 +65,15 @@ export async function runQueuedLanding(input: QueueLandingInput, deps: QueueLand
52
65
  const artifact = join(dirname(input.statePath), 'land-queue-gates', `${safeCard}-${input.pr}-${input.head.slice(0, 12)}-${randomUUID()}`);
53
66
  mkdirSync(artifact, { recursive: true });
54
67
  const gate = await invoke(process.execPath, [input.entry, '--config-dir', input.configDir,
55
- 'self', 'gate', '--changed', '--base', baseHead!, '--remote', input.remote, '--shards', '4', '--artifact-dir', artifact], input.cwd);
56
- if (gate.status !== 0) return fail('remote-changed-gate', gate.stderr || gate.stdout || `exit ${gate.status}`);
68
+ 'self', 'gate', '--changed', '--base', baseHead!, '--remote', input.remote, '--shards', '4', '--artifact-dir', artifact], input.cwd, cardEnv());
69
+ if (gate.status !== 0) return refuse('remote-changed-gate', gate.stderr || gate.stdout || `exit ${gate.status}`);
57
70
  let summary: Record<string, unknown>;
58
71
  try { summary = JSON.parse(read(join(artifact, 'summary.json'))) as Record<string, unknown>; }
59
72
  catch (error) { return fail('remote-changed-gate', `summary unreadable: ${String(error)}`); }
60
73
  if (summary.head40 !== input.head || summary.base40 !== baseHead || summary.remoteHost !== input.remote
61
74
  || summary.verdict !== 'passed' || summary.exitCode !== 0 || summary.introduced !== 0
62
75
  || summary.unknown !== 0 || summary.preconditionUnmet !== 0) {
63
- return fail('remote-changed-gate', 'summary does not prove this head/base/remote passed with zero unknown');
76
+ return refuse('remote-changed-gate', 'summary does not prove this head/base/remote passed with zero unknown');
64
77
  }
65
78
  const fresh = await invoke('gh', ['pr', 'view', String(input.pr), '--json', 'headRefOid,state,isDraft'], input.cwd);
66
79
  let latest: { headRefOid?: unknown; state?: unknown; isDraft?: unknown };
@@ -68,12 +81,12 @@ export async function runQueuedLanding(input: QueueLandingInput, deps: QueueLand
68
81
  catch { return fail('pr-head', `current PR state unreadable: ${fresh.stderr || fresh.stdout || fresh.status}`); }
69
82
  if (fresh.status !== 0 || latest.state !== 'OPEN' || latest.isDraft !== false
70
83
  || typeof latest.headRefOid !== 'string' || latest.headRefOid.toLowerCase() !== input.head.toLowerCase()) {
71
- return fail('pr-head', `PR #${input.pr} changed after gate or is not ready`);
84
+ return refuse('pr-head', `PR #${input.pr} changed after gate or is not ready`);
72
85
  }
73
86
  const enrolled = await invoke(input.command, [String(input.pr), input.cwd, '--review', input.reviewResult, '--expected-head', input.head], input.cwd,
74
- { ...process.env, LAND_RR_DIR: dirname(input.reviewResult) });
87
+ cardEnv({ LAND_RR_DIR: dirname(input.reviewResult) }));
75
88
  if (enrolled.status !== 0 || !new RegExp(`^OK #${input.pr} head=${input.head.slice(0, 12)}(?:\\s|$)`, 'm').test(enrolled.stdout)) {
76
- return fail('land-enqueue-refused', enrolled.stdout || enrolled.stderr || `exit ${enrolled.status}`);
89
+ return refuse('land-enqueue-refused', enrolled.stdout || enrolled.stderr || `exit ${enrolled.status}`);
77
90
  }
78
91
  return { status: 0, stdout: `queued #${input.pr} head ${input.head.slice(0, 12)} gate ${artifact} · ${enrolled.stdout.slice(-250)}`, stderr: '' };
79
92
  }
@@ -28,6 +28,7 @@ import { getUserConfig, userConfigPath } from '../user-config.js';
28
28
  import type { DetachedSpawn } from '../cli/tasks-cli.js';
29
29
  import { LIVE_MOVE_HISTORY_EVENT, shellQuote, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
30
30
  import { reconcileHandMergedCard } from './postland-card.js';
31
+ import { advanceLandedPieceMission } from './mission.js';
31
32
  import { resolveParentHosts, type ParentHostConfig } from './parent-host.js';
32
33
  import { LIVE_RETRY_MOVES } from './judge.js';
33
34
  import { decisionCardGrounds, decisionRaiseArgs, type DecisionCardEvidence, type NextAction } from './actions.js';
@@ -93,7 +94,7 @@ export interface LiveMoveDeps {
93
94
  handMergePr?: (pr: number, cwd: string) => Promise<HandMergePrView | null>;
94
95
  /** One existing pr land operation; inject in tests instead of invoking the CLI. */
95
96
  /** TA-REJUDGE-ON-HEAD — `opts.overlapEvidence` 가 있으면 `pr land --overlap-evidence <file>` 로 넘긴다(없으면 종전 인자). */
96
- land?: (pr: number, head: string, cwd: string, opts?: { overlapEvidence?: string }) => Promise<{ status: number; stdout: string; stderr?: string }>;
97
+ land?: (pr: number, head: string, cwd: string, opts?: { overlapEvidence?: string; cardId?: string }) => Promise<{ status: number; stdout: string; stderr?: string }>;
97
98
  /** `decision-card` — `decisions raise` 한 번(시험 주입 · 기본 = 같은 우주의 CLI 자식). */
98
99
  raiseDecision?: (args: string[]) => Promise<{ status: number; stdout: string; stderr?: string }>;
99
100
  log?: (category: string, event: string, data: Record<string, unknown>) => void;
@@ -102,6 +103,8 @@ export interface LiveMoveDeps {
102
103
  /** TA-LAND-AFTER-REVIEW — injected queue adapter; absent uses configured command after a remote changed gate. */
103
104
  queueLanding?: (input: QueueLandingInput) => Promise<{ status: number; stdout: string; stderr?: string }>;
104
105
  landQueueConfig?: { command: string; remote: string } | null;
106
+ /** Confirmed direct landing wakes successor pieces; tests inject an observation-only seam. */
107
+ advanceLandedPiece?: (pieceId: string, statePath: string) => Promise<unknown>;
105
108
  }
106
109
 
107
110
  /** `executed` = 부작용을 실제로 냈다(리뷰를 띄웠다 · 제안을 적었다). ok 이지만 이미 한 수(같은 머리·이미 제안)면 false. */
@@ -280,13 +283,16 @@ export function liveLandArgs(entry: string, configDir: string, pr: number, head:
280
283
  }
281
284
 
282
285
  /** The CLI owns the freeze, gate and merge checks; no direct gh merge or bypass flags. */
283
- export async function defaultLand(pr: number, head: string, cwd: string, opts: { overlapEvidence?: string } = {}): Promise<{ status: number; stdout: string; stderr?: string }> {
286
+ export async function defaultLand(pr: number, head: string, cwd: string, opts: { overlapEvidence?: string; cardId?: string } = {}): Promise<{ status: number; stdout: string; stderr?: string }> {
284
287
  const { ELANOUS_CLI_ENTRY } = await import('../cli/tasks-cli.js');
285
288
  const { getElanousConfigDirOverride } = await import('../elanous-config-dir.js');
286
289
  const { effectiveInstanceRoot } = await import('../instance/resolve.js');
287
290
  const args = liveLandArgs(ELANOUS_CLI_ENTRY, getElanousConfigDirOverride() ?? effectiveInstanceRoot(), pr, head, cwd, opts.overlapEvidence);
291
+ const cardEnv = opts.cardId ? { [(await import('../cli/pr-land-recovery.js')).PR_LAND_CARD_ID_ENV]: opts.cardId } : undefined;
288
292
  return new Promise((resolveResult, reject) => {
289
- const child = spawn(process.execPath, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] });
293
+ // LAND-REFUSAL-EDGES — the card rides along so a refusal row can be bound to this card (observation only).
294
+ const env = cardEnv ? { ...process.env, ...cardEnv } : undefined;
295
+ const child = spawn(process.execPath, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'], ...(env ? { env } : {}) });
290
296
  let stdout = '';
291
297
  let stderr = '';
292
298
  child.stdout.on('data', (chunk: Buffer) => { stdout = (stdout + chunk.toString()).slice(-300); });
@@ -660,8 +666,13 @@ export async function executeLiveLand(
660
666
  const settled = reconcileHandMergedCard({ number: pr, url: hand.url ?? view.url ?? '', headRefOid: view.head, state: 'MERGED',
661
667
  baseRefName: hand.baseRefName ?? 'main', mergedAt: hand.mergedAt ?? '', mergeCommit: hand.mergeCommit },
662
668
  cwd, deps.statePath ? { statePath: deps.statePath } : {});
663
- if (settled.outcome === 'reconciled')
669
+ if (settled.outcome === 'reconciled') {
670
+ const path = deps.statePath ?? taskAgentStatePath();
671
+ try { await (deps.advanceLandedPiece ?? ((pieceId, statePath) => advanceLandedPieceMission(pieceId, { statePath })))(card.id, path); }
672
+ catch (error) { try { (deps.log ?? ((c, e, d) => debug.log(c, e, d)))('task-agent', 'mission-auto-advance-error',
673
+ { card: card.id, pr, error: String(error).slice(0, 250) }); } catch { /* fail-soft */ } }
664
674
  return withRepo(observe(deps, { kind, card: card.id, ok: true, executed: true, detail: `PR #${pr} 손 병합 정산 — card ${settled.status} (merge ${settled.mergeSha.slice(0, 12)})` }));
675
+ }
665
676
  }
666
677
  }
667
678
  return reject(card.id, `PR #${pr} is ${view.state}`, reviewRepo);
@@ -802,8 +813,8 @@ export async function executeLiveLand(
802
813
  entry: (await import('../cli/tasks-cli.js')).ELANOUS_CLI_ENTRY,
803
814
  configDir: (await import('../elanous-config-dir.js')).getElanousConfigDirOverride() ?? (await import('../instance/resolve.js')).effectiveInstanceRoot() })
804
815
  : overlapEvidence
805
- ? await (deps.land ?? defaultLand)(pr, view.head, landCwd, { overlapEvidence })
806
- : await (deps.land ?? defaultLand)(pr, view.head, landCwd);
816
+ ? await (deps.land ?? defaultLand)(pr, view.head, landCwd, { overlapEvidence, cardId: card.id })
817
+ : await (deps.land ?? defaultLand)(pr, view.head, landCwd, { cardId: card.id });
807
818
  ok = outcome.status === 0;
808
819
  detail = (ok ? outcome.stdout || `${queueConfig ? 'queued' : 'land merged'} #${pr} head ${view.head.slice(0, 12)}` : outcome.stderr || outcome.stdout || `exit ${outcome.status}`).slice(-300);
809
820
  if (!ok) failure = classifyLandFailure(outcome);
@@ -857,6 +868,11 @@ export async function executeLiveLand(
857
868
  return observe(deps, withRepo({ kind, card: card.id, ok: false, executed: true, landAttempt,
858
869
  detail: `land ${ok ? 'succeeded' : 'failed'} but card update failed: ${String(error).slice(-230)}` }));
859
870
  }
871
+ if (ok && !queueConfig) {
872
+ try { await (deps.advanceLandedPiece ?? ((pieceId, statePath) => advanceLandedPieceMission(pieceId, { statePath })))(card.id, path); }
873
+ catch (error) { try { (deps.log ?? ((c, e, d) => debug.log(c, e, d)))('task-agent', 'mission-auto-advance-error',
874
+ { card: card.id, pr, error: String(error).slice(0, 250) }); } catch { /* fail-soft */ } }
875
+ }
860
876
  return observe(deps, withRepo({ kind, card: card.id, ok, executed: true, detail, landAttempt, ...(queueConfig && ok ? { queued: true } : {}) }));
861
877
  }
862
878