elanous 0.2.35 → 0.2.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (686) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/chunks/{d06f9160.a3d9062f95de8ad7.js → 053a429e.9a63436527cc751c.js} +1 -1
  4. package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +287 -0
  5. package/apps/pwa/out/_next/static/chunks/{4346.8601952e73bf5803.js → 1201.afbfc5b1c5e5cbe4.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/190.285c832bd9626f8c.js +64 -0
  11. package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +36 -0
  12. package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +149 -0
  15. package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{3103.0df8da390948bb84.js → 2500.cbc1257b774aae52.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/{7644.17e37ba6f1d4226e.js → 2683.c9773a0c589b031b.js} +3 -3
  20. package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +24 -0
  21. package/apps/pwa/out/_next/static/chunks/{4718-17d2af636796a330.js → 275-02ea4c2a33980422.js} +3 -3
  22. package/apps/pwa/out/_next/static/chunks/2812ca6a.3b9f4a7a08885744.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{8714.ff0b7ce3ec3e3ae2.js → 2941.3c3546f96bc6efa7.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +24 -0
  26. package/apps/pwa/out/_next/static/chunks/{9214.63a510d39178e997.js → 2986.45d7652e4f13557e.js} +2 -2
  27. package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/3136.30aaaa5fa03662a3.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{3677-4215f826f6aa68e5.js → 3148-98efd4869d660a87.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +226 -0
  31. package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3324.a09703033abcbd2f.js +34 -0
  34. package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +8 -0
  36. package/apps/pwa/out/_next/static/chunks/3410.7f9af5ab77cbe65f.js +115 -0
  37. package/apps/pwa/out/_next/static/chunks/3538.a445e50bb359d068.js +32 -0
  38. package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +286 -0
  40. package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/{9512.5a76207a730e0491.js → 3727.7949ccaacaa71242.js} +2 -2
  42. package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{8557-e7898769499cd56f.js → 3757-180308bc61021b05.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +74 -0
  45. package/apps/pwa/out/_next/static/chunks/{359-2250789a2d3499e7.js → 3840-5825d56d46976a92.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{da5176c6.6773b6c5994e1d99.js → 3a3d9966.cc4d4585a2708e7c.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +104 -0
  51. package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/{9952.5daf5f94063a2b3e.js → 4286.b70c4520306817e8.js} +1 -1
  53. package/apps/pwa/out/_next/static/chunks/4304.e9b2512834a9e23e.js +23 -0
  54. package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{938.66ad1ef0e5abae1c.js → 4615.8525eb0add35eba6.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/5085-bce4904931767ca6.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +93 -0
  59. package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/{6236.e18cced2d5ba6afb.js → 528.38ce20ef8aa251ff.js} +16 -16
  61. package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +122 -0
  62. package/apps/pwa/out/_next/static/chunks/{3408.21d1570602f4b6c0.js → 552.b7d061ad91eeac51.js} +2 -2
  63. package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5711.957b095705c12560.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/{1530.0e612369b6fd7ea0.js → 575.d929793a53f27c4b.js} +1 -1
  66. package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/599.c39c571b6733f2a2.js +41 -0
  70. package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +79 -0
  71. package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6466-92e65a48490b68a9.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +27 -0
  84. package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/6925.562d532110879886.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/{7385.50a308a477bdfc21.js → 6943.c6b24124853a47b2.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/{630.fe5a46428d63b013.js → 727.7deb87749b0a343a.js} +1 -1
  88. package/apps/pwa/out/_next/static/chunks/{2018.a741297bce759490.js → 7481.39f7a4654907bf6e.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/{8444.4c26b379ca2b9596.js → 771.c3cdb6c1f7f47c02.js} +17 -17
  92. package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{3589.5444a06bcf6e775c.js → 7891.03f910124a737985.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +62 -0
  100. package/apps/pwa/out/_next/static/chunks/{b2f6ba4d.fb56fdbbf798df33.js → 873d6c12.09bd499f57171543.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/{5101.e32282718f99ed6f.js → 8904.7d51af2dc033965c.js} +2 -2
  102. package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +90 -0
  104. package/apps/pwa/out/_next/static/chunks/{5637.281e5dec4ea6ecf1.js → 914.8abefd48d579547b.js} +2 -2
  105. package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/{4705-194e64e47ca0fbdb.js → 9250-072df22eaadaa6b5.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +77 -0
  111. package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{8637.47f5b35afcae5e6b.js → 9514.131c52cc75fe6439.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{1674.2a65fd5668e1cc5f.js → 9789.60f723d18097ec30.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9f31e478.fefcbcd3c388ebc5.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-083747f1d4518f61.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-e2de2e59111c9aad.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f2b2e4bf6e981450.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2af16e62c12f22df.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{0368f25d-ad84af92fefee68f.js → ccae1c4b-0cf414f5eff1b10d.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{cbe38a15.5a032598e39970c6.js → ceba0382.650712b56b85b582.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/{b6705a4f-b9a9047de9eecfd0.js → da5ecc5c-b005ad8cac737d57.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{56d372f2.681ab4ec4c998fae.js → f9a61e4d.1fc2c1dbdd49fe46.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +1 -0
  183. package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → uC-N0emedeNOFuaBQFv-I}/_buildManifest.js +1 -1
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +22 -22
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +22 -22
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +22 -22
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +21 -21
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +21 -21
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +22 -22
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +21 -21
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +22 -22
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +22 -22
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +21 -21
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +22 -22
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +22 -22
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +22 -22
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +22 -22
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +21 -21
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +21 -21
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +22 -22
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +22 -22
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +22 -22
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +21 -21
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +21 -21
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +22 -22
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +22 -22
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +21 -21
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +21 -21
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +21 -21
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +22 -22
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +22 -22
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +21 -21
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +22 -22
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +22 -22
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +22 -22
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +22 -22
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +22 -22
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +21 -21
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +22 -22
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +22 -22
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +22 -22
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +22 -22
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +22 -22
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +22 -22
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +22 -22
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +22 -22
  277. package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
  278. package/docs/goal-context/README.md +3 -0
  279. package/graphs/default-loop.yaml +6 -1
  280. package/graphs/implement-loop.yaml +24 -0
  281. package/graphs/release/recipes.yaml +6 -0
  282. package/graphs/release/release-loop.yaml +17 -4
  283. package/graphs/wizard/recipes.yaml +44 -0
  284. package/graphs/wizard/wizard-loop.yaml +44 -0
  285. package/graphs/work/research-report.yaml +2 -0
  286. package/package.json +1 -1
  287. package/scripts/ci-typecheck-changed.ts +139 -5
  288. package/scripts/coord-role-pack.ts +1 -1
  289. package/scripts/first10-gate.ts +416 -0
  290. package/scripts/fleet/wsl-node-setup.sh +432 -0
  291. package/scripts/release-loop/docs-node.ts +204 -8
  292. package/scripts/release-loop/gate-node.ts +249 -53
  293. package/scripts/release-loop/node-verdict.ts +2 -0
  294. package/scripts/release-loop/resume-cap.ts +14 -34
  295. package/scripts/release-loop/resume-release.ts +37 -11
  296. package/scripts/release-loop/traffic-node.ts +59 -0
  297. package/scripts/release-loop/traffic-transition.ts +159 -0
  298. package/scripts/rhythm/daily.ts +137 -3
  299. package/scripts/ux-sim.ts +53 -0
  300. package/skills/README.md +1 -0
  301. package/src/acp/core-turn-bridge.ts +48 -6
  302. package/src/agent/delegate-hint.ts +16 -0
  303. package/src/agent/runner.ts +82 -2
  304. package/src/agent/task-notification.ts +56 -10
  305. package/src/agent/types.ts +4 -0
  306. package/src/agent-substrate/pr-reviewer.ts +55 -3
  307. package/src/agent-substrate/review-intent.ts +29 -2
  308. package/src/agent-substrate/review-observation.ts +3 -0
  309. package/src/agent-substrate/self-review-cli.ts +168 -16
  310. package/src/autopilot/mission-codebase-gate.ts +141 -12
  311. package/src/autopilot/pr-manager.ts +25 -5
  312. package/src/boot/daemon-tools/self-implement.ts +1 -0
  313. package/src/budget/usage-outcomes.ts +8 -4
  314. package/src/capture/tui-self-report.ts +102 -0
  315. package/src/chat/goal-continue-verdict.ts +41 -0
  316. package/src/chat/index.ts +30 -4
  317. package/src/chat/internal-turn-origin.ts +1 -0
  318. package/src/chat/paste-fold.ts +86 -0
  319. package/src/chat/tool-render/block.ts +32 -0
  320. package/src/chat/tool-render/dispatch.ts +2 -20
  321. package/src/chat/tool-render/result-text.ts +98 -0
  322. package/src/chat/turn-typeahead.ts +70 -7
  323. package/src/cli/config-audit.ts +119 -0
  324. package/src/cli/doctor-cli.ts +22 -0
  325. package/src/cli/guardian-cli.ts +10 -0
  326. package/src/cli/herdr-cli.ts +34 -0
  327. package/src/cli/light-entry-route.ts +6 -3
  328. package/src/cli/log-event-names.ts +2 -0
  329. package/src/cli/make-cli.ts +247 -11
  330. package/src/cli/msg-cli.ts +117 -3
  331. package/src/cli/pr-cli.ts +29 -16
  332. package/src/cli/pr-land-base-read.ts +11 -2
  333. package/src/cli/pr-land-heavy-remote.ts +6 -3
  334. package/src/cli/pr-land-overlap-evidence.ts +23 -4
  335. package/src/cli/pr-land-recovery.ts +117 -1
  336. package/src/cli/pty-takeover-cli.ts +8 -7
  337. package/src/cli/release-cli.ts +21 -5
  338. package/src/cli/release-single-flight.ts +1 -1
  339. package/src/cli/tasks-card-show.ts +162 -0
  340. package/src/cli/tasks-cli.ts +574 -356
  341. package/src/cli/tasks-read-cli.ts +197 -0
  342. package/src/core-turn/run-core-turn.ts +4 -2
  343. package/src/core-turn/run-goal-loop.ts +73 -16
  344. package/src/core-turn/types.ts +6 -1
  345. package/src/dashboard/context/keys.ts +8 -31
  346. package/src/dashboard/index.ts +202 -49
  347. package/src/dashboard/input/agent-wake.ts +7 -1
  348. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
  349. package/src/dashboard/input/chat-main-slash-command.ts +4 -2
  350. package/src/dashboard/input/goal-continue.ts +210 -0
  351. package/src/dashboard/input/goal-interim.ts +2 -0
  352. package/src/dashboard/input/internal-turn.ts +2 -8
  353. package/src/dashboard/input/seat-autowake.ts +9 -7
  354. package/src/dashboard/input/turn-autoheal.ts +52 -0
  355. package/src/dashboard/seat-boot-preamble.ts +132 -5
  356. package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
  357. package/src/dashboard/slash-runtime/dashboard-handlers.ts +3 -2
  358. package/src/dashboard/slash-runtime/model-choices.ts +15 -0
  359. package/src/dashboard/stale-install-check.ts +3 -99
  360. package/src/debug/batch-queue.ts +119 -0
  361. package/src/debug/tui-log-tag.ts +67 -0
  362. package/src/display/agent-surface.ts +7 -0
  363. package/src/domains/standalone-log-sink.ts +15 -2
  364. package/src/esc-abort-gate.ts +69 -0
  365. package/src/git-fs/worktree.ts +95 -1
  366. package/src/graph-runner/graph-cli.ts +18 -0
  367. package/src/graph-runner/runner.ts +20 -11
  368. package/src/graph-wizard/generate.ts +108 -4
  369. package/src/graph-wizard/steps.ts +15 -0
  370. package/src/grounding/proactive-ground.ts +86 -0
  371. package/src/harness/control-inbox.ts +49 -1
  372. package/src/harness/harness-cli-command.ts +51 -7
  373. package/src/harness/harness-incidents.ts +52 -1
  374. package/src/harness/pod-control-send.ts +33 -5
  375. package/src/harness/self-send-remote.ts +69 -0
  376. package/src/harness/self-send-routing-guard.ts +6 -0
  377. package/src/harness/self-send-target.ts +4 -3
  378. package/src/index.ts +327 -12
  379. package/src/input-core/context-key-runtime.ts +21 -0
  380. package/src/light-cli.ts +6 -1
  381. package/src/llm-wellformed.ts +70 -0
  382. package/src/llm.ts +35 -4
  383. package/src/loops/msg-wake.ts +35 -39
  384. package/src/loops/orchestrator/inbox.ts +59 -11
  385. package/src/loops/orchestrator/knowhow-pack.ts +364 -0
  386. package/src/loops/orchestrator/tick.ts +5 -1
  387. package/src/maturity/feature-maturity.ts +1 -1
  388. package/src/models/prompts.ts +17 -2
  389. package/src/msg/msg-post-office.ts +116 -0
  390. package/src/mss/logging/log-store.ts +79 -22
  391. package/src/nexus/api/decisions-route.ts +38 -18
  392. package/src/nexus/api/graph-wizard-api.ts +20 -2
  393. package/src/nexus/boot/register-mcp-clients.ts +263 -38
  394. package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
  395. package/src/onboarding/first-run.ts +37 -6
  396. package/src/onboarding/web-first.ts +43 -11
  397. package/src/ops/overview-collect.ts +12 -6
  398. package/src/ops/overview.ts +3 -3
  399. package/src/persona/loader.ts +11 -0
  400. package/src/persona/types.ts +8 -0
  401. package/src/prompt-library/session-guidance.ts +14 -0
  402. package/src/provider-summary.ts +8 -0
  403. package/src/pty-shell/herdr-agent-report.ts +118 -9
  404. package/src/pty-shell/herdr-prompt.ts +266 -0
  405. package/src/pty-shell/pty-control-ipc.ts +151 -8
  406. package/src/pty-shell/pty-special-keys.ts +42 -2
  407. package/src/pty-shell/stale-install-check.ts +99 -0
  408. package/src/pty-shell/tui-run-state.ts +14 -2
  409. package/src/release-loop/auto-start.ts +20 -2
  410. package/src/release-loop/checklist.ts +76 -4
  411. package/src/release-loop/rehearsal.ts +36 -20
  412. package/src/repl/index.ts +19 -1
  413. package/src/seat-loop/knowhow-lint.ts +1 -1
  414. package/src/self-dev/decompose-proposal.ts +172 -20
  415. package/src/self-dev/decompose.ts +61 -0
  416. package/src/self-dev/dev-cli.ts +37 -3
  417. package/src/self-dev/dev-pipeline.ts +8 -2
  418. package/src/self-dev/draft-triage-rules.ts +31 -0
  419. package/src/self-dev/glm-credential-guard.ts +77 -0
  420. package/src/self-dev/graph-journey-nodes.ts +1 -0
  421. package/src/self-dev/graph-journey-route.ts +12 -2
  422. package/src/self-dev/orchestrate-cli.ts +68 -3
  423. package/src/self-dev/orchestrate.ts +116 -17
  424. package/src/self-dev/run-supervisor.ts +55 -2
  425. package/src/self-dev/run-types.ts +1 -1
  426. package/src/self-health/autoheal.ts +153 -0
  427. package/src/self-health/signatures.ts +6 -0
  428. package/src/self-implement/device-first.ts +116 -0
  429. package/src/self-implement/doctor-visit.ts +239 -1
  430. package/src/self-implement/evidence-command-budget.ts +80 -0
  431. package/src/self-implement/goal-author-cli.ts +1 -0
  432. package/src/self-implement/goal-author-decompose.ts +265 -4
  433. package/src/self-implement/goal-author.ts +33 -8
  434. package/src/self-implement/goal-elaborate.ts +176 -22
  435. package/src/self-implement/goal-refine.ts +3 -0
  436. package/src/self-implement/graph-variant.ts +40 -6
  437. package/src/self-implement/headless-elanous-driver.ts +19 -3
  438. package/src/self-implement/off-diff-evidence.ts +58 -6
  439. package/src/self-implement/orchestrator.ts +222 -21
  440. package/src/self-implement/pod-warm-pool-profile.ts +1 -0
  441. package/src/self-implement/pwa-import-graph.ts +1 -1
  442. package/src/self-implement/rework-policy.ts +30 -0
  443. package/src/self-implement/run-ledger.ts +108 -0
  444. package/src/self-implement/run-ttl.ts +38 -24
  445. package/src/self-implement/scope-adjacency.ts +3 -1
  446. package/src/self-implement/seams.ts +60 -4
  447. package/src/self-implement/wiring-check.ts +358 -0
  448. package/src/shell-env-bootstrap.ts +11 -4
  449. package/src/skills/runner.ts +4 -2
  450. package/src/skills/tools/agent.ts +290 -48
  451. package/src/skills/tools/schedule-wakeup.ts +23 -4
  452. package/src/skills/tools/shell.ts +61 -6
  453. package/src/skills/tools/terminal-modal-inject.ts +1 -2
  454. package/src/skills/tools/terminal-modal.ts +10 -8
  455. package/src/skills/url-router.ts +41 -1
  456. package/src/smart-wizard/run.ts +66 -0
  457. package/src/status/bar.ts +34 -6
  458. package/src/status/status-provider-info.ts +37 -6
  459. package/src/steward/rejudge-tick.ts +10 -2
  460. package/src/steward/ta-repair-event-collect.ts +17 -6
  461. package/src/task-agent/actions.ts +3 -1
  462. package/src/task-agent/land-queue.ts +21 -8
  463. package/src/task-agent/live-moves.ts +22 -6
  464. package/src/task-agent/mission.ts +30 -0
  465. package/src/task-agent/rejudge-on-head.ts +15 -0
  466. package/src/task-agent/repair-cycle.ts +138 -32
  467. package/src/task-agent/repair-next-move.ts +31 -3
  468. package/src/task-agent/repair-outcomes.ts +29 -0
  469. package/src/task-agent/repair-worker.ts +14 -4
  470. package/src/task-agent/shadow.ts +41 -3
  471. package/src/task-agent/task-card-prefix.ts +2 -0
  472. package/src/task-agent/task-hand.ts +477 -22
  473. package/src/task-agent/task-parent-role-llm.ts +36 -0
  474. package/src/task-agent/tier-split.ts +78 -9
  475. package/src/task-orchestrator/surfaces/pod-account-broker.ts +9 -0
  476. package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
  477. package/src/task-orchestrator/surfaces/pod-command-job.ts +86 -5
  478. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
  479. package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
  480. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +11 -0
  481. package/src/task-orchestrator/surfaces/pod-pool.ts +76 -4
  482. package/src/task-orchestrator/surfaces/pod-provenance.ts +8 -2
  483. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
  484. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
  485. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
  486. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
  487. package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
  488. package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
  489. package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
  490. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +4 -0
  491. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +485 -36
  492. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
  493. package/src/task-orchestrator/surfaces/self-implement-pod.ts +396 -19
  494. package/src/task-orchestrator/surfaces/self-implement.ts +42 -2
  495. package/src/tool-runtime/index.ts +15 -2
  496. package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
  497. package/src/tty-foreground.ts +155 -0
  498. package/src/tui/chat/goal-interim.ts +173 -0
  499. package/src/tui/chat/log-view.ts +205 -18
  500. package/src/tui/chat/self-health-status.ts +232 -0
  501. package/src/tui/entry.ts +370 -81
  502. package/src/tui/input/composer.ts +8 -1
  503. package/src/tui/slash/compact-command.ts +7 -0
  504. package/src/tui/slash/compact.ts +1 -7
  505. package/src/tui/slash/resume.ts +75 -0
  506. package/src/tui-client/local-chat-turn.ts +45 -2
  507. package/src/tui-client/next-dashboard-runtime.ts +8 -0
  508. package/src/tui-client/next-loop-command.ts +70 -0
  509. package/src/tui-client/next-wakeup.ts +191 -0
  510. package/src/tui.ts +37 -0
  511. package/src/ui/modal-adapter.ts +2 -2
  512. package/src/ux-sim/classic-tui-seat-scenarios.ts +516 -0
  513. package/src/ux-sim/cli-config-audit-device.ts +121 -0
  514. package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
  515. package/src/ux-sim/event-monkey.ts +3 -2
  516. package/src/ux-sim/fake-bin.ts +45 -0
  517. package/src/ux-sim/fake-herdr.ts +238 -0
  518. package/src/ux-sim/fake-llm.ts +111 -6
  519. package/src/ux-sim/fault-glm-no-credential.ts +116 -0
  520. package/src/ux-sim/fault-nextmove-dispatch.ts +102 -1
  521. package/src/ux-sim/fault-scope-escape-lift.ts +33 -6
  522. package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
  523. package/src/ux-sim/goal-device.ts +619 -0
  524. package/src/ux-sim/in-process-cli.ts +22 -5
  525. package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
  526. package/src/ux-sim/mock-authoring-first-run.ts +97 -0
  527. package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
  528. package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
  529. package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
  530. package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
  531. package/src/ux-sim/next-tui-seat-scenarios.ts +631 -0
  532. package/src/ux-sim/onboarding-first-run-device.ts +269 -0
  533. package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
  534. package/src/ux-sim/subagent-tools-device.ts +81 -0
  535. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
  536. package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
  537. package/src/version/packed-revision.json +1 -1
  538. package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +0 -32
  540. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +0 -41
  541. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +0 -24
  542. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +0 -74
  543. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +0 -148
  553. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +0 -34
  555. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +0 -77
  556. package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +0 -62
  559. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +0 -90
  560. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +0 -36
  563. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +0 -79
  565. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +0 -122
  567. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +0 -286
  570. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +0 -24
  573. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +0 -23
  582. package/apps/pwa/out/_next/static/chunks/5483-dd5d7697f6bdb106.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +0 -287
  586. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +0 -8
  593. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +0 -27
  595. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +0 -93
  597. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +0 -149
  604. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +0 -104
  605. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +0 -226
  615. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +0 -64
  617. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +0 -115
  622. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/morning/page-47c5d4db587266bd.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/term/page-dc0a532f5b9196ec.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +0 -1
  686. /package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → uC-N0emedeNOFuaBQFv-I}/_ssgManifest.js +0 -0
@@ -30,13 +30,18 @@ import { controlInboxEnv } from '../../harness/control-inbox.js';
30
30
  import { finishPodFragment, writePodFragment } from '../../harness/self-send-target.js';
31
31
  import { mintRunId, normalizeRunId } from '../../harness/harness-space.js';
32
32
  import { TA_LAND_ENV } from '../../task-agent/task-hand.js';
33
- import { appendRunLedgerEntry, loadRunLedger, runLedgerDir, runLedgerPath } from '../../self-implement/run-ledger.js';
33
+ import { appendRunLedgerEntry, loadRunLedger, runLedgerDir, runLedgerPath, type RunLedgerEntry } from '../../self-implement/run-ledger.js';
34
34
  import { runSuffixKey } from '../../self-implement/salvage-branches.js';
35
35
  import type { GoalExecutionRecord } from '../../self-implement/orchestrator.js';
36
36
  import { hostRepositoryUnavailable, runHostRegate, type HostRegateResult } from '../../self-implement/host-regate.js';
37
37
  import { resolvePodHostAcpReview, runPodHostAcpReview, type PodHostAcpReviewOutcome } from './pod-host-acp-review.js';
38
38
  import { REVIEW_DEFERRED_TO_HOST_ENV, REVIEW_DEFERRED_TO_HOST_MERGE_REASON } from '../../self-implement/review-deferred-to-host.js';
39
39
  import { classifyPodTerminal, applyPodTerminal, podTerminalPrBody, type PrTerminalRecord, type DraftResidueContext } from '../../self-dev/draft-residue.js';
40
+ import { assessSiWarmReply, decideSiWarmNextStep, type SiWarmCommand, type SiWarmReply,
41
+ type SiWarmReturnedBytes } from './pod-si-warm-protocol.js';
42
+ import { cleanAndReturnChildPod, type ChildPodReuseOperations } from './pod-child-reuse.js';
43
+ import { executeSiWarmTransport, type SiWarmFixedRunner,
44
+ type SiWarmPodIdentity } from './pod-si-warm-transport.js';
40
45
 
41
46
  export const POD_CONTROL_INBOX_DIR = '/tmp/elanous-control.inbox';
42
47
  /** Pod Job 수명 상한(`activeDeadlineSeconds`) — 대표 2026-09-26 90분 → 180분(90분에 `DeadlineExceeded` 로 죽은 런 둘). */
@@ -59,6 +64,9 @@ export const POD_JOB_DEADLINE_SECONDS = 10_800;
59
64
  // POD-DIET (10-06 03:47~05:18 · node-b goal Pods · 89 one-minute samples · 42 Pods): per-Pod observed max median 4.6Gi ·
60
65
  // p75 6.2Gi · p90 11.7Gi — 23/42 went above the old 4Gi request, so the scheduler over-packed. 6Gi ≈ p75; limits stay.
61
66
  // Node allocatable ≈ 343Gi ≫ 25 × 6Gi. One-minute samples can miss the true peak (lower bound).
67
+ import { POD_LAUNCH_FINISHED_EVENT, POD_LAUNCH_STARTED_EVENT, provenanceRowFromAnnotations, siTaskPodProvenance } from './pod-launch-history.js';
68
+ import { podProvenanceMetadata, type PodProvenanceMetadata } from './pod-provenance.js';
69
+ import { packageVersion } from '../../version/code-revision.js';
62
70
  import { podWorkLabels, type PodWorkIdentity, type PodPlacement, type PodPlacementKind, type PodPoolMember, type PodPoolScheduler } from './pod-pool.js';
63
71
  export { POD_CHILD_REQUESTS } from './pod-lease.js';
64
72
  import { measurePoolLease, recommendConcurrency, POD_CHILD_REQUESTS, POD_SI_ADMISSION_CAP_BYTES, POD_HOST_LEASE_ANNOTATION, POD_JOB_TTL_AFTER_FINISHED_SECONDS, LEASE_KUBECTL_MAX_BUFFER, memoryQuantityBytes } from './pod-lease.js';
@@ -97,7 +105,7 @@ import { ZAI_POD_EGRESS_LABEL, checkZaiPodSecret, countActiveZaiJobs, decideZaiP
97
105
  import { ZAI_CODING_DEFAULT_MODEL, ZAI_OPENROUTER_FALLBACK_MODEL, zaiSettingsFromConfig, type ZaiCodingPlanSettings } from '../../llm/zai-coding-plan.js';
98
106
  import { normalizePlanningFallbackReason, selectEnhanceLlm } from '../../prompt-enhance/enhance.js';
99
107
  import { inferProviderFromModel } from '../../llm.js';
100
- import { classifyPodExit, extractPodFailureReason, podTerminalRow, type PodExitClass } from './pod-failure-reason.js';
108
+ import { classifyPodExit, extractPodFailureReason, podChildFailureAttribution, podTerminalRow, POD_TERMINATION_JOB_JSONPATH, POD_TERMINATION_PODS_JSONPATH, readPodTermination, type PodExitClass, type PodTermination } from './pod-failure-reason.js';
101
109
  import { kubectlTransientReason, retryKubectlTransient } from './kubectl-transient-retry.js';
102
110
  import { OLD_DOOR_STAMP_ENV } from '../../self-dev/old-door.js';
103
111
  import { resolveDefaultSourceHead, seedMirrorOnce, type MirrorSeedResult } from './pod-mirror-seed.js';
@@ -105,7 +113,22 @@ import { decideWarmReuse, type WarmReuseEvidenceByConsumer, type WarmReuseSwitch
105
113
  import type { WarmWorkerCommand } from './pod-warm-worker-protocol.js';
106
114
  import type { WarmPodTransportResult } from './pod-warm-worker-pod.js';
107
115
 
108
- export type Kubectl = (args: readonly string[], input?: string) => { status: number | null; stdout: string; stderr: string };
116
+ export type Kubectl = (args: readonly string[], input?: string, timeoutMs?: number) => { status: number | null; stdout: string; stderr: string };
117
+
118
+ /** TC's si-v1 transport supplies this receipt. No lease is considered reusable from a Job exit alone. */
119
+ export interface SiWarmChildAttempt {
120
+ leaseFenced: boolean;
121
+ command: SiWarmCommand | null;
122
+ /** The consumer executes this fenced transport. A provider cannot assert its own reply verdict. */
123
+ transport: { pod: SiWarmPodIdentity; runner: SiWarmFixedRunner; now?: () => number };
124
+ payload: Uint8Array;
125
+ credentialBundle: Uint8Array;
126
+ /** Collect verified ledger/artifact bytes into the existing host stores. */
127
+ adopt: (command: SiWarmCommand, reply: SiWarmReply, bytes: SiWarmReturnedBytes) => Promise<void>;
128
+ cleanup: ChildPodReuseOperations;
129
+ /** The provider fences a worker even when a transport failure hides its command receipt. */
130
+ quarantineUnknown: (reason: string) => Promise<void>;
131
+ }
109
132
  type OpenPrByBranch = { status: 'found'; prNumber: number; prUrl: string }
110
133
  | { status: 'not-found' | 'failed'; reason: string };
111
134
 
@@ -123,6 +146,13 @@ const APP_GH_AUTH_COMMAND = `bun -e '${APP_GH_AUTH_SCRIPT}'`;
123
146
  const APP_GH_EXEC = `unset GH_TOKEN GITHUB_TOKEN; GH_CONFIG_DIR="${APP_GH_CONFIG_PATH}" exec "$@"`;
124
147
 
125
148
  export interface PodSpawnOptions {
149
+ /** si-v1 living worker consumer. Absent means the existing one-shot Job path. */
150
+ siWarmAttempt?: (input: Parameters<SelfImplementJobSpawn>[0]) => Promise<SiWarmChildAttempt | null>;
151
+ /** POD-REUSE-SI-PROVIDER-WIRE: must apply cold-path host regate, ACP, terminal and repair checks before warm adoption. */
152
+ siWarmHostPostprocess?: (result: SelfImplementJobDone, attempt: SiWarmChildAttempt,
153
+ input: Parameters<SelfImplementJobSpawn>[0]) => Promise<SelfImplementJobDone>;
154
+ /** Injected test ledger; production writes to the existing run ledger. */
155
+ siWarmLedger?: (entry: RunLedgerEntry) => void;
126
156
  /** 이미지 판(라벨 elanous.commit) — 주입(시험·감독기가 이미 잰 값). 없으면 docker 로 잰다. */
127
157
  imageCommit?: string | null;
128
158
  /** codex 계정 이름(`~/.elanous/auth.json` 의 `openai-codex:<이름>`). 기본 team. */
@@ -1116,7 +1146,7 @@ export function podSigtermTrapScript(seqFile: string = POD_USAGE_PARTIAL_SEQ_FIL
1116
1146
  return `trap '{ [ -n "$si_pid" ] && kill "$si_pid" 2>/dev/null || true; [ -n "\${usage_partial_pid:-}" ] && kill "$usage_partial_pid" 2>/dev/null || true; si_seq=$(cat ${seqFile} 2>/dev/null || true); case "$si_seq" in ""|*[!0-9]*) si_seq=0;; esac; si_seq=$((10#$si_seq + 1)); { [ -f scripts/usage-rollup.ts ] && bun scripts/usage-rollup.ts --since 12h --partial --seq "$si_seq"; } & si_rollup_pid=$!; for si_i in 1 2 3 4 5 6 7 8; do kill -0 "$si_rollup_pid" 2>/dev/null || break; sleep 1; done; kill "$si_rollup_pid" 2>/dev/null || true; wait "$si_rollup_pid" 2>/dev/null || true; exit 143; }' TERM`;
1117
1147
  }
1118
1148
 
1119
- export function podJobManifest(o: { name: string; namespace: string; image: string; workIdentity?: PodWorkIdentity; boundPrNumber?: number; /** 레지스트리 이미지면 IfNotPresent(노드가 pull) · 반입 이미지면 Never. */ imagePullPolicy?: 'Never' | 'IfNotPresent'; repoUrl: string; source?: PodSource; repairCommitOnly?: { pr: number; baseHead: string }; hostMirror?: string; args: readonly string[]; passEnv: readonly string[]; deadlineSeconds: number; runId?: string; parentRunId?: string; armEnv?: Readonly<Record<string, string>>; hostId?: string; imageCommit?: string | null; skillEnvs?: readonly string[]; memoryLimit?: string; memoryRequest?: string; goalDoc?: string; /** AUTHOR-POD2 — run `harness say` on /creds/feature inside the Pod (authoring happens off the host). */ authorSentence?: boolean; authorGrade?: 'full' | 'lite'; grokCredential?: 'subscription' | 'api_key'; codexAccounts?: readonly string[]; appCredential?: boolean; /** Test seam — default POD_GH_STALE_SECONDS. */ githubStaleSeconds?: number; /** Which goal execution and attempt this Job is — a resumed host verifies it before following the Job (POD9). */ execution?: { key: string; attempt: number }; hostLeaseAdmitted?: boolean; /** POD-ROLE-LLM — OpenRouter 자식 Pod 에 리뷰어용 codex 자격을 깐다. */ reviewerCodexAuth?: boolean; /** BEDROCK-PROVIDER ② — bedrock 자식만: 이름 있는 AWS Secret 의 키(secretKeyRef) ⊕ 리전 ⊕ 이그레스 라벨. */ bedrock?: BedrockPodSpec; /** ZAI-POD-CHILD — glm(ZAI) 자식만: 이름 있는 ZAI Secret 의 키(secretKeyRef) ⊕ 이그레스·동시 상한 라벨(Pod ⊕ Job). */ zai?: ZaiPodSpec; /** Codex Job may use the same named Secret only for an explicitly admitted ZAI fallback. */ zaiFallback?: ZaiPodSpec; fallbackChain?: { steps: readonly FallbackStep[]; source: 'host' | 'default' }; /** TA-POD-WARMBOOT-PARITY — the child's final line (podResultMarkerShellLine), just before `exit $rc`. */ resultMarkerLine?: string }): Record<string, unknown> {
1149
+ export function podJobManifest(o: { name: string; namespace: string; image: string; workIdentity?: PodWorkIdentity; boundPrNumber?: number; /** 레지스트리 이미지면 IfNotPresent(노드가 pull) · 반입 이미지면 Never. */ imagePullPolicy?: 'Never' | 'IfNotPresent'; repoUrl: string; source?: PodSource; repairCommitOnly?: { pr: number; baseHead: string }; hostMirror?: string; args: readonly string[]; passEnv: readonly string[]; deadlineSeconds: number; runId?: string; parentRunId?: string; armEnv?: Readonly<Record<string, string>>; hostId?: string; imageCommit?: string | null; skillEnvs?: readonly string[]; memoryLimit?: string; memoryRequest?: string; goalDoc?: string; /** AUTHOR-POD2 — run `harness say` on /creds/feature inside the Pod (authoring happens off the host). */ authorSentence?: boolean; authorGrade?: 'full' | 'lite'; grokCredential?: 'subscription' | 'api_key'; codexAccounts?: readonly string[]; appCredential?: boolean; /** Test seam — default POD_GH_STALE_SECONDS. */ githubStaleSeconds?: number; /** Which goal execution and attempt this Job is — a resumed host verifies it before following the Job (POD9). */ execution?: { key: string; attempt: number }; hostLeaseAdmitted?: boolean; /** POD-ROLE-LLM — OpenRouter 자식 Pod 에 리뷰어용 codex 자격을 깐다. */ reviewerCodexAuth?: boolean; /** BEDROCK-PROVIDER ② — bedrock 자식만: 이름 있는 AWS Secret 의 키(secretKeyRef) ⊕ 리전 ⊕ 이그레스 라벨. */ bedrock?: BedrockPodSpec; /** ZAI-POD-CHILD — glm(ZAI) 자식만: 이름 있는 ZAI Secret 의 키(secretKeyRef) ⊕ 이그레스·동시 상한 라벨(Pod ⊕ Job). */ zai?: ZaiPodSpec; /** Codex Job may use the same named Secret only for an explicitly admitted ZAI fallback. */ zaiFallback?: ZaiPodSpec; fallbackChain?: { steps: readonly FallbackStep[]; source: 'host' | 'default' }; /** TA-POD-WARMBOOT-PARITY — the child's final line (podResultMarkerShellLine), just before `exit $rc`. */ resultMarkerLine?: string; /** POD-LAUNCH-PROVENANCE — the shared provenance set (labels ⊕ annotations ⊕ child env) for this si-task Job. */ provenance?: PodProvenanceMetadata }): Record<string, unknown> {
1120
1150
  if (o.repairCommitOnly && (o.source?.kind !== 'pr' || o.source.number !== o.repairCommitOnly.pr || !/^[0-9a-f]{40}$/.test(o.repairCommitOnly.baseHead) || o.args.includes('--open-pr') || o.args.includes('--merge-by-host') || o.args.includes('--auto-merge'))) {
1121
1151
  throw new Error('repair commit-only requires matching PR source and no PR/merge flags');
1122
1152
  }
@@ -1183,6 +1213,9 @@ export function podJobManifest(o: { name: string; namespace: string; image: stri
1183
1213
  // Record that fact before the main command, without treating clone completion as install completion.
1184
1214
  `printf 'ELANOUS_POD_DEPS skipped %s image-prepared-no-install\\n' "$(date +%s)" || true`,
1185
1215
  ...(o.repairCommitOnly ? [`[ "$(git rev-parse HEAD)" = '${o.repairCommitOnly.baseHead}' ] || { echo 'ELANOUS_POD_REPAIR_FAILED source-head-mismatch'; exit 8; }`] : []),
1216
+ // PR checkout and, when requested, the repair HEAD pin have passed before this child starts.
1217
+ // A supervisor input may continue the repair, but cannot launch its source again.
1218
+ ...(o.source?.kind === 'pr' ? ['export ELANOUS_POD_VERIFIED_PR_SOURCE=1'] : []),
1186
1219
  ...(goalPath ? [
1187
1220
  `mkdir -p -- "$(dirname -- ${goalPath})" && cp -- /creds/goal-doc ${goalPath} || exit 6`,
1188
1221
  ] : []),
@@ -1201,7 +1234,7 @@ export function podJobManifest(o: { name: string; namespace: string; image: stri
1201
1234
  // AUTHOR-LITE2-POD — 등급은 환경변수 `ELANOUS_AUTHOR_GRADE` 로 싣는다(옛 Pod elanous 는 모르는 환경변수를 무시하고 full 로 돈다).
1202
1235
  siTaskPodStageShell('run', 'start'),
1203
1236
  o.repairCommitOnly
1204
- ? `export ${OLD_DOOR_STAMP_ENV}=self-implement; elanous self implement "$(cat /creds/feature)" --json --no-open-pr ${quoted} > /tmp/si.out 2>&1 & si_pid=$!; wait "$si_pid"; rc=$?; ${RUN_END}; if [ "$rc" -eq 0 ]; then elanous self repair-commit-export '${o.repairCommitOnly.pr}' '${o.repairCommitOnly.baseHead}' /tmp/si.out "$PWD" "$HOME/outbox" || rc=8; fi`
1237
+ ? `export ${OLD_DOOR_STAMP_ENV}=self-implement; elanous self implement "$(cat /creds/feature)" --json --no-open-pr ${quoted} > /tmp/si.out 2>&1 & si_pid=$!; wait "$si_pid"; rc=$?; ${RUN_END}; if elanous self repair-commit-export '${o.repairCommitOnly.pr}' '${o.repairCommitOnly.baseHead}' /tmp/si.out "$PWD" "$HOME/outbox"; then rc=0; elif [ "$rc" -eq 0 ]; then rc=8; fi`
1205
1238
  : o.authorSentence
1206
1239
  ? `echo "ELANOUS_AUTHOR_ON_POD started host=$(hostname) at=$(date -u +%Y-%m-%dT%H:%M:%SZ)"; author_t0=$(date +%s); ${o.authorGrade === 'lite' || o.authorGrade === 'full' ? `ELANOUS_AUTHOR_GRADE=${o.authorGrade} ` : ''}elanous harness say --substrate local --json${quotedAsk}${quotedChildLlm} -- "$(cat /creds/feature)" > /tmp/si.out 2>&1 & si_pid=$!; wait "$si_pid"; rc=$?; ${RUN_END}; echo "ELANOUS_AUTHOR_ON_POD finished host=$(hostname) rc=$rc seconds=$(( $(date +%s) - author_t0 ))"; ${POD_RESULT_FLATTEN}`
1207
1240
  : goalPath
@@ -1276,15 +1309,15 @@ if [ "$found" -eq 0 ]; then echo ELANOUS_RUN_LEDGER_NONE; fi`,
1276
1309
  return {
1277
1310
  apiVersion: 'batch/v1',
1278
1311
  kind: 'Job',
1279
- metadata: { name: o.name, namespace: o.namespace, labels: { 'elanous.substrate': 'pod', 'elanous.job': o.name, ...podRunLabels(o), ...(o.workIdentity ? podWorkLabels(o.workIdentity) : {}), ...(o.zai || o.zaiFallback ? { [ZAI_POD_EGRESS_LABEL]: 'true' } : {}) },
1280
- ...((o.execution || o.hostLeaseAdmitted) ? { annotations: { ...(o.execution ? { [POD_EXECUTION_KEY_ANNOTATION]: o.execution.key, [POD_ATTEMPT_ANNOTATION]: String(o.execution.attempt) } : {}), ...(o.hostLeaseAdmitted ? { [POD_HOST_LEASE_ANNOTATION]: 'true' } : {}) } } : {}) },
1312
+ metadata: { name: o.name, namespace: o.namespace, labels: { 'elanous.substrate': 'pod', 'elanous.job': o.name, ...podRunLabels(o), ...(o.workIdentity ? podWorkLabels(o.workIdentity) : {}), ...(o.zai || o.zaiFallback ? { [ZAI_POD_EGRESS_LABEL]: 'true' } : {}), ...o.provenance?.labels },
1313
+ ...((o.execution || o.hostLeaseAdmitted || o.provenance) ? { annotations: { ...o.provenance?.annotations, ...(o.execution ? { [POD_EXECUTION_KEY_ANNOTATION]: o.execution.key, [POD_ATTEMPT_ANNOTATION]: String(o.execution.attempt) } : {}), ...(o.hostLeaseAdmitted ? { [POD_HOST_LEASE_ANNOTATION]: 'true' } : {}) } } : {}) },
1281
1314
  spec: {
1282
1315
  backoffLimit: 0,
1283
1316
  ttlSecondsAfterFinished: POD_JOB_TTL_AFTER_FINISHED_SECONDS,
1284
1317
  activeDeadlineSeconds: o.deadlineSeconds,
1285
1318
  template: {
1286
1319
  // ⭐ Pod 라벨 — local 팔만 `elanous.egress/local-llm` 을 단다. docker/h1/policy-local-llm.yaml 이 그 라벨에만 호스트 LLM 포트 «하나»를 연다.
1287
- metadata: { labels: { 'elanous.job': o.name, ...podRunLabels(o), ...(o.workIdentity ? podWorkLabels(o.workIdentity) : {}), ...(o.armEnv?.ELANOUS_LLM_PROVIDER === 'local' ? { 'elanous.egress/local-llm': 'true' } : {}), ...(o.bedrock ? { [BEDROCK_POD_EGRESS_LABEL]: 'true' } : {}), ...(o.zai || o.zaiFallback ? { [ZAI_POD_EGRESS_LABEL]: 'true' } : {}) } },
1320
+ metadata: { labels: { 'elanous.job': o.name, ...podRunLabels(o), ...(o.workIdentity ? podWorkLabels(o.workIdentity) : {}), ...(o.armEnv?.ELANOUS_LLM_PROVIDER === 'local' ? { 'elanous.egress/local-llm': 'true' } : {}), ...(o.bedrock ? { [BEDROCK_POD_EGRESS_LABEL]: 'true' } : {}), ...(o.zai || o.zaiFallback ? { [ZAI_POD_EGRESS_LABEL]: 'true' } : {}), ...o.provenance?.labels }, ...(o.provenance ? { annotations: o.provenance.annotations } : {}) },
1288
1321
  spec: {
1289
1322
  restartPolicy: 'Never',
1290
1323
  securityContext: { runAsUser: 1000, fsGroup: 1000 },
@@ -1311,6 +1344,8 @@ if [ "$found" -eq 0 ]; then echo ELANOUS_RUN_LEDGER_NONE; fi`,
1311
1344
  { name: 'ELANOUS_POD_NAMESPACE', valueFrom: { fieldRef: { fieldPath: 'metadata.namespace' } } },
1312
1345
  ...(o.hostId ? [{ name: 'ELANOUS_HOST_ID', value: o.hostId }] : []),
1313
1346
  ...(o.imageCommit ? [{ name: 'ELANOUS_IMAGE_COMMIT', value: o.imageCommit }] : []),
1347
+ // POD-LAUNCH-PROVENANCE — the child knows who launched it, why and when (ELANOUS_POD_<key> · no secrets).
1348
+ ...(o.provenance?.env ?? []),
1314
1349
  // ⭐ 런 계약(graph-run-contract.ts) — 이 칸이 «실제로» Pod 이고, 부모가 정한 계약도 Pod 다. 안의 그래프가 노드마다 대조한다.
1315
1350
  { name: ACTUAL_SUBSTRATE_ENV, value: 'pod' }, { name: RUN_CONTRACT_ENV, value: carryRunContract({ substrate: 'pod' }) },
1316
1351
  ...Object.entries(o.armEnv ?? {}).map(([name, value]) => ({ name, value })),
@@ -1421,6 +1456,14 @@ function readJobPodImage(kubectl: Kubectl, namespace: string, job: string, jobUi
1421
1456
  return { podName: pod.metadata.name, podUid, podCreatedAt, imageID, digest, digestUnavailable: digest ? null : 'nonstandard-image-id' };
1422
1457
  }
1423
1458
 
1459
+ /** A repair Pod succeeds only with a verified result/bundle, even if its child gate exited 1. */
1460
+ export function repairPodExitCode(input: { state: string; repairCommitOnly: boolean; repairArtifactReady: boolean;
1461
+ disposition?: { stage?: string; ok?: boolean } }): 0 | 1 {
1462
+ if (input.state !== 'complete') return 1;
1463
+ if (input.repairCommitOnly) return input.repairArtifactReady ? 0 : 1;
1464
+ return input.disposition?.stage !== 'host-regate-failed' && input.disposition?.ok !== false ? 0 : 1;
1465
+ }
1466
+
1424
1467
  export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplementJobSpawn {
1425
1468
  if (options.repairCommitOnly && (options.source?.kind !== 'pr' || options.source.number !== options.repairCommitOnly.pr || !/^[0-9a-f]{40}$/.test(options.repairCommitOnly.baseHead))) {
1426
1469
  throw new Error('repair commit-only requires a matching PR source and exact head');
@@ -1436,10 +1479,290 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
1436
1479
  if (hostMirror && !isAbsolute(hostMirror)) throw new Error('pod.hostMirror must be an absolute directory path');
1437
1480
  const hostSupervised = options.hostSupervised ?? true;
1438
1481
  const resultMarkerOn = options.resultMarker ?? !options.kubectl;
1482
+ const writeWarmLedger = options.siWarmLedger
1483
+ ?? ((entry: RunLedgerEntry) => appendRunLedgerEntry(entry, runLedgerDir(env.ELANOUS_STATE_DIR)));
1439
1484
  return (input) => {
1440
1485
  if (options.repairCommitOnly && (input.autoMerge || input.openPr || input.base !== `pr-${options.repairCommitOnly.pr}`)) {
1441
1486
  throw new Error('repair commit-only refuses auto merge, new PR, or a different base');
1442
1487
  }
1488
+ if (options.siWarmAttempt && !options.siWarmHostPostprocess) {
1489
+ throw new Error('si-v1 warm execution requires cold-path host postprocess parity');
1490
+ }
1491
+ if (options.siWarmAttempt) {
1492
+ const done = (async (): Promise<SelfImplementJobDone> => {
1493
+ let attempt: SiWarmChildAttempt;
1494
+ try {
1495
+ const acquired = await options.siWarmAttempt!(input);
1496
+ if (!acquired) {
1497
+ // No lease was fenced: use the existing one-shot Job path.
1498
+ const { siWarmAttempt: _unused, siWarmHostPostprocess: _postprocess, ...coldOptions } = options;
1499
+ return podSelfImplementSpawn(coldOptions)(input).done;
1500
+ }
1501
+ attempt = acquired;
1502
+ }
1503
+ catch (error) {
1504
+ // A lost exec reply may conceal an already opened PR. Never start another child here.
1505
+ const message = error instanceof Error ? error.message : String(error);
1506
+ debug.log('pod.reuse', 'attempt-unavailable', { spaceId: input.spaceId, reason: message }, { level: 'warn' });
1507
+ return { exitCode: 1, output: '', error: { code: 'si-warm-reconcile-only', message } };
1508
+ }
1509
+ let transport: Awaited<ReturnType<typeof executeSiWarmTransport>>;
1510
+ try {
1511
+ transport = await executeSiWarmTransport({ command: attempt.command,
1512
+ pod: attempt.transport.pod, runner: attempt.transport.runner,
1513
+ leaseFenced: attempt.leaseFenced, payload: attempt.payload,
1514
+ credentialBundle: attempt.credentialBundle, now: attempt.transport.now });
1515
+ } catch (error) {
1516
+ const message = error instanceof Error ? error.message : String(error);
1517
+ try { await attempt.quarantineUnknown('transport-exception'); }
1518
+ catch (quarantineError) {
1519
+ // Both failures must survive: the first transport error names the cause, the
1520
+ // quarantine error names the unfinished disposition. Record the judgement.
1521
+ const quarantineMessage = quarantineError instanceof Error ? quarantineError.message : String(quarantineError);
1522
+ const combined = `transport:${message}; quarantine:${quarantineMessage}`;
1523
+ try { writeWarmLedger({ runId: attempt.command?.runId ?? input.spaceId,
1524
+ event: 'pod-reuse-quarantine-failed',
1525
+ data: { spaceId: input.spaceId, workerId: attempt.command?.workerId ?? null,
1526
+ leaseId: attempt.command?.leaseId ?? null, reason: combined } }); }
1527
+ catch (ledgerError) { debug.log('pod.reuse', 'ledger-unavailable', { spaceId: input.spaceId,
1528
+ event: 'pod-reuse-quarantine-failed', reason: ledgerError instanceof Error ? ledgerError.message : String(ledgerError) }, { level: 'warn' }); }
1529
+ debug.log('pod.reuse', 'quarantine-failed', { spaceId: input.spaceId, reason: combined }, { level: 'error' });
1530
+ return { exitCode: 1, output: '', error: { code: 'si-warm-worker-state-unknown', message: combined } };
1531
+ }
1532
+ // The quarantine is confirmed: record the settled disposal (fail-soft — the
1533
+ // disposition survives a ledger write failure) before the reconcile-only return.
1534
+ try { writeWarmLedger({ runId: attempt.command?.runId ?? input.spaceId,
1535
+ event: 'pod-reuse-quarantined',
1536
+ data: { spaceId: input.spaceId, workerId: attempt.command?.workerId ?? null,
1537
+ leaseId: attempt.command?.leaseId ?? null, reason: 'transport-exception' } }); }
1538
+ catch (ledgerError) { debug.log('pod.reuse', 'ledger-unavailable', { spaceId: input.spaceId,
1539
+ event: 'pod-reuse-quarantined', reason: ledgerError instanceof Error ? ledgerError.message : String(ledgerError) }, { level: 'warn' }); }
1540
+ return { exitCode: 1, output: '', error: { code: 'si-warm-reconcile-only', message } };
1541
+ }
1542
+ const validation = transport.boundary === 'exec-attempted'
1543
+ ? assessSiWarmReply(attempt.command, transport.reply, transport.bytes,
1544
+ attempt.payload, attempt.credentialBundle)
1545
+ : undefined;
1546
+ const next = decideSiWarmNextStep({ boundary: transport.boundary,
1547
+ leaseFenced: attempt.leaseFenced, ...(validation ? { validation } : {}) });
1548
+ debug.log('pod.reuse', 'admission-decision', { spaceId: input.spaceId, boundary: transport.boundary,
1549
+ next: next.next, reason: transport.reason, validationReason: transport.validationReason ?? null });
1550
+ if (next.next === 'cold-job' && transport.boundary === 'not-entered' && attempt.leaseFenced) {
1551
+ const { siWarmAttempt: _unused, ...coldOptions } = options;
1552
+ // The acquired lease must not silently ride along into a cold Job: dispose it first,
1553
+ // record the disposition, and refuse to start the cold Job when disposal fails.
1554
+ const coldLease = attempt.command ? { workerId: attempt.command.workerId,
1555
+ podUid: attempt.command.podUid, leaseId: attempt.command.leaseId,
1556
+ generation: attempt.command.generation, key: attempt.command.key,
1557
+ sourceSha: attempt.command.sourceSha } : null;
1558
+ if (coldLease) {
1559
+ const recordColdDisposition = (event: string, action: string, residue: Record<string, unknown> = {}) => {
1560
+ debug.log('pod.reuse', event, { spaceId: input.spaceId, workerId: coldLease.workerId,
1561
+ leaseId: coldLease.leaseId, action, reason: transport.reason, ...residue });
1562
+ try { writeWarmLedger({ runId: attempt.command?.runId ?? input.spaceId, event,
1563
+ data: { spaceId: input.spaceId, workerId: coldLease.workerId, leaseId: coldLease.leaseId,
1564
+ action, reason: transport.reason, ...residue } }); }
1565
+ catch (error) { debug.log('pod.reuse', 'ledger-unavailable', { spaceId: input.spaceId, event,
1566
+ reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
1567
+ };
1568
+ try {
1569
+ // The acquired lease is disposed by the same eligibility standard as the
1570
+ // entered path: process count zero, pinned-source git reset/clean/status,
1571
+ // credential count zero, and an observable return decision — before the
1572
+ // lease can go back into the warm pool or a cold Job starts.
1573
+ const returned = await cleanAndReturnChildPod(coldLease, { ...attempt.cleanup,
1574
+ observe: (event, data) => {
1575
+ debug.log('pod.reuse', event, { spaceId: input.spaceId, ...data },
1576
+ { level: event === 'return-decision'
1577
+ && ((data as { outcome?: string }).outcome === 'eligible'
1578
+ || (data as { outcome?: string }).outcome === 'returned') ? 'info' : 'warn' });
1579
+ attempt.cleanup.observe(event, data);
1580
+ // A ledger write failure is an observation failure: the settled return
1581
+ // or quarantine disposition must survive it (fail-soft after the decision).
1582
+ try { writeWarmLedger({ runId: attempt.command?.runId ?? input.spaceId,
1583
+ event: `pod-reuse-${event}`,
1584
+ data: { spaceId: input.spaceId, ...data } }); }
1585
+ catch (ledgerError) { debug.log('pod.reuse', 'ledger-unavailable', { spaceId: input.spaceId,
1586
+ runId: attempt.command?.runId ?? input.spaceId, event: `pod-reuse-${event}`,
1587
+ reason: ledgerError instanceof Error ? ledgerError.message : String(ledgerError) },
1588
+ { level: 'warn' }); }
1589
+ } });
1590
+ recordColdDisposition('pod-reuse-cold-fallback-dispose', returned.outcome,
1591
+ { dispositionReason: returned.reason });
1592
+ } catch (error) {
1593
+ const message = error instanceof Error ? error.message : String(error);
1594
+ try { await attempt.cleanup.quarantine(coldLease, { clean: false, reason: 'cold-fallback-dispose-failed', observedResidue: null }); }
1595
+ catch (quarantineError) {
1596
+ const quarantineMessage = quarantineError instanceof Error ? quarantineError.message : String(quarantineError);
1597
+ recordColdDisposition('pod-reuse-cold-fallback-dispose-failed', 'quarantine-failed',
1598
+ { error: `disposal:${message}; quarantine:${quarantineMessage}` });
1599
+ return { exitCode: 1, output: '', error: { code: 'si-warm-worker-state-unknown',
1600
+ message: `disposal:${message}; quarantine:${quarantineMessage}` } };
1601
+ }
1602
+ recordColdDisposition('pod-reuse-cold-fallback-dispose-failed', 'quarantined', { error: message });
1603
+ return { exitCode: 1, output: '', error: { code: 'si-warm-worker-state-unknown', message } };
1604
+ }
1605
+ }
1606
+ return podSelfImplementSpawn(coldOptions)(input).done;
1607
+ }
1608
+ const command = attempt.command;
1609
+ const lease = command && { workerId: command.workerId, podUid: command.podUid,
1610
+ leaseId: command.leaseId, generation: command.generation, key: command.key,
1611
+ sourceSha: command.sourceSha };
1612
+ const recordQuarantine = (event: string, reason: string, residue: Record<string, unknown> = {}) => {
1613
+ debug.log('pod.reuse', event, { spaceId: input.spaceId, workerId: command?.workerId ?? null,
1614
+ leaseId: command?.leaseId ?? null, reason, ...residue }, { level: 'warn' });
1615
+ try { writeWarmLedger({ runId: command?.runId ?? input.spaceId, event,
1616
+ data: { spaceId: input.spaceId, workerId: command?.workerId ?? null,
1617
+ leaseId: command?.leaseId ?? null, reason, ...residue } }); }
1618
+ catch (error) { debug.log('pod.reuse', 'ledger-unavailable', { spaceId: input.spaceId,
1619
+ event, reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
1620
+ };
1621
+ const retireLease = async (reason: string) => {
1622
+ recordQuarantine('pod-reuse-quarantine-intent', reason);
1623
+ if (!lease) {
1624
+ try { await attempt.quarantineUnknown(reason); }
1625
+ catch (error) {
1626
+ // The unsettled quarantine is an account of its own: keep both the
1627
+ // primary path reason and the quarantine cause in the run ledger,
1628
+ // then let the caller surface the unknown worker state.
1629
+ const message = error instanceof Error ? error.message : String(error);
1630
+ recordQuarantine('pod-reuse-quarantine-failed', `${reason}; quarantine:${message}`);
1631
+ throw error;
1632
+ }
1633
+ recordQuarantine('pod-reuse-quarantined', reason);
1634
+ return;
1635
+ }
1636
+ // An uncertain exec may still be running. Keep it fenced and revoke its run credentials.
1637
+ let processRemaining: number | null = null;
1638
+ let credentialRemaining: number | null = null;
1639
+ try { processRemaining = (await attempt.cleanup.stopChildProcesses(lease)).remaining; }
1640
+ catch (error) { debug.log('pod.reuse', 'process-stop-failed', { spaceId: input.spaceId,
1641
+ reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
1642
+ try { credentialRemaining = (await attempt.cleanup.removeRunCredentials(lease)).remaining; }
1643
+ catch (error) { debug.log('pod.reuse', 'credential-revoke-failed', { spaceId: input.spaceId,
1644
+ reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
1645
+ const observedResidue = [processRemaining, credentialRemaining]
1646
+ .filter((value): value is number => typeof value === 'number'
1647
+ && Number.isSafeInteger(value) && value >= 0)
1648
+ .reduce((sum, value) => sum + value, 0);
1649
+ try {
1650
+ await attempt.cleanup.quarantine(lease, { clean: false, reason,
1651
+ observedResidue: observedResidue > 0 ? observedResidue : null });
1652
+ } catch (error) {
1653
+ // The lease stays unfenced and the worker state unknown: record the
1654
+ // unsettled disposal (primary reason plus the quarantine cause)
1655
+ // before the caller reports the unknown worker state.
1656
+ const message = error instanceof Error ? error.message : String(error);
1657
+ recordQuarantine('pod-reuse-quarantine-failed', `${reason}; quarantine:${message}`);
1658
+ throw error;
1659
+ }
1660
+ recordQuarantine('pod-reuse-quarantined', reason, { processRemaining, credentialRemaining });
1661
+ };
1662
+ if (next.next !== 'adopt-warm' || !transport.measured || !command
1663
+ || !transport.reply || !transport.bytes) {
1664
+ const reconcileDisposition = transport.verifiedBytesForReconcile
1665
+ ? parseSelfImplementJson(new TextDecoder().decode(transport.verifiedBytesForReconcile.terminal))
1666
+ : null;
1667
+ const hostDisposition = reconcileDisposition ? (({ worktreePath: _podOnly, ...host }) => host)(reconcileDisposition) : null;
1668
+ let quarantineError: string | undefined;
1669
+ try { await retireLease(validation?.reason ?? 'response-unknown'); }
1670
+ catch (error) { debug.log('pod.reuse', 'quarantine-failed', { spaceId: input.spaceId,
1671
+ reason: error instanceof Error ? error.message : String(error) }, { level: 'error' });
1672
+ quarantineError = error instanceof Error ? error.message : String(error); }
1673
+ return { exitCode: 1, output: '',
1674
+ ...(hostDisposition ? { disposition: hostDisposition } : {}),
1675
+ error: { code: quarantineError
1676
+ || (transport.quarantineWorker && !transport.quarantineRecorded)
1677
+ ? 'si-warm-worker-state-unknown' : 'si-warm-reconcile-only',
1678
+ message: `si-v1 exec may have run; reconcile before retry (${transport.reason})${transport.quarantineError ? `; transport quarantine: ${transport.quarantineError}` : ''}${quarantineError ? `; worker-state-unknown: ${quarantineError}` : ''}` } };
1679
+ }
1680
+ const terminal = new TextDecoder().decode(transport.bytes.terminal);
1681
+ const disposition = parseSelfImplementJson(terminal);
1682
+ if (!disposition) {
1683
+ let quarantineError: string | undefined;
1684
+ try { await retireLease('terminal-disposition-unreadable'); }
1685
+ catch (error) { debug.log('pod.reuse', 'quarantine-failed', { spaceId: input.spaceId,
1686
+ reason: error instanceof Error ? error.message : String(error) }, { level: 'error' });
1687
+ quarantineError = error instanceof Error ? error.message : String(error); }
1688
+ return { exitCode: 1, output: '', error: { code: quarantineError
1689
+ ? 'si-warm-worker-state-unknown' : 'si-warm-terminal-unreadable',
1690
+ message: quarantineError ?? 'validated si-v1 terminal was not a self-implement disposition' } };
1691
+ }
1692
+ try { await attempt.adopt(command, transport.reply, transport.bytes); }
1693
+ catch (error) {
1694
+ const message = error instanceof Error ? error.message : String(error);
1695
+ let quarantineError: string | undefined;
1696
+ try { await retireLease('adopt-failed'); }
1697
+ catch (quarantineFailure) { debug.log('pod.reuse', 'quarantine-failed', { spaceId: input.spaceId,
1698
+ reason: quarantineFailure instanceof Error ? quarantineFailure.message : String(quarantineFailure) }, { level: 'error' });
1699
+ quarantineError = quarantineFailure instanceof Error ? quarantineFailure.message : String(quarantineFailure); }
1700
+ debug.log('pod.reuse', 'adopt-failed', { spaceId: input.spaceId, reason: message }, { level: 'warn' });
1701
+ return { exitCode: 1, output: '', disposition, error: { code: quarantineError
1702
+ ? 'si-warm-worker-state-unknown' : 'si-warm-reconcile-only', message: quarantineError ?? message } };
1703
+ }
1704
+ let returnOutcome: 'returned' | 'quarantined' = 'quarantined';
1705
+ let workerStateUnknown: string | undefined;
1706
+ try {
1707
+ const returned = await cleanAndReturnChildPod(lease!, { ...attempt.cleanup,
1708
+ observe: (event, data) => {
1709
+ debug.log('pod.reuse', event, { spaceId: input.spaceId, ...data },
1710
+ { level: event === 'return-decision' && (data.outcome === 'eligible' || data.outcome === 'returned') ? 'info' : 'warn' });
1711
+ attempt.cleanup.observe(event, data);
1712
+ // The lease disposition is already settled by the time this callback runs; the warm
1713
+ // ledger is an observation of it. A ledger write failure must stay an observation
1714
+ // failure — escaping here would quarantine a lease that was already returned.
1715
+ try { writeWarmLedger({ runId: command.runId, event: `pod-reuse-${event}`,
1716
+ data: { spaceId: input.spaceId, ...data } }); }
1717
+ catch (error) { debug.log('pod.reuse', 'ledger-unavailable', { spaceId: input.spaceId, runId: command.runId,
1718
+ event: `pod-reuse-${event}`, reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
1719
+ } });
1720
+ returnOutcome = returned.outcome;
1721
+ } catch (error) {
1722
+ workerStateUnknown = error instanceof Error ? error.message : String(error);
1723
+ debug.log('pod.reuse', 'return-unavailable', { spaceId: input.spaceId,
1724
+ reason: workerStateUnknown }, { level: 'error' });
1725
+ // The inner return/quarantine result is unclear: quarantine the lease explicitly,
1726
+ // and only a second quarantine failure leaves the worker state unknown.
1727
+ try {
1728
+ await attempt.quarantineUnknown(`return-quarantine-unavailable:${workerStateUnknown}`);
1729
+ try { writeWarmLedger({ runId: command!.runId, event: 'pod-reuse-quarantined',
1730
+ data: { spaceId: input.spaceId, workerId: command!.workerId, leaseId: command!.leaseId,
1731
+ reason: `return-quarantine-unavailable:${workerStateUnknown}` } }); }
1732
+ catch { /* ledger loss must not mask the quarantine outcome */ }
1733
+ // The explicit quarantine settled the disposal: the caller result must
1734
+ // account for it as quarantined instead of claiming an unknown state.
1735
+ workerStateUnknown = undefined;
1736
+ } catch (quarantineError) {
1737
+ const quarantineMessage = quarantineError instanceof Error ? quarantineError.message : String(quarantineError);
1738
+ workerStateUnknown = `return:${workerStateUnknown}; quarantine:${quarantineMessage}`;
1739
+ try { writeWarmLedger({ runId: command!.runId, event: 'pod-reuse-quarantine-failed',
1740
+ data: { spaceId: input.spaceId, workerId: command!.workerId, leaseId: command!.leaseId,
1741
+ reason: workerStateUnknown } }); }
1742
+ catch { debug.log('pod.reuse', 'ledger-unavailable', { spaceId: input.spaceId,
1743
+ event: 'pod-reuse-quarantine-failed', reason: workerStateUnknown }, { level: 'warn' }); }
1744
+ }
1745
+ }
1746
+ const log = new TextDecoder().decode(transport.bytes.log);
1747
+ // Pod checkout paths cannot be used by the host supervisor.
1748
+ const { worktreePath: _podOnly, ...hostDisposition } = disposition;
1749
+ if (workerStateUnknown) return { exitCode: 1, output: log.slice(-4096), disposition: hostDisposition,
1750
+ error: { code: 'si-warm-worker-state-unknown', message: workerStateUnknown } };
1751
+ debug.log('pod.reuse', 'child-result', { spaceId: input.spaceId, workerId: command.workerId,
1752
+ leaseId: command.leaseId, returnOutcome, stage: disposition.stage ?? null });
1753
+ try {
1754
+ return await options.siWarmHostPostprocess!({ exitCode: transport.reply.exitCode,
1755
+ output: log.slice(-4096), disposition: hostDisposition }, attempt, input);
1756
+ } catch (error) {
1757
+ const message = error instanceof Error ? error.message : String(error);
1758
+ debug.log('pod.reuse', 'host-postprocess-failed', { spaceId: input.spaceId,
1759
+ reason: message }, { level: 'error' });
1760
+ return { exitCode: 1, output: log.slice(-4096), disposition: hostDisposition,
1761
+ error: { code: 'si-warm-host-postprocess-failed', message } };
1762
+ }
1763
+ })();
1764
+ return { address: `self-impl:${input.spaceId}`, done };
1765
+ }
1443
1766
  const name = podJobName(input.spaceId);
1444
1767
  let parentGoal: string | undefined;
1445
1768
  let parentGoalUnreadable = false;
@@ -2313,7 +2636,22 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2313
2636
  debug.log('self-implement.pod', fit.fitted ? 'grok-deadline-fitted' : 'grok-deadline-kept', { job: name, requestedSeconds: jobDeadlineSeconds, deadlineSeconds: fit.deadlineSeconds, availableSeconds: fit.availableSeconds, relay: Boolean(credentialRelay), marginMs: POD_GROK_EXPIRY_MARGIN_MS });
2314
2637
  jobDeadlineSeconds = fit.deadlineSeconds;
2315
2638
  }
2316
- const job = podJobManifest({ name, namespace, fallbackChain, ...(resultMarkerLine ? { resultMarkerLine } : {}), image: jobImage, workIdentity, ...(env.ELANOUS_TASK_BOUND_PR && /^[1-9]\d*$/.test(env.ELANOUS_TASK_BOUND_PR) && Number.isSafeInteger(Number(env.ELANOUS_TASK_BOUND_PR)) ? { boundPrNumber: Number(env.ELANOUS_TASK_BOUND_PR) } : {}), ...(member?.imageRef ? { imagePullPolicy: 'IfNotPresent' as const } : {}), repoUrl, ...(options.source ? { source: options.source } : {}), ...(options.repairCommitOnly ? { repairCommitOnly: options.repairCommitOnly } : {}), ...(hostMirror ? { hostMirror } : {}), args: jobArgs, passEnv: jobPassEnv, deadlineSeconds: jobDeadlineSeconds, ...(goalDoc ? { goalDoc } : env.ELANOUS_POD_AUTHOR_ON_POD === '1' && !shard ? { authorSentence: true, ...(env.ELANOUS_POD_AUTHOR_GRADE === 'lite' || env.ELANOUS_POD_AUTHOR_GRADE === 'full' ? { authorGrade: env.ELANOUS_POD_AUTHOR_GRADE } : {}) } : {}), runId: launchRunId, ...(parentRunId ? { parentRunId } : {}), ...(jobArmEnv ? { armEnv: jobArmEnv } : {}), hostId: resolveHostId(env), skillEnvs: Object.keys(skillEnvs), memoryLimit, memoryRequest, imageCommit: jobImageCommit, ...(grok ? { grokCredential: 'grokAuth' in creds && creds.grokAuth ? 'subscription' as const : 'api_key' as const } : {}), ...(codexAccounts ? { codexAccounts } : {}), ...(hostRefresh ? { appCredential: true } : {}), execution: { key: executionKey, attempt: oomRetried ? 2 : 1 }, hostLeaseAdmitted: !!releaseAdmission, ...(roleCodexCredential ? { reviewerCodexAuth: true } : {}), ...(bedrockSpec ? { bedrock: bedrockSpec } : {}), ...(zaiSpec ? { zai: zaiSpec } : {}), ...(zaiFallbackSpec ? { zaiFallback: zaiFallbackSpec } : {}) }); // kubectl 주입(=시험)이면 docker 를 부르지 않는다
2639
+ // POD-LAUNCH-PROVENANCE — fail-closed: a si-task Job without its ★ identity is never applied.
2640
+ let provenance: PodProvenanceMetadata;
2641
+ try {
2642
+ let version: string | undefined;
2643
+ try { version = packageVersion(); } catch { version = undefined; }
2644
+ provenance = podProvenanceMetadata(siTaskPodProvenance({ env, runId: launchRunId, ...(parentRunId ? { parentRunId } : {}), workIdentity,
2645
+ requestedAt: new Date((options.now ?? Date.now)()).toISOString(), feature: input.feature, launchHost: resolveHostId(env),
2646
+ commit: seedSource.kind === 'commit' ? seedSource.sha : seedCommit ?? jobImageCommit, ...(version ? { version } : {}),
2647
+ ...(memoryRequest ? { memReq: memoryRequest } : {}) }));
2648
+ } catch (error) {
2649
+ const message = error instanceof Error ? error.message : String(error);
2650
+ debug.log('pod.provenance', 'si-task-refused', { job: name, reason: message }, { level: 'warn' });
2651
+ cleanupSecret();
2652
+ return { exitCode: 1, output: '', error: { code: 'pod-provenance', message } };
2653
+ }
2654
+ const job = podJobManifest({ provenance, name, namespace, fallbackChain, ...(resultMarkerLine ? { resultMarkerLine } : {}), image: jobImage, workIdentity, ...(env.ELANOUS_TASK_BOUND_PR && /^[1-9]\d*$/.test(env.ELANOUS_TASK_BOUND_PR) && Number.isSafeInteger(Number(env.ELANOUS_TASK_BOUND_PR)) ? { boundPrNumber: Number(env.ELANOUS_TASK_BOUND_PR) } : {}), ...(member?.imageRef ? { imagePullPolicy: 'IfNotPresent' as const } : {}), repoUrl, ...(options.source ? { source: options.source } : {}), ...(options.repairCommitOnly ? { repairCommitOnly: options.repairCommitOnly } : {}), ...(hostMirror ? { hostMirror } : {}), args: jobArgs, passEnv: jobPassEnv, deadlineSeconds: jobDeadlineSeconds, ...(goalDoc ? { goalDoc } : env.ELANOUS_POD_AUTHOR_ON_POD === '1' && !shard ? { authorSentence: true, ...(env.ELANOUS_POD_AUTHOR_GRADE === 'lite' || env.ELANOUS_POD_AUTHOR_GRADE === 'full' ? { authorGrade: env.ELANOUS_POD_AUTHOR_GRADE } : {}) } : {}), runId: launchRunId, ...(parentRunId ? { parentRunId } : {}), ...(jobArmEnv ? { armEnv: jobArmEnv } : {}), hostId: resolveHostId(env), skillEnvs: Object.keys(skillEnvs), memoryLimit, memoryRequest, imageCommit: jobImageCommit, ...(grok ? { grokCredential: 'grokAuth' in creds && creds.grokAuth ? 'subscription' as const : 'api_key' as const } : {}), ...(codexAccounts ? { codexAccounts } : {}), ...(hostRefresh ? { appCredential: true } : {}), execution: { key: executionKey, attempt: oomRetried ? 2 : 1 }, hostLeaseAdmitted: !!releaseAdmission, ...(roleCodexCredential ? { reviewerCodexAuth: true } : {}), ...(bedrockSpec ? { bedrock: bedrockSpec } : {}), ...(zaiSpec ? { zai: zaiSpec } : {}), ...(zaiFallbackSpec ? { zaiFallback: zaiFallbackSpec } : {}) }); // kubectl 주입(=시험)이면 docker 를 부르지 않는다
2317
2655
  const carriedBranch = goalDoc ? 'goal-doc' as const : env.ELANOUS_POD_AUTHOR_ON_POD === '1' && !shard ? 'author' as const : undefined;
2318
2656
  const carriedChildLlm = carriedBranch ? podDelegatedChildLlm(jobArgs) : undefined;
2319
2657
  jobApplyStartedAt = Date.now();
@@ -2322,6 +2660,11 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2322
2660
  if (a.status !== 0) { cleanupSecret(); return { exitCode: 1, output: a.stderr, error: { code: 'pod-apply', message: a.stderr.trim() } }; }
2323
2661
  releaseAdmission?.applied?.(name, context, namespace);
2324
2662
  const imageFacts = { job: name, childRunId: liveChildRunId, image: jobImage, imageCommit: jobImageCommit, context };
2663
+ // POD-LAUNCH-PROVENANCE — append-only «started» row: who · why · when, on the parent's existing run ledger.
2664
+ const startedRow = { job: name, run: launchRunId, attempt: oomRetried ? 2 : 1, provenance: provenanceRowFromAnnotations(provenance.annotations) };
2665
+ try { appendRunLedgerEntry({ runId: ledgerRunId, event: POD_LAUNCH_STARTED_EVENT, timestamp: new Date((options.now ?? Date.now)()).toISOString(), data: startedRow }, ledgerDir); }
2666
+ catch (error) { debug.log('pod.provenance', 'history-unavailable', { job: name, row: 'started', reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
2667
+ debug.log('pod.provenance', 'job-started', startedRow);
2325
2668
  try { appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-job-image', data: imageFacts }, ledgerDir); }
2326
2669
  catch (error) { debug.log('self-implement.pod', 'job-image-ledger-unavailable', { job: name, reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
2327
2670
  debug.log('self-implement.pod', 'job-image', imageFacts);
@@ -2396,6 +2739,9 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2396
2739
  let failedReason = '';
2397
2740
  let containerReason: string | null = null;
2398
2741
  let containerExitCode: number | null = null;
2742
+ // JOB-FAILURE-TERMINATION-CAPTURE — this Job's Kubernetes facts, read once at the failure verdict (before GC).
2743
+ // Observation only: failedReason · containerReason · containerExitCode keep driving the classification.
2744
+ let podTermination: PodTermination | null = null;
2399
2745
  // METER-POD-ROLLUP-GAP — abort 때 Job 삭제 «전»에 거둔 로그 사본(삭제 뒤엔 PARTIAL 줄도 못 읽는다).
2400
2746
  let abortLogs = '';
2401
2747
  // ⭐ 런 «도중» 원장 증분 회수 — 호스트 슈퍼바이저가 Pod 걸음을 실시간으로 본다(🅣 요청 · 힐 루프 runtime 성형의 전제).
@@ -2447,10 +2793,17 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2447
2793
  if (/Failed|FailureTarget/.test(types)) {
2448
2794
  releaseAdmission?.observed?.();
2449
2795
  state = 'failed';
2450
- const reason = kubectl(['-n', namespace, 'get', 'job', name, '-o', 'jsonpath={.status.conditions[?(@.type=="Failed")].reason}']);
2451
- failedReason = reason.status === 0 ? reason.stdout.trim() : '';
2796
+ // One Job read serves both: column one is the classification reason, all three the capture (no re-read a GC could empty).
2797
+ let jobRead: { status: number | null; stdout: string } | null = null;
2798
+ let jobReadError: unknown;
2799
+ try { jobRead = kubectl(['-n', namespace, 'get', 'job', name, '-o', `jsonpath=${POD_TERMINATION_JOB_JSONPATH}`]); }
2800
+ catch (error) { jobReadError = error; }
2801
+ failedReason = jobRead?.status === 0 ? (jobRead.stdout.split('\t')[0] ?? '').trim() : '';
2802
+ // One Pods read serves both: its first three columns are the classification layout, the rest the termination capture.
2803
+ let podsRead: { status: number | null; stdout: string } | null = null;
2452
2804
  try {
2453
- const pods = kubectl(['-n', namespace, 'get', 'pods', '-l', `job-name=${name}`, '-o', 'jsonpath={range .items[*]}{.metadata.creationTimestamp}{"\\t"}{range .status.containerStatuses[?(@.name=="child")]}{.state.terminated.reason}{"\\t"}{.state.terminated.exitCode}{end}{"\\n"}{end}']);
2805
+ const pods = kubectl(['-n', namespace, 'get', 'pods', '-l', `job-name=${name}`, '-o', `jsonpath=${POD_TERMINATION_PODS_JSONPATH}`]);
2806
+ podsRead = pods;
2454
2807
  if (pods.status === 0 && pods.stdout) {
2455
2808
  const rows = pods.stdout.trimEnd().split('\n').map((line) => line.split('\t'));
2456
2809
  const latest = rows.filter(([created]) => created && !Number.isNaN(Date.parse(created)))
@@ -2463,6 +2816,14 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2463
2816
  }
2464
2817
  } catch { /* Pod 가 사라졌거나 조회 불가 — 종료 사유는 미상. */ }
2465
2818
  debug.log('self-implement.pod', 'container-terminated', { job: name, container: 'child', reason: containerReason, exitCode: containerExitCode, jobReason: failedReason || null, memoryLimit });
2819
+ podTermination = readPodTermination({ kubectl, namespace, job: name, path: 'job-failed-condition', jobRead, podsRead, jobUid: lifecycleJobUid });
2820
+ if (jobReadError !== undefined) {
2821
+ // Today's outcome stays (the throw ends the spawn as pod-error); the capture is in the ledger first.
2822
+ try { appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-child-evidence', data: { childEvidence: null, childRunId: liveChildRunId, job: name, podTermination } }, ledgerDir); }
2823
+ catch (error) { debug.log('self-implement.pod', 'child-evidence-write-failed', { job: name, childRunId: liveChildRunId, reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
2824
+ debug.log('self-implement.pod', 'pod-termination-captured', { job: name, podTermination, jobReadThrew: true }, { level: 'warn' });
2825
+ throw jobReadError;
2826
+ }
2466
2827
  break;
2467
2828
  }
2468
2829
  // TA-POD-WARMBOOT-PARITY: the condition is not there yet — the child may already be done (k3d condition lag).
@@ -2474,6 +2835,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2474
2835
  state = seen === 0 ? 'complete' : 'failed';
2475
2836
  // The child's own rc (the Pod's terminated state may lag like the condition) — exit-code paths read it as before.
2476
2837
  if (seen !== 0) containerExitCode = seen;
2838
+ if (seen !== 0) podTermination = readPodTermination({ kubectl, namespace, job: name, path: 'result-marker', jobUid: lifecycleJobUid });
2477
2839
  debug.log('self-implement.pod', 'result-marker-early', { job: name, waitedMs: Date.now() - waitStartedAt, rc: seen });
2478
2840
  break;
2479
2841
  }
@@ -2745,7 +3107,17 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2745
3107
  if (noResultDiagnostic && !noResultDiagnostic.includes('stage=unknown')) {
2746
3108
  debug.log('self-implement.pod', 'no-result-ledger-diagnostic', { job: name, childRunId: liveChildRunId, diagnostic: noResultDiagnostic }, { compact: { stringMax: 500 } });
2747
3109
  }
3110
+ // POD-LAUNCH-PROVENANCE — append-only «finished» row paired with its started row on job·run.
3111
+ // Keyed on launchRunId like the started row; a reattached Job's inherited child run rides along as childRun.
3112
+ // exitCode stays null when the container's code was not read (never filled in as 0).
3113
+ const finishedRow = { job: name, run: launchRunId, ...(liveChildRunId !== launchRunId ? { childRun: liveChildRunId } : {}),
3114
+ attempt: oomRetried ? 2 : 1, phase: state, exitCode: containerExitCode,
3115
+ reason: failedReason || containerReason || (state === 'complete' ? 'complete' : 'unknown') };
3116
+ try { appendRunLedgerEntry({ runId: ledgerRunId, event: POD_LAUNCH_FINISHED_EVENT, timestamp: new Date((options.now ?? Date.now)()).toISOString(), data: finishedRow }, ledgerDir); }
3117
+ catch (error) { debug.log('pod.provenance', 'history-unavailable', { job: name, row: 'finished', reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
3118
+ debug.log('pod.provenance', 'job-finished', finishedRow);
2748
3119
  debug.log('self-implement.pod', 'job-finished', { job: name, ...(member ? { context: member.context } : {}), state, containerReason, stage: disposition?.stage ?? null, prUrl: disposition?.prUrl ?? null, childRunId: liveChildRunId, ledgerCompleteness,
3120
+ ...(podTermination ? { podTermination } : {}),
2749
3121
  ...(state === 'failed' && !oomKilled && failedReason !== 'DeadlineExceeded'
2750
3122
  ? { ...(childFailure ? { childStage: childFailure.stage } : disposition?.stage ? { childStage: disposition.stage } : {}),
2751
3123
  // POD-NORESULT: a parsed result row without error text is not a missing result line (UX 10-07 01:01: 28 of 28 exit-2 Jobs printed one).
@@ -2838,7 +3210,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2838
3210
  // Every terminal attempt writes a marker, including one with no parseable child facts.
2839
3211
  // The next attempt must never inherit an earlier Pod's classification.
2840
3212
  const childEvidence = noResultLogEvidence ?? disposition?.childEvidence ?? null;
2841
- try { appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-child-evidence', data: { childEvidence, childRunId: liveChildRunId, job: name } }, ledgerDir); }
3213
+ try { appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-child-evidence', data: { childEvidence, childRunId: liveChildRunId, job: name, ...(podTermination ? { podTermination } : {}) } }, ledgerDir); }
2842
3214
  catch (error) { debug.log('self-implement.pod', 'child-evidence-write-failed', { job: name, childRunId: liveChildRunId, reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
2843
3215
  }
2844
3216
  let prLookup: OpenPrByBranch | undefined;
@@ -2888,11 +3260,14 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2888
3260
  const finishedDisposition = deadlineExceeded && disposition
2889
3261
  ? { ...disposition, failureClassification: 'run-deadline-exceeded' as const }
2890
3262
  : disposition;
2891
- const podExitCode = state === 'complete' && disposition?.stage !== 'host-regate-failed' && disposition?.ok !== false ? 0 : 1;
3263
+ // A gate environment deficit can exit the child with 1 while still yielding a
3264
+ // verified repair bundle. The host rejudges the new PR head after CAS apply.
3265
+ const podExitCode = repairPodExitCode({ state, repairCommitOnly: !!options.repairCommitOnly,
3266
+ repairArtifactReady, disposition });
2892
3267
  // SCHED-CONTRACT: a failed child must say why outside the Pod, not «no error diagnostic».
2893
3268
  const rawPodReason = podExitCode === 1 ? extractPodFailureReason({ logs, logTailReason, containerReason, jobReason: failedReason || undefined, deadlineSeconds, result: disposition ? { stage: disposition.stage, prUrl: disposition.prUrl ?? null, prNumber: disposition.prNumber ?? null } : null }) : undefined;
2894
3269
  const podReason = rawPodReason
2895
- ? noResultLogEvidence ? boundedPodLogText(rawPodReason, POD_NO_RESULT_LOG_REASON_MAX_CHARS) : rawPodReason
3270
+ ? redactSecretText(noResultLogEvidence ? boundedPodLogText(rawPodReason, POD_NO_RESULT_LOG_REASON_MAX_CHARS) : rawPodReason)
2896
3271
  : undefined;
2897
3272
  if (podReason) debug.log('self-implement.pod', 'failure-reason', { job: name, reason: podReason });
2898
3273
  if (podExitCode === 1) {
@@ -3016,6 +3391,10 @@ function podPrOpenFailure(ledger: Record<string, unknown> | undefined | null, te
3016
3391
  }
3017
3392
 
3018
3393
  function lastPodChildFailure(logs: string): { stage: string; error: string; rawError: string } | null {
3394
+ // Keep canonical duplicate-cap attribution while preserving the raw terminal error
3395
+ // used by PR-open failure diagnosis below.
3396
+ const attribution = podChildFailureAttribution(logs);
3397
+ if (!attribution) return null;
3019
3398
  for (const line of logs.split('\n').reverse()) {
3020
3399
  if (!line.trimStart().startsWith('{')) continue;
3021
3400
  let result: unknown;
@@ -3025,10 +3404,8 @@ function lastPodChildFailure(logs: string): { stage: string; error: string; rawE
3025
3404
  const terminal = podTerminalRow(row);
3026
3405
  if (!terminal) continue;
3027
3406
  if (terminal.ok !== false || typeof terminal.error !== 'string') return null;
3028
- const lines = redactSecretText(terminal.error).replace(/\/home\/[^/\s]+\//g, '~/').split(/\r\n|\n|\r/);
3029
- const first = lines[0]!.slice(0, 240);
3030
- const last = lines.at(-1)!.slice(0, 240);
3031
- return { stage: terminal.stage, error: first === last ? first : `${first}\n${last}`, rawError: terminal.error };
3407
+ if (terminal.stage !== attribution.stage) return null;
3408
+ return { ...attribution, error: redactSecretText(attribution.error), rawError: terminal.error };
3032
3409
  }
3033
3410
  return null;
3034
3411
  }