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
@@ -204,7 +204,7 @@ interface SelfDevTerminalOutcome {
204
204
  stage: string | null;
205
205
  merged: boolean | null;
206
206
  prUrl: string | null;
207
- blockReason?: 'parent-unlanded' | 'dependency-needs-human';
207
+ blockReason?: 'parent-unlanded' | 'dependency-needs-human' | 'dependency-deferred';
208
208
  parentPrNumber?: number | null;
209
209
  parentNoPr?: true;
210
210
  }
@@ -270,7 +270,8 @@ export function hasDelivered(result: SelfDevJobResult): boolean {
270
270
 
271
271
  /** 열린 PR 을 사람에게 보여줄 때 분류 칸에 싣는 문면. 없는 mergeReason 은 「사유 모름」— 값을 짓지 않는다. */
272
272
  export function openPrAwaitingHumanMessage(result: Pick<SelfDevJobResult, 'prNumber' | 'prUrl' | 'mergeReason'>): string {
273
- const pointer = result.prNumber !== undefined ? `#${result.prNumber}` : (result.prUrl ?? '');
273
+ const pointer = typeof result.prNumber === 'number' && Number.isSafeInteger(result.prNumber) && result.prNumber > 0
274
+ ? `#${result.prNumber}` : (result.prUrl ?? '');
274
275
  const reason = result.mergeReason && result.mergeReason.length > 0 ? result.mergeReason : '사유 모름';
275
276
  return `열린 PR ${pointer} · ${reason}`;
276
277
  }
@@ -488,17 +489,42 @@ export function queryPreflightWarning(
488
489
  }
489
490
  }
490
491
 
492
+ function hasConcretePrEvidence(result: Pick<SelfDevJobResult, 'prNumber' | 'prUrl'>): boolean {
493
+ const number = result.prNumber;
494
+ if (typeof number === 'number' && Number.isSafeInteger(number) && number > 0) return true;
495
+ if (typeof result.prUrl !== 'string') return false;
496
+ // Match the raw URL. WHATWG URL normalizes dot segments before exposing
497
+ // pathname, which would turn a noncanonical pointer into apparent evidence.
498
+ const match = /^https:\/\/github\.com\/[A-Za-z0-9][A-Za-z0-9_.-]*\/[A-Za-z0-9][A-Za-z0-9_.-]*\/pull\/([1-9]\d*)$/.exec(result.prUrl);
499
+ return match !== null && Number.isSafeInteger(Number(match[1]));
500
+ }
501
+
502
+ function hasOpenedPrPointer(result: Pick<SelfDevJobResult, 'prNumber' | 'prUrl'>): boolean {
503
+ const number = result.prNumber;
504
+ if (typeof number === 'number' && Number.isSafeInteger(number) && number > 0) return true;
505
+ if (typeof result.prUrl !== 'string') return false;
506
+ // `stage=pr-opened` is a separate observation and may come from a non-GitHub
507
+ // host. Keep its host-neutral pull pointer contract, with no null or issue URL.
508
+ const match = /^https:\/\/[A-Za-z0-9][A-Za-z0-9.-]*\/(?:[A-Za-z0-9][A-Za-z0-9_.-]*\/)*pull\/([1-9]\d*)$/.exec(result.prUrl);
509
+ return match !== null && Number.isSafeInteger(Number(match[1]));
510
+ }
511
+
491
512
  export function classifyFailure(
492
513
  result: SelfDevJobResult,
493
514
  preflightWarning: PreflightWarningObservation = 'unknown',
494
515
  ): FailureKind | null {
495
516
  if (result.blockReason === 'parent-unlanded') return 'parent-unlanded';
517
+ // A child may claim no changes after committing and opening its draft. The
518
+ // parent must retain the PR for review instead of reworking the same goal.
519
+ if (result.status === 'failed' && result.completionDisposition === 'completed-without-changes'
520
+ && hasConcretePrEvidence(result)) return 'awaiting-human';
521
+ if (result.blockReason === 'dependency-deferred' || result.error?.code === 'DEP_BLOCKED_REBASE_READY') return 'blocked-upstream';
496
522
  if (result.blockReason === 'dependency-needs-human' || result.error?.code === 'GOAL_DONE_BOUNDARY_MISSING') return 'awaiting-human';
497
523
  const ledgerKind = result.failureClassification === undefined
498
524
  ? undefined
499
525
  : result.failureClassification === 'run-deadline-exceeded'
500
526
  // 기한 사망은 transient 가 아니다. 브랜치/PR 이 있으면 수확(false-failure), 없으면 재분해.
501
- ? (result.branch || result.prUrl || result.prNumber !== undefined ? 'false-failure' : 'unconverged-decomposable')
527
+ ? (result.branch || hasOpenedPrPointer(result) ? 'false-failure' : 'unconverged-decomposable')
502
528
  : LEDGER_FAILURE_KIND[result.failureClassification];
503
529
 
504
530
  // ⭐ 수렴 실패인데 하니스가 «쪼개는 법»을 이미 냈으면 그것은 다른 처방이다.
@@ -518,7 +544,7 @@ export function classifyFailure(
518
544
  result.status === 'done'
519
545
  && result.stage === 'pr-opened'
520
546
  && !hasLanded(result)
521
- && (Boolean(result.prUrl) || result.prNumber !== undefined)
547
+ && hasOpenedPrPointer(result)
522
548
  ) {
523
549
  return 'awaiting-human';
524
550
  }
@@ -616,8 +642,15 @@ export function classifyFailures(
616
642
  const kind = classifyFailure(result, queryPreflightWarning(preflightIdentifiers, queryPreflight));
617
643
  if (kind === null) return [];
618
644
  const error = result.error;
619
- const awaitingHuman = kind === 'awaiting-human'
620
- ? failureObservationFields('AWAITING_HUMAN', openPrAwaitingHumanMessage(result))
645
+ const prChangeConflict = kind === 'awaiting-human' && result.status === 'failed'
646
+ && result.completionDisposition === 'completed-without-changes'
647
+ && hasConcretePrEvidence(result);
648
+ const prPointer = typeof result.prNumber === 'number' && Number.isSafeInteger(result.prNumber) && result.prNumber > 0
649
+ ? `#${result.prNumber}` : result.prUrl;
650
+ const awaitingHuman = prChangeConflict
651
+ ? failureObservationFields('PR_CHANGE_CONFLICT', `PR ${prPointer} exists while child reported completed-without-changes`)
652
+ : kind === 'awaiting-human'
653
+ ? failureObservationFields('AWAITING_HUMAN', openPrAwaitingHumanMessage(result))
621
654
  : kind === 'parent-unlanded'
622
655
  ? failureObservationFields('PARENT_UNLANDED', parentUnlandedProgressLine(result.feature.split('\n')[0]!, result.parentPrNumber, result.parentNoPr === true))
623
656
  : undefined;
@@ -1009,13 +1042,16 @@ export function orchestrateSelfDev(opts: OrchestrateSelfDevOptions): Promise<Sel
1009
1042
  taskId: `boundary:${taskCardId}:blocked:${index + 1}`,
1010
1043
  feature: goal.feature,
1011
1044
  status: 'blocked',
1012
- blockReason: 'dependency-needs-human',
1013
- stopReason: 'needs-human',
1014
- error: { code: 'DEPENDENCY_NEEDS_HUMAN', message: `선행 needs-human: ${predecessor}` },
1045
+ blockReason: 'dependency-deferred',
1046
+ stopReason: 'rebase-ready',
1047
+ error: { code: 'DEP_BLOCKED_REBASE_READY', message: `선행 조각 ${predecessor} 재수복 뒤 다음 런 이월` },
1015
1048
  });
1049
+ try { debug.log('self-dev.slice', 'dep-blocked', { slice: goal.id ?? String(index), blockedBy: predecessor,
1050
+ reason: 'GOAL_DONE_BOUNDARY_MISSING', disposition: 'rebase-ready' }); } catch { /* observation is fail-soft */ }
1016
1051
  }
1017
1052
  const withheld = [...blockedGoalIndexes].map((index) => index + 1);
1018
- try { debug.log('self-dev.orchestrate', 'done-boundary-missing', { taskCardId, boundaryMissing, withheld, action: 'needs-human', eligibleToLaunch: opts.goals.length - blockedGoalIndexes.size }); } catch { /* fail-soft */ }
1053
+ try { debug.log('self-dev.orchestrate', 'done-boundary-missing', { taskCardId, boundaryMissing, withheld,
1054
+ action: 'partial-needs-human', dependentDisposition: 'rebase-ready', eligibleToLaunch: opts.goals.length - blockedGoalIndexes.size }); } catch { /* fail-soft */ }
1019
1055
  opts = { ...opts, goals: opts.goals.flatMap((goal, index) => blockedGoalIndexes.has(index)
1020
1056
  ? []
1021
1057
  : [{ ...goal, id: goal.id ?? String(index) }]) };
@@ -1290,6 +1326,7 @@ export function orchestrateSelfDev(opts: OrchestrateSelfDevOptions): Promise<Sel
1290
1326
  const taskIdByLocal = new Map<string, string>(); // goal-local id → live taskId
1291
1327
  const taskIdByGoal = new Map<SelfDevGoal, string>(); // original shard → current or resumed taskId
1292
1328
  const created: Array<{ task: ReturnType<typeof createTask>; goal: SelfDevGoal }> = [];
1329
+ const repairedGoals = new Set<SelfDevGoal>();
1293
1330
  opts.goals.forEach((g, i) => {
1294
1331
  const prior = resumedByGoal.get(g);
1295
1332
  if (prior) {
@@ -1762,8 +1799,38 @@ export function orchestrateSelfDev(opts: OrchestrateSelfDevOptions): Promise<Sel
1762
1799
  dispStage: fDisp?.stage ?? 'none', screenSpace: fScreen.screenSpace,
1763
1800
  });
1764
1801
  }
1802
+ const failedGoal = taskByGoal.get(ev.taskId);
1803
+ const failedTask = graph.getTask(ev.taskId);
1765
1804
  const failedResult = results.get(ev.taskId)!;
1766
1805
  const stopReason = opts.stopAfterFailure?.(failedResult) ?? null;
1806
+ // A child without a PR gets one supervised, narrower attempt. Keep the original
1807
+ // failure in the checkpoint; redirect only its actual dependents to the replacement.
1808
+ if (stopReason === null && taskCardId?.trim() && failedGoal && failedTask?.surface.kind === 'self-implement' && !repairedGoals.has(failedGoal)
1809
+ && !fDisp?.prUrl && fDisp?.merged !== true && fDisp?.harvestable !== true) {
1810
+ repairedGoals.add(failedGoal);
1811
+ const reason = `${ev.errorCode}: ${ev.errorMessage}`.slice(0, FAILURE_MESSAGE_MAX_LENGTH);
1812
+ const repairFeature = `${failedGoal.feature.trimEnd()}\n\n## 자동 수복 1회\n앞선 조각 실패: ${reason}\n실패 범위만 좁혀 재시도하고 원래 완료 경계를 보존한다.`;
1813
+ const replacement = createTask({
1814
+ title: goalTitle(failedGoal),
1815
+ description: repairFeature.slice(0, TASK_DEFAULTS.descriptionMaxLen),
1816
+ surface: failedTask.surface.kind === 'self-implement'
1817
+ ? { ...failedTask.surface, feature: repairFeature }
1818
+ : failedTask.surface,
1819
+ isolation: failedTask.isolation,
1820
+ }, { now: now() });
1821
+ graph.addTask(replacement);
1822
+ graph.updateTask(replacement.id, { dependsOn: [...failedTask.dependsOn] }, { now: now() });
1823
+ taskByGoal.set(replacement.id, failedGoal);
1824
+ spaceIdByTask.set(replacement.id, spaceIdForTask(replacement));
1825
+ taskIdByGoal.set(failedGoal, replacement.id);
1826
+ created.push({ task: replacement, goal: failedGoal });
1827
+ graph.supersede(ev.taskId, [replacement.id], { now: now() });
1828
+ results.set(ev.taskId, { ...results.get(ev.taskId)!, status: 'superseded' });
1829
+ try { debug.log('self-dev.slice', 'repair-retry', { slice: failedGoal.id ?? ev.taskId, failedTaskId: ev.taskId,
1830
+ replacementTaskId: replacement.id, reason, attempt: 1 }); } catch { /* observation is fail-soft */ }
1831
+ scheduleTick();
1832
+ break;
1833
+ }
1767
1834
  if (stopReason !== null) {
1768
1835
  let remainingGoals = 0;
1769
1836
  for (const task of created.map(({ task }) => graph.getTask(task.id)).filter((task): task is NonNullable<typeof task> => task !== undefined)) {
@@ -1781,24 +1848,56 @@ export function orchestrateSelfDev(opts: OrchestrateSelfDevOptions): Promise<Sel
1781
1848
  }
1782
1849
  if (remainingGoals > 0) opts.onStopAfterFailure?.({ reason: stopReason, remainingGoals });
1783
1850
  }
1784
- // S3 cascade — dependents of a failed task can never become
1785
- // ready (a dep will never be `done`) → cancel them honestly
1786
- // instead of leaving them `blocked` (which stalls the run onto
1787
- // the stuck-guard). subtree() = failed task + its downstream.
1851
+ // A hot-file edge only serializes execution. It does not make the later
1852
+ // slice depend on the earlier slice's result. Cancel only the explicit
1853
+ // dependency closure; release hot-only edges so independent PRs proceed.
1854
+ const localGoalId = (goal: SelfDevGoal): string => goal.id ?? String(opts.goals.indexOf(goal));
1855
+ const blockedGoalIds = new Set<string>(failedGoal ? [localGoalId(failedGoal)] : []);
1856
+ let expanded = true;
1857
+ while (expanded) {
1858
+ expanded = false;
1859
+ for (const { goal } of created) {
1860
+ const localId = localGoalId(goal);
1861
+ if (blockedGoalIds.has(localId)) continue;
1862
+ if ((goal.dependsOn ?? []).some((id) => blockedGoalIds.has(id))) {
1863
+ blockedGoalIds.add(localId);
1864
+ expanded = true;
1865
+ }
1866
+ }
1867
+ }
1788
1868
  let cascaded = 0;
1789
- for (const t of graph.subtree(ev.taskId)) {
1790
- if (t.id === ev.taskId || isTerminalStatus(t.status)) continue;
1869
+ for (const { task, goal } of created) {
1870
+ const t = graph.getTask(task.id);
1871
+ if (!t || t.id === ev.taskId || isTerminalStatus(t.status)) continue;
1872
+ const localId = localGoalId(goal);
1873
+ if (!blockedGoalIds.has(localId)) continue;
1791
1874
  try {
1792
1875
  graph.updateTask(t.id, { status: 'cancelled' }, { now: now() });
1793
1876
  results.set(t.id, {
1794
1877
  taskId: t.id,
1795
1878
  feature: taskByGoal.get(t.id)?.feature ?? '',
1796
1879
  status: 'cancelled',
1797
- error: { code: 'DEP_FAILED', message: `dependency ${ev.taskId} failed` },
1880
+ error: taskCardId?.trim()
1881
+ ? { code: 'DEP_BLOCKED_REBASE_READY', message: `dependency ${ev.taskId} failed; rebase-ready next run` }
1882
+ : { code: 'DEP_FAILED', message: `dependency ${ev.taskId} failed` },
1798
1883
  });
1884
+ try { debug.log('self-dev.slice', 'dep-blocked', { slice: localId, blockedBy: failedGoal?.id ?? ev.taskId,
1885
+ reason: ev.errorCode, disposition: 'rebase-ready' }); } catch { /* observation is fail-soft */ }
1799
1886
  cascaded++;
1800
1887
  } catch { /* best-effort */ }
1801
1888
  }
1889
+ for (const { task, goal } of created) {
1890
+ const current = graph.getTask(task.id);
1891
+ if (!current || isTerminalStatus(current.status)) continue;
1892
+ const independent = current.dependsOn.filter((id) => {
1893
+ const parent = graph.getTask(id);
1894
+ return parent && (parent.status === 'failed' || parent.status === 'cancelled' || parent.status === 'superseded')
1895
+ && !(goal.dependsOn ?? []).includes(taskByGoal.has(id) ? localGoalId(taskByGoal.get(id)!) : '');
1896
+ });
1897
+ if (independent.length) graph.updateTask(task.id, {
1898
+ dependsOn: current.dependsOn.filter((id) => !independent.includes(id)),
1899
+ }, { now: now() });
1900
+ }
1802
1901
  debug.log('self-dev.orchestrate', 'job.failed', {
1803
1902
  taskId: ev.taskId,
1804
1903
  feature: shortFeature(ev.taskId),
@@ -10,7 +10,7 @@ import { recordSelfDevRunSupervisorStop, selfDevRunsDir } from './run-store.js';
10
10
  import { debug } from '../debug/log.js';
11
11
  import { sweepFrozenMerges } from '../self-implement/frozen-merges.js';
12
12
  import { routeSupervisorVerdict } from './supervisor-verdict-edges.js';
13
- import { recordTaskAgentShadowMove, runCardFor, type TaskAgentShadowInput } from '../task-agent/shadow.js';
13
+ import type { TaskAgentShadowInput } from '../task-agent/shadow.js';
14
14
  import { cardPrNumber, taskAgentStatePath } from '../task-agent/task-hand.js';
15
15
  import {
16
16
  classifyMustFixRound, inferMustFixEvidence, judgeMustFixScope, proposeMustFixSplit,
@@ -40,6 +40,8 @@ export interface SupervisorRound {
40
40
  mainSyncRelaunchTaskIds?: string[];
41
41
  /** Original feature and relaunch goal text of those tasks — a rerun may mint a new taskId, so the piece is also found by goal. */
42
42
  mainSyncRelaunchFeatures?: string[];
43
+ /** PR 없는 미분류 실패에 대해 실제 분해 실행기로 수복한 원래 골. 새 taskId에도 한 번 상한을 지킨다. */
44
+ selfHealDecomposeFeatures?: string[];
43
45
  /**
44
46
  * Tasks of this round that ended `status=failed` without a PR. Omitted when there are none — and on older
45
47
  * history, which never measured it, so the no-PR streak guard reads it as «not measured» and stays off.
@@ -130,6 +132,7 @@ export interface SupervisorDecision {
130
132
  };
131
133
  oscillation?: { taskIds: string[]; helper: 'review-oscillation'; signature: string; repairGoals?: Record<string, string>; heldTaskIds?: string[] };
132
134
  pendingDecision?: 'attempt-care-escalation';
135
+ selfHeal?: { reason: 'supervisor-unclassified-decompose'; attempt: 1; taskIds: string[] };
133
136
  }
134
137
 
135
138
  export interface SupervisorLimits {
@@ -352,6 +355,8 @@ export function decideNextRun(input: {
352
355
  reviewMustFixTrend?: ReviewRework['trend'];
353
356
  /** True: the rerun consumes the authored goal. False: it cannot, so oscillation stops for a human. Undefined: pure decision. */
354
357
  repairGoalExecution?: boolean;
358
+ /** 분해 제안을 실제 조각 실행으로 승격할 수 있는 supervisor 경로에만 true. */
359
+ decompositionExecution?: boolean;
355
360
  }): SupervisorDecision {
356
361
  const results = [...input.results];
357
362
  const history = [...(input.history ?? [])];
@@ -502,6 +507,29 @@ export function decideNextRun(input: {
502
507
  }
503
508
 
504
509
  if (!t.actionable) {
510
+ const spent = new Set(history.flatMap((entry) => entry.selfHealDecomposeFeatures ?? []).map(resumeKey));
511
+ const candidates = input.decompositionExecution === true && round + 1 <= maxRounds
512
+ ? activeResults.filter((result) => result.status === 'failed' && result.prNumber === undefined && !result.prUrl
513
+ && !result.providerErrors && !result.blockReason
514
+ && (result.decomposeProposal?.pieces.length ?? 0) >= 2
515
+ && t.needsHuman.includes(result.taskId)
516
+ && t.classifications.some((classification) => classification.taskId === result.taskId && classification.kind === 'unclassified')
517
+ && !spent.has(resumeKey(result.feature)))
518
+ : [];
519
+ // rerun은 라운드 전체를 받는다. 다른 needs-human 조각을 함께 다시 띄우지 않도록 첫 조각은 단독 후보로만 허용한다.
520
+ const candidate = candidates.length === 1 && t.needsHuman.every((id) => id === candidates[0]!.taskId)
521
+ ? candidates[0] : undefined;
522
+ if (candidate) {
523
+ const taskIds = [candidate.taskId];
524
+ return { ...base, action: 'relaunch',
525
+ decomposable: taskIds,
526
+ needsHuman: t.needsHuman.filter((id) => !taskIds.includes(id)),
527
+ classifications: t.classifications.map((classification) => taskIds.includes(classification.taskId)
528
+ ? { ...classification, action: 'decompose-and-retry' as const } : classification),
529
+ selfHeal: { reason: 'supervisor-unclassified-decompose', attempt: 1, taskIds },
530
+ why: `supervisor-unclassified-decompose (attempt: 1/1) — PR 없는 미분류 조각 ${taskIds.length}개를 실증된 분해 제안으로 한 번 재걸기`,
531
+ };
532
+ }
505
533
  if (t.needsHuman.length > 0) {
506
534
  return {
507
535
  ...base,
@@ -772,6 +800,12 @@ export function appendRound(
772
800
  decision.relaunchGoals?.[id],
773
801
  ].filter((feature): feature is string => feature !== undefined)),
774
802
  } : {}),
803
+ ...(decision?.action !== 'stop' && decision?.selfHeal ? {
804
+ selfHealDecomposeFeatures: decision.selfHeal.taskIds.flatMap((id) => {
805
+ const feature = results.find((result) => result.taskId === id)?.feature;
806
+ return feature === undefined ? [] : [feature];
807
+ }),
808
+ } : {}),
775
809
  ...(decision?.action === 'add-repair-task' && decision.oscillation ? (() => {
776
810
  // Each repaired task is recorded under its original goal feature and, when a rerun runs the authored goal as
777
811
  // the piece's new feature (orchestrate), under that repair text too — so the repair's own oscillation stops.
@@ -1028,6 +1062,7 @@ export async function rejudgeTerminalTaskCard(runId: string | null, deps: {
1028
1062
  external?: Parameters<typeof import('../task-agent/rejudge-on-head.js').rejudgeAsyncResultCard>[2];
1029
1063
  } = {}): Promise<void> {
1030
1064
  const statePath = deps.statePath ?? taskAgentStatePath();
1065
+ const { runCardFor } = await import('../task-agent/shadow.js');
1031
1066
  const card = runCardFor(runId, { statePath, ...(deps.env ? { env: deps.env } : {}) });
1032
1067
  if (!card || card.status !== 'launched' || card.taLand !== true || cardPrNumber(card) === undefined) return;
1033
1068
  const { rejudgeAsyncResultCard } = await import('../task-agent/rejudge-on-head.js');
@@ -1081,9 +1116,10 @@ export async function superviseRun(opts: SuperviseRunOptions): Promise<Superviso
1081
1116
  const allUnreviewedAreNoDiff = unreviewed.length > 0
1082
1117
  && unreviewed.every((result) => result.reviewReason === 'no-diff');
1083
1118
 
1084
- const decision = decideNextRun({
1119
+ let decision = decideNextRun({
1085
1120
  results,
1086
1121
  history,
1122
+ decompositionExecution: opts.promoteDecomposition !== undefined,
1087
1123
  // Undeclared = cannot run the repair goal: an add-repair-task would otherwise be a same-strategy relaunch.
1088
1124
  repairGoalExecution: opts.repairGoalExecution === true,
1089
1125
  ...(aggregateReviewTrend(results) ? { reviewMustFixTrend: aggregateReviewTrend(results) } : {}),
@@ -1118,6 +1154,20 @@ export async function superviseRun(opts: SuperviseRunOptions): Promise<Superviso
1118
1154
  decomposePromotion = { attempted: true, reason: `shim-failed: ${String(error)}` };
1119
1155
  }
1120
1156
  }
1157
+ if (decision.selfHeal) {
1158
+ const promoted = decomposePromotion.attempted && (decomposePromotion.pieceCount ?? 0) >= 2;
1159
+ try { opts.observe?.('supervisor-self-heal', { runId, reason: decision.selfHeal.reason,
1160
+ attempt: decision.selfHeal.attempt, taskIds: decision.selfHeal.taskIds,
1161
+ outcome: promoted ? 'promoted' : 'needs-human', promotionReason: decomposePromotion.reason }); } catch { /* fail-open */ }
1162
+ if (!promoted) {
1163
+ decision = { ...decision, action: 'stop', stopReason: 'needs-human',
1164
+ decomposable: decision.decomposable.filter((id) => !decision.selfHeal!.taskIds.includes(id)),
1165
+ needsHuman: [...new Set([...decision.needsHuman, ...decision.selfHeal.taskIds])],
1166
+ classifications: decision.classifications.map((classification) => decision.selfHeal!.taskIds.includes(classification.taskId)
1167
+ ? { ...classification, action: 'needs-human' as const } : classification),
1168
+ why: `${decision.selfHeal.reason} (attempt: 1/1) — 분해 승격 실패(${decomposePromotion.reason}); 자동 재실행 없이 사람 확인` };
1169
+ }
1170
+ }
1121
1171
 
1122
1172
  try {
1123
1173
  const walkSummary = results.some((r) => r.walk !== undefined)
@@ -1145,6 +1195,7 @@ export async function superviseRun(opts: SuperviseRunOptions): Promise<Superviso
1145
1195
  kinds: decision.classifications.map((c) => `${c.kind}:${c.action}`),
1146
1196
  decomposePromotionAttempted: decomposePromotion.attempted,
1147
1197
  decomposePromotionReason: decomposePromotion.reason,
1198
+ ...(decision.selfHeal ? { selfHealReason: decision.selfHeal.reason, selfHealAttempt: decision.selfHeal.attempt } : {}),
1148
1199
  ...(decomposePromotion.pieceCount === undefined ? {} : { decomposePieceCount: decomposePromotion.pieceCount }),
1149
1200
  ...(decomposePromotion.dependsOnEdges === undefined ? {} : { decomposeDependsOnEdges: decomposePromotion.dependsOnEdges }),
1150
1201
  ...(decomposePromotion.hotPathEdges === undefined ? {} : { decomposeHotPathEdges: decomposePromotion.hotPathEdges }),
@@ -1188,6 +1239,7 @@ export async function superviseRun(opts: SuperviseRunOptions): Promise<Superviso
1188
1239
  runId,
1189
1240
  reason: decision.stopReason,
1190
1241
  outcome: persistence.outcome,
1242
+ ...(decision.selfHeal ? { selfHealReason: decision.selfHeal.reason, selfHealAttempt: decision.selfHeal.attempt } : {}),
1191
1243
  ...storageObservation,
1192
1244
  });
1193
1245
  } catch { /* fail-open */ }
@@ -1195,6 +1247,7 @@ export async function superviseRun(opts: SuperviseRunOptions): Promise<Superviso
1195
1247
  if (decision.stopReason && opts.taskAgentShadow !== false) {
1196
1248
  // TASK-AGENT-SHADOW — 판단부를 그림자로 부른다(실행 0). 어떤 오류도 런의 결말을 바꾸지 않는다.
1197
1249
  try {
1250
+ const { recordTaskAgentShadowMove } = await import('../task-agent/shadow.js');
1198
1251
  const pr = results.find((result) => typeof result.prNumber === 'number' && result.prNumber > 0)?.prNumber;
1199
1252
  const reviewed = results.filter((result) => result.prNumber === pr && result.selfReview && result.merged !== true);
1200
1253
  const selfReview = pr && reviewed.length === 1 ? reviewed[0]!.selfReview : undefined;
@@ -98,7 +98,7 @@ export interface SelfDevJobResult {
98
98
  /** Commits this child added against its own `--base`. 0 is not completion progress. */
99
99
  commitsAheadOfBase?: number;
100
100
  /** A dependency is done but its result is not on main; no child was launched. */
101
- blockReason?: 'parent-unlanded' | 'dependency-needs-human';
101
+ blockReason?: 'parent-unlanded' | 'dependency-needs-human' | 'dependency-deferred';
102
102
  parentPrNumber?: number;
103
103
  /** The upstream completed in a worktree without opening a PR. */
104
104
  parentNoPr?: true;
@@ -0,0 +1,153 @@
1
+ // ── 자동 회복 (TUI-400-AUTOHEAL-FALLBACK · 대표 10-22) ──
2
+ //
3
+ // 대표 «400 같은 오류로 멈추면 스스로 회복 · 자동 provider fallback 이 없으면 작업을 못 잇는다».
4
+ // 실측(10-22 07:1x OPT): TUI 턴이 «Codex API 400(대화 기록 어긋남 의심)» 로 끝나고 멈췄다 — 지문
5
+ // `codex-400-bad-request` 는 «/session new 뒤 다시» 를 사람에게 «보여줄» 뿐이었고, OP 가 손으로 쳐서 회복했다.
6
+ //
7
+ // 이 모듈은 «판정»만 갖는다(순수 · 관측·화면은 호출부가 남긴다). 사다리:
8
+ // ① 같은 턴 400(대화 기록) → 새 백엔드 세션 ⊕ 직전 요약(짧게)으로 1회 재시도
9
+ // ② 그래도 400 → `llm.fallbackChain` 다음 공급자로 그 턴 재시도
10
+ // ③ 그래도 실패 → 턴당 2회 상한에서 멈추고 사람에게 이유 한 줄
11
+ // ⛔ 답·도구 호출이 이미 흘렀으면 다시 보내지 않는다(중복 출력·부작용). ⛔ 무한 반복 금지(AUTOHEAL_MAX_ATTEMPTS).
12
+ // 📋 관측 = `debug.log('self-health.autoheal', attempt|recovered|exhausted|skipped, …)` — 호출부(plain-turn 런타임).
13
+
14
+ import { matchFailureText, type FailureSignature } from './signatures.js';
15
+
16
+ /** 턴당 자동 회복 상한 — ① 새 세션 ② 공급자. ⛔ 늘리면 «무한 반복 금지» 판정선이 같이 움직인다. */
17
+ export const AUTOHEAL_MAX_ATTEMPTS = 2;
18
+
19
+ export type AutohealStep = 'new-session' | 'provider-fallback';
20
+
21
+ /** 재시도 요청에 실리는 ACP `_meta` 키 — 서버 다리(`core-turn-bridge`)가 «이 턴은 다음 공급자로» 를 읽는다.
22
+ * ⛔ 공급자 «이름»은 싣지 않는다 — 고르는 것은 서버가 자기 `llm.fallbackChain` 으로 한다(클라이언트가 지갑을 못 고른다). */
23
+ export const AUTOHEAL_META_KEY = 'elanousAutoheal';
24
+
25
+ export interface AutohealProviderFallbackMeta {
26
+ readonly providerFallback: true;
27
+ }
28
+
29
+ export function autohealProviderFallbackMeta(): Record<string, AutohealProviderFallbackMeta> {
30
+ return { [AUTOHEAL_META_KEY]: { providerFallback: true } };
31
+ }
32
+
33
+ /** 프롬프트 `_meta` 에 «다음 공급자로» 표지가 있나. */
34
+ export function readAutohealProviderFallback(meta: Readonly<Record<string, unknown>> | undefined): boolean {
35
+ const value = meta?.[AUTOHEAL_META_KEY];
36
+ return typeof value === 'object' && value !== null
37
+ && (value as { providerFallback?: unknown }).providerFallback === true;
38
+ }
39
+
40
+ /** 자동 회복을 거는 지문 — 오류 «원문»으로 판정한다(지문 번역문으로 판정하면 안 걸린다 · #27452 교훈). */
41
+ export function autohealSignatureFor(detail: string): FailureSignature | null {
42
+ const sig = matchFailureText(detail);
43
+ return sig?.autoheal ? sig : null;
44
+ }
45
+
46
+ export type AutohealStopReason =
47
+ | 'not-autoheal-signature'
48
+ | 'output-emitted'
49
+ | 'tool-dispatched'
50
+ | 'aborted'
51
+ | 'history-changed'
52
+ | 'no-fallback-provider'
53
+ | 'max-attempts';
54
+
55
+ export type AutohealDecision =
56
+ | { readonly kind: 'retry'; readonly step: AutohealStep; readonly attempt: number; readonly provider?: string }
57
+ | { readonly kind: 'stop'; readonly reason: AutohealStopReason };
58
+
59
+ export interface AutohealDecisionInput {
60
+ /** 이번 실패의 오류 원문. */
61
+ readonly detail: string;
62
+ /** 이미 한 자동 회복 횟수(0 = 첫 실패). */
63
+ readonly attemptsDone: number;
64
+ /** 이 턴에서 답·도구 호출이 화면/서버로 흘렀나. */
65
+ readonly emitted: boolean;
66
+ /** 도구 실행 수가 바뀌었나(모르면 false — 그때는 emitted 로만 가른다). */
67
+ readonly toolDispatched: boolean;
68
+ readonly aborted: boolean;
69
+ /** ② 칸에서 쓸 다음 공급자(없으면 null). ① 칸에서는 안 본다. */
70
+ readonly fallbackProvider: string | null;
71
+ }
72
+
73
+ /** 다음 한 걸음. 순수 — 같은 입력이면 같은 답. */
74
+ export function decideAutohealStep(input: AutohealDecisionInput): AutohealDecision {
75
+ if (!autohealSignatureFor(input.detail)) return { kind: 'stop', reason: 'not-autoheal-signature' };
76
+ if (input.aborted) return { kind: 'stop', reason: 'aborted' };
77
+ if (input.emitted) return { kind: 'stop', reason: 'output-emitted' };
78
+ if (input.toolDispatched) return { kind: 'stop', reason: 'tool-dispatched' };
79
+ if (input.attemptsDone >= AUTOHEAL_MAX_ATTEMPTS) return { kind: 'stop', reason: 'max-attempts' };
80
+ if (input.attemptsDone === 0) return { kind: 'retry', step: 'new-session', attempt: 1 };
81
+ if (!input.fallbackProvider) return { kind: 'stop', reason: 'no-fallback-provider' };
82
+ return { kind: 'retry', step: 'provider-fallback', attempt: 2, provider: input.fallbackProvider };
83
+ }
84
+
85
+ /** 화면 한 줄 — 시도할 때. */
86
+ export function formatAutohealAttemptLine(decision: Extract<AutohealDecision, { kind: 'retry' }>): string {
87
+ const what = decision.step === 'new-session' ? '새 세션 ⊕ 요약으로' : `공급자 ${decision.provider ?? '?'} 로`;
88
+ return `자동 회복: ${what} 다시 시도 (${decision.attempt}/${AUTOHEAL_MAX_ATTEMPTS})`;
89
+ }
90
+
91
+ export interface AutohealAttemptRecord {
92
+ readonly step: AutohealStep;
93
+ readonly provider?: string;
94
+ }
95
+
96
+ /** 화면 한 줄 — 상한에서 멈출 때. 한글 두 칸으로 130칸 안(지문 한 줄과 같은 규율). */
97
+ export function formatAutohealExhaustedNotice(
98
+ attempts: readonly AutohealAttemptRecord[],
99
+ reason: AutohealStopReason,
100
+ opts: { rawHint?: string } = {},
101
+ ): string {
102
+ const steps = attempts.map((a) => (a.step === 'new-session' ? '새 세션' : `공급자 ${a.provider ?? '?'}`)).join(' → ');
103
+ const why = reason === 'no-fallback-provider' ? `${steps} · 대체 공급자 없음` : steps;
104
+ const raw = opts.rawHint ? ` · 원문 ${opts.rawHint}` : '';
105
+ return `⚠ 자동 회복 ${attempts.length}회 실패(${why}) → 잠시 뒤 다시 · eln usage${raw}`;
106
+ }
107
+
108
+ /** 상한에서 멈춘 턴 — 메시지는 «원문 그대로»(지문·#27452 판정이 원문으로 돈다), 회복 이력은 따로 싣는다. */
109
+ export class AutohealExhaustedError extends Error {
110
+ constructor(
111
+ readonly original: unknown,
112
+ readonly attempts: readonly AutohealAttemptRecord[],
113
+ readonly reason: AutohealStopReason,
114
+ ) {
115
+ super(original instanceof Error ? original.message : String(original));
116
+ this.name = 'AutohealExhaustedError';
117
+ }
118
+ }
119
+
120
+ /** 직전 요약을 «짧게» — 이미 있는 압축 요약(`compactConversation`)을 쓰고, 실패·시간 초과면
121
+ * 같은 압축 모듈의 대화록(`buildCompactTranscript`) 꼬리로 대신한다. ⛔ 여기서 요약을 다시 만들지 않는다. */
122
+ export async function summarizeForAutoheal<T>(
123
+ prior: readonly T[],
124
+ deps: {
125
+ compact: (history: readonly T[]) => Promise<{ summary: string }>;
126
+ transcript: (history: readonly T[]) => string;
127
+ timeoutMs?: number;
128
+ maxChars?: number;
129
+ },
130
+ ): Promise<{ summary: string; source: 'compact' | 'transcript-tail' | 'empty' }> {
131
+ const maxChars = deps.maxChars ?? 1_200;
132
+ const clip = (text: string, tail: boolean): string => {
133
+ const trimmed = text.trim();
134
+ if (trimmed.length <= maxChars) return trimmed;
135
+ return tail ? `…${trimmed.slice(-maxChars)}` : `${trimmed.slice(0, maxChars)}…`;
136
+ };
137
+ try {
138
+ let timer: ReturnType<typeof setTimeout> | undefined;
139
+ const timeout = new Promise<never>((_, reject) => {
140
+ timer = setTimeout(() => reject(new Error('autoheal summary timed out')), deps.timeoutMs ?? 20_000);
141
+ });
142
+ try {
143
+ const { summary } = await Promise.race([deps.compact(prior), timeout]);
144
+ if (summary.trim()) return { summary: clip(summary, false), source: 'compact' };
145
+ } finally {
146
+ if (timer) clearTimeout(timer);
147
+ }
148
+ } catch { /* 요약 실패는 대화록 꼬리로 — 회복을 막지 않는다 */ }
149
+ const transcript = deps.transcript(prior);
150
+ return transcript.trim()
151
+ ? { summary: clip(transcript, true), source: 'transcript-tail' }
152
+ : { summary: '', source: 'empty' };
153
+ }
@@ -34,6 +34,9 @@ export interface FailureSignature {
34
34
  readonly cause: string;
35
35
  /** 다음 행동 — 한국어 한 줄. */
36
36
  readonly next: string;
37
+ /** 자동 수복 — 있으면 TUI 턴이 사람에게 넘기기 «전에» 스스로 회복을 시도한다(`self-health/autoheal.ts`).
38
+ * `new-session-then-provider` = ① 새 백엔드 세션 ⊕ 직전 요약 → ② fallbackChain 다음 공급자(턴당 2회 상한). */
39
+ readonly autoheal?: 'new-session-then-provider';
37
40
  }
38
41
 
39
42
  /** 이벤트 루프 정지를 «지문»으로 볼 문턱 — 0.25s 표본은 잦아 소음이고, 결함 #1(14s)·#14(최대 2.35s)는 이 위다. */
@@ -48,6 +51,9 @@ export const FAILURE_SIGNATURES: readonly FailureSignature[] = [
48
51
  text: [/\b(?:Codex|LLM) API 400\b/],
49
52
  cause: '모델 API 가 요청을 400 으로 거절(대화 기록 어긋남 의심)',
50
53
  next: '/session new 뒤 짧게 다시 묻기',
54
+ // TUI-400-AUTOHEAL-FALLBACK(대표 10-22) — 위 처방을 사람이 치기 전에 TUI 가 먼저 스스로 해 본다.
55
+ // 처방 한 줄은 자동 회복이 «안 걸린» 경우(답이 이미 흐름·배선 없음)에만 보인다.
56
+ autoheal: 'new-session-then-provider',
51
57
  },
52
58
  {
53
59
  id: 'provider-fallback-exhausted',