elanous 0.2.40 → 0.2.42

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 (685) hide show
  1. package/README.md +7 -7
  2. package/apps/pwa/out/404/index.html +1 -1
  3. package/apps/pwa/out/404.html +1 -1
  4. package/apps/pwa/out/_next/static/{HjeK7zONHfR7op1hKXp4k → X1ucLw10Cds_h614NoEnh}/_buildManifest.js +1 -1
  5. package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/{4769.9fd582071301f382.js → 1063.2fb8a9dc55c731f2.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +36 -0
  8. package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/{470.51a72a2348306455.js → 1262.e804feb8fd1acb8c.js} +2 -2
  10. package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/{7219-15bdd9a80661af8e.js → 1455-530ca16c7e71baff.js} +1 -1
  13. package/apps/pwa/out/_next/static/chunks/{1281.d81877e35b9068f4.js → 1487.2f67b79444062da6.js} +1 -1
  14. package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +32 -0
  16. package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +286 -0
  22. package/apps/pwa/out/_next/static/chunks/2160.a097e7b138ae1c55.js +23 -0
  23. package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +34 -0
  26. package/apps/pwa/out/_next/static/chunks/{1350.59f40e39e02d91b1.js → 2456.b6de0e1c05f28843.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2690.0521c738b7749931.js +115 -0
  32. package/apps/pwa/out/_next/static/chunks/{5436.fdf6fa8ae3e9588d.js → 2974.595d1e29d040cb6a.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/{5383.bdfa5d886e39a826.js → 3207.a756c95e9ec8c3c8.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +93 -0
  35. package/apps/pwa/out/_next/static/chunks/{2177.df8547f9d7215c4e.js → 3347.f846266b5e5f3ede.js} +3 -3
  36. package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +41 -0
  37. package/apps/pwa/out/_next/static/chunks/{9184.45afbf44fec87574.js → 3482.a9ae9d2ad6a5bd97.js} +1 -1
  38. package/apps/pwa/out/_next/static/chunks/3507.97e1977bc4d5fb0a.js +2 -0
  39. package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +24 -0
  41. package/apps/pwa/out/_next/static/chunks/{8099.1cccf31c1baa7e1c.js → 3741.9cf76acaa2ee5298.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{4864a2ca.1c1c280a7772c5e5.js → 3d0154af.5331fec737ffe8c3.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4043.6b91203436c9c86b.js +309 -0
  48. package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +77 -0
  49. package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/{3330.7443183b7e6fdbdf.js → 4276.336d76d858fcdf1b.js} +1 -1
  51. package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +148 -0
  55. package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +74 -0
  56. package/apps/pwa/out/_next/static/chunks/{3b355b3d.6f73c98bf6f9c749.js → 50061469.0326382241ef3b2d.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +149 -0
  58. package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +27 -0
  60. package/apps/pwa/out/_next/static/chunks/{8d173e38.18a2f7b4e1848bdb.js → 53c73f84.373b6160adfa89a4.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{1537-6bb97b5214928ea9.js → 5431-72a1dbde59400691.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/5885.0a3e52c8faccec98.js +287 -0
  70. package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/{261.0d471e8aded799f3.js → 6131.348b7d6bdcd267ce.js} +3 -3
  73. package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +90 -0
  74. package/apps/pwa/out/_next/static/chunks/{9175.2de5209a5ce6f68a.js → 6377.bc7df239edbff244.js} +1 -1
  75. package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{2226.2cf61ec781827219.js → 6632.0eac1c554f8f2ef3.js} +2 -2
  78. package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +104 -0
  82. package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +94 -0
  83. package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7279-c199ea83f34338fa.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/{b84cad00.594027ebe0531fe2.js → 73d2eb0e.4966ad55293c801a.js} +3 -3
  90. package/apps/pwa/out/_next/static/chunks/{6257.c0037b8949239f5e.js → 7411.9b4b8b747dc7b802.js} +2 -2
  91. package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +24 -0
  92. package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/{9189505a.980427ac048c8c60.js → 7a98bc80.fa935989e829f9c2.js} +1 -1
  98. package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/8138.6c10b2a356d52fca.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/{2566.beaffc3a5e1fcd2e.js → 8262.ddc03e06b733f184.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +8 -0
  103. package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +79 -0
  105. package/apps/pwa/out/_next/static/chunks/{8272-025653884f9645d2.js → 8546-6f03f8ea34dd61d9.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/{6051-0ae955eedb10adb9.js → 8673-bab689a55f7e13b9.js} +3 -3
  107. package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{4351.0f37a6db2b34d50b.js → 9249.976f1e69a9d80754.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9353-12bfff0c130104cf.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9415.69e4a21c60c7d2db.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{6749.0744ce6eb08d40e9.js → 9427.96aa912ddb5801e0.js} +16 -16
  119. package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{7611.85f045bf232053ac.js → 9633.ce5bddc56784da72.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/{3746-f80a78f220bf37b5.js → 9656-374232558fd528d0.js} +1 -1
  123. package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +62 -0
  124. package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/9a852a62-6192a6ea9346ced3.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/live-run/{page-83d27757e2b8060a.js → page-0e3d7b9421b79dac.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/term/{page-139d722de1dcd6c1.js → page-bf067887b3307423.js} +1 -1
  170. package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{409c787b.e48c5bec8ec10456.js → b450776b.3db34d8d965f82d3.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/{ca3702f8.2913182e73889fa2.js → e8543907.5b040a5f22a0b0e5.js} +7 -7
  179. package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +1 -0
  185. package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
  186. package/apps/pwa/out/approvals/index.html +1 -1
  187. package/apps/pwa/out/approvals/index.txt +22 -22
  188. package/apps/pwa/out/autopilot/index.html +1 -1
  189. package/apps/pwa/out/autopilot/index.txt +22 -22
  190. package/apps/pwa/out/board/index.html +1 -1
  191. package/apps/pwa/out/board/index.txt +22 -22
  192. package/apps/pwa/out/botlab/index.html +1 -1
  193. package/apps/pwa/out/botlab/index.txt +21 -21
  194. package/apps/pwa/out/bots/index.html +1 -1
  195. package/apps/pwa/out/bots/index.txt +21 -21
  196. package/apps/pwa/out/ceo/index.html +1 -1
  197. package/apps/pwa/out/ceo/index.txt +22 -22
  198. package/apps/pwa/out/chat/index.html +1 -1
  199. package/apps/pwa/out/chat/index.txt +21 -21
  200. package/apps/pwa/out/consult/index.html +1 -1
  201. package/apps/pwa/out/consult/index.txt +22 -22
  202. package/apps/pwa/out/control/index.html +1 -1
  203. package/apps/pwa/out/control/index.txt +22 -22
  204. package/apps/pwa/out/decisions/index.html +1 -1
  205. package/apps/pwa/out/decisions/index.txt +21 -21
  206. package/apps/pwa/out/design-check/index.html +1 -1
  207. package/apps/pwa/out/design-check/index.txt +22 -22
  208. package/apps/pwa/out/editor/index.html +1 -1
  209. package/apps/pwa/out/editor/index.txt +23 -24
  210. package/apps/pwa/out/exec/index.html +1 -1
  211. package/apps/pwa/out/exec/index.txt +22 -22
  212. package/apps/pwa/out/field/index.html +1 -1
  213. package/apps/pwa/out/field/index.txt +22 -22
  214. package/apps/pwa/out/healthz +1 -1
  215. package/apps/pwa/out/index.html +1 -1
  216. package/apps/pwa/out/index.txt +21 -21
  217. package/apps/pwa/out/inside/index.html +1 -1
  218. package/apps/pwa/out/inside/index.txt +22 -22
  219. package/apps/pwa/out/intake/index.html +1 -1
  220. package/apps/pwa/out/intake/index.txt +22 -22
  221. package/apps/pwa/out/live/index.html +1 -1
  222. package/apps/pwa/out/live/index.txt +23 -24
  223. package/apps/pwa/out/live-run/index.html +1 -1
  224. package/apps/pwa/out/live-run/index.txt +23 -24
  225. package/apps/pwa/out/loops/index.html +1 -1
  226. package/apps/pwa/out/loops/index.txt +21 -21
  227. package/apps/pwa/out/market/index.html +1 -1
  228. package/apps/pwa/out/market/index.txt +21 -21
  229. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  230. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  231. package/apps/pwa/out/morning/index.html +1 -1
  232. package/apps/pwa/out/morning/index.txt +22 -22
  233. package/apps/pwa/out/observatory/index.html +1 -1
  234. package/apps/pwa/out/observatory/index.txt +22 -22
  235. package/apps/pwa/out/ops/checklist/index.html +1 -1
  236. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  237. package/apps/pwa/out/ops/release/index.html +1 -1
  238. package/apps/pwa/out/ops/release/index.txt +21 -21
  239. package/apps/pwa/out/ops/seats/index.html +1 -1
  240. package/apps/pwa/out/ops/seats/index.txt +21 -21
  241. package/apps/pwa/out/outputs/index.html +1 -1
  242. package/apps/pwa/out/outputs/index.txt +21 -21
  243. package/apps/pwa/out/reflection/index.html +1 -1
  244. package/apps/pwa/out/reflection/index.txt +22 -22
  245. package/apps/pwa/out/scheduler/index.html +1 -1
  246. package/apps/pwa/out/scheduler/index.txt +22 -22
  247. package/apps/pwa/out/sessions/index.html +1 -1
  248. package/apps/pwa/out/sessions/index.txt +21 -21
  249. package/apps/pwa/out/settings/devices/index.html +1 -1
  250. package/apps/pwa/out/settings/devices/index.txt +22 -22
  251. package/apps/pwa/out/settings/index.html +1 -1
  252. package/apps/pwa/out/settings/index.txt +22 -22
  253. package/apps/pwa/out/setup/done/index.html +1 -1
  254. package/apps/pwa/out/setup/done/index.txt +22 -22
  255. package/apps/pwa/out/setup/index.html +1 -1
  256. package/apps/pwa/out/setup/index.txt +22 -22
  257. package/apps/pwa/out/share/index.html +1 -1
  258. package/apps/pwa/out/share/index.txt +22 -22
  259. package/apps/pwa/out/showroom/index.html +1 -1
  260. package/apps/pwa/out/showroom/index.txt +21 -21
  261. package/apps/pwa/out/tasks/index.html +1 -1
  262. package/apps/pwa/out/tasks/index.txt +22 -22
  263. package/apps/pwa/out/term/index.html +1 -1
  264. package/apps/pwa/out/term/index.txt +22 -22
  265. package/apps/pwa/out/today/index.html +1 -1
  266. package/apps/pwa/out/today/index.txt +22 -22
  267. package/apps/pwa/out/trace/index.html +1 -1
  268. package/apps/pwa/out/trace/index.txt +22 -22
  269. package/apps/pwa/out/vault/index.html +1 -1
  270. package/apps/pwa/out/vault/index.txt +22 -22
  271. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  272. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  273. package/apps/pwa/out/workflows/index.html +1 -1
  274. package/apps/pwa/out/workflows/index.txt +22 -22
  275. package/apps/pwa/out/workspace/index.html +1 -1
  276. package/apps/pwa/out/workspace/index.txt +22 -22
  277. package/apps/pwa/out/worktrees/index.html +1 -1
  278. package/apps/pwa/out/worktrees/index.txt +22 -22
  279. package/bin/elanous.mjs +6 -1
  280. package/catalog/models/openai/gpt-6.1-sol.yaml +16 -0
  281. package/catalog/models/openai/gpt-6.1-terra.yaml +16 -0
  282. package/docs/goal-context/04-mock-scenarios.md +13 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/demo/persona-teacher/lesson-pack.yaml +16 -0
  285. package/graphs/demo/persona-teacher/recipes.yaml +17 -0
  286. package/graphs/demo/persona-teacher/weekly-lesson.yaml +36 -0
  287. package/graphs/heal/heal-loop.yaml +1 -0
  288. package/graphs/overlays/stop-heal-ladder.yaml +136 -2
  289. package/graphs/release/release-loop.yaml +3 -1
  290. package/graphs/units/gate/gate.yaml +20 -0
  291. package/graphs/units/git/git.yaml +26 -0
  292. package/graphs/units/implement/implement.yaml +19 -0
  293. package/graphs/units/landing/landing.yaml +18 -0
  294. package/graphs/units/review/review.yaml +20 -0
  295. package/graphs/units/verbs/recipes.yaml +13 -10
  296. package/graphs/units/verbs/research.yaml +20 -0
  297. package/graphs/work/research-report.yaml +21 -3
  298. package/package.json +1 -1
  299. package/scripts/disk-steward.ts +46 -0
  300. package/scripts/fleet/node-setup.sh +50 -0
  301. package/scripts/graph-units/verbs/research.ts +55 -0
  302. package/scripts/heal/run-role.ts +99 -5
  303. package/scripts/land-global-checks.ts +6 -1
  304. package/scripts/lib/decompose-ab.ts +1 -0
  305. package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
  306. package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
  307. package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
  308. package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
  309. package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
  310. package/scripts/lib/tui-regress-checks.ts +33 -13
  311. package/scripts/llm-cost-ledger.ts +179 -8
  312. package/scripts/measure-nl-routing-corpus.ts +10 -2
  313. package/scripts/persona-teacher/weekly-lesson-node.ts +172 -0
  314. package/scripts/public-copy-lint.ts +163 -19
  315. package/scripts/ratchets/train-side-invariants.sh +0 -1
  316. package/scripts/release-loop/gate-autoheal.ts +117 -0
  317. package/scripts/release-loop/gate-baseline-receipt.ts +55 -10
  318. package/scripts/release-loop/gate-diff.ts +22 -3
  319. package/scripts/release-loop/gate-image-pin.ts +81 -0
  320. package/scripts/release-loop/gate-node-sim.ts +207 -0
  321. package/scripts/release-loop/gate-node.ts +489 -62
  322. package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
  323. package/scripts/release-loop/gate-radius-live.ts +97 -13
  324. package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
  325. package/scripts/release-loop/gate-shard-load-flaky.ts +256 -0
  326. package/scripts/release-loop/gate-train-receipts.ts +122 -0
  327. package/scripts/release-loop/gate-triage-node.ts +70 -10
  328. package/scripts/release-loop/resume-release.ts +330 -23
  329. package/scripts/release-loop/traffic-node.ts +6 -3
  330. package/scripts/release-loop/unattended-release.ts +4 -2
  331. package/scripts/shadow-authoring-probe.ts +20 -0
  332. package/scripts/ux-sim.ts +37 -3
  333. package/scripts/warm-pool-provider-config.ts +263 -0
  334. package/skills/omni-crawl/SKILL.md +5 -2
  335. package/skills/omni-crawl/scripts/main.ts +84 -23
  336. package/src/acp/core-turn-bridge.ts +99 -4
  337. package/src/agent/registry.ts +2 -0
  338. package/src/agent/task-notification.ts +25 -5
  339. package/src/agent/types.ts +6 -0
  340. package/src/agent-mission/mission-cli.ts +24 -0
  341. package/src/agent-mission/mission-out.ts +595 -0
  342. package/src/agent-mission/tool-install.ts +88 -2
  343. package/src/agent-substrate/context-strategy.ts +4 -4
  344. package/src/agent-substrate/self-review-cli.ts +267 -40
  345. package/src/auto-research/research-turn.ts +133 -51
  346. package/src/autopilot/discovery/wiki-claim-proposer.ts +22 -1
  347. package/src/autopilot/pr-manager.ts +38 -7
  348. package/src/autopilot/pty-control-loop.ts +2 -0
  349. package/src/boot/daemon-tools/self-implement.ts +46 -9
  350. package/src/budget/shadow-arms.ts +52 -0
  351. package/src/capture/tui-self-report.ts +22 -6
  352. package/src/chat/index.ts +1 -1
  353. package/src/chat/pickers/state.ts +7 -1
  354. package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
  355. package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
  356. package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
  357. package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
  358. package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
  359. package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
  360. package/src/cli/log-event-names.ts +5 -0
  361. package/src/cli/mcp-login.ts +8 -18
  362. package/src/cli/msg-cli.ts +57 -1
  363. package/src/cli/pr-land-heavy-remote.ts +47 -9
  364. package/src/cli/pr-land-overlap-evidence.ts +100 -1
  365. package/src/cli/pr-land-pod-shadow-job.ts +60 -0
  366. package/src/cli/release-checklist-read-cli.ts +20 -10
  367. package/src/cli/release-cli.ts +27 -1
  368. package/src/cli/research-cli.ts +4 -5
  369. package/src/cli/sim-cli.ts +7 -1
  370. package/src/cli/tasks-cli.ts +12 -4
  371. package/src/codex/models.ts +30 -15
  372. package/src/compact/auto.ts +8 -1
  373. package/src/control-plane/ledger.ts +52 -2
  374. package/src/control-plane/server.ts +16 -2
  375. package/src/core-turn/run-core-turn.ts +313 -89
  376. package/src/core-turn/run-goal-loop.ts +106 -2
  377. package/src/core-turn/types.ts +2 -0
  378. package/src/dashboard/acp-boot.ts +72 -3
  379. package/src/dashboard/classic-sidetab-mission-job.ts +58 -0
  380. package/src/dashboard/classic-sidetab-mission.ts +185 -0
  381. package/src/dashboard/index.ts +155 -15
  382. package/src/dashboard/input/agent-wake.ts +23 -1
  383. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +9 -0
  384. package/src/dashboard/mission-cli-consumer.ts +153 -0
  385. package/src/dashboard/seat-boot-preamble.ts +171 -1
  386. package/src/dashboard/side-basic-runtime.ts +54 -1
  387. package/src/dashboard/sidetab-runtime.ts +90 -1
  388. package/src/dashboard/skill-catalog-preamble.ts +101 -0
  389. package/src/dashboard/skill-detection-runtime.ts +55 -15
  390. package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
  391. package/src/dashboard/turn-preamble.ts +65 -16
  392. package/src/dashboard/turn-prompt-runtime.ts +4 -2
  393. package/src/disk-steward/judge.ts +73 -0
  394. package/src/disk-steward/ledger.ts +122 -0
  395. package/src/disk-steward/steward.ts +373 -0
  396. package/src/domains/guardian-tick.ts +191 -2
  397. package/src/graph-runner/graph-cli.ts +44 -7
  398. package/src/graph-runner/graph-tick.ts +10 -2
  399. package/src/graph-runner/in-process-registry.ts +37 -0
  400. package/src/graph-runner/runner.ts +34 -4
  401. package/src/grok/agent-search.ts +14 -4
  402. package/src/grok/credential.ts +28 -11
  403. package/src/grounding/ref-index.ts +19 -0
  404. package/src/grounding/sources-cli.ts +9 -1
  405. package/src/harness/harness-cli-command.ts +267 -14
  406. package/src/harness/harness-incidents.ts +312 -7
  407. package/src/harness/harness-pod-dispatch.ts +81 -15
  408. package/src/harness/harness-space.ts +15 -1
  409. package/src/harness/harness-stop.ts +155 -11
  410. package/src/harness/progress-worker-entry.ts +59 -0
  411. package/src/harness/progress-worker-runtime.ts +11 -0
  412. package/src/index.ts +52 -7
  413. package/src/instance/dev-project.ts +25 -0
  414. package/src/instance/spawn-elanous.ts +6 -4
  415. package/src/intelligence-map/model-alias.ts +6 -5
  416. package/src/intelligence-map/model-catalog.ts +59 -2
  417. package/src/llm/model-defaults.ts +4 -4
  418. package/src/llm.ts +208 -19
  419. package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
  420. package/src/loops/orchestrator/tick.ts +61 -0
  421. package/src/maturity/feature-maturity.ts +1 -1
  422. package/src/mcp/mcp-oauth.ts +3 -1
  423. package/src/model-tier/llm-tier-map.ts +9 -9
  424. package/src/model-tier/turn-tier.ts +1 -1
  425. package/src/msg/msg-mirror-github.ts +80 -0
  426. package/src/msg/msg-mirror-policy.ts +61 -0
  427. package/src/msg/msg-mirror-runner.ts +219 -0
  428. package/src/msg/msg-mirror-state.ts +33 -0
  429. package/src/msg/msg-store.ts +11 -0
  430. package/src/native-tool-catalog.ts +2 -2
  431. package/src/nexus/api/harness-traversal.ts +11 -0
  432. package/src/output-truncation.ts +41 -12
  433. package/src/pr-tool/census.ts +3 -2
  434. package/src/project/project-store.ts +48 -1
  435. package/src/pty-shell/tui-run-state.ts +188 -2
  436. package/src/release-loop/checklist-target-path-hint.ts +13 -0
  437. package/src/release-loop/checklist.ts +9 -1
  438. package/src/release-loop/gate-host-reservation.ts +144 -0
  439. package/src/release-loop/release-schedule.ts +90 -1
  440. package/src/repl/index.ts +43 -2
  441. package/src/research/axis-fanout.ts +121 -16
  442. package/src/research/bloom-exemplars.ts +137 -0
  443. package/src/research/gap-followup.ts +13 -1
  444. package/src/research/plugin-discovery.ts +36 -14
  445. package/src/research-bridge/invoke.ts +22 -5
  446. package/src/research-bridge/types.ts +2 -0
  447. package/src/self-dev/ask-launch-flow.ts +39 -25
  448. package/src/self-dev/decompose.ts +119 -5
  449. package/src/self-dev/dev-cli.ts +17 -17
  450. package/src/self-dev/graph-front-nodes.ts +23 -0
  451. package/src/self-dev/launch-preflight-text.ts +5 -6
  452. package/src/self-dev/launch-preflight.ts +9 -4
  453. package/src/self-dev/orchestrate.ts +27 -2
  454. package/src/self-dev/review-provider-fallback.ts +9 -2
  455. package/src/self-dev/run-supervisor.ts +226 -6
  456. package/src/self-dev/run-types.ts +7 -0
  457. package/src/self-implement/doctor-visit.ts +88 -0
  458. package/src/self-implement/gate-artifacts.ts +13 -0
  459. package/src/self-implement/gate-cli.ts +54 -24
  460. package/src/self-implement/gate-remote.ts +23 -5
  461. package/src/self-implement/goal-author-clarification.ts +31 -12
  462. package/src/self-implement/goal-author.ts +403 -8
  463. package/src/self-implement/graph-overlay-yaml.ts +7 -0
  464. package/src/self-implement/graph-stage-units.ts +172 -0
  465. package/src/self-implement/graph-templates.ts +162 -1
  466. package/src/self-implement/graph-variant.ts +37 -4
  467. package/src/self-implement/headless-elanous-driver.ts +31 -2
  468. package/src/self-implement/heal-intake.ts +112 -4
  469. package/src/self-implement/heal-triage.ts +20 -0
  470. package/src/self-implement/host-regate.ts +31 -8
  471. package/src/self-implement/knowhow-pack.ts +38 -0
  472. package/src/self-implement/merge-train.ts +5 -0
  473. package/src/self-implement/orchestrator.ts +359 -30
  474. package/src/self-implement/regate-detail.ts +38 -1
  475. package/src/self-implement/rework-child-provider.ts +25 -0
  476. package/src/self-implement/run-chart.ts +119 -0
  477. package/src/self-implement/run-ledger.ts +176 -17
  478. package/src/self-implement/run-stop.ts +208 -5
  479. package/src/self-implement/running-runs.ts +35 -12
  480. package/src/self-implement/self-implement-cli.ts +36 -4
  481. package/src/self-implement/stop-autoheal-operational.ts +43 -0
  482. package/src/self-implement/stop-autoheal.ts +28 -6
  483. package/src/session/chat.ts +69 -58
  484. package/src/session/request-size-guard.ts +123 -0
  485. package/src/session-runtime/index.ts +98 -4
  486. package/src/session-runtime/tier-flip.ts +3 -3
  487. package/src/sidetab-core/model.ts +150 -0
  488. package/src/sidetab-core/visible-agent-mission.ts +186 -0
  489. package/src/skills/name-match.ts +20 -0
  490. package/src/skills/tools/agent.ts +30 -2
  491. package/src/skills/tools/omni-search.ts +67 -5
  492. package/src/task-agent/parent-host.ts +14 -1
  493. package/src/task-agent/pod-distributor-entry.ts +3 -0
  494. package/src/task-agent/task-hand.ts +31 -1
  495. package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
  496. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +43 -0
  497. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
  498. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +29 -4
  499. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
  500. package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
  501. package/src/task-orchestrator/surfaces/pod-source-receive.ts +163 -13
  502. package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
  503. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +209 -39
  504. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
  505. package/src/task-orchestrator/surfaces/self-implement-pod.ts +280 -60
  506. package/src/task-orchestrator/surfaces/self-implement.ts +18 -0
  507. package/src/tokens.ts +35 -2
  508. package/src/tool-runtime/agent-runtime.ts +1 -0
  509. package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
  510. package/src/tool-runtime/skill-exec-runtime.ts +33 -13
  511. package/src/tool-runtime/types.ts +1 -0
  512. package/src/tui/entry.ts +24 -7
  513. package/src/tui/sidetab/attach.ts +47 -0
  514. package/src/tui/sidetab/list.ts +45 -0
  515. package/src/tui/sidetab/nl-tool.ts +2 -136
  516. package/src/tui/sidetab/peek.ts +52 -0
  517. package/src/tui-client/dashboard-session.ts +3 -0
  518. package/src/tui-client/local-chat-turn.ts +26 -13
  519. package/src/tui.ts +22 -0
  520. package/src/user-config.ts +11 -5
  521. package/src/ux-sim/fake-kubectl.ts +37 -3
  522. package/src/ux-sim/fault-needs-human-reason-repair.ts +107 -0
  523. package/src/ux-sim/fault-pod-child-result.ts +42 -0
  524. package/src/ux-sim/fault-pool-cap.ts +11 -6
  525. package/src/ux-sim/mock-scenario-catalog.json +41 -0
  526. package/src/ux-sim/mock-scenario-catalog.ts +156 -0
  527. package/src/ux-sim/release-sim-rig.ts +262 -0
  528. package/src/ux-sim/scenario.ts +116 -23
  529. package/src/ux-sim/seminar-rehearsal.ts +109 -0
  530. package/src/ux-sim/subagent-tools-device.ts +2 -2
  531. package/src/version/packed-revision.json +1 -1
  532. package/src/voice/voice-tts-singleton.ts +18 -3
  533. package/src/web-search/grok.ts +5 -9
  534. package/apps/pwa/out/_next/static/chunks/1060.014f1f01a17aec26.js +0 -115
  535. package/apps/pwa/out/_next/static/chunks/1415.79821ec7ae99acdb.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/1452.162bb2d9d699e82a.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/147.f92f63bbc5e85fa5.js +0 -286
  538. package/apps/pwa/out/_next/static/chunks/1661.fb425a1d8a065b72.js +0 -149
  539. package/apps/pwa/out/_next/static/chunks/1671-1c22b40b50b208f2.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/1758.0204d3f48783c49d.js +0 -90
  541. package/apps/pwa/out/_next/static/chunks/1806.027bf78b6a94d340.js +0 -104
  542. package/apps/pwa/out/_next/static/chunks/2047.8f23e210995d4548.js +0 -2
  543. package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/2066.a77257c8c350770a.js +0 -23
  545. package/apps/pwa/out/_next/static/chunks/2096-a938496bc996dcbd.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/2281-b8cede695c6c650e.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/2499.02fbfd18126c10c0.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/2522.f2766b76d22c8bdf.js +0 -34
  550. package/apps/pwa/out/_next/static/chunks/2615.3c9738153de3ef3f.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/2727.e703d99ac414916d.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/2752.7904b8df0254d0ae.js +0 -27
  553. package/apps/pwa/out/_next/static/chunks/2762-5051a862dfa40e99.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/2767-31784bfedf8e245d.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/2774-719820e3f5b2a3eb.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/2829-734fe8bf2eee7347.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/311-32dcac79970985e8.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/3175-f93f7495cd28253c.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/3184.8da993f5502d2140.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/3231-d7c981db0ff8bdcc.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/3250.151309c5176d6b4b.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/3517.a5aa1797a9dbf2ee.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/3567-45f676877ed9e8a5.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/3819.8a1de79b2e8c7298.js +0 -24
  566. package/apps/pwa/out/_next/static/chunks/39.9b37b0be4c128a83.js +0 -77
  567. package/apps/pwa/out/_next/static/chunks/4023.a19045970a9ce16a.js +0 -36
  568. package/apps/pwa/out/_next/static/chunks/413-24c8284bda08241d.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/4135.e45d6ebc29e20647.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/4283.65502f5d0e6ff6c0.js +0 -287
  571. package/apps/pwa/out/_next/static/chunks/4305-4e28fa92a7b34a5b.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/4335-50efa61fd7613142.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/4720.ecbd1693fa151068.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/483.725e4a61be922788.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/4969-4b209d7307410c00.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/5068-c7f53862f83c0917.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/5315.bc96711c24dfefe2.js +0 -74
  578. package/apps/pwa/out/_next/static/chunks/5542.efbf14f16baed4dd.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/5622.94893f5aea7185d0.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/5644.8f401a25601d05fc.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/5658.35f70eb9871a54bf.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/5721.7bdc0e904c76ab51.js +0 -8
  583. package/apps/pwa/out/_next/static/chunks/5790-eef0ca20884a6bdf.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/5802.ef0d8598ca68fe84.js +0 -62
  585. package/apps/pwa/out/_next/static/chunks/5890.fb974729788dcb71.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/5924.5ef25cddd36d5dbf.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/5979-e59c099ebf8d1f35.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/6020.714cfeada2315e2e.js +0 -94
  589. package/apps/pwa/out/_next/static/chunks/6027-dfe0349d8c50f698.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/6178.bc4730c86cf74536.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/6273.d808b0dcb3c2b155.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/6292.6ef1df64fa6a4c8a.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/647-af8dd920ba46533c.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/6541-170dc5c59e135c0c.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/6624.981ef7caeb680560.js +0 -32
  596. package/apps/pwa/out/_next/static/chunks/6742-a1ad4a94ba7bc37a.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/6836-493dc55c39187949.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/6856-53ac421c06039a18.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/6908.06008c67f6380ea9.js +0 -148
  600. package/apps/pwa/out/_next/static/chunks/6915.096931864206f522.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/6925.5e181fb7dcf90193.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/6cc1d1d6.9a98dd4622f1afc6.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/7203-800e11037adc41eb.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/7279.6170f591105936bb.js +0 -93
  605. package/apps/pwa/out/_next/static/chunks/7349-373165c7fbdcc3df.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7514-a533ba0ca1cae4f4.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/7515.1ad6efe157fa4448.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/7521.d919cc1fab80c1d9.js +0 -24
  609. package/apps/pwa/out/_next/static/chunks/7538.90e97bbdf9178cff.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/7825-39203196a12579b2.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/7869.5e1a9a12fd70d6c7.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/8086.1ab9103c41be884f.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/8179-e61fffbdb70f1152.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/8265.bdeb991b34db6a06.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/8357.1aaa713b052a78b1.js +0 -309
  616. package/apps/pwa/out/_next/static/chunks/8638-e42615f2166165b5.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/8639-92c11d069792429e.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/8691.54e22831d5e8ccf8.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/9069.657590a84afb8fac.js +0 -41
  620. package/apps/pwa/out/_next/static/chunks/9125-ae588d88a0293b93.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/9311.f9f641a46a508611.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/9371-a6fee8378ebfa3ee.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/9421-3aa9ff4fa7f63d8a.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/9992.07ce73c10bd5e6a1.js +0 -79
  625. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76394dc618d322c8.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/app/approvals/page-1b948637c37b3abd.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-c63400f1bcf3e47c.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/app/board/page-95d0957267819586.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ba957ff875a026a0.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/app/bots/page-bb6fd0714879cb87.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8f9038520d2acbef.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/app/chat/page-d4b48397e05fce2c.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/app/consult/page-72d5744245dc0c27.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/app/control/page-37625dc8300fa43a.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/app/decisions/page-fbef9d160272dbc1.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/app/design-check/page-58424168df84928e.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/app/editor/page-72c12ba430ac57c0.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/app/exec/page-d53f3e9ed806d7e0.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/app/field/page-4d2fbd45feee0829.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76394dc618d322c8.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/inside/page-8783dc0ed7590a2c.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/intake/page-3706cb390606e930.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/layout-9b0a86598e0111fd.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/live/page-4edb8df90f4537ce.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/loops/page-47398b9ba1cc5e1b.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/market/page-fb86f55cfe2e681d.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e22345fc8fd47b1b.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/morning/page-fca2e59a81744d9e.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/not-found-6e96bda63100b31e.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/observatory/page-4d17ad8e0db8cea4.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-121f92766c33beaa.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-43f14212c545f92d.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ccec2023e7a974ec.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/outputs/page-b04f33f548b89a94.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/page-c8792823c0917021.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/reflection/page-8c0e32782ceef4cb.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-94bd3922eb230ce8.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bca565887bafa03c.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ac1dffafe649fc6c.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/settings/page-52374edb5e23e455.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ad4ebca120d43ca7.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76394dc618d322c8.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/setup/page-718b89ce4b4ae4e4.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/share/page-204eca33eeeaddec.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/showroom/page-e58ba9bcdb9ac0f9.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/tasks/page-98f6dd50bafd7734.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/today/page-5a4bdd72bff27057.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/trace/page-6f6ab17d44f984ce.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/vault/page-aabb7bd15fb72da9.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e4322319164a4436.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/workflows/page-e9efc0c8f32e2371.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/workspace/page-ccde99f07aaf71f7.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/c696986b.5dc8bb1143af16d1.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/d5d3cefc-373c4eb722ed848b.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/d8de0de2-dd0f4ac8e5ab1832.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/framework-002b472a66935d31.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/main-49b88d47292c0476.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/main-app-fff2549cb10a133f.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/pages/_app-32abbbba3f3b76b7.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/pages/_error-9d9cfef60c60dd7a.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/webpack-cc7f483fa294034a.js +0 -1
  683. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
  684. package/scripts/ratchets/next-tui-entry-budget.ts +0 -124
  685. /package/apps/pwa/out/_next/static/{HjeK7zONHfR7op1hKXp4k → X1ucLw10Cds_h614NoEnh}/_ssgManifest.js +0 -0
@@ -70,12 +70,48 @@ export function recordPodSourceIoSummary(logs: string, job: string, runId: strin
70
70
  if (!ioSummary) return;
71
71
  try {
72
72
  const measured = JSON.parse(ioSummary) as Record<string, unknown>;
73
- log('pod.source', 'io-summary', { job, runId, runIdSource, ...measured, hostOriginCalls });
73
+ const pushCounterReady = /^ELANOUS_POD_GIT_PUSH_COUNTER ready\r?$/m.test(logs);
74
+ const pushCalls = (logs.match(/^ELANOUS_POD_GIT_PUSH_ATTEMPT\r?$/gm) ?? []).length;
75
+ log('pod.source', 'io-summary', { job, runId, runIdSource, ...measured, hostOriginCalls,
76
+ ...(pushCounterReady ? { pushCalls } : {}) });
74
77
  } catch (error) {
75
78
  log('pod.source', 'io-summary-invalid', { job, runId, runIdSource, reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' });
76
79
  }
77
80
  }
78
81
 
82
+ export type PodSourceAttemptOutcome = {
83
+ classification: 'explicit-source-failure' | 'source-complete' | 'status-not-recorded';
84
+ sourceStage: string | null;
85
+ sourceKind: string | null;
86
+ sourceVia: string | null;
87
+ sourceStatus: string | null;
88
+ baseSha: string | null;
89
+ exitCode: number | null;
90
+ failureCode: string | null;
91
+ };
92
+
93
+ /** Keep missing telemetry distinct from an observed source-stage failure. */
94
+ export function parsePodSourceAttemptOutcome(logs: string | null, fallback: { sourceKind?: string | null; baseSha?: string | null } = {}): PodSourceAttemptOutcome {
95
+ const resultLine = logs ? /^ELANOUS_POD_SOURCE_RESULT (\{[^\r\n]+\})\r?$/m.exec(logs)?.[1] : undefined;
96
+ const result = resultLine ? (() => { try { return JSON.parse(resultLine) as Record<string, unknown>; } catch { return null; } })() : null;
97
+ const explicitBaseFailure = !!logs && /^ELANOUS_POD_SOURCE_BASE_SHA_UNAVAILABLE [^\r\n]+\r?$/m.test(logs);
98
+ const ioLine = logs ? /^ELANOUS_POD_SOURCE_IO (\{[^\r\n]+\})\r?$/m.exec(logs)?.[1] : undefined;
99
+ const io = ioLine ? (() => { try { return JSON.parse(ioLine) as Record<string, unknown>; } catch { return null; } })() : null;
100
+ const validString = (value: unknown): string | null => typeof value === 'string' && value.length > 0 ? value : null;
101
+ const resultFailure = validString(result?.failureCode) ?? (explicitBaseFailure ? 'base-sha-unavailable' : null);
102
+ const status = validString(result?.sourceStatus) ?? (io?.sourceStatus === 'complete' || io?.sourceStatus === 'incomplete' ? io.sourceStatus : null);
103
+ return {
104
+ classification: resultFailure || explicitBaseFailure ? 'explicit-source-failure' : status === 'complete' ? 'source-complete' : 'status-not-recorded',
105
+ sourceStage: validString(result?.sourceStage) ?? (explicitBaseFailure ? 'base-sha' : null),
106
+ sourceKind: validString(result?.sourceKind) ?? fallback.sourceKind ?? null,
107
+ sourceVia: validString(result?.sourceVia) ?? validString(io?.sourceVia) ?? (/^ELANOUS_POD_SOURCE_VIA (image|mirror|github|bundle|min-sync)\r?$/m.exec(logs ?? '')?.[1] ?? null),
108
+ sourceStatus: status,
109
+ baseSha: validString(result?.baseSha) ?? fallback.baseSha ?? null,
110
+ exitCode: typeof result?.exitCode === 'number' && Number.isInteger(result.exitCode) ? result.exitCode : null,
111
+ failureCode: resultFailure,
112
+ };
113
+ }
114
+
79
115
  /** Select a timestamp for a DeadlineExceeded observation without making detector time look like Job completion.
80
116
  * `podFinishedAt` must come from readPodTermination for the same verified Job uid. */
81
117
  export function podJobFinishedTiming(input: { jobCreatedAt: string | null; jobCompletedAt: string | null;
@@ -99,6 +135,7 @@ import { POD_LAUNCH_FINISHED_EVENT, POD_LAUNCH_STARTED_EVENT, provenanceRowFromA
99
135
  import { podProvenanceMetadata, type PodProvenanceMetadata } from './pod-provenance.js';
100
136
  import { packageVersion } from '../../version/code-revision.js';
101
137
  import { minihLocationFrom, podWorkLabels, type PodWorkIdentity, type PodPlacement, type PodPlacementKind, type PodPoolMember, type PodPoolScheduler } from './pod-pool.js';
138
+ import { acquirePodPoolSlot, POD_DISTRIBUTOR_ENTRY_ENV, type PodDistributorAdapter } from './pod-distributor.js';
102
139
  export { POD_CHILD_REQUESTS } from './pod-lease.js';
103
140
  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';
104
141
  import { ACTUAL_SUBSTRATE_ENV, RUN_CONTRACT_ENV, carryRunContract, completionFloorFor } from '../../self-implement/graph-run-contract.js';
@@ -128,7 +165,7 @@ import { normalizeFallbackChain, type FallbackStep } from '../../oauth/fallback-
128
165
  import { goalTypeOf, type GoalType } from '../../../scripts/measure-pod-memory-by-goal.js';
129
166
  import { declaredGoalType, type GoalType as DeclaredGoalType } from '../../self-implement/goal-author.js';
130
167
  import { readPodMemoryAdvice, type PodMemoryAdvice } from '../../cli/pod-memory-advice.js';
131
- import { DEFAULT_BUDGET_GATE_MAX_USED_PERCENT, getUserConfig, roleLlmEnvName, type UserConfig } from '../../user-config.js';
168
+ import { DEFAULT_BUDGET_GATE_MAX_USED_PERCENT, getUserConfig, resolveRoleLlm, roleLlmEnvName, type UserConfig } from '../../user-config.js';
132
169
  import { worktreeAddTimeoutSec } from '../../git-fs/worktree.js';
133
170
  import { podChildProviderOf, podChildProviderRefusal, type PodChildProvider } from './pod-child-providers.js';
134
171
  import { BEDROCK_POD_EGRESS_LABEL, bedrockPodEnv, checkBedrockPodSecret, type BedrockPodSpec } from './pod-bedrock-child.js';
@@ -137,7 +174,7 @@ import { ZAI_POD_EGRESS_LABEL, checkZaiPodSecret, countActiveZaiJobs, decideZaiP
137
174
  import { ZAI_CODING_DEFAULT_MODEL, ZAI_OPENROUTER_FALLBACK_MODEL, zaiSettingsFromConfig, type ZaiCodingPlanSettings } from '../../llm/zai-coding-plan.js';
138
175
  import { normalizePlanningFallbackReason, selectEnhanceLlm } from '../../prompt-enhance/enhance.js';
139
176
  import { inferProviderFromModel } from '../../llm.js';
140
- import { classifyPodExit, extractPodFailureReason, podChildFailureAttribution, podDeadlineResultMarker, podJobConditionReason, podTerminalRow, POD_TERMINATION_JOB_JSONPATH, POD_TERMINATION_PODS_JSONPATH, readPodTermination, type PodExitClass, type PodTermination } from './pod-failure-reason.js';
177
+ import { classifyPodExit, extractPodFailureReason, podChildEvidenceLedgerRow, podChildFailureAttribution, podDeadlineResultMarker, podJobConditionReason, podTerminalRow, POD_TERMINATION_JOB_JSONPATH, POD_TERMINATION_PODS_JSONPATH, readPodTermination, type PodExitClass, type PodTermination } from './pod-failure-reason.js';
141
178
  import { kubectlTransientReason, retryKubectlTransient } from './kubectl-transient-retry.js';
142
179
  import { OLD_DOOR_STAMP_ENV } from '../../self-dev/old-door.js';
143
180
  import { resolveDefaultSourceHead, seedMirrorOnce, type MirrorSeedResult } from './pod-mirror-seed.js';
@@ -285,6 +322,8 @@ export interface PodSpawnOptions {
285
322
  readSkillEnv?: () => Record<string, string>;
286
323
  /** ☸️ 여러 클러스터 풀(pod-pool.ts) — Job 마다 우선순위 순 첫 빈 자리로. 없으면 현재 컨텍스트 하나. */
287
324
  pool?: PodPoolScheduler;
325
+ /** POD-DISTRIBUTOR-WIRE — replaceable admission seam; tasks-hand only in the first wire slice. */
326
+ podDistributorAdapter?: PodDistributorAdapter;
288
327
  /** ☸️ 원격 그라운딩 주소(P13) — 없으면 호스트 env ELANOUS_GROUNDING_URL → 설정 pod.groundingUrl. 셋 다 없으면 토큰을 안 만든다. */
289
328
  groundingUrl?: string;
290
329
  /** 시험 심 — 토큰 발급·회수. GitHub credential 토큰에는 호스트가 검증한 저장소를 서명한다. */
@@ -771,9 +810,10 @@ export function podGitPushGuardScript(runId?: string): string {
771
810
  ' *) echo "[pod] git-guard: refused push to $rref (only this run\'s branches)" >&2; exit 1 ;;',
772
811
  ' esac',
773
812
  'done',
813
+ 'case "$2" in https://github.com/*|http://github.com/*|git@github.com:*|ssh://git@github.com/*) printf \'ELANOUS_POD_GIT_PUSH_ATTEMPT\\n\' >&2 ;; esac',
774
814
  'exit 0',
775
815
  'ELANOUS_PRE_PUSH',
776
- `chmod 755 "${POD_GIT_HOOKS_DIR}/pre-push" && git config --global core.hooksPath "${POD_GIT_HOOKS_DIR}"`,
816
+ `chmod 755 "${POD_GIT_HOOKS_DIR}/pre-push" && git config --global core.hooksPath "${POD_GIT_HOOKS_DIR}" && printf 'ELANOUS_POD_GIT_PUSH_COUNTER ready\\n'`,
777
817
  ].join('\n');
778
818
  }
779
819
 
@@ -1602,21 +1642,63 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
1602
1642
  if (options.siWarmAttempt && !options.siWarmHostPostprocess) {
1603
1643
  throw new Error('si-v1 warm execution requires cold-path host postprocess parity');
1604
1644
  }
1605
- if (options.siWarmAttempt) {
1645
+ let siWarmEnabled = true;
1646
+ const taskCard = env.ELANOUS_POD_TASK_CARD ?? env.ELANOUS_TASK_CARD_ID;
1647
+ if (taskCard) {
1648
+ let stage: 'config' | 'evidence' | 'decision' = 'config';
1649
+ try {
1650
+ const config = options.warmReuseConfig?.();
1651
+ stage = 'evidence';
1652
+ const evidence = options.warmReuseEvidence?.();
1653
+ stage = 'decision';
1654
+ const decision = decideWarmReuse('ta', config, evidence);
1655
+ siWarmEnabled = decision.live;
1656
+ debug.log('pod.warm', 'ta-admission-decision', { ...decision,
1657
+ execution: decision.live ? 'warm-attempt' : 'fresh-job' });
1658
+ } catch {
1659
+ siWarmEnabled = false;
1660
+ debug.log('pod.warm', 'ta-admission-unavailable', { spaceId: input.spaceId,
1661
+ reason: stage === 'decision' ? 'warm-decision-failed' : `injected-${stage}-failed`, execution: 'fresh-job' }, { level: 'warn' });
1662
+ }
1663
+ }
1664
+ if (options.siWarmAttempt && siWarmEnabled) {
1606
1665
  const done = (async (): Promise<SelfImplementJobDone> => {
1666
+ // POD-REUSE-REQUEST-CLEAN-FU — one fail-soft row per request decision. `runId` is the
1667
+ // ledger partition (warm child, then parent run, then the legacy spaceId fallback);
1668
+ // `correlationId` always names the request's spaceId. `warm-path-selected` is recorded
1669
+ // before transport, so only the later return/quarantine row settles whether reuse completed.
1670
+ // A ledger write failure is an observation failure only.
1671
+ const recordWarmRequestDecision = (data: Record<string, unknown>, runId?: string) => {
1672
+ const parentRunId = env.ELANOUS_RUN_ID;
1673
+ const ledgerRunId = runId ?? parentRunId ?? input.spaceId;
1674
+ const runIdSource = runId ? 'warm-child-run' : parentRunId ? 'parent-run' : 'space-id-fallback';
1675
+ try { writeWarmLedger({ runId: ledgerRunId, event: 'pod-reuse-request-decision',
1676
+ data: { ...data, correlationId: input.spaceId, runIdSource } }); }
1677
+ catch (error) { debug.log('pod.reuse', 'ledger-unavailable', { spaceId: input.spaceId,
1678
+ event: 'pod-reuse-request-decision',
1679
+ reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
1680
+ };
1607
1681
  let attempt: SiWarmChildAttempt;
1608
1682
  try {
1609
1683
  const acquired = await options.siWarmAttempt!(input);
1610
1684
  if (!acquired) {
1611
1685
  // No lease was fenced: use the existing one-shot Job path.
1686
+ recordWarmRequestDecision({ spaceId: input.spaceId, outcome: 'cold-job',
1687
+ workerId: null, leaseId: null, generation: null, podUid: null });
1612
1688
  const { siWarmAttempt: _unused, siWarmHostPostprocess: _postprocess, ...coldOptions } = options;
1613
1689
  return podSelfImplementSpawn(coldOptions)(input).done;
1614
1690
  }
1615
1691
  attempt = acquired;
1692
+ recordWarmRequestDecision({ spaceId: input.spaceId, outcome: 'warm-path-selected',
1693
+ workerId: acquired.command?.workerId ?? null, leaseId: acquired.command?.leaseId ?? null,
1694
+ generation: acquired.command?.generation ?? null, podUid: acquired.command?.podUid ?? null },
1695
+ acquired.command?.runId);
1616
1696
  }
1617
1697
  catch (error) {
1618
1698
  // A lost exec reply may conceal an already opened PR. Never start another child here.
1619
1699
  const message = error instanceof Error ? error.message : String(error);
1700
+ recordWarmRequestDecision({ spaceId: input.spaceId, outcome: 'acquire-failed', reason: message,
1701
+ workerId: null, leaseId: null, generation: null, podUid: null });
1620
1702
  debug.log('pod.reuse', 'attempt-unavailable', { spaceId: input.spaceId, reason: message }, { level: 'warn' });
1621
1703
  return { exitCode: 1, output: '', error: { code: 'si-warm-reconcile-only', message } };
1622
1704
  }
@@ -1985,7 +2067,8 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
1985
2067
  return 'pool-slot-unavailable';
1986
2068
  };
1987
2069
  const recordSlotObservation = (attempt: { observationKey: string; requestedAtMs: number; requestedAt: string },
1988
- outcome: 'requested' | 'queued' | 'admitted' | 'rejected', reasonCode: string): void => {
2070
+ outcome: 'requested' | 'queued' | 'admitted' | 'rejected', reasonCode: string,
2071
+ cancellation?: { abortReason?: string; waitReason: string | null }): void => {
1989
2072
  const pool = options.pool;
1990
2073
  let occupants: Record<string, number> | null = null;
1991
2074
  try { occupants = pool ? pool.snapshot() : null; } catch { /* observation must not change scheduling */ }
@@ -1994,6 +2077,8 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
1994
2077
  observationKey: attempt.observationKey, runId: childRunId, host: resolveHostId(env),
1995
2078
  requestedAt: attempt.requestedAt, waitedMs: Math.max(0, slotNow() - attempt.requestedAtMs),
1996
2079
  queued: outcome === 'queued', poolCapacity, occupants, reasonCode, parentId: ledgerRunId, outcome,
2080
+ ...(cancellation ? { waitReason: cancellation.waitReason,
2081
+ ...(cancellation.abortReason === undefined ? {} : { abortReason: cancellation.abortReason }) } : {}),
1997
2082
  };
1998
2083
  debug.log('pod.slot', outcome, data, { level: outcome === 'admitted' || outcome === 'requested' ? 'info' : 'warn' });
1999
2084
  try {
@@ -2045,6 +2130,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2045
2130
  const attempt = { observationKey: `${childRunId}:pod-slot:${requestedAtMs}:${++slotAttemptNumber}`,
2046
2131
  requestedAtMs, requestedAt: new Date(requestedAtMs).toISOString() };
2047
2132
  let firstSlotReasonCode: string | undefined;
2133
+ stageReason['pool-slot'] = null;
2048
2134
  let slotQueuedRecorded = false;
2049
2135
  const stop = watchStall('pool-slot');
2050
2136
  // MINIH-MODE (0.2.37): the location is declared by the launch env — absent/unknown keeps the configured
@@ -2056,11 +2142,15 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2056
2142
  if (input.signal?.aborted) return null;
2057
2143
  // The reason comes back inside this call, so a concurrent launch cannot overwrite it.
2058
2144
  const kind = podPlacementKind(oomRetried ? retryTier : memoryTier, selectedGoalType, requestKind);
2059
- const acquired = await options.pool.tryAcquire(unfitContexts, (reason) => {
2060
- stageReason['pool-slot'] = reason;
2061
- firstSlotReasonCode ??= slotReasonCode(reason);
2062
- },
2063
- { kind, ...(minihLocation ? { minihLocation } : {}), onPlacement: (placement) => { lastPlacement = placement; } });
2145
+ const acquired = await acquirePodPoolSlot({ entry: env[POD_DISTRIBUTOR_ENTRY_ENV], pool: options.pool,
2146
+ ...(options.podDistributorAdapter ? { adapter: options.podDistributorAdapter } : {}),
2147
+ request: { requestId: attempt.observationKey, idempotencyKey: attempt.observationKey,
2148
+ owner: { runId: childRunId, ...(env.ELANOUS_TASK_CARD_ID ? { cardId: env.ELANOUS_TASK_CARD_ID } : {}),
2149
+ ...(env.ELANOUS_POD_OWNER_KIND === 'seat' && env.ELANOUS_POD_OWNER_ID ? { seat: env.ELANOUS_POD_OWNER_ID } : {}) },
2150
+ lane: 'ta', workload: { memoryLimit, kind }, skip: unfitContexts, onEmpty: (reason) => {
2151
+ stageReason['pool-slot'] = reason;
2152
+ firstSlotReasonCode ??= slotReasonCode(reason);
2153
+ }, mode: { kind, ...(minihLocation ? { minihLocation } : {}), onPlacement: (placement) => { lastPlacement = placement; } } } });
2064
2154
  if (acquired) {
2065
2155
  recordSlotObservation(attempt, 'admitted', firstSlotReasonCode ?? 'admitted');
2066
2156
  debug.log('self-implement.pod', 'pool-slot', { spaceId: input.spaceId, context: acquired.context, inflight: options.pool.snapshot(), ...(lastPlacement ? { placement: lastPlacement } : {}) });
@@ -2110,7 +2200,10 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2110
2200
  let member: PodPoolMember | null;
2111
2201
  try { member = await acquireSlot(); } catch (error) { podAdmitError(error); throw error; }
2112
2202
  if (options.pool && !member) {
2113
- if (lastSlotAttempt) recordSlotObservation(lastSlotAttempt, 'rejected', lastSlotReasonCode ?? 'aborted');
2203
+ if (lastSlotAttempt) recordSlotObservation(lastSlotAttempt, 'rejected', lastSlotReasonCode ?? 'aborted', {
2204
+ waitReason: stageReason['pool-slot'] ?? null,
2205
+ ...(typeof input.signal?.reason === 'string' ? { abortReason: input.signal.reason } : {}),
2206
+ });
2114
2207
  exitJourneyNode('pool-admit', { provenance: 'self-implement-pod', outcome: 'refused', data: { spaceId: input.spaceId, reason: 'no-slot' } });
2115
2208
  return { exitCode: null, output: '', error: { code: 'aborted', message: 'aborted before a pool slot opened', ...(lastSlotReasonCode ? { reasonCode: lastSlotReasonCode } : {}) } };
2116
2209
  }
@@ -2134,14 +2227,41 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2134
2227
  } catch (error) { debug.log('self-implement.pod', 'failure-capture-ledger-unavailable', { job: name, reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
2135
2228
  };
2136
2229
  let recorded = false;
2230
+ let jobApplied = false;
2137
2231
  let groundingMinted: string | null = null;
2138
2232
  try {
2139
2233
  if (!context) return { exitCode: 1, output: '', error: { code: 'pod-context', message: 'Pod Job context를 확인할 수 없다' } };
2140
- const cleanupSecret = () => { kubectl(['-n', namespace, 'delete', 'secret', `${name}-creds`, '--ignore-not-found']); };
2234
+ const cleanupSecret = () => {
2235
+ // Once the Job exists, its credential Secret must live at least as long as the Job.
2236
+ // Early error/abort paths may run while the Pod is still reading /creds; leave cleanup
2237
+ // to the Job ownerReference/TTL until Kubernetes reports this Job terminal or absent.
2238
+ if (jobApplied) {
2239
+ const lifecycle = kubectl(['-n', namespace, 'get', 'job', name, '-o', 'jsonpath={.metadata.uid} {.status.active} {.status.succeeded} {.status.failed}']);
2240
+ const [uid, , succeeded, failed] = lifecycle.stdout.trim().split(/\s+/u);
2241
+ const terminal = Number(succeeded) > 0 || Number(failed) > 0;
2242
+ if (lifecycle.status === 0 && uid && !terminal) {
2243
+ debug.log('self-implement.pod', 'secret-cleanup-deferred-job-live', { job: name });
2244
+ return;
2245
+ }
2246
+ if (lifecycle.status !== 0 && !/notfound/iu.test(lifecycle.stderr)) {
2247
+ debug.log('self-implement.pod', 'secret-cleanup-deferred-job-unmeasured', { job: name }, { level: 'warn' });
2248
+ return;
2249
+ }
2250
+ }
2251
+ kubectl(['-n', namespace, 'delete', 'secret', `${name}-creds`, '--ignore-not-found']);
2252
+ };
2141
2253
  let repairResultAnnounced = false;
2142
2254
  let repairArtifactReady = false;
2143
2255
  let hostOriginCalls: number | null = 0;
2144
2256
  let sourceBaseSha: string | undefined;
2257
+ const recordSourceAttemptOutcome = (logs: string | null, captureStatus: 'captured' | 'logs-unavailable', observedChildRunId?: string) => {
2258
+ const optionBaseSha = options.source && 'baseSha' in options.source ? options.source.baseSha : undefined;
2259
+ const outcome = parsePodSourceAttemptOutcome(logs, { sourceKind: options.source?.kind ?? 'default', baseSha: sourceBaseSha ?? optionBaseSha });
2260
+ const data = { job: name, childRunId: observedChildRunId ?? childRunId ?? null, attempt: oomRetried ? 2 : 1, captureStatus, ...outcome };
2261
+ debug.log('pod.source', 'attempt-outcome', data, outcome.classification === 'status-not-recorded' ? { level: 'warn' } : undefined);
2262
+ try { appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-source-attempt-outcome', data }, ledgerDir); }
2263
+ catch (error) { debug.log('pod.source', 'attempt-outcome-ledger-unavailable', { job: name, childRunId: childRunId ?? null, reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
2264
+ };
2145
2265
  const collectFullLogs = (unavailableEvent: string, replace?: ReadonlySet<string>, onEvent?: (event: string, data: Record<string, unknown>) => void, childId?: string): { status: 'ok' | 'unavailable' | 'incomplete'; childLedgerIncomplete: boolean; samples: ReturnType<typeof parseMemSamples> } => {
2146
2266
  let full: ReturnType<Kubectl>;
2147
2267
  try {
@@ -2150,8 +2270,10 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2150
2270
  if (!full.stdout && unavailableEvent === 'failed-job-logs-unavailable') throw new Error('empty child logs');
2151
2271
  } catch (error) {
2152
2272
  debug.log('self-implement.pod', unavailableEvent, { job: name, reason: error instanceof Error ? error.message : String(error) });
2273
+ recordSourceAttemptOutcome(null, 'logs-unavailable', childId);
2153
2274
  return { status: 'unavailable', childLedgerIncomplete: false, samples: [] };
2154
2275
  }
2276
+ recordSourceAttemptOutcome(full.stdout, 'captured', childId);
2155
2277
  const via = /^ELANOUS_POD_SOURCE_VIA (image|mirror|github)\r?$/m.exec(full.stdout)?.[1];
2156
2278
  // #28246 names why the mirror was skipped on the line before `VIA github`; carry it on the same event.
2157
2279
  const mirrorSkip = /^ELANOUS_POD_SOURCE_MIRROR_SKIP (no-mount|rev-parse-failed|clone-failed)\r?$/m.exec(full.stdout)?.[1];
@@ -2274,13 +2396,22 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2274
2396
  /** 넘친 glm Pod 는 자식 인자도 OpenRouter GLM 으로 — Job 스크립트·리뷰어 고정·키 전달이 openrouter 갈래를 그대로 탄다. */
2275
2397
  const jobArgs = zaiRoute === 'openrouter' ? zaiOverflowChildArgs(args, ZAI_OPENROUTER_FALLBACK_MODEL) : args;
2276
2398
  const grok = options.provider === 'grok';
2277
- const openrouter = options.provider === 'openrouter' || zaiRoute === 'openrouter';
2399
+ // The delegated child provider is also a launch source. Callers that carry
2400
+ // --child-llm-provider in args must not leave the host's Secret wiring on
2401
+ // the default provider path.
2402
+ const delegatedChildProvider = podDelegatedChildLlm(jobArgs)?.provider;
2403
+ const openrouter = options.provider === 'openrouter' || zaiRoute === 'openrouter' || delegatedChildProvider === 'openrouter';
2278
2404
  const openGateway = options.provider === 'opengateway';
2279
2405
  const anthropic = options.provider === 'anthropic';
2280
2406
  const bedrockChild = options.provider === 'bedrock';
2281
2407
  const zaiChild = zaiRoute === 'zai';
2282
2408
  /** ZAI 로 입장한 자식도 플랜 한도 오류 뒤 OpenRouter 로 전환할 수 있다. 실행 중 폴백 자격을 발사 전에 확보한다. */
2283
2409
  const openrouterCredentialRequired = openrouter || (zaiChild && zaiLaunchOverage !== 'stop');
2410
+ const hostConfig = (options.fallbackConfig ?? getUserConfig)();
2411
+ const reviewProvider = resolveRoleLlm('review', { config: hostConfig, env: { ...env, ...options.armEnv } }).provider;
2412
+ // A non-OpenRouter child can still run a review role pinned to OpenRouter. Pass that
2413
+ // credential through the same Secret path, but don't make it a launch requirement.
2414
+ const openrouterCredentialNeeded = openrouterCredentialRequired || reviewProvider === 'openrouter';
2284
2415
  /** API 키 자식 — codex 계정·자격 파일을 안 쓴다(키는 작업별 creds Secret 의 `env-<KEY>` · bedrock·glm 은 이름 있는 Secret 으로만). */
2285
2416
  const apiKeyChild = openrouter || openGateway || anthropic || bedrockChild || zaiChild;
2286
2417
  const plannedAccount = retryAccount ?? (grok ? 'grok' : openrouter ? 'openrouter' : openGateway ? 'opengateway' : anthropic ? 'anthropic' : bedrockChild ? 'bedrock' : zaiChild ? 'glm' : options.accountBroker?.() ?? options.account ?? 'team');
@@ -2324,7 +2455,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2324
2455
  }
2325
2456
  return credential;
2326
2457
  }) : undefined;
2327
- const openrouterKey = openrouterCredentialRequired ? env.OPENROUTER_API_KEY?.trim() || (options.readKeyCache ?? defaultReadKeyCache)('OPENROUTER_API_KEY')?.trim() : undefined;
2458
+ const openrouterKey = openrouterCredentialNeeded ? env.OPENROUTER_API_KEY?.trim() || (options.readKeyCache ?? defaultReadKeyCache)('OPENROUTER_API_KEY')?.trim() : undefined;
2328
2459
  if (openrouterCredentialRequired && !openrouterKey) throw new Error('pod: Pod 에 openrouter 키 없음 — 호스트 키 캐시 또는 OPENROUTER_API_KEY 필요');
2329
2460
  const openGatewayEnvKey = openGateway ? env.OPENGATEWAY_API_KEY?.trim() : undefined;
2330
2461
  const openGatewayCachedKey = openGateway ? (options.readKeyCache ?? defaultReadKeyCache)('OPENGATEWAY_API_KEY')?.trim() : undefined;
@@ -2407,7 +2538,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2407
2538
  }
2408
2539
  }
2409
2540
  // Grok 자격은 전용 Secret 키 하나로만 보낸다 — passEnv 의 API 키 중복 전달은 막는다.
2410
- const passKeys = [...new Set([...(options.passEnv ?? []), ...(openrouterCredentialRequired ? ['OPENROUTER_API_KEY'] : []), ...(openGateway ? ['OPENGATEWAY_API_KEY'] : []), ...(anthropic ? ['ANTHROPIC_API_KEY'] : [])])].filter((key) => key !== 'ELANOUS_LIVE_DETAIL_UNTIL'
2541
+ const passKeys = [...new Set([...(options.passEnv ?? []), ...(openrouterCredentialNeeded && openrouterKey ? ['OPENROUTER_API_KEY'] : []), ...(openGateway ? ['OPENGATEWAY_API_KEY'] : []), ...(anthropic ? ['ANTHROPIC_API_KEY'] : [])])].filter((key) => key !== 'ELANOUS_LIVE_DETAIL_UNTIL'
2411
2542
  && key !== POD_GITHUB_CREDENTIAL_TOKEN_ENV && key !== POD_GITHUB_CREDENTIAL_URL_ENV
2412
2543
  && (!grok || !['XAI_API_KEY', 'GROK_API_KEY', 'GROK_CODE_XAI_API_KEY'].includes(key)));
2413
2544
  const skillEnvs: Record<string, string> = options.skillEnv
@@ -2584,8 +2715,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2584
2715
  authorChoice = { ...authorChoice, model: childModel, modelSource: 'fallback-child' };
2585
2716
  } else debug.log('self-implement.pod', 'role-llm-armed', { job: name, role: 'planning', model: authorChoice.model, source: authorChoice.modelSource, account: roleCodexAccount });
2586
2717
  }
2587
- const hostKey = (k: string): string | undefined => k === 'OPENROUTER_API_KEY' && openrouterCredentialRequired ? openrouterKey : k === 'OPENGATEWAY_API_KEY' && openGateway ? openGatewayKey : k === 'ANTHROPIC_API_KEY' && anthropic ? anthropicKey : env[k] ?? (options.readKeyCache ?? defaultReadKeyCache)(k);
2588
- const hostConfig = (options.fallbackConfig ?? getUserConfig)();
2718
+ const hostKey = (k: string): string | undefined => k === 'OPENROUTER_API_KEY' && openrouterCredentialNeeded ? openrouterKey : k === 'OPENGATEWAY_API_KEY' && openGateway ? openGatewayKey : k === 'ANTHROPIC_API_KEY' && anthropic ? anthropicKey : env[k] ?? (options.readKeyCache ?? defaultReadKeyCache)(k);
2589
2719
  const hostFallbackNames = hostConfig.llm.fallbackChain;
2590
2720
  const zaiOverage = zaiLaunchOverage ?? zaiSettingsFromConfig(hostConfig.llm).overage;
2591
2721
  const normalizedFallback = normalizeFallbackChain(hostFallbackNames);
@@ -2842,22 +2972,6 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2842
2972
  slotId: env.ELANOUS_POD_SLOT_ID,
2843
2973
  work: !goalDoc && env.ELANOUS_POD_AUTHOR_ON_POD === '1' && !shard ? 'authoring' : (oomRetried ? retryTier : memoryTier) === 'lite' ? 'lite' : 'harness',
2844
2974
  };
2845
- // TA-POD-WARMBOOT-PARITY shadow only: read injected evidence, then keep the fresh-Job path.
2846
- // This boundary must not open host configuration or credential files for a warm decision.
2847
- if (workIdentity.taskCard) {
2848
- let stage: 'config' | 'evidence' | 'decision' = 'config';
2849
- try {
2850
- const config = options.warmReuseConfig?.();
2851
- stage = 'evidence';
2852
- const evidence = options.warmReuseEvidence?.();
2853
- stage = 'decision';
2854
- const decision = decideWarmReuse('ta', config, evidence);
2855
- debug.log('pod.warm', 'ta-shadow-observation', { ...decision, execution: 'fresh-job' });
2856
- } catch {
2857
- debug.log('pod.warm', 'ta-shadow-unavailable', { spaceId: input.spaceId,
2858
- reason: stage === 'decision' ? 'warm-decision-failed' : `injected-${stage}-failed`, execution: 'fresh-job' }, { level: 'warn' });
2859
- }
2860
- }
2861
2975
  // TA-POD-WARMBOOT-PARITY (GATE-WARM-BOOT parity · #27805): a commit-pinned source on a pool host — put that commit into
2862
2976
  // the host mirror first (once per host·commit in this process) so podSourceScript finds it instead of fetching
2863
2977
  // from GitHub. Best effort: a failed seed only logs; the Job is applied either way.
@@ -2934,6 +3048,19 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2934
3048
  const a = kubectl(['apply', '-f', '-'], JSON.stringify(job));
2935
3049
  zaiPendingApply.delete(name); // apply 뒤엔 Job 라벨이 센다(성공) · 실패면 셀 것이 없다
2936
3050
  if (a.status !== 0) { cleanupSecret(); return { exitCode: 1, output: a.stderr, error: { code: 'pod-apply', message: a.stderr.trim() } }; }
3051
+ jobApplied = true;
3052
+ // Bind the credential Secret immediately after Job creation, before waiting for a Pod
3053
+ // or doing any other fallible work. Kubernetes then removes both on Job TTL cleanup.
3054
+ const jobUid = kubectl(['-n', namespace, 'get', 'job', name, '-o', 'jsonpath={.metadata.uid}']);
3055
+ const uid = jobUid.status === 0 ? jobUid.stdout.trim() : '';
3056
+ lifecycleJobUid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu.test(uid) ? uid : undefined;
3057
+ if (lifecycleJobUid) {
3058
+ const owned = kubectl(['-n', namespace, 'patch', 'secret', `${name}-creds`, '--type=merge', '-p', JSON.stringify({ metadata: { ownerReferences: [{ apiVersion: 'batch/v1', kind: 'Job', name, uid: lifecycleJobUid }] } })]);
3059
+ if (owned.status !== 0) debug.log('self-implement.pod', 'secret-owner-failed', { job: name, stderr: owned.stderr.trim() }, { level: 'warn' });
3060
+ else debug.log('self-implement.pod', 'secret-owner-attached', { job: name, owner: 'job' });
3061
+ } else {
3062
+ debug.log('self-implement.pod', 'secret-owner-job-uid-unavailable', { job: name }, { level: 'warn' });
3063
+ }
2937
3064
  releaseAdmission?.applied?.(name, context, namespace);
2938
3065
  try { appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-config-snapshot', data: {
2939
3066
  job: name, hash: configSnapshot.hash, keyCount: configSnapshot.keyCount,
@@ -2996,16 +3123,10 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2996
3123
  }
2997
3124
  debug.log('self-implement.pod', 'source-delivered', { job: name, kind: 'bundle', headCommit: options.source.headCommit });
2998
3125
  }
2999
- // ☸️ P2: 비밀의 소유자 = Job — 호스트가 죽어도 Job 의 TTL 삭제와 함께 k8s 가 비밀을 거둔다(자격 사본이 클러스터에 남지 않는다).
3000
- const uid = kubectl(['-n', namespace, 'get', 'job', name, '-o', 'jsonpath={.metadata.uid}']).stdout.trim();
3001
- lifecycleJobUid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu.test(uid) ? uid : undefined;
3002
- if (uid) {
3003
- const owned = kubectl(['-n', namespace, 'patch', 'secret', `${name}-creds`, '--type=merge', '-p', JSON.stringify({ metadata: { ownerReferences: [{ apiVersion: 'batch/v1', kind: 'Job', name, uid }] } })]);
3004
- if (owned.status !== 0) debug.log('self-implement.pod', 'secret-owner-failed', { job: name, stderr: owned.stderr.trim() }, { level: 'warn' });
3005
- }
3006
3126
  }
3007
3127
  try {
3008
- appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-child-run', data: { childRunId: liveChildRunId, job: name, attempt: oomRetried ? 2 : 1, ...(goalFile ? { goalFile } : {}) } }, ledgerDir);
3128
+ appendRunLedgerEntry({ runId: ledgerRunId, timestamp: new Date((options.now ?? Date.now)()).toISOString(),
3129
+ event: 'pod-child-run', data: { childRunId: liveChildRunId, job: name, attempt: oomRetried ? 2 : 1, ...(goalFile ? { goalFile } : {}) } }, ledgerDir);
3009
3130
  appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-job-applied', data: { job: name, childRunId: liveChildRunId, jobUid: lifecycleJobUid, host: member?.sshHost ?? resolveHostId(env), context, namespace } }, ledgerDir);
3010
3131
  if (lastPlacement) appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-placement', data: { job: name, childRunId: liveChildRunId, attempt: oomRetried ? 2 : 1, member: lastPlacement.member, kind: lastPlacement.kind, outcome: lastPlacement.outcome, preferred: lastPlacement.preferred, reason: lastPlacement.reason } }, ledgerDir);
3011
3132
  appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-memory-selected', data: { job: name, childRunId: liveChildRunId, attempt: oomRetried ? 2 : 1, limit: memoryLimit, ...(appliedMemoryRequest ? { request: appliedMemoryRequest } : {}), tier: oomRetried ? retryTier : memoryTier, source: oomRetried ? 'oom-retry' : memorySource, reason: oomRetried ? 'OOMKilled' : memoryReason, declaredGoalType: selectedGoalType } }, ledgerDir);
@@ -3181,11 +3302,11 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
3181
3302
  if (seen !== null) {
3182
3303
  releaseAdmission?.observed?.();
3183
3304
  state = seen === 0 ? 'complete' : 'failed';
3184
- // The child's own rc (the Pod's terminated state may lag like the condition) — exit-code paths read it as before.
3185
- if (seen !== 0) containerExitCode = seen;
3305
+ // The shared marker is authoritative while Pod status lags; preserve the child's rc, including 0, on the parent.
3306
+ containerExitCode = seen;
3186
3307
  if (seen !== 0) podTermination = readPodTermination({ kubectl, namespace, job: name, path: 'result-marker', jobUid: lifecycleJobUid });
3187
3308
  if (seen !== 0) captureFailedJob(liveChildRunId);
3188
- debug.log('self-implement.pod', 'result-marker-early', { job: name, waitedMs: Date.now() - waitStartedAt, rc: seen });
3309
+ debug.log('self-implement.pod', 'result-marker-early', { job: name, runId: liveChildRunId, waitedMs: Date.now() - waitStartedAt, rc: seen });
3189
3310
  break;
3190
3311
  }
3191
3312
  }
@@ -3452,11 +3573,24 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
3452
3573
  };
3453
3574
  }
3454
3575
  let noResultDiagnostic: string | null = null;
3576
+ let noResultLedgerObservation: { available: boolean; bytes: number; rows: number; lastEvent: string | null } = {
3577
+ available: false, bytes: 0, rows: 0, lastEvent: null,
3578
+ };
3455
3579
  // POD-NORESULT: a terminal Job without a parsed disposition is incomplete even when the Job condition says Complete.
3456
3580
  const noResultCandidate = !podVanished && !disposition && !oomKilled && failedReason !== 'DeadlineExceeded' &&
3457
3581
  (state === 'complete' || (state === 'failed' && containerExitCode !== 0));
3458
3582
  if (noResultCandidate) {
3459
- try { noResultDiagnostic = podNoResultDiagnostic(readFileSync(runLedgerPath(liveChildRunId, ledgerDir), 'utf8')); }
3583
+ try {
3584
+ const ledgerText = readFileSync(runLedgerPath(liveChildRunId, ledgerDir), 'utf8');
3585
+ const ledgerRows = ledgerText.split('\n').filter(Boolean);
3586
+ let lastEvent: string | null = null;
3587
+ try {
3588
+ const parsed = JSON.parse(ledgerRows.at(-1) ?? 'null') as { event?: unknown } | null;
3589
+ lastEvent = typeof parsed?.event === 'string' ? parsed.event : null;
3590
+ } catch { /* Keep counts when the last ledger row is malformed. */ }
3591
+ noResultLedgerObservation = { available: true, bytes: Buffer.byteLength(ledgerText), rows: ledgerRows.length, lastEvent };
3592
+ noResultDiagnostic = podNoResultDiagnostic(ledgerText);
3593
+ }
3460
3594
  catch { /* ledger not returned: do not invent a stage */ }
3461
3595
  noResultDiagnostic ??= 'child terminal result missing; last ledger stage=unknown; round=unknown; mustFix=unknown';
3462
3596
  }
@@ -3468,20 +3602,41 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
3468
3602
  const missingStage = noResultDiagnostic?.includes('stage=unknown') ?? false;
3469
3603
  if (shouldCaptureFailureLog || missingStage) {
3470
3604
  const logRead = readPodNoResultLogTail({ run: kubectl, namespace, job: name, maxLines: POD_NO_RESULT_LOG_TAIL_LINES });
3605
+ const logObservation = 'tail' in logRead
3606
+ ? { available: true, readState: 'tail-read', lines: logRead.tail.length, normalizedTailBytes: Buffer.byteLength(logRead.tail.join('\n')) }
3607
+ : { available: false, readState: logRead.unavailable === 'empty log output' ? 'empty' : 'read-failed', reason: logRead.unavailable, lines: 0, normalizedTailBytes: 0 };
3608
+ const childLedgerResultMissing = noResultCandidate && Boolean(noResultDiagnostic?.includes('child terminal result missing'));
3609
+ const observation = {
3610
+ classification: disposition ? 'result-parsed' : 'insufficient-evidence',
3611
+ noResultCandidate,
3612
+ launchRunIdPresent: Boolean(liveChildRunId),
3613
+ childLedger: noResultCandidate ? noResultLedgerObservation : null,
3614
+ childLedgerResultPresent: noResultCandidate ? !childLedgerResultMissing : null,
3615
+ resultParsed: Boolean(disposition),
3616
+ resultLineObserved: Boolean(terminal),
3617
+ pod: { jobReason: failedReason ?? null, containerReason: containerReason ?? null, exitCode: containerExitCode ?? null },
3618
+ childLog: logObservation,
3619
+ missing: [
3620
+ ...(noResultCandidate && !noResultLedgerObservation.available ? ['child-ledger'] : []),
3621
+ ...(childLedgerResultMissing ? ['child-ledger-result'] : []),
3622
+ ...(!disposition ? ['child-result-line', 'child-result-classification'] : []),
3623
+ ...(!logObservation.available ? ['child-log-cause-lines'] : []),
3624
+ ],
3625
+ };
3471
3626
  if ('tail' in logRead) {
3472
3627
  noResultLogEvidence = missingStage
3473
- ? { stderr: logRead.tail.join('\n'), logTail: logRead.tail, logTailLines: logRead.tail.length }
3474
- : { podLogTail: logRead.tail, podLogTailLines: logRead.tail.length };
3628
+ ? { stderr: logRead.tail.join('\n'), logTail: logRead.tail, logTailLines: logRead.tail.length, observation }
3629
+ : { podLogTail: logRead.tail, podLogTailLines: logRead.tail.length, observation };
3475
3630
  debug.log('self-implement.pod', missingStage ? 'no-result-log-tail' : 'failed-pod-log-tail', {
3476
- job: name, childRunId: liveChildRunId, diagnostic: noResultDiagnostic, lines: logRead.tail.length, logTail: logRead.tail,
3631
+ job: name, childRunId: liveChildRunId, diagnostic: noResultDiagnostic, ...observation, lines: logRead.tail.length, logTail: logRead.tail,
3477
3632
  }, { compact: { stringMax: 500 } });
3478
3633
  } else {
3479
3634
  const unavailable = `log-unavailable: ${logRead.unavailable}`;
3480
3635
  noResultLogEvidence = missingStage
3481
- ? { stderr: unavailable }
3482
- : { podLogUnavailable: logRead.unavailable };
3636
+ ? { stderr: unavailable, observation }
3637
+ : { podLogUnavailable: logRead.unavailable, observation };
3483
3638
  debug.log('self-implement.pod', missingStage ? 'no-result-log-tail' : 'failed-pod-log-tail', {
3484
- job: name, childRunId: liveChildRunId, diagnostic: noResultDiagnostic,
3639
+ job: name, childRunId: liveChildRunId, diagnostic: noResultDiagnostic, ...observation,
3485
3640
  logUnavailable: missingStage ? unavailable : logRead.unavailable,
3486
3641
  }, { level: 'warn' });
3487
3642
  }
@@ -3498,12 +3653,57 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
3498
3653
  // exitCode stays null when the container's code was not read (never filled in as 0).
3499
3654
  const finishedRow = { job: name, run: launchRunId, ...(liveChildRunId !== launchRunId ? { childRun: liveChildRunId } : {}),
3500
3655
  attempt: oomRetried ? 2 : 1, phase: state, exitCode: containerExitCode,
3501
- reason: failedReason || containerReason || (state === 'complete' ? 'complete' : 'unknown') };
3656
+ reason: failedReason || containerReason || (state === 'complete' ? 'complete' : 'unknown'),
3657
+ // POD-TERMINAL-EVIDENCE-JOIN: keep classifier and termination cause on this Job/childRun/attempt row.
3658
+ failureClassification: disposition?.failureClassification ?? null,
3659
+ classificationBasis: disposition?.childEvidence?.classificationBasis ?? null,
3660
+ // The child-run status is a different axis from the implementation's abandoned classification.
3661
+ // Preserve it even when the child did not emit a parseable self-implement disposition.
3662
+ podExitClass: state === 'failed' ? classifyPodExit({ containerReason: containerReason ?? null,
3663
+ containerExitCode: containerExitCode ?? null, jobReason: failedReason || null, logs }).class : null,
3664
+ childFailureStage: childFailure?.stage ?? null,
3665
+ terminationReason: typeof disposition?.childEvidence?.terminationReason === 'string'
3666
+ ? redactSecretText(disposition.childEvidence.terminationReason).slice(0, 200) : null };
3502
3667
  try { appendRunLedgerEntry({ runId: ledgerRunId, event: POD_LAUNCH_FINISHED_EVENT, timestamp: new Date((options.now ?? Date.now)()).toISOString(), data: finishedRow }, ledgerDir); }
3503
3668
  catch (error) { debug.log('pod.provenance', 'history-unavailable', { job: name, row: 'finished', reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
3504
3669
  debug.log('pod.provenance', 'job-finished', finishedRow);
3505
- 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,
3670
+ // Keep report-deficit incidents queryable as one bounded event. The child detail field is
3671
+ // intentionally capped elsewhere, so cause evidence must not depend on that full payload.
3672
+ const reportDeficit = disposition?.failureClassification === 'report-deficit';
3673
+ const noResultIncident = state === 'failed' && failedReason !== 'DeadlineExceeded' && !disposition;
3674
+ if (reportDeficit || noResultIncident) {
3675
+ const evidence = disposition?.childEvidence;
3676
+ const diagnosticLines = [
3677
+ ...(Array.isArray(evidence?.podLogTail) ? evidence.podLogTail : []),
3678
+ ...(typeof evidence?.detail === 'string' ? evidence.detail.split('\n') : []),
3679
+ ...(typeof evidence?.detailTail === 'string' ? evidence.detailTail.split('\n') : []),
3680
+ ...(typeof evidence?.stderr === 'string' ? evidence.stderr.split('\n') : []),
3681
+ ...(Array.isArray(noResultLogEvidence?.logTail) ? noResultLogEvidence.logTail as string[] : []),
3682
+ ...(Array.isArray(noResultLogEvidence?.podLogTail) ? noResultLogEvidence.podLogTail as string[] : []),
3683
+ ...(typeof noResultLogEvidence?.stderr === 'string' ? noResultLogEvidence.stderr.split('\n') : []),
3684
+ ].slice(-12).map((line) => redactSecretText(line).slice(0, 500));
3685
+ debug.log('pod.child', reportDeficit ? 'report-deficit-cause' : 'terminal-cause', {
3686
+ job: name, run: launchRunId, childRun: liveChildRunId, attempt: oomRetried ? 2 : 1,
3687
+ // A missing parsed result is an incident trigger, not proof of the child's classifier.
3688
+ classification: disposition?.failureClassification ?? null,
3689
+ ...(noResultIncident ? { trigger: 'no-result' } : {}),
3690
+ podExitClass: finishedRow.podExitClass,
3691
+ classificationBasis: evidence?.classificationBasis ?? null,
3692
+ phase: state, exitCode: containerExitCode,
3693
+ reason: failedReason || containerReason || 'unknown',
3694
+ terminationReason: evidence?.terminationReason ?? null,
3695
+ providerErrors: disposition?.providerErrors ?? null,
3696
+ oomKilled, podTermination: podTermination ?? null,
3697
+ detailTail: evidence?.detailTail ?? null,
3698
+ lastLines: diagnosticLines,
3699
+ }, { level: 'warn', compact: { stringMax: 4_500 } });
3700
+ }
3701
+ 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, attempt: oomRetried ? 2 : 1, ledgerCompleteness,
3702
+ ...(noResultLogEvidence ? { stopEvidenceTail: podStopEvidenceTail(noResultLogEvidence) } : {}),
3506
3703
  ...(podTermination ? { podTermination } : {}),
3704
+ failureClassification: finishedRow.failureClassification,
3705
+ classificationBasis: finishedRow.classificationBasis,
3706
+ terminationReason: finishedRow.terminationReason,
3507
3707
  ...(state === 'failed' && !oomKilled && failedReason !== 'DeadlineExceeded'
3508
3708
  ? { ...(childFailure ? { childStage: childFailure.stage } : disposition?.stage ? { childStage: disposition.stage } : {}),
3509
3709
  // 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).
@@ -3569,7 +3769,10 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
3569
3769
  if (!await acquireAdmission()) return admissionFailure();
3570
3770
  member = await acquireSlot();
3571
3771
  if (options.pool && !member) {
3572
- if (lastSlotAttempt) recordSlotObservation(lastSlotAttempt, 'rejected', lastSlotReasonCode ?? 'aborted');
3772
+ if (lastSlotAttempt) recordSlotObservation(lastSlotAttempt, 'rejected', lastSlotReasonCode ?? 'aborted', {
3773
+ waitReason: stageReason['pool-slot'] ?? null,
3774
+ ...(typeof input.signal?.reason === 'string' ? { abortReason: input.signal.reason } : {}),
3775
+ });
3573
3776
  return { exitCode: null, output: '', error: { code: 'aborted', message: 'aborted before a pool slot opened', ...(lastSlotReasonCode ? { reasonCode: lastSlotReasonCode } : {}) } };
3574
3777
  }
3575
3778
  if (member) context = member.context;
@@ -3595,13 +3798,21 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
3595
3798
  }
3596
3799
  // The host still has the complete Pod log here. The CLI only retains a short stdout tail,
3597
3800
  // so preserve the parsed child facts in the parent ledger before that tail is returned.
3598
- if (state === 'failed' || state === 'aborted' || noResultLogEvidence || (state === 'complete' && noResultDiagnostic !== null)) {
3801
+ const childEvidenceRow = podChildEvidenceLedgerRow({
3802
+ job: name,
3803
+ childRunId: liveChildRunId,
3804
+ state,
3805
+ result: disposition ?? null,
3806
+ noResultDiagnostic,
3807
+ noResultLogEvidence,
3808
+ podTermination,
3809
+ });
3810
+ if (childEvidenceRow) {
3599
3811
  // Every terminal attempt writes a marker, including one with no parseable child facts.
3600
3812
  // The next attempt must never inherit an earlier Pod's classification.
3601
- const childEvidence = noResultLogEvidence
3602
- ? { ...(disposition?.childEvidence ?? {}), ...noResultLogEvidence }
3603
- : disposition?.childEvidence ?? null;
3604
- try { appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-child-evidence', data: { childEvidence, childRunId: liveChildRunId, job: name, ...(podTermination ? { podTermination } : {}) } }, ledgerDir); }
3813
+ // Also persist completed Jobs whose child result is unsuccessful; Kubernetes
3814
+ // Completed is container success, not proof the requested work converged.
3815
+ try { appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-child-evidence', data: childEvidenceRow }, ledgerDir); }
3605
3816
  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' }); }
3606
3817
  }
3607
3818
  let prLookup: OpenPrByBranch | undefined;
@@ -3831,6 +4042,15 @@ function boundedPodLogText(source: string, maxChars: number): string {
3831
4042
  return redacted.length > maxChars ? `${redacted.slice(0, maxChars)}…[truncated]` : redacted;
3832
4043
  }
3833
4044
 
4045
+ /** A compact, redacted stop clue carried on the attempt-scoped finished row. */
4046
+ function podStopEvidenceTail(evidence: Record<string, unknown>): string[] {
4047
+ const raw = Array.isArray(evidence.logTail) ? evidence.logTail
4048
+ : Array.isArray(evidence.podLogTail) ? evidence.podLogTail
4049
+ : typeof evidence.stderr === 'string' ? evidence.stderr.split(/\r\n|\n|\r/u) : [];
4050
+ return raw.slice(-12).filter((line): line is string => typeof line === 'string' && line.length > 0)
4051
+ .map((line) => redactSecretText(line).slice(0, 240));
4052
+ }
4053
+
3834
4054
  /** 로그 꼬리 — 마지막 N줄만, 한 줄씩 비밀값 마스킹. */
3835
4055
  export function podNoResultLogTailLines(source: string, maxLines: number = POD_NO_RESULT_LOG_TAIL_LINES): string[] {
3836
4056
  const lines = source.replace(/\r\n/g, '\n').split('\n');