elanous 0.2.34 → 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 (802) 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/{abb4b98b.163e0f56e84ae35d.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/1201.afbfc5b1c5e5cbe4.js +1 -0
  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/2500.cbc1257b774aae52.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/{6086.913a69e6fa3e4a8b.js → 2683.c9773a0c589b031b.js} +4 -4
  20. package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +24 -0
  21. package/apps/pwa/out/_next/static/chunks/{5576-82d3703636d5c4b9.js → 275-02ea4c2a33980422.js} +3 -3
  22. package/apps/pwa/out/_next/static/chunks/{ffdc3a04.b9c23c1b28dd4a96.js → 2812ca6a.3b9f4a7a08885744.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2941.3c3546f96bc6efa7.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +24 -0
  26. package/apps/pwa/out/_next/static/chunks/{9550.d5f76828f972058c.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/{8817.61bb7ffbba502ecb.js → 3136.30aaaa5fa03662a3.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/{9131-fce7256c4180c4a5.js → 3148-98efd4869d660a87.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/{3498.cf2a15a8a9e5b926.js → 3155.2587a55196ecb394.js} +3 -3
  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/{3103.84470c8445962f04.js → 3324.a09703033abcbd2f.js} +1 -1
  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/{3819.163d4777f0a597f6.js → 3538.a445e50bb359d068.js} +2 -2
  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/{3414.172ad4ca2d9b08e8.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/3757-180308bc61021b05.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +74 -0
  45. package/apps/pwa/out/_next/static/chunks/3840-5825d56d46976a92.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{9b48c871.204d5d13e7809bd0.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/{6740.43de73fc427c9fe2.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/{8548.036c344973968847.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/{3411-f87314c6c66ebc73.js → 5085-bce4904931767ca6.js} +1 -1
  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/{3110.0a7065f25c841818.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/{1644.35dd25240ae24e4b.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/{3837.722e053fb9f321ad.js → 5711.957b095705c12560.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/{2124.ed5bf480cea7f85b.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/{7562.948255cbc3e79d33.js → 599.c39c571b6733f2a2.js} +2 -2
  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/{5446.edf141cff9ef647d.js → 6925.562d532110879886.js} +1 -1
  86. package/apps/pwa/out/_next/static/chunks/{7005.1623d2aea78eb85f.js → 6943.c6b24124853a47b2.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/727.7deb87749b0a343a.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/{8368.014caa8de2f5af34.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/{2554.3b5e200f5f5cfcd6.js → 771.c3cdb6c1f7f47c02.js} +16 -16
  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/{3121.779fafe3e44612c5.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/{9a8cb466.cc9fc9e6e46038aa.js → 873d6c12.09bd499f57171543.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/{7431.3051e9b8a4372d2d.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/914.8abefd48d579547b.js +94 -0
  105. package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/{1895-60ed0e341c658bd4.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/{2547.dd27303624cb4da8.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/9789.60f723d18097ec30.js +1 -0
  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-4fb31eb476dcbad3.js → page-083747f1d4518f61.js} +1 -1
  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/{5014f970-22bef0b5210f7d60.js → ccae1c4b-0cf414f5eff1b10d.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{4fa33ebd.21c1bd5b294496e6.js → ceba0382.650712b56b85b582.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/da5ecc5c-b005ad8cac737d57.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/f9a61e4d.1fc2c1dbdd49fe46.js +1 -0
  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/{L04y73dlwKeTW-GetaTF3 → 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/bin/elanous.mjs +3 -2
  278. package/catalog/providers/opengateway.yaml +25 -0
  279. package/docs/goal-context/01-goal-authoring-checks.md +8 -0
  280. package/docs/goal-context/03-verification-menu.md +24 -0
  281. package/docs/goal-context/04-mock-scenarios.md +100 -0
  282. package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
  283. package/docs/goal-context/README.md +7 -0
  284. package/graphs/catalog/catalog.yaml +1 -1
  285. package/graphs/default-loop.yaml +63 -4
  286. package/graphs/document-loop.yaml +51 -3
  287. package/graphs/implement-loop.yaml +77 -4
  288. package/graphs/journey/ta-journey.yaml +11 -1
  289. package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
  290. package/graphs/journey/units/author-dialogue/observe.ts +96 -0
  291. package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
  292. package/graphs/operate-loop.yaml +51 -3
  293. package/graphs/release/recipes.yaml +6 -0
  294. package/graphs/release/release-loop.yaml +17 -4
  295. package/graphs/research-loop.yaml +137 -3
  296. package/graphs/test-diet/test-diet.yaml +3 -0
  297. package/graphs/wizard/recipes.yaml +44 -0
  298. package/graphs/wizard/wizard-loop.yaml +44 -0
  299. package/graphs/work/research-report.yaml +2 -0
  300. package/package.json +1 -1
  301. package/scripts/ci-typecheck-changed.ts +139 -5
  302. package/scripts/coord-role-pack.ts +19 -6
  303. package/scripts/first10-gate.ts +416 -0
  304. package/scripts/fleet/wsl-node-setup.sh +432 -0
  305. package/scripts/hq/standby-snapshot.ts +17 -12
  306. package/scripts/release-loop/docs-land-node.ts +21 -5
  307. package/scripts/release-loop/docs-node.ts +204 -8
  308. package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
  309. package/scripts/release-loop/gate-node.ts +427 -72
  310. package/scripts/release-loop/gate-partial.ts +65 -11
  311. package/scripts/release-loop/gate-radius-live.ts +177 -0
  312. package/scripts/release-loop/gate-radius-shadow.ts +1 -1
  313. package/scripts/release-loop/node-verdict.ts +14 -1
  314. package/scripts/release-loop/npm-publish-node.ts +66 -12
  315. package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
  316. package/scripts/release-loop/pwa-remote.ts +166 -0
  317. package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
  318. package/scripts/release-loop/resume-cap.ts +14 -34
  319. package/scripts/release-loop/resume-release.ts +78 -15
  320. package/scripts/release-loop/traffic-node.ts +59 -0
  321. package/scripts/release-loop/traffic-transition.ts +159 -0
  322. package/scripts/release-loop/unattended-release.ts +2 -0
  323. package/scripts/rhythm/daily.ts +137 -3
  324. package/scripts/test-diet/lib.ts +6 -1
  325. package/scripts/test-diet/node.ts +194 -13
  326. package/scripts/ux-sim.ts +92 -0
  327. package/skills/README.md +1 -0
  328. package/src/acp/core-turn-bridge.ts +48 -6
  329. package/src/agent/delegate-hint.ts +16 -0
  330. package/src/agent/runner.ts +82 -2
  331. package/src/agent/self-ambient-cache.ts +8 -0
  332. package/src/agent/task-notification.ts +56 -10
  333. package/src/agent/types.ts +4 -0
  334. package/src/agent-substrate/acp-reviewer.ts +39 -4
  335. package/src/agent-substrate/pr-reviewer.ts +72 -3
  336. package/src/agent-substrate/review-intent.ts +29 -2
  337. package/src/agent-substrate/review-observation.ts +3 -0
  338. package/src/agent-substrate/self-review-cli.ts +229 -28
  339. package/src/autopilot/mission-codebase-gate.ts +141 -12
  340. package/src/autopilot/pr-manager.ts +240 -41
  341. package/src/boot/daemon-tools/self-implement.ts +1 -0
  342. package/src/budget/run-usage-rollup.ts +1 -0
  343. package/src/budget/usage-outcomes.ts +8 -4
  344. package/src/capture/tui-self-report.ts +102 -0
  345. package/src/chat/goal-continue-verdict.ts +41 -0
  346. package/src/chat/index.ts +30 -6
  347. package/src/chat/internal-turn-origin.ts +1 -0
  348. package/src/chat/paste-fold.ts +86 -0
  349. package/src/chat/pickers/modal-runtime.ts +10 -27
  350. package/src/chat/tool-render/block.ts +32 -0
  351. package/src/chat/tool-render/dispatch.ts +2 -20
  352. package/src/chat/tool-render/result-text.ts +98 -0
  353. package/src/chat/turn-typeahead.ts +70 -7
  354. package/src/cli/agent-cli.ts +13 -2
  355. package/src/cli/config-audit.ts +119 -0
  356. package/src/cli/doctor-cli.ts +26 -1
  357. package/src/cli/guardian-cli.ts +10 -0
  358. package/src/cli/herdr-cli.ts +34 -0
  359. package/src/cli/light-entry-route.ts +50 -7
  360. package/src/cli/log-event-names.ts +2 -0
  361. package/src/cli/make-cli.ts +247 -11
  362. package/src/cli/msg-cli.ts +117 -3
  363. package/src/cli/pod-cli.ts +77 -3
  364. package/src/cli/pr-cli.ts +34 -18
  365. package/src/cli/pr-land-base-read.ts +11 -2
  366. package/src/cli/pr-land-heavy-remote.ts +6 -3
  367. package/src/cli/pr-land-overlap-evidence.ts +23 -4
  368. package/src/cli/pr-land-pod-shadow-job.ts +3 -0
  369. package/src/cli/pr-land-recovery.ts +117 -1
  370. package/src/cli/pty-takeover-cli.ts +8 -7
  371. package/src/cli/release-checklist-read-cli.ts +79 -0
  372. package/src/cli/release-cli.ts +92 -106
  373. package/src/cli/release-single-flight.ts +1 -1
  374. package/src/cli/remote-resolve.ts +1 -1
  375. package/src/cli/root-tui-entry.ts +48 -0
  376. package/src/cli/sim-cli.ts +22 -0
  377. package/src/cli/tasks-card-show.ts +162 -0
  378. package/src/cli/tasks-cli.ts +1065 -338
  379. package/src/cli/tasks-read-cli.ts +197 -0
  380. package/src/cli/usage-cli.ts +13 -11
  381. package/src/clipboard/history.ts +179 -13
  382. package/src/config.ts +8 -1
  383. package/src/core-turn/run-core-turn.ts +4 -2
  384. package/src/core-turn/run-goal-loop.ts +73 -16
  385. package/src/core-turn/types.ts +6 -1
  386. package/src/dashboard/chat/acp-chat.ts +8 -0
  387. package/src/dashboard/context/keys.ts +8 -31
  388. package/src/dashboard/index.ts +280 -59
  389. package/src/dashboard/input/agent-wake.ts +7 -1
  390. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
  391. package/src/dashboard/input/chat-main-slash-command.ts +4 -2
  392. package/src/dashboard/input/goal-continue.ts +210 -0
  393. package/src/dashboard/input/goal-interim.ts +2 -0
  394. package/src/dashboard/input/internal-turn.ts +2 -8
  395. package/src/dashboard/input/seat-autowake.ts +9 -7
  396. package/src/dashboard/input/turn-autoheal.ts +52 -0
  397. package/src/dashboard/render/theme-resolver.ts +33 -4
  398. package/src/dashboard/seat-boot-preamble.ts +132 -5
  399. package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
  400. package/src/dashboard/slash-runtime/dashboard-handlers.ts +3 -2
  401. package/src/dashboard/slash-runtime/model-choices.ts +15 -0
  402. package/src/dashboard/stale-install-check.ts +3 -99
  403. package/src/debug/batch-queue.ts +119 -0
  404. package/src/debug/tui-log-tag.ts +67 -0
  405. package/src/display/agent-surface.ts +7 -0
  406. package/src/domains/schedule-registry.ts +16 -2
  407. package/src/domains/standalone-log-sink.ts +15 -2
  408. package/src/esc-abort-gate.ts +69 -0
  409. package/src/git-fs/idle-refresh.ts +76 -0
  410. package/src/git-fs/index.ts +18 -7
  411. package/src/git-fs/worktree.ts +137 -5
  412. package/src/graph-kinds/registry.ts +2 -2
  413. package/src/graph-runner/graph-cli.ts +18 -0
  414. package/src/graph-runner/runner.ts +173 -21
  415. package/src/graph-wizard/generate.ts +108 -4
  416. package/src/graph-wizard/steps.ts +15 -0
  417. package/src/grok/credential.ts +10 -3
  418. package/src/grounding/proactive-ground.ts +86 -0
  419. package/src/harness/control-inbox.ts +49 -1
  420. package/src/harness/harness-cli-command.ts +163 -35
  421. package/src/harness/harness-incidents.ts +85 -1
  422. package/src/harness/launch-utterance-ledger.ts +208 -0
  423. package/src/harness/pod-control-send.ts +33 -5
  424. package/src/harness/self-send-remote.ts +69 -0
  425. package/src/harness/self-send-routing-guard.ts +6 -0
  426. package/src/harness/self-send-target.ts +4 -3
  427. package/src/impl-discipline/detector.ts +16 -4
  428. package/src/impl-discipline/system-prompt.ts +11 -0
  429. package/src/impl-discipline/types.ts +2 -2
  430. package/src/index.ts +822 -154
  431. package/src/input-core/context-key-runtime.ts +21 -0
  432. package/src/intake-plane/already-built-hint.ts +4 -2
  433. package/src/intake-plane/requirement-funnel.ts +29 -1
  434. package/src/light-cli.ts +32 -11
  435. package/src/llm/opengateway-models.ts +11 -0
  436. package/src/llm/provider-credentials.ts +14 -0
  437. package/src/llm/provider-detect.ts +8 -1
  438. package/src/llm/runtime-model-family.ts +2 -1
  439. package/src/llm-wellformed.ts +70 -0
  440. package/src/llm.ts +247 -59
  441. package/src/loops/msg-wake.ts +35 -39
  442. package/src/loops/orchestrator/inbox.ts +59 -11
  443. package/src/loops/orchestrator/knowhow-pack.ts +364 -0
  444. package/src/loops/orchestrator/tick.ts +5 -1
  445. package/src/maturity/feature-maturity.ts +1 -1
  446. package/src/model-tier/llm-tier-map.ts +15 -1
  447. package/src/models/prompts.ts +17 -2
  448. package/src/msg/msg-post-office.ts +116 -0
  449. package/src/mss/logging/log-store.ts +79 -22
  450. package/src/native-tool-catalog.ts +15 -1
  451. package/src/nexus/api/decisions-route.ts +38 -18
  452. package/src/nexus/api/graph-wizard-api.ts +20 -2
  453. package/src/nexus/api/loop-resources.ts +13 -1
  454. package/src/nexus/boot/register-mcp-clients.ts +263 -38
  455. package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
  456. package/src/oauth/codex.ts +7 -0
  457. package/src/onboarding/first-run.ts +37 -6
  458. package/src/onboarding/web-first.ts +43 -11
  459. package/src/ops/overview-collect.ts +30 -9
  460. package/src/ops/overview.ts +22 -9
  461. package/src/persona/loader.ts +11 -0
  462. package/src/persona/types.ts +8 -0
  463. package/src/pr-tool/census.ts +261 -27
  464. package/src/prompt-library/session-guidance.ts +14 -0
  465. package/src/provider-summary.ts +8 -0
  466. package/src/pty-shell/herdr-agent-report.ts +118 -9
  467. package/src/pty-shell/herdr-prompt.ts +266 -0
  468. package/src/pty-shell/pty-control-ipc.ts +151 -8
  469. package/src/pty-shell/pty-manifest.ts +7 -0
  470. package/src/pty-shell/pty-special-keys.ts +42 -2
  471. package/src/pty-shell/stale-install-check.ts +99 -0
  472. package/src/pty-shell/tui-run-state.ts +14 -2
  473. package/src/release-loop/auto-start.ts +20 -2
  474. package/src/release-loop/checklist.ts +100 -4
  475. package/src/release-loop/landed-but-yellow.ts +129 -5
  476. package/src/release-loop/light-rc.ts +1 -0
  477. package/src/release-loop/rehearsal.ts +37 -21
  478. package/src/repl/index.ts +192 -17
  479. package/src/repl/ops-msg-bridge.ts +32 -0
  480. package/src/seat-loop/knowhow-lint.ts +1 -1
  481. package/src/self-dev/ask-launch-flow.ts +44 -5
  482. package/src/self-dev/cli-help-text.ts +17 -0
  483. package/src/self-dev/decompose-proposal.ts +172 -20
  484. package/src/self-dev/decompose.ts +61 -0
  485. package/src/self-dev/dev-cli.ts +48 -12
  486. package/src/self-dev/dev-pipeline.ts +8 -2
  487. package/src/self-dev/draft-residue.ts +37 -1
  488. package/src/self-dev/draft-sweep.ts +137 -11
  489. package/src/self-dev/draft-triage-rules.ts +138 -0
  490. package/src/self-dev/fleet-reduce.ts +3 -2
  491. package/src/self-dev/glm-credential-guard.ts +77 -0
  492. package/src/self-dev/graph-front-nodes.ts +112 -0
  493. package/src/self-dev/graph-journey-nodes.ts +2 -0
  494. package/src/self-dev/graph-journey-route.ts +12 -2
  495. package/src/self-dev/harness-run-cli.ts +3 -15
  496. package/src/self-dev/orchestrate-cli-text.ts +10 -0
  497. package/src/self-dev/orchestrate-cli.ts +68 -3
  498. package/src/self-dev/orchestrate.ts +116 -17
  499. package/src/self-dev/review-provider-fallback.ts +35 -1
  500. package/src/self-dev/run-supervisor.ts +55 -2
  501. package/src/self-dev/run-types.ts +1 -1
  502. package/src/self-dev/self-orchestrate-runtime.ts +1 -11
  503. package/src/self-dev/shard-aggregate.ts +42 -5
  504. package/src/self-dev/shard-run.ts +8 -1
  505. package/src/self-health/autoheal.ts +153 -0
  506. package/src/self-health/signatures.ts +6 -0
  507. package/src/self-implement/blocked-draft-policy.ts +20 -0
  508. package/src/self-implement/classify-shadow.ts +3 -7
  509. package/src/self-implement/device-first.ts +116 -0
  510. package/src/self-implement/doctor-visit.ts +257 -2
  511. package/src/self-implement/evidence-command-budget.ts +80 -0
  512. package/src/self-implement/gate-baseline.ts +56 -17
  513. package/src/self-implement/gate-cli.ts +1 -0
  514. package/src/self-implement/gate-remote.ts +31 -20
  515. package/src/self-implement/goal-author-cli.ts +1 -0
  516. package/src/self-implement/goal-author-decompose.ts +534 -45
  517. package/src/self-implement/goal-author.ts +282 -7
  518. package/src/self-implement/goal-elaborate.ts +449 -0
  519. package/src/self-implement/goal-refine.ts +273 -0
  520. package/src/self-implement/graph-overlay-yaml.ts +14 -3
  521. package/src/self-implement/graph-variant.ts +40 -6
  522. package/src/self-implement/headless-elanous-driver.ts +19 -3
  523. package/src/self-implement/off-diff-evidence.ts +58 -6
  524. package/src/self-implement/orchestrator.ts +370 -62
  525. package/src/self-implement/pod-warm-pool-profile.ts +1 -0
  526. package/src/self-implement/pwa-import-graph.ts +1 -1
  527. package/src/self-implement/rework-budget-judgment.ts +5 -8
  528. package/src/self-implement/rework-policy.ts +30 -0
  529. package/src/self-implement/run-ledger.ts +108 -0
  530. package/src/self-implement/run-stop.ts +10 -1
  531. package/src/self-implement/run-ttl.ts +38 -24
  532. package/src/self-implement/running-runs.ts +29 -1
  533. package/src/self-implement/scope-adjacency.ts +115 -0
  534. package/src/self-implement/seams.ts +187 -28
  535. package/src/self-implement/stop-autoheal.ts +87 -1
  536. package/src/self-implement/wiring-check.ts +358 -0
  537. package/src/session-runtime/index.ts +1 -1
  538. package/src/setup/llm-env-detect.ts +5 -0
  539. package/src/shell-env-bootstrap.ts +11 -4
  540. package/src/skills/runner.ts +4 -2
  541. package/src/skills/tools/agent.ts +408 -40
  542. package/src/skills/tools/msg-ask.ts +100 -0
  543. package/src/skills/tools/ops-ledger.ts +2 -1
  544. package/src/skills/tools/schedule-wakeup.ts +23 -4
  545. package/src/skills/tools/shell.ts +61 -6
  546. package/src/skills/tools/terminal-modal-inject.ts +1 -2
  547. package/src/skills/tools/terminal-modal.ts +10 -8
  548. package/src/skills/url-router.ts +41 -1
  549. package/src/smart-wizard/run.ts +66 -0
  550. package/src/status/bar.ts +34 -6
  551. package/src/status/status-provider-info.ts +37 -6
  552. package/src/steward/hold-hygiene.ts +24 -6
  553. package/src/steward/rejudge-tick.ts +10 -2
  554. package/src/steward/ta-repair-event-collect.ts +17 -6
  555. package/src/steward/triage-budget.ts +194 -0
  556. package/src/steward/triage.ts +20 -3
  557. package/src/task-agent/actions.ts +72 -2
  558. package/src/task-agent/green-sweep.ts +4 -0
  559. package/src/task-agent/land-queue.ts +21 -8
  560. package/src/task-agent/live-moves.ts +182 -10
  561. package/src/task-agent/mission.ts +30 -0
  562. package/src/task-agent/parent-host.ts +123 -3
  563. package/src/task-agent/rejudge-on-head.ts +15 -0
  564. package/src/task-agent/repair-cycle.ts +138 -32
  565. package/src/task-agent/repair-next-move.ts +31 -3
  566. package/src/task-agent/repair-outcomes.ts +29 -0
  567. package/src/task-agent/repair-worker.ts +14 -4
  568. package/src/task-agent/shadow.ts +48 -4
  569. package/src/task-agent/task-card-prefix.ts +2 -0
  570. package/src/task-agent/task-hand.ts +525 -57
  571. package/src/task-agent/task-parent-role-llm.ts +36 -0
  572. package/src/task-agent/tier-split.ts +196 -0
  573. package/src/task-agent/work-order-build.ts +2 -0
  574. package/src/task-agent/work-order.ts +3 -2
  575. package/src/task-orchestrator/generator-prompt.ts +60 -11
  576. package/src/task-orchestrator/surfaces/pod-account-broker.ts +42 -0
  577. package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
  578. package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
  579. package/src/task-orchestrator/surfaces/pod-command-job.ts +130 -11
  580. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
  581. package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
  582. package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
  583. package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
  584. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +19 -2
  585. package/src/task-orchestrator/surfaces/pod-pool.ts +76 -4
  586. package/src/task-orchestrator/surfaces/pod-provenance.ts +82 -0
  587. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
  588. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
  589. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
  590. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
  591. package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
  592. package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
  593. package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
  594. package/src/task-orchestrator/surfaces/pod-source-receive.ts +18 -0
  595. package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
  596. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +6 -2
  597. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +7 -0
  598. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +521 -40
  599. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
  600. package/src/task-orchestrator/surfaces/self-implement-pod.ts +759 -50
  601. package/src/task-orchestrator/surfaces/self-implement.ts +65 -2
  602. package/src/tool-runtime/index.ts +15 -2
  603. package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
  604. package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
  605. package/src/tty-foreground.ts +155 -0
  606. package/src/tui/README.md +2 -0
  607. package/src/tui/chat/background-job-status.ts +54 -0
  608. package/src/tui/chat/goal-interim.ts +173 -0
  609. package/src/tui/chat/log-view.ts +267 -0
  610. package/src/tui/chat/self-health-status.ts +232 -0
  611. package/src/tui/entry.ts +695 -0
  612. package/src/tui/input/composer.ts +151 -0
  613. package/src/tui/seat-mail-boot.ts +59 -0
  614. package/src/tui/slash/compact-command.ts +7 -0
  615. package/src/tui/slash/compact.ts +94 -0
  616. package/src/tui/slash/new-session.ts +35 -0
  617. package/src/tui/slash/resume.ts +75 -0
  618. package/src/tui-client/local-chat-turn.ts +282 -0
  619. package/src/tui-client/local-harness-command.ts +63 -0
  620. package/src/tui-client/local-provider-command.ts +184 -0
  621. package/src/tui-client/next-dashboard-runtime.ts +8 -0
  622. package/src/tui-client/next-loop-command.ts +70 -0
  623. package/src/tui-client/next-wakeup.ts +191 -0
  624. package/src/tui.ts +37 -0
  625. package/src/ui/modal-adapter.ts +2 -2
  626. package/src/user-config.ts +4 -2
  627. package/src/ux-sim/classic-tui-seat-scenarios.ts +516 -0
  628. package/src/ux-sim/cli-config-audit-device.ts +121 -0
  629. package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
  630. package/src/ux-sim/event-monkey.ts +379 -0
  631. package/src/ux-sim/fake-bin.ts +87 -7
  632. package/src/ux-sim/fake-herdr.ts +238 -0
  633. package/src/ux-sim/fake-llm.ts +111 -6
  634. package/src/ux-sim/fault-glm-no-credential.ts +116 -0
  635. package/src/ux-sim/fault-nextmove-dispatch.ts +367 -0
  636. package/src/ux-sim/fault-pod-codex-503.ts +211 -0
  637. package/src/ux-sim/fault-scope-escape-lift.ts +216 -0
  638. package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
  639. package/src/ux-sim/goal-device.ts +619 -0
  640. package/src/ux-sim/in-process-cli.ts +22 -5
  641. package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
  642. package/src/ux-sim/mock-authoring-first-run.ts +97 -0
  643. package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
  644. package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
  645. package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
  646. package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
  647. package/src/ux-sim/next-tui-seat-scenarios.ts +631 -0
  648. package/src/ux-sim/onboarding-first-run-device.ts +269 -0
  649. package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
  650. package/src/ux-sim/subagent-tools-device.ts +81 -0
  651. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
  652. package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
  653. package/src/version/packed-revision.json +1 -1
  654. package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +0 -79
  655. package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +0 -94
  658. package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +0 -23
  660. package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +0 -115
  662. package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +0 -8
  663. package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/2987-30cf9c2eb7b8bdd5.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/3001-5a52788c813b6113.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +0 -104
  681. package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +0 -286
  682. package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +0 -149
  683. package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +0 -148
  684. package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +0 -64
  685. package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +0 -74
  688. package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/5028-f0722e6114c313e7.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/5249.96a848656b582a93.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +0 -62
  695. package/apps/pwa/out/_next/static/chunks/5489.ec2dd1b5272a19dc.js +0 -24
  696. package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/6053-d893974de92e6198.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +0 -77
  708. package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +0 -90
  711. package/apps/pwa/out/_next/static/chunks/7193-cf355cca5ba6c5d5.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/7386.5d8e7e42e818dfb6.js +0 -287
  717. package/apps/pwa/out/_next/static/chunks/7448.478958ffbbba0ac0.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +0 -27
  722. package/apps/pwa/out/_next/static/chunks/7952.b192c31b6a0e00cc.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +0 -36
  725. package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +0 -93
  738. package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +0 -24
  740. package/apps/pwa/out/_next/static/chunks/9739.8d5f36ac67a3b236.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/live-run/page-d7bff0f0905a662c.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-398c0faa173203f7.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/term/page-df3445b207ceceab.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +0 -1
  794. package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +0 -122
  795. package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +0 -1
  796. package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +0 -1
  797. package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +0 -1
  798. package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +0 -1
  799. package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +0 -1
  800. package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +0 -1
  801. package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +0 -1
  802. /package/apps/pwa/out/_next/static/{L04y73dlwKeTW-GetaTF3 → uC-N0emedeNOFuaBQFv-I}/_ssgManifest.js +0 -0
@@ -448,6 +448,18 @@ function consumeRecord(
448
448
  return;
449
449
  }
450
450
  messages.push(message);
451
+ // A Pod sender asks for this exact record's acknowledgement before publishing
452
+ // it. Missing ack is safe: delivery has happened, but the sender must report
453
+ // read state as unobserved rather than infer it from file disappearance.
454
+ if (existsSync(`${recordPath}.ack-request`)) {
455
+ // Rename consumes the request atomically. If the sender already removed it,
456
+ // this cannot leave a late ack file after the sender's cleanup.
457
+ try { renameSync(`${recordPath}.ack-request`, `${recordPath}.ack`); }
458
+ catch (error) {
459
+ if ((error as NodeJS.ErrnoException).code !== 'ENOENT')
460
+ logger(opts)('control-inbox', 'memo-ack-failed', { spaceId, path: recordPath, reason: String(error) });
461
+ }
462
+ }
451
463
  }
452
464
 
453
465
  /** Inspect existing ready records without claiming, deleting, or creating any inbox entry. */
@@ -541,7 +553,43 @@ export function cleanupStaleControlInbox(spaceId: string, maxAgeMs: number, opts
541
553
  restoreClaim(claimPath, recordPath, spaceId, opts);
542
554
  }
543
555
  }
544
- logger(opts)('control-inbox', 'cleanup', { spaceId, path, maxAgeMs, count });
556
+ // A sender killed without an EXIT trap can leave receipt markers behind.
557
+ // Its wait is capped at 60s; keep at least two minutes before sweeping only
558
+ // markers whose exact record no longer exists. Never infer a read from cleanup.
559
+ let markerCount = 0;
560
+ let tempCount = 0;
561
+ let markerNames: string[] = [];
562
+ try { markerNames = readdirSync(ready); } catch { /* absent ready directory */ }
563
+ const markerCutoff = Date.now() - Math.max(maxAgeMs, 120_000);
564
+ for (const name of markerNames) {
565
+ // Only the Pod publisher's mktemp shape; local enqueue has a different name.
566
+ if (/^\.write-[A-Za-z0-9]{8}$/.test(name)) {
567
+ const tempPath = join(ready, name);
568
+ try {
569
+ if (statSync(tempPath).mtimeMs > markerCutoff) continue;
570
+ rmSync(tempPath);
571
+ tempCount += 1;
572
+ } catch (error) {
573
+ if ((error as NodeJS.ErrnoException).code !== 'ENOENT')
574
+ logger(opts)('control-inbox', 'cleanup-temp-failed', { spaceId, path: tempPath, reason: String(error) });
575
+ }
576
+ continue;
577
+ }
578
+ const suffix = name.endsWith('.ack-request') ? '.ack-request' : name.endsWith('.ack') ? '.ack' : null;
579
+ if (!suffix) continue;
580
+ const recordName = name.slice(0, -suffix.length);
581
+ if (!isReadyRecord(recordName) || existsSync(join(ready, recordName))) continue;
582
+ const markerPath = join(ready, name);
583
+ try {
584
+ if (statSync(markerPath).mtimeMs > markerCutoff) continue;
585
+ rmSync(markerPath);
586
+ markerCount += 1;
587
+ } catch (error) {
588
+ if ((error as NodeJS.ErrnoException).code !== 'ENOENT')
589
+ logger(opts)('control-inbox', 'cleanup-marker-failed', { spaceId, path: markerPath, reason: String(error) });
590
+ }
591
+ }
592
+ logger(opts)('control-inbox', 'cleanup', { spaceId, path, maxAgeMs, count, markerCount, tempCount });
545
593
  return count;
546
594
  }
547
595
 
@@ -20,9 +20,10 @@ import { runGitCommand } from '../git-fs/runner.js';
20
20
  import { GOAL_TYPES, lintGoalFile, parseGoalId, parseGoalType, resolveGoalAuthorGrade, tracedPathReferences, type GoalAuthorGrade, type GoalAuthorGradeSelection, type GoalType } from '../self-implement/goal-author.js';
21
21
  import { templateForGoalType } from '../self-implement/graph-templates.js';
22
22
  import { appendRunLedgerEntry, listRunLedgers, loadFederatedRunLedger, loadRunLedger, queryRunScreenKey, runLedgerDir, type RunLedgerEntry, type RunLedgerMatch, type RunLedgerWriter } from '../self-implement/run-ledger.js';
23
- import { classifyPodExit, type PodExitClass } from '../task-orchestrator/surfaces/pod-failure-reason.js';
23
+ import { classifyPodExit, parsePodTermination, type PodExitClass, type PodTermination } from '../task-orchestrator/surfaces/pod-failure-reason.js';
24
24
  import type { PodChildEvidence } from '../task-orchestrator/surfaces/self-implement.js';
25
- import { classifyPodExitStop, recordRunStop, runStopRecorded, RUN_STOP_EVENT } from '../self-implement/run-stop.js';
25
+ import { classifyPodExitStop, readRunStopRecord, recordRunStop, runStopRecorded, RUN_STOP_EVENT } from '../self-implement/run-stop.js';
26
+ import { captureStopKnowhowCandidate } from '../self-implement/stop-autoheal.js';
26
27
  import { ensureOpenRouterChildModelLive, resolveChildLlmEffort, resolveImplementationChildModel } from '../self-dev/dev-cli.js';
27
28
  import { resolveHarnessTarget } from '../self-implement/harness-target-options.js';
28
29
  import { buildRunProgressRows, isPartialRunningRuns, queryRunningRuns, renderRunProgressTable } from '../self-implement/running-runs.js';
@@ -418,7 +419,7 @@ function resolveLaunchSubstrate(opts: HarnessSubstrateOpts): ResolvedHarnessSubs
418
419
  }
419
420
  type PodExit = { status: number | null; signal?: string | null };
420
421
  type PodExitReason = 'signal' | 'human-stop' | 'supervisor' | 'no-launch' | 'unknown' | 'preflight-refused'
421
- | 'pod-error' | 'launch-gate-blocked' | 'ENOBUFS' | 'OOMKilled';
422
+ | 'pod-error' | 'launch-gate-blocked' | 'dep-blocked' | 'ENOBUFS' | 'OOMKilled';
422
423
 
423
424
  function unknownPodExitTailReason(output: string): PodExitReason | undefined {
424
425
  const tail = output.slice(-16_000);
@@ -426,6 +427,7 @@ function unknownPodExitTailReason(output: string): PodExitReason | undefined {
426
427
  if (/\bENOBUFS\b/i.test(tail)) return 'ENOBUFS';
427
428
  if (/launch gate[^\r\n]*blocked|blocked[^\r\n]*launch gate/i.test(tail)) return 'launch-gate-blocked';
428
429
  if (/\bpod-error\b/i.test(tail)) return 'pod-error';
430
+ if (/\b(?:DEP_FAILED|DEPENDENCY_NEEDS_HUMAN|DEP_BLOCKED_REBASE_READY)\b/.test(tail)) return 'dep-blocked';
429
431
  return undefined;
430
432
  }
431
433
  /** GitHub lists at most this many files for one pull request; a list that reaches it is not provably complete. */
@@ -450,7 +452,7 @@ export function classifyHarnessPodExit(
450
452
  loadCheckpoint?: typeof loadSelfDevRun;
451
453
  runId?: string;
452
454
  } = {},
453
- ): { lines: string[]; reason: PodExitReason | 'pod-failure' } {
455
+ ): { lines: string[]; reason: PodExitReason | 'pod-failure'; podErrorCode?: 'pod-job-failed' } {
454
456
  const occupiedNewLine = output.split('\n').find((line) =>
455
457
  /^\[self-dev\] run run-[a-z0-9_-]{8,64} \[preflight:new-path-occupied:[0-9a-f-]{36}\] /.test(line));
456
458
  const observedRunId = deps.runId ?? harnessPodRunId(output);
@@ -475,6 +477,7 @@ export function classifyHarnessPodExit(
475
477
  }
476
478
  let podFailure: string | undefined;
477
479
  let podJobFailed = false;
480
+ let podJobFailedFromResult = false;
478
481
  let podChildFailed = false;
479
482
  for (const line of output.split('\n').reverse()) {
480
483
  if (!line.trimStart().startsWith('[{') || !line.includes('"error"')) continue;
@@ -487,6 +490,7 @@ export function classifyHarnessPodExit(
487
490
  if (typeof error?.code !== 'string' || typeof error.message !== 'string' || !error.code.startsWith('pod-')) continue;
488
491
  podFailure = error.message;
489
492
  podJobFailed = error.code === 'pod-job-failed';
493
+ podJobFailedFromResult = podJobFailed;
490
494
  podChildFailed = error.code === 'pod-child-failed';
491
495
  break;
492
496
  }
@@ -505,7 +509,7 @@ export function classifyHarnessPodExit(
505
509
  if (podFailure) {
506
510
  const childError = podJobFailed ? podFailure.split('childError=')[1]?.split('\\n', 1)[0]?.split('\n', 1)[0] : undefined;
507
511
  try { debug.log('harness.pod', 'exit-classified', { runId, reason: 'pod-failure', status: exit.status, signal: exit.signal ?? null }); } catch { /* observation is fail-soft */ }
508
- return { reason: 'pod-failure', lines: [podChildFailed
512
+ return { reason: 'pod-failure', ...(podJobFailedFromResult ? { podErrorCode: 'pod-job-failed' as const } : {}), lines: [podChildFailed
509
513
  ? `Pod 안 자식이 실패했다 — ${podFailure.split('\\n', 1)[0]}`
510
514
  : podJobFailed && childError && childError !== 'no-result-line'
511
515
  ? `Pod 안 자식이 실패했다 — ${childError}`
@@ -572,7 +576,9 @@ export function recordClassifiedHarnessPodExit(runId: string | undefined, reason
572
576
  context: { entrance?: string; seat?: string; output?: string } = {}): void {
573
577
  if (!runId) return;
574
578
  try {
575
- const childEvidence = reason === 'preflight-refused' ? undefined : latestPodChildEvidence(loadRunLedger(runId));
579
+ const ledger = reason === 'preflight-refused' ? undefined : loadRunLedger(runId);
580
+ const childEvidence = latestPodChildEvidence(ledger);
581
+ const podTermination = latestPodTermination(ledger);
576
582
  const signal = status > 128
577
583
  ? Object.entries(osConstants.signals).find(([, number]) => number === status - 128)?.[0] ?? null : null;
578
584
  const cwd = process.cwd();
@@ -583,17 +589,42 @@ export function recordClassifiedHarnessPodExit(runId: string | undefined, reason
583
589
  cwd: `${basename(dirname(cwd))}/${basename(cwd)}`, hostname: hostname().split('.')[0]!, pid: process.pid,
584
590
  ...(context.output ? { lastLines: incidentLastLines(context.output) } : {}),
585
591
  ...(childEvidence ? { childEvidence } : {}),
592
+ ...(podTermination ? { podTermination } : {}),
586
593
  }, effectiveInstanceRoot());
587
594
  } catch { /* incident writes cannot change Pod output or exit */ }
588
595
  }
589
596
 
590
- function latestPodChildEvidence(entries: readonly RunLedgerEntry[] | null | undefined): PodChildEvidence | undefined {
597
+ /**
598
+ * The current attempt's `pod-child-evidence` rows (same job · childRunId as the last `pod-child-run`), oldest first.
599
+ * Also fenced by position: only rows written after that start count, so a reused job/childRunId pair cannot
600
+ * hand an earlier attempt's row (childEvidence or podTermination) to a later one.
601
+ */
602
+ function currentPodChildEvidenceRows(entries: readonly RunLedgerEntry[] | null | undefined): { job: string; rows: Record<string, unknown>[] } | undefined {
591
603
  // The current attempt's start is the fence. An earlier Pod's terminal facts cannot
592
604
  // classify a later attempt when that attempt has no JSON or its ledger write failed.
593
- const current = entries?.filter((entry) => entry.event === 'pod-child-run').at(-1)?.data;
605
+ let startIndex = -1;
606
+ entries?.forEach((entry, index) => { if (entry.event === 'pod-child-run') startIndex = index; });
607
+ const current = startIndex >= 0 ? entries![startIndex]!.data : undefined;
594
608
  if (typeof current?.job !== 'string' || typeof current.childRunId !== 'string') return undefined;
595
- const data = entries?.filter((entry) => entry.event === 'pod-child-evidence'
596
- && entry.data?.job === current.job && entry.data?.childRunId === current.childRunId).at(-1)?.data;
609
+ const rows = (entries ?? []).filter((entry, index) => index > startIndex && entry.event === 'pod-child-evidence'
610
+ && entry.data?.job === current.job && entry.data?.childRunId === current.childRunId).map((entry) => entry.data);
611
+ return { job: current.job, rows };
612
+ }
613
+
614
+ /** JOB-FAILURE-TERMINATION-CAPTURE — the current attempt's latest well-formed capture of its own Job (a later
615
+ * evidence row of the same attempt without one does not drop it); another Job's or round's never crosses over. */
616
+ function latestPodTermination(entries: readonly RunLedgerEntry[] | null | undefined): PodTermination | undefined {
617
+ const current = currentPodChildEvidenceRows(entries);
618
+ if (!current) return undefined;
619
+ for (const row of current.rows.slice().reverse()) {
620
+ const parsed = parsePodTermination(row.podTermination, current.job);
621
+ if (parsed) return parsed;
622
+ }
623
+ return undefined;
624
+ }
625
+
626
+ function latestPodChildEvidence(entries: readonly RunLedgerEntry[] | null | undefined): PodChildEvidence | undefined {
627
+ const data = currentPodChildEvidenceRows(entries)?.rows.at(-1);
597
628
  const evidence = data?.childEvidence;
598
629
  if (!evidence || typeof evidence !== 'object' || Array.isArray(evidence)) return undefined;
599
630
  const row = evidence as Record<string, unknown>;
@@ -601,6 +632,8 @@ function latestPodChildEvidence(entries: readonly RunLedgerEntry[] | null | unde
601
632
  if (('scopeEscape' in row && row.scopeEscape !== true)
602
633
  || ('goalCauseObserved' in row && row.goalCauseObserved !== true)
603
634
  || ('classification' in row && typeof row.classification !== 'string')
635
+ || ('newScope' in row && !Array.isArray(row.newScope))
636
+ || ('scopeStopReasons' in row && !Array.isArray(row.scopeStopReasons))
604
637
  || ('abandonedClassification' in row && !object(row.abandonedClassification))
605
638
  || ('accountAvailability' in row && !object(row.accountAvailability))) return undefined;
606
639
  return row as PodChildEvidence;
@@ -769,7 +802,7 @@ async function onPod(opts: unknown, entrance: 'cli-harness-ask' | 'cli-harness-s
769
802
  export function recordHarnessPodStop(
770
803
  runId: string | undefined,
771
804
  status: number,
772
- classified: { reason: string; lines: string[] },
805
+ classified: { reason: string; lines: string[]; podErrorCode?: 'pod-job-failed' },
773
806
  output?: string,
774
807
  deps: { loadLedger?: typeof loadRunLedger; record?: typeof recordRunStop; write?: RunLedgerWriter } = {},
775
808
  ): boolean {
@@ -780,6 +813,14 @@ export function recordHarnessPodStop(
780
813
  if (ledger?.some((entry) => entry.event === RUN_STOP_EVENT)) return false;
781
814
  const childEvidence = latestPodChildEvidence(ledger);
782
815
  const scopeEscape = childEvidence?.scopeEscape === true;
816
+ // SCOPE-ESCAPE-AS-REFINE — out-of-scope edits without a stop reason are «new scope», not a scope-escape stop.
817
+ if (childEvidence?.newScope?.length || childEvidence?.scopeStopReasons?.length) {
818
+ try {
819
+ debug.log('harness.pod', scopeEscape ? 'scope-escape-stop' : 'scope-new-scope', { runId, scopeEscape,
820
+ ...(childEvidence.newScope ? { newScope: childEvidence.newScope } : {}),
821
+ ...(childEvidence.scopeStopReasons ? { scopeStopReasons: childEvidence.scopeStopReasons } : {}) });
822
+ } catch { /* observation cannot change the stop record */ }
823
+ }
783
824
  if (classified.reason === 'preflight-refused') {
784
825
  (deps.record ?? recordRunStop)({
785
826
  runId, site: 'preflight', class: 'launch-failed',
@@ -805,11 +846,32 @@ export function recordHarnessPodStop(
805
846
  }
806
847
  // The classified line is our own one-line verdict («Pod 안 자식이 실패했다 — OOMKilled»), not the raw output tail.
807
848
  const verdict = classified.lines[0]?.split(' — ').slice(1).join(' — ').trim();
808
- (deps.record ?? recordRunStop)({
849
+ const stopEntry = (deps.record ?? recordRunStop)({
809
850
  runId, site: 'pod-exit', class: scopeEscape ? 'scope-escape' : classifyPodExitStop(classified.reason),
810
851
  cause: `Pod exit ${status}: ${scopeEscape ? 'scope-escape' : classified.reason}${verdict ? ` — ${verdict}` : ''}`,
811
852
  evidenceRef, nextMove, ...(childEvidence ? { childEvidence } : {}),
853
+ ...(classified.podErrorCode === 'pod-job-failed' ? { terminationReason: classified.podErrorCode } : {}),
812
854
  }, ...(deps.write ? [deps.write] : []));
855
+ // Host-only Pod exits do not pass through orchestrator.autohealRecordedStop. Capture the
856
+ // exact Job failure here, after the durable stop write, without initiating a heal action.
857
+ if (classified.podErrorCode === 'pod-job-failed' && stopEntry) {
858
+ try {
859
+ const record = readRunStopRecord(stopEntry);
860
+ if (record) {
861
+ const goalId = ledger?.find((entry) => entry.goalId)?.goalId;
862
+ const captured = captureStopKnowhowCandidate({ runId, ...(goalId ? { goalId } : {}), record },
863
+ join(effectiveInstanceRoot(), 'self-implement', 'knowhow-candidates'));
864
+ if (captured) debug.log('self-implement.autoheal', 'knowhow-candidate', {
865
+ runId, cell: captured.candidate.cell, reason: captured.candidate.reason,
866
+ created: captured.created, occurrences: captured.candidate.occurrences, path: captured.path,
867
+ });
868
+ }
869
+ } catch (error) {
870
+ try { debug.log('self-implement.autoheal', 'knowhow-candidate-failed', {
871
+ runId, error: error instanceof Error ? error.message : String(error),
872
+ }); } catch { /* observation is fail-soft */ }
873
+ }
874
+ }
813
875
  return true;
814
876
  } catch { return false; /* ledger observation cannot change Pod output or exit */ }
815
877
  }
@@ -2378,8 +2440,9 @@ function githubRemoteRepository(url: string): string | undefined {
2378
2440
  interface GraphqlPrDetail {
2379
2441
  readonly files: string[] | null;
2380
2442
  readonly comments: string[] | null;
2381
- readonly reviews: Array<{ state?: string; body?: string }> | null;
2443
+ readonly reviews: Array<{ state?: string; body?: string; submittedAt?: string; commitOid?: string }> | null;
2382
2444
  readonly headSha: string | null;
2445
+ readonly headCommittedAt: string | null;
2383
2446
  readonly mergeCommit: { oid: string; message: string } | null;
2384
2447
  }
2385
2448
 
@@ -2407,10 +2470,10 @@ async function graphqlPrDetails(repository: string, numbers: readonly number[],
2407
2470
  // Fields the batch could not prove complete (each one is read again over REST by the caller).
2408
2471
  const incompleteFields = { files: 0, comments: 0, reviews: 0 };
2409
2472
  await mapBounded(batches, DRAFT_SWEEP_CONCURRENCY, async (batch) => {
2410
- const fields = batch.map((number) => `p${number}: pullRequest(number: ${number}) { number headRefOid `
2473
+ const fields = batch.map((number) => `p${number}: pullRequest(number: ${number}) { number headRefOid headRef { target { ... on Commit { committedDate } } } `
2411
2474
  + 'files(first: 100) { totalCount nodes { path } pageInfo { hasNextPage } } '
2412
2475
  + 'comments(first: 100) { totalCount nodes { body } pageInfo { hasNextPage } } '
2413
- + 'reviews(first: 100) { totalCount nodes { state body } pageInfo { hasNextPage } } '
2476
+ + 'reviews(first: 100) { totalCount nodes { state body submittedAt commit { oid } } pageInfo { hasNextPage } } '
2414
2477
  + 'mergeCommit { oid message } }').join(' ');
2415
2478
  const query = `query { repository(owner: ${JSON.stringify(owner)}, name: ${JSON.stringify(name)}) { ${fields} } }`;
2416
2479
  let repositoryNode: Record<string, unknown> | undefined;
@@ -2421,9 +2484,10 @@ async function graphqlPrDetails(repository: string, numbers: readonly number[],
2421
2484
  if (!repositoryNode || typeof repositoryNode !== 'object' || Array.isArray(repositoryNode)) { failedBatches += 1; return; }
2422
2485
  for (const number of batch) {
2423
2486
  const pr = repositoryNode[`p${number}`] as {
2424
- number?: number; headRefOid?: string;
2487
+ number?: number; headRefOid?: string; headRef?: { target?: { committedDate?: string } | null } | null;
2425
2488
  files?: GraphqlConnection<{ path?: string }>; comments?: GraphqlConnection<{ body?: string }>;
2426
- reviews?: GraphqlConnection<{ state?: string; body?: string }>; mergeCommit?: { oid?: string; message?: string } | null;
2489
+ reviews?: GraphqlConnection<{ state?: string; body?: string; submittedAt?: string; commit?: { oid?: string } | null }>;
2490
+ mergeCommit?: { oid?: string; message?: string } | null;
2427
2491
  } | null | undefined;
2428
2492
  if (!pr || pr.number !== number) continue;
2429
2493
  const files = completeNodes(pr.files);
@@ -2433,8 +2497,10 @@ async function graphqlPrDetails(repository: string, numbers: readonly number[],
2433
2497
  files: files && files.every((file) => typeof file?.path === 'string') ? files.map((file) => file.path!) : null,
2434
2498
  comments: comments && comments.every((comment) => typeof comment?.body === 'string') ? comments.map((comment) => comment.body!) : null,
2435
2499
  reviews: reviews && reviews.every((review) => review && typeof review === 'object')
2436
- ? reviews.map((review) => ({ state: review.state, body: review.body })) : null,
2500
+ ? reviews.map((review) => ({ state: review.state, body: review.body, submittedAt: review.submittedAt,
2501
+ commitOid: review.commit?.oid })) : null,
2437
2502
  headSha: typeof pr.headRefOid === 'string' && pr.headRefOid ? pr.headRefOid : null,
2503
+ headCommittedAt: typeof pr.headRef?.target?.committedDate === 'string' ? pr.headRef.target.committedDate : null,
2438
2504
  mergeCommit: pr.mergeCommit && typeof pr.mergeCommit.oid === 'string' && typeof pr.mergeCommit.message === 'string'
2439
2505
  ? { oid: pr.mergeCommit.oid, message: pr.mergeCommit.message } : null,
2440
2506
  };
@@ -2565,30 +2631,80 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
2565
2631
  }
2566
2632
  throw new Error(`${what === 'review' ? 'Review' : what === 'same-cell' ? 'Same-cell' : 'Landing'} comment inventory exceeded pagination limit`);
2567
2633
  };
2634
+ const reviewsFor = async (repository: string, number: number): Promise<Array<{ state?: string; body?: string; submittedAt?: string; commitOid?: string }>> => {
2635
+ const reviews: Array<{ state?: string; body?: string; submittedAt?: string; commitOid?: string }> = [];
2636
+ for (let page = 1; page <= 100; page++) {
2637
+ const batch = await ghJsonAsync<Array<{ state?: string; body?: string; submitted_at?: string; commit_id?: string }>>(
2638
+ ['api', `repos/${repository}/pulls/${number}/reviews?per_page=100&page=${page}`]);
2639
+ if (!Array.isArray(batch) || batch.length > 100) throw new Error('Incomplete review inventory');
2640
+ reviews.push(...batch.map((review) => ({ state: review.state, body: review.body,
2641
+ submittedAt: review.submitted_at, commitOid: review.commit_id })));
2642
+ if (batch.length < 100) return reviews;
2643
+ }
2644
+ throw new Error('Review inventory exceeded pagination limit');
2645
+ };
2646
+ const checkRunsFor = async (repository: string, sha: string): Promise<Array<{ conclusion?: string | null }> | undefined> => {
2647
+ const runs: Array<{ conclusion?: string | null }> = [];
2648
+ for (let page = 1; page <= 100; page++) {
2649
+ const result = await ghJsonAsync<{ total_count?: number; check_runs?: Array<{ conclusion?: string | null }> }>(
2650
+ ['api', `repos/${repository}/commits/${sha}/check-runs?per_page=100&page=${page}`]);
2651
+ if (!Array.isArray(result?.check_runs) || result.check_runs.length > 100) throw new Error('Incomplete check-run inventory');
2652
+ runs.push(...result.check_runs);
2653
+ if (Number.isSafeInteger(result.total_count) && runs.length >= result.total_count!) return runs;
2654
+ if (result.check_runs.length < 100) return Number.isSafeInteger(result.total_count) && runs.length < result.total_count! ? undefined : runs;
2655
+ }
2656
+ return undefined;
2657
+ };
2658
+ const headCommitTimeFor = async (repository: string, number: number): Promise<string | undefined> => {
2659
+ let latest: string | undefined;
2660
+ for (let page = 1; page <= 100; page++) {
2661
+ const batch = await ghJsonAsync<Array<{ commit?: { committer?: { date?: string } } }>>(
2662
+ ['api', `repos/${repository}/pulls/${number}/commits?per_page=100&page=${page}`]);
2663
+ if (!Array.isArray(batch) || batch.length > 100) throw new Error('Incomplete PR commit inventory');
2664
+ for (const commit of batch) {
2665
+ const date = commit.commit?.committer?.date;
2666
+ if (!date || !Number.isFinite(Date.parse(date))) throw new Error('Incomplete PR commit timestamp');
2667
+ latest = date;
2668
+ }
2669
+ if (batch.length < 100) return latest;
2670
+ }
2671
+ throw new Error('PR commit inventory exceeded pagination limit');
2672
+ };
2568
2673
  const reviewGateForDraft = async (draft: SweepDraft, repository: string): Promise<SweepReviewGate | undefined> => {
2569
2674
  const cached = await detailFor(repository, draft.number);
2570
2675
  const sha = cached?.headSha
2571
2676
  ?? (await ghJsonAsync<{ head?: { sha?: string } }>(['api', `repos/${repository}/pulls/${draft.number}`]))?.head?.sha;
2572
2677
  if (!sha) return undefined;
2678
+ const reviews = cached?.reviews ?? await reviewsFor(repository, draft.number);
2679
+ if (!Array.isArray(reviews)) throw new Error('Incomplete review inventory');
2573
2680
  const comments = cached?.comments ?? await issueCommentsFor(repository, draft.number, 'review');
2574
- const reviews = cached?.reviews
2575
- ?? await ghJsonAsync<Array<{ state?: string; body?: string }>>(['api', `repos/${repository}/pulls/${draft.number}/reviews?per_page=100`]);
2576
- if (!Array.isArray(reviews) || reviews.length > 100) throw new Error('Incomplete review inventory');
2577
- const text = [...comments, ...reviews.map((review) => review.body ?? '')].join('\n');
2681
+ const legacyText = [...comments, ...reviews.map((review) => review.body ?? '')].join('\n');
2682
+ const currentHeadReviews = reviews.filter((review) => review && typeof review === 'object'
2683
+ && review.commitOid === sha
2684
+ && typeof review.submittedAt === 'string' && Number.isFinite(Date.parse(review.submittedAt)))
2685
+ .sort((a, b) => Date.parse(a.submittedAt!) - Date.parse(b.submittedAt!));
2686
+ const latestHeadReview = currentHeadReviews.at(-1);
2687
+ const triageReview = latestHeadReview?.state === 'APPROVED' ? 'approved'
2688
+ : latestHeadReview?.state === 'CHANGES_REQUESTED' ? 'changes-requested'
2689
+ : latestHeadReview?.state === 'COMMENTED' ? 'commented'
2690
+ : latestHeadReview?.state === 'DISMISSED' ? 'dismissed'
2691
+ : latestHeadReview?.state === 'PENDING' ? 'pending' : 'unknown';
2578
2692
  const [status, checkRuns] = await Promise.all([
2579
2693
  ghJsonAsync<{ state?: string }>(['api', `repos/${repository}/commits/${sha}/status`]),
2580
- ghJsonAsync<{ check_runs?: Array<{ conclusion?: string | null }> }>(['api', `repos/${repository}/commits/${sha}/check-runs?per_page=100`]),
2694
+ checkRunsFor(repository, sha),
2581
2695
  ]);
2582
- if (!checkRuns || !Array.isArray(checkRuns.check_runs)) throw new Error('Incomplete check-run inventory');
2583
- const conclusions = checkRuns.check_runs.map((run) => run.conclusion ?? null);
2584
- const gatePass = (status?.state === 'success' || status?.state === undefined)
2585
- && conclusions.length > 0 && conclusions.every((conclusion) => conclusion === 'success' || conclusion === 'skipped' || conclusion === 'neutral');
2696
+ const conclusions = checkRuns?.map((run) => run.conclusion ?? null) ?? [];
2697
+ const gatePass = status?.state === 'success'
2698
+ && checkRuns !== undefined && conclusions.length > 0
2699
+ && conclusions.every((conclusion) => conclusion === 'success' || conclusion === 'skipped' || conclusion === 'neutral');
2586
2700
  const gateFail = status?.state === 'failure' || status?.state === 'error'
2587
2701
  || conclusions.some((conclusion) => conclusion === 'failure' || conclusion === 'cancelled' || conclusion === 'timed_out' || conclusion === 'action_required');
2588
2702
  return {
2589
- ...(reviews.some((review) => review.state === 'APPROVED') || /(?:^|\n)\s*VERDICT:\s*PASS\b/i.test(text) ? { review: 'pass' as const } : {}),
2590
- ...(mustFixRemains(text) ? { mustFix: true } : {}),
2703
+ ...(reviews.some((review) => review.state === 'APPROVED') || /(?:^|\n)\s*VERDICT:\s*PASS\b/i.test(legacyText)
2704
+ ? { review: 'pass' as const } : {}),
2705
+ ...(mustFixRemains(legacyText) ? { mustFix: true } : {}),
2591
2706
  ...(gatePass && !gateFail ? { gate: 'pass' as const } : gateFail ? { gate: 'fail' as const } : {}),
2707
+ triageReview,
2592
2708
  };
2593
2709
  };
2594
2710
  const claimCommentsFor = async (repository: string, number: number): Promise<string[]> => {
@@ -2618,11 +2734,15 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
2618
2734
  const prs = (await listed(open, repository, 'open')).filter((pr) => pr.draft);
2619
2735
  await prefetchDetails(repository, prs.map((pr) => pr.number));
2620
2736
  const matches = ledgerMatches ??= listRunLedgers().matches;
2621
- return mapBounded(prs, DRAFT_SWEEP_CONCURRENCY, async (pr): Promise<SweepDraft> => ({
2622
- number: pr.number, title: pr.title, branch: pr.head.ref,
2623
- labels: pr.labels.map((item) => item.name), createdAt: pr.created_at, body: pr.body ?? undefined,
2624
- changedFiles: await prFiles(repository, pr.number), ...(pr.updated_at ? { updatedAt: pr.updated_at } : {}),
2625
- runId: currentDraftSweepRunId(matches, repository, pr.number) }));
2737
+ return mapBounded(prs, DRAFT_SWEEP_CONCURRENCY, async (pr): Promise<SweepDraft> => {
2738
+ return {
2739
+ number: pr.number, title: pr.title, branch: pr.head.ref,
2740
+ labels: pr.labels.map((item) => item.name), createdAt: pr.created_at, body: pr.body ?? undefined,
2741
+ changedFiles: await prFiles(repository, pr.number),
2742
+ ...(pr.updated_at ? { updatedAt: pr.updated_at } : {}),
2743
+ runId: currentDraftSweepRunId(matches, repository, pr.number),
2744
+ };
2745
+ });
2626
2746
  })());
2627
2747
  return draftRows.get(repository)!;
2628
2748
  };
@@ -2677,6 +2797,8 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
2677
2797
  },
2678
2798
  listDrafts: async (page, perPage, repository): Promise<SweepDraft[]> =>
2679
2799
  (await enrichedDrafts(repository)).slice((page - 1) * perPage, page * perPage),
2800
+ getHeadCommitTime: async (repository, number) => (await detailFor(repository, number))?.headCommittedAt
2801
+ ?? await headCommitTimeFor(repository, number).catch(() => undefined),
2680
2802
  listMerged: async (page, perPage, repository): Promise<SweepMergedPr[]> =>
2681
2803
  (await enrichedMerged(repository)).slice((page - 1) * perPage, page * perPage),
2682
2804
  getRunStatus: async (draft, repository) => runStatusFor(draft, repository),
@@ -2943,7 +3065,7 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
2943
3065
  owner: 'unknown', ownerSource: 'unknown', step: 'replay', reason: sweepFailureReason(error) });
2944
3066
  }
2945
3067
  }
2946
- const result: DraftSweepResult = await runDraftSweep({ repository, apply: opts.apply === true, adapters: deps.adapters ?? github!,
3068
+ const result: DraftSweepResult = await runDraftSweep({ repository, apply: opts.apply === true, includeTriage: opts.json === true, adapters: deps.adapters ?? github!,
2947
3069
  closeCap: cap.closeCap, closeCapSource: cap.closeCapSource, alreadyClosed: replayClosed });
2948
3070
  const reason = result.error ? sweepFailureReason(result.error) : undefined;
2949
3071
  const ttlStarted = Date.now();
@@ -3454,7 +3576,13 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
3454
3576
  if (say) {
3455
3577
  registerHarnessAskSayOptions(harnessCmd.command('say <sentence...>').description('문장을 받아 구동한다'))
3456
3578
  .addOption(new Option('--author-grade <grade>', 'say 저작 등급 (full|lite)').choices(['full', 'lite']))
3579
+ .option('--move-id <id>', 'NEXTMOVE-GENERAL-RELAUNCH-MOVEID — 이 발사를 고른 TA next-move 결정의 수 id(관측 조인 칸 · 발사 동작은 바꾸지 않는다)')
3457
3580
  .action(async (sentence: string[], opts: HarnessAskSayChildLlmOptions & HarnessDryRunOpts) => {
3581
+ const moveId = (opts as { moveId?: unknown }).moveId;
3582
+ // 발사 쪽 영수증 — TA 일반 재발사가 실은 수 id 를 받았다는 한 줄(관측만 · fail-soft · 옵션은 아래로 내려가지 않는다).
3583
+ if (typeof moveId === 'string' && moveId) {
3584
+ try { debug.log('harness', 'move-id-received', { entrance: 'cli-harness-say', moveId }); } catch { /* fail-soft */ }
3585
+ }
3458
3586
  const repair = opts as HarnessSubstrateOpts;
3459
3587
  if (repair.repairCommitOnly !== undefined && (repair.substrate !== 'pod' || !/^pr:[1-9]\d*$/.test(repair.source ?? '')
3460
3588
  || !/^[0-9a-f]{40}$/.test(repair.repairCommitOnly) || repair.autoMerge !== false || repair.target !== undefined)) {
@@ -4,6 +4,7 @@ import { join } from 'node:path';
4
4
  import { redactSecretText } from '../debug/log.js';
5
5
  import { refuseProductionLedgerWriteInTest } from './ledger-write-guard.js';
6
6
  import type { PodChildEvidence } from '../task-orchestrator/surfaces/self-implement.js';
7
+ import { parsePodTermination, type PodTermination } from '../task-orchestrator/surfaces/pod-failure-reason.js';
7
8
 
8
9
  export interface RunExit {
9
10
  runId: string;
@@ -18,6 +19,14 @@ export interface RunExit {
18
19
  pid?: number;
19
20
  lastLines?: string[];
20
21
  childEvidence?: PodChildEvidence;
22
+ /** JOB-FAILURE-TERMINATION-CAPTURE — the current attempt's Job/Pod termination facts, captured before GC. */
23
+ podTermination?: PodTermination;
24
+ /** INCIDENT-REASON-FROM-LASTLINES — 기록된 reason 이 unknown 이라 lastLines 로 다시 분류했으면 원래 값. */
25
+ recordedReason?: string;
26
+ /** reason 을 어디서 얻었나 — 'lastLines' 면 위 분류 규칙으로 정했다(기록 원문은 recordedReason). */
27
+ reasonSource?: 'lastLines';
28
+ /** lastLines 에 ux-sim 장치 조각 경로가 보였다 — 장치 먼저 조각의 실패를 따로 셀 수 있게. */
29
+ slice?: 'device';
21
30
  }
22
31
 
23
32
  export interface IncidentBurst {
@@ -44,6 +53,40 @@ function kstDate(at: number): string {
44
53
  return new Date(at + KST_OFFSET_MS).toISOString().slice(0, 10);
45
54
  }
46
55
 
56
+ // ── INCIDENT-REASON-FROM-LASTLINES (0.2.36 · 10-22 · OP 대응 피처) ───────────────────────────────
57
+ // 기록된 reason 이 «unknown» 인데 마지막 출력 줄에 사유가 그대로 있는 사고가 다수(10-22 경보) — 읽는 쪽에서
58
+ // 결정론으로 다시 분류한다. 우선순위 = 더 구체적인 종료 사유 먼저. 아무것도 안 맞으면 unknown 그대로(추측 0).
59
+ const LAST_LINE_REASONS: ReadonlyArray<[RegExp, string]> = [
60
+ // 근본 원인 먼저 — 뒤 조각의 DEPENDENCY_NEEDS_HUMAN 은 앞 조각 실패의 «증상»이라 맨 뒤 쪽.
61
+ [/goal-elaboration needs-human:\s*goal-elaboration-ungrounded-path\b/, 'goal-elaboration-ungrounded-path'],
62
+ [/goal-elaboration needs-human:\s*goal-elaboration-protected-path\b/, 'goal-elaboration-protected-path'],
63
+ [/goal-elaboration needs-human:\s*goal-elaboration-scope-conflict\b/, 'goal-elaboration-scope-conflict'],
64
+ [/goal-elaboration needs-human:\s*goal-elaboration-fixed-layer-conflict\b/, 'goal-elaboration-fixed-layer-conflict'],
65
+ [/pod-deadline-exceeded|DeadlineExceeded/, 'pod-deadline-exceeded'],
66
+ [/GOAL_DONE_BOUNDARY_MISSING/, 'goal-done-boundary-missing'],
67
+ [/BackoffLimitExceeded/, 'pod-backoff-limit'],
68
+ [/childError=no-resul/, 'pod-child-no-result'],
69
+ [/pod-job-failed/, 'pod-job-failed'],
70
+ [/DEPENDENCY_NEEDS_HUMAN/, 'dependency-needs-human'],
71
+ [/\[needs-human\]|needs-human/, 'needs-human'],
72
+ ];
73
+ const DEVICE_SLICE_PATH = /src\/ux-sim\/[\w.-]*-device(?:\.test)?\.ts|DEVICE-FIRST/;
74
+
75
+ /** lastLines 에서 종료 사유를 꺼낸다 — 안 맞으면 null(unknown 유지). */
76
+ export function classifyIncidentReasonFromLastLines(lines: readonly string[] | undefined): string | null {
77
+ if (!lines?.length) return null;
78
+ const text = lines.join('\n');
79
+ for (const [pattern, reason] of LAST_LINE_REASONS) if (pattern.test(text)) return reason;
80
+ return null;
81
+ }
82
+
83
+ function refinedReasonFields(reason: string, lines: readonly string[] | undefined): Pick<RunExit, 'reason' | 'recordedReason' | 'reasonSource' | 'slice'> {
84
+ const slice = lines?.some((line) => DEVICE_SLICE_PATH.test(line)) ? { slice: 'device' as const } : {};
85
+ if (reason !== 'unknown') return { reason, ...slice };
86
+ const refined = classifyIncidentReasonFromLastLines(lines);
87
+ return refined ? { reason: refined, recordedReason: reason, reasonSource: 'lastLines', ...slice } : { reason, ...slice };
88
+ }
89
+
47
90
  /** Read only recorded exits. Missing ledgers are not evidence that no runs failed. */
48
91
  export function readRunExits(root: string): RunExit[] {
49
92
  const dir = join(root, 'incidents');
@@ -71,7 +114,8 @@ export function readRunExits(root: string): RunExit[] {
71
114
  || !(row.status === null || typeof row.status === 'number')
72
115
  || !(row.signal === null || typeof row.signal === 'string')) continue;
73
116
  seen.add(row.runId);
74
- rows.push({ runId: row.runId, reason: row.reason, status: row.status, signal: row.signal, at: row.at,
117
+ const lines = Array.isArray(row.lastLines) && row.lastLines.every((line) => typeof line === 'string') ? row.lastLines : undefined;
118
+ rows.push({ runId: row.runId, ...refinedReasonFields(row.reason, lines), status: row.status, signal: row.signal, at: row.at,
75
119
  ...(typeof row.entrance === 'string' ? { entrance: row.entrance } : {}),
76
120
  ...(typeof row.seat === 'string' ? { seat: row.seat } : {}),
77
121
  ...(typeof row.cwd === 'string' ? { cwd: row.cwd } : {}),
@@ -81,12 +125,19 @@ export function readRunExits(root: string): RunExit[] {
81
125
  ? { lastLines: row.lastLines } : {}),
82
126
  ...(row.childEvidence && typeof row.childEvidence === 'object' && !Array.isArray(row.childEvidence)
83
127
  ? { childEvidence: row.childEvidence } : {}),
128
+ ...podTerminationField(row.podTermination),
84
129
  });
85
130
  }
86
131
  }
87
132
  return rows.sort((a, b) => Date.parse(a.at) - Date.parse(b.at) || a.runId.localeCompare(b.runId));
88
133
  }
89
134
 
135
+ function podTerminationField(value: unknown): { podTermination?: PodTermination } {
136
+ const job = value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>).job : undefined;
137
+ const parsed = typeof job === 'string' ? parsePodTermination(value, job) : undefined;
138
+ return parsed ? { podTermination: parsed } : {};
139
+ }
140
+
90
141
  /** SQLite's process-owned write lock serializes ledger checks and appends across processes. */
91
142
  export function recordRunExit(row: RunExit, root: string): void {
92
143
  if (refuseProductionLedgerWriteInTest(root, 'incidents')) return;
@@ -209,6 +260,39 @@ export function recentBurst(root: string, now: Date | number, { lookbackMs = 15
209
260
  return recent.sort((a, b) => Date.parse(a.lastAt) - Date.parse(b.lastAt)).at(-1) ?? null;
210
261
  }
211
262
 
263
+ /** 사고 선례 1건 — 현재 사고 이전의 같은 reason 종료 기록(결정론 · 기록된 실제 exit 만). */
264
+ export interface IncidentPrecedent {
265
+ runId: string;
266
+ reason: string;
267
+ status: number | null;
268
+ signal: string | null;
269
+ at: string;
270
+ lastLines?: string[];
271
+ }
272
+
273
+ /**
274
+ * 사고 선례 연결 — 현재 사고(reason·at) 이전에 같은 reason 으로 종료된 기록된 실제 exit 만
275
+ * 돌려준다(유사 과거 지어내기 금지 · readRunExits 재사용 · READ-ONLY). 현재 runId 는 제외하고
276
+ * 시간 내림차순, 기본 5건까지. 기록이 없으면 빈 배열(«기록 없음»).
277
+ */
278
+ export function findIncidentPrecedents(
279
+ current: { reason: string; at: string; runId?: string },
280
+ root: string,
281
+ { limit = 5 }: { limit?: number } = {},
282
+ ): IncidentPrecedent[] {
283
+ const at = Date.parse(current.at);
284
+ if (!current.reason.trim() || !Number.isFinite(at)) return [];
285
+ return readRunExits(root)
286
+ .filter((row) => row.reason === current.reason && row.runId !== current.runId
287
+ && Date.parse(row.at) < at)
288
+ .sort((a, b) => Date.parse(b.at) - Date.parse(a.at) || b.runId.localeCompare(a.runId))
289
+ .slice(0, Math.max(0, limit))
290
+ .map((row) => ({
291
+ runId: row.runId, reason: row.reason, status: row.status, signal: row.signal, at: row.at,
292
+ ...(Array.isArray(row.lastLines) ? { lastLines: row.lastLines } : {}),
293
+ }));
294
+ }
295
+
212
296
  export function formatIncidentBurstWarning(burst: IncidentBurst): string {
213
297
  const time = new Date(Date.parse(burst.lastAt) + KST_OFFSET_MS).toISOString().slice(11, 16);
214
298
  const owner = burst.seat || burst.entrance ? ` [seat=${burst.seat ?? '-'} entrance=${burst.entrance ?? '-'}]` : '';