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
@@ -16,12 +16,14 @@ import { isAbsolute, join, resolve } from 'node:path';
16
16
  import { spawnSync } from 'node:child_process';
17
17
  import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
18
18
  import { debug } from '../debug/log.js';
19
+ import { incidentLastLines } from './harness-incidents.js';
19
20
  import { selfDevRunsDir } from '../self-dev/run-store.js';
20
21
  import { launchBindingRunIds, launchRegistryDir, readLaunchBinding } from './launch-registry.js';
21
22
  import { loadRunLedger, resolveFederatedRunLedgerDirectories, runLedgerDir } from '../self-implement/run-ledger.js';
22
23
 
23
24
  const RUN_ID = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
24
25
  const FULL_RUN_ID = /^run-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
26
+ const STOP_POD_OBSERVATION_BUDGET_MS = 4_000;
25
27
 
26
28
  export class AmbiguousHarnessStopRunIdError extends Error {
27
29
  constructor(given: string, candidates: readonly string[]) {
@@ -151,12 +153,14 @@ export interface HarnessStopDeps {
151
153
  kill: (pid: number, signal: NodeJS.Signals) => void;
152
154
  sleep: (ms: number) => Promise<void>;
153
155
  kubeContexts: () => string[];
154
- kubectl: (args: readonly string[]) => { status: number | null; stdout: string; stderr: string };
156
+ kubectl: (args: readonly string[], timeoutMs?: number) => { status: number | null; stdout: string; stderr: string };
155
157
  namespace: string;
156
158
  graceMs: number;
159
+ observePodsBeforeDelete?: (runId: string, context: string, label: HarnessStopJobMatchedBy, budget: HarnessStopObservationBudget) => void;
157
160
  }
158
161
 
159
162
  export type HarnessStopJobMatchedBy = 'elanous.run' | 'elanous.child-run';
163
+ type HarnessStopObservationBudget = { startedAt: number | null; budgetMs: number; observedPods: number };
160
164
 
161
165
  /**
162
166
  * 문맥 하나의 Pod Job 삭제 결과(HARNESS-STOP-POD-LABEL) — «0개 지움» 의 종류를 가른다.
@@ -218,12 +222,130 @@ export function psProcessStartMs(pid: number): number | null {
218
222
 
219
223
  export function defaultHarnessStopDeps(overrides: Partial<HarnessStopDeps> = {}, opts: { launchRegistryDir?: string } = {}): HarnessStopDeps {
220
224
  const registry = opts.launchRegistryDir ?? launchRegistryDir();
225
+ const namespace = overrides.namespace ?? 'elanous-test';
226
+ const graceMs = overrides.graceMs ?? 10_000;
221
227
  const env = { ...process.env };
222
228
  for (const key of ['HTTPS_PROXY', 'https_proxy', 'HTTP_PROXY', 'http_proxy', 'ALL_PROXY', 'all_proxy']) delete env[key];
223
- const kubectl = (args: readonly string[]) => {
224
- const r = spawnSync('kubectl', [...args], { encoding: 'utf8', timeout: 15_000, env, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
229
+ const kubectl = (args: readonly string[], timeoutMs = 15_000) => {
230
+ const r = spawnSync('kubectl', [...args], { encoding: 'utf8', timeout: timeoutMs, env, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
225
231
  return { status: r.status, stdout: r.stdout ?? '', stderr: r.stderr ?? String(r.error ?? '') };
226
232
  };
233
+ const runKubectl = overrides.kubectl ?? kubectl;
234
+ const maxObservedPods = 2;
235
+ const listTimeoutMs = 1_500;
236
+ const logTimeoutMs = 750;
237
+ const observePodsBeforeDelete = (runId: string, context: string, label: HarnessStopJobMatchedBy, budget: HarnessStopObservationBudget): void => {
238
+ const requestedAt = new Date().toISOString();
239
+ const reporterSeat = process.env.ELANOUS_HARNESS_SEAT ?? null;
240
+ budget.startedAt ??= performance.now();
241
+ const remainingMs = () => Math.max(0, budget.budgetMs - (performance.now() - budget.startedAt!));
242
+ const emit = (data: Record<string, unknown>) => debug.log('harness.stop', 'job-termination-predelete', {
243
+ runId, context, matchedBy: label, requestedAt, reporter: 'harness-stop', reporterSeat, reporterCommand: 'harness stop', ...data,
244
+ });
245
+ if (remainingMs() <= 0) {
246
+ emit({ status: 'budget-exhausted', pods: [], omittedPods: null, observationBudgetMs: budget.budgetMs });
247
+ return;
248
+ }
249
+ try {
250
+ const listed = runKubectl(['--context', context, '-n', namespace, 'get', 'pods', '-l', `${label}=${runId}`, '-o', 'json'], Math.min(listTimeoutMs, remainingMs()));
251
+ let pods: unknown[] = [];
252
+ let listStatus: 'observed' | 'unavailable' | 'invalid' = 'observed';
253
+ if (listed.status !== 0) listStatus = 'unavailable';
254
+ else {
255
+ try {
256
+ const parsed = JSON.parse(listed.stdout) as { items?: unknown };
257
+ if (!Array.isArray(parsed.items)) listStatus = 'invalid';
258
+ else pods = parsed.items;
259
+ } catch { listStatus = 'invalid'; }
260
+ }
261
+ const selectedPods = pods.slice(0, Math.max(0, maxObservedPods - budget.observedPods));
262
+ budget.observedPods += selectedPods.length;
263
+ const evidence = selectedPods.map((raw) => {
264
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return { status: 'invalid-pod-record' };
265
+ const pod = raw as {
266
+ metadata?: { name?: unknown; labels?: unknown; ownerReferences?: unknown };
267
+ spec?: { nodeName?: unknown; activeDeadlineSeconds?: unknown; containers?: unknown };
268
+ status?: { phase?: unknown; reason?: unknown; message?: unknown; startTime?: unknown; conditions?: unknown; containerStatuses?: unknown };
269
+ };
270
+ const meta = pod.metadata && typeof pod.metadata === 'object' ? pod.metadata : {};
271
+ const spec = pod.spec && typeof pod.spec === 'object' ? pod.spec : {};
272
+ const status = pod.status && typeof pod.status === 'object' ? pod.status : {};
273
+ const arraysValid = (meta.ownerReferences === undefined || Array.isArray(meta.ownerReferences))
274
+ && (spec.containers === undefined || Array.isArray(spec.containers))
275
+ && (status.conditions === undefined || Array.isArray(status.conditions))
276
+ && (status.containerStatuses === undefined || Array.isArray(status.containerStatuses));
277
+ if (!arraysValid) return { status: 'invalid-pod-record' };
278
+ const name = typeof meta.name === 'string' ? meta.name : null;
279
+ const deadlineSeconds = typeof spec.activeDeadlineSeconds === 'number' && Number.isFinite(spec.activeDeadlineSeconds) && spec.activeDeadlineSeconds >= 0 ? spec.activeDeadlineSeconds : null;
280
+ const startedAt = typeof status.startTime === 'string' ? status.startTime : null;
281
+ let deadlineAt: string | null = null;
282
+ if (deadlineSeconds !== null && startedAt) {
283
+ const startMs = Date.parse(startedAt);
284
+ const deadlineMs = startMs + deadlineSeconds * 1000;
285
+ if (Number.isFinite(startMs) && Number.isFinite(deadlineMs)) {
286
+ try { deadlineAt = new Date(deadlineMs).toISOString(); } catch { deadlineAt = null; }
287
+ }
288
+ }
289
+ let tail: string[] | null = null;
290
+ let tailStatus: 'observed' | 'unavailable' | 'not-requested' | 'budget-exhausted' = 'not-requested';
291
+ if (name && remainingMs() > 0) {
292
+ const logs = runKubectl(['--context', context, '-n', namespace, 'logs', `pod/${name}`, '-c', 'child', '--tail=20'], Math.min(logTimeoutMs, remainingMs()));
293
+ if (logs.status === 0) { tail = incidentLastLines(logs.stdout); tailStatus = 'observed'; }
294
+ else { tail = incidentLastLines(logs.stderr); tailStatus = 'unavailable'; }
295
+ } else if (name) tailStatus = 'budget-exhausted';
296
+ const owners = Array.isArray(meta.ownerReferences) ? (meta.ownerReferences as Array<{ kind?: unknown; name?: unknown }>).slice(0, 20) : [];
297
+ const labels = meta.labels && typeof meta.labels === 'object' ? meta.labels as Record<string, unknown> : {};
298
+ const containers = Array.isArray(spec.containers) ? (spec.containers as Array<{ name?: unknown; image?: unknown; imagePullPolicy?: unknown }>).slice(0, 20) : [];
299
+ const conditions = Array.isArray(status.conditions) ? (status.conditions as Array<{ type?: unknown; status?: unknown; reason?: unknown; message?: unknown; lastTransitionTime?: unknown }>).slice(0, 20) : [];
300
+ const containerStatuses = Array.isArray(status.containerStatuses) ? (status.containerStatuses as Array<{ name?: unknown; imageID?: unknown; state?: unknown }>).slice(0, 20) : [];
301
+ return {
302
+ pod: name,
303
+ job: owners.find((owner) => owner?.kind === 'Job' && typeof owner.name === 'string')?.name ?? null,
304
+ childRunId: typeof labels['elanous.child-run'] === 'string' ? labels['elanous.child-run'] : null,
305
+ nodeName: typeof spec.nodeName === 'string' ? spec.nodeName : null,
306
+ images: containers.map((container) => container && typeof container === 'object' ? ({
307
+ name: typeof container.name === 'string' ? container.name : null,
308
+ image: typeof container.image === 'string' ? container.image : null,
309
+ imagePullPolicy: typeof container.imagePullPolicy === 'string' ? container.imagePullPolicy : null,
310
+ }) : { status: 'invalid-container-record' }),
311
+ phase: typeof status.phase === 'string' ? status.phase : null,
312
+ reason: typeof status.reason === 'string' ? status.reason : null,
313
+ message: typeof status.message === 'string' ? incidentLastLines(status.message).at(-1) ?? null : null,
314
+ startTime: startedAt, activeDeadlineSeconds: deadlineSeconds, deadlineAt,
315
+ conditions: conditions.map((condition) => condition && typeof condition === 'object' ? ({
316
+ type: typeof condition.type === 'string' ? condition.type : null,
317
+ status: typeof condition.status === 'string' ? condition.status : null,
318
+ reason: typeof condition.reason === 'string' ? condition.reason : null,
319
+ message: typeof condition.message === 'string' ? incidentLastLines(condition.message).at(-1) ?? null : null,
320
+ lastTransitionTime: typeof condition.lastTransitionTime === 'string' ? condition.lastTransitionTime : null,
321
+ }) : { status: 'invalid-condition-record' }),
322
+ containers: containerStatuses.map((container) => {
323
+ if (!container || typeof container !== 'object') return { status: 'invalid-container-status-record' };
324
+ const state = container.state && typeof container.state === 'object' ? container.state as Record<string, unknown> : {};
325
+ const waiting = state.waiting && typeof state.waiting === 'object' ? state.waiting as { reason?: unknown; message?: unknown } : null;
326
+ const terminated = state.terminated && typeof state.terminated === 'object' ? state.terminated as { reason?: unknown; exitCode?: unknown; signal?: unknown; finishedAt?: unknown } : null;
327
+ return {
328
+ name: typeof container.name === 'string' ? container.name : null,
329
+ imageID: typeof container.imageID === 'string' ? container.imageID : null,
330
+ waiting: waiting ? { reason: typeof waiting.reason === 'string' ? waiting.reason : null, message: typeof waiting.message === 'string' ? incidentLastLines(waiting.message).at(-1) ?? null : null } : null,
331
+ terminated: terminated ? {
332
+ reason: typeof terminated.reason === 'string' ? terminated.reason : null,
333
+ exitCode: typeof terminated.exitCode === 'number' && Number.isFinite(terminated.exitCode) ? terminated.exitCode : null,
334
+ signal: typeof terminated.signal === 'number' && Number.isFinite(terminated.signal) ? terminated.signal : null,
335
+ finishedAt: typeof terminated.finishedAt === 'string' ? terminated.finishedAt : null,
336
+ } : null,
337
+ };
338
+ }),
339
+ tailSource: 'kubectl-logs-merged-streams', tailStatus, tail,
340
+ };
341
+ });
342
+ emit({ status: listStatus, pods: evidence, omittedPods: Math.max(0, pods.length - selectedPods.length), observationBudgetMs: budget.budgetMs,
343
+ ...(listStatus === 'unavailable' ? { reason: incidentLastLines(listed.stderr).at(-1) ?? 'kubectl failed' } : {}) });
344
+ } catch (error) {
345
+ emit({ status: 'invalid', pods: [], omittedPods: null, observationBudgetMs: budget.budgetMs,
346
+ reason: incidentLastLines(error instanceof Error ? error.message : String(error)).at(-1) ?? 'observation failed' });
347
+ }
348
+ };
227
349
  return {
228
350
  // This universe first; then the host-wide launch binding, so a run launched from another worktree is still found.
229
351
  readPidRecord: (runId) => readPidRecordFrom(selfDevRunsDir(), runId) ?? pidRecordFromLaunchBinding(runId, registry),
@@ -243,12 +365,13 @@ export function defaultHarnessStopDeps(overrides: Partial<HarnessStopDeps> = {},
243
365
  kill: (pid, signal) => { process.kill(pid, signal); },
244
366
  sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
245
367
  kubeContexts: () => {
246
- const r = kubectl(['config', 'get-contexts', '-o', 'name']);
368
+ const r = runKubectl(['config', 'get-contexts', '-o', 'name']);
247
369
  return r.status === 0 ? r.stdout.split('\n').map((l) => l.trim()).filter(Boolean) : [];
248
370
  },
249
- kubectl,
250
- namespace: 'elanous-test',
251
- graceMs: 10_000,
371
+ kubectl: runKubectl,
372
+ observePodsBeforeDelete,
373
+ namespace,
374
+ graceMs,
252
375
  ...overrides,
253
376
  };
254
377
  }
@@ -271,7 +394,7 @@ function countDeletedJobLines(stdout: string): number {
271
394
  }
272
395
 
273
396
  /** 문맥 하나의 Pod Job 삭제 — 결과를 넷(deleted·none·unreachable·pods-only)으로 가르고 문맥마다 관측 `harness.stop` `job-delete` 를 남긴다. */
274
- function deleteRunPodJobs(deps: HarnessStopDeps, runId: string, context: string): HarnessStopJobDelete {
397
+ function deleteRunPodJobs(deps: HarnessStopDeps, runId: string, context: string, budget: HarnessStopObservationBudget): HarnessStopJobDelete {
275
398
  const unreachable = (stderr: string): HarnessStopJobDelete => {
276
399
  const error = stderr.slice(0, 200);
277
400
  debug.log('harness.stop', 'job-delete', { runId, context, outcome: 'unreachable', matchedBy: null, error }, { level: 'warn' });
@@ -281,6 +404,14 @@ function deleteRunPodJobs(deps: HarnessStopDeps, runId: string, context: string)
281
404
  for (const label of POD_JOB_LABELS) {
282
405
  // `-o name` → «job.batch/<name>» 한 줄씩. 맨 출력은 «job.batch "<name>" deleted» 라 «job.batch/» 로만 세면
283
406
  // 지워도 늘 0 이었다(10-11 · 여섯 번 «0개 지움» 뒤 Pod Terminating). 두 꼴을 다 센다(#26194).
407
+ try { deps.observePodsBeforeDelete?.(runId, context, label, budget); }
408
+ catch (error) {
409
+ debug.log('harness.stop', 'job-termination-predelete', {
410
+ runId, context, matchedBy: label, reporter: 'harness-stop', reporterSeat: process.env.ELANOUS_HARNESS_SEAT ?? null,
411
+ reporterCommand: 'harness stop', status: 'invalid', pods: [], omittedPods: null,
412
+ reason: incidentLastLines(error instanceof Error ? error.message : String(error)).at(-1) ?? 'observation failed',
413
+ }, { level: 'warn' });
414
+ }
284
415
  const r = deps.kubectl(['--context', context, '-n', deps.namespace, 'delete', 'job', '-l', `${label}=${runId}`, '--wait=false', '-o', 'name']);
285
416
  if (r.status !== 0) return unreachable(r.stderr);
286
417
  const deleted = countDeletedJobLines(r.stdout);
@@ -326,6 +457,18 @@ export async function stopHarnessRun(runId: string, deps: HarnessStopDeps, conte
326
457
  const add = (candidate: StopProcessCandidate) => {
327
458
  if (!seen.has(candidate.pid)) { seen.add(candidate.pid); candidates.push(candidate); }
328
459
  };
460
+ const requestSignal = (candidate: StopProcessCandidate, signal: NodeJS.Signals) => {
461
+ const requestAt = new Date().toISOString();
462
+ let delivery: 'accepted' | 'failed' = 'accepted';
463
+ try { deps.kill(candidate.pid, signal); }
464
+ catch { delivery = 'failed'; }
465
+ debug.log('harness.stop', 'process-signal-request', {
466
+ runId, signal, requestAt, targetPid: candidate.pid, targetStartedAt: new Date(candidate.startedAt).toISOString(),
467
+ targetDiscovery: candidate.via, delivery, reporter: 'harness-stop',
468
+ reporterSeat: process.env.ELANOUS_HARNESS_SEAT ?? null, reporterCommand: 'harness stop',
469
+ });
470
+ return delivery === 'accepted';
471
+ };
329
472
  let recordMismatch = false;
330
473
  if (record) {
331
474
  const recordedStart = deps.processStartMs(record.pid);
@@ -350,7 +493,7 @@ export async function stopHarnessRun(runId: string, deps: HarnessStopDeps, conte
350
493
  verified.push(candidate);
351
494
  }
352
495
  for (const candidate of verified) {
353
- try { deps.kill(candidate.pid, 'SIGTERM'); } catch { /* 방금 끝났다 */ }
496
+ requestSignal(candidate, 'SIGTERM');
354
497
  }
355
498
  for (const candidate of verified) {
356
499
  processState = 'stopped';
@@ -362,14 +505,15 @@ export async function stopHarnessRun(runId: string, deps: HarnessStopDeps, conte
362
505
  const still = deps.processStartMs(candidate.pid);
363
506
  const expectedStart = candidate.via === 'pid.json' ? record!.startedAt : candidate.startedAt;
364
507
  if (still !== null && Math.abs(still - expectedStart) <= START_TOLERANCE_MS) {
365
- try { deps.kill(candidate.pid, 'SIGKILL'); processState = 'killed'; } catch { /* 끝났다 */ }
508
+ if (requestSignal(candidate, 'SIGKILL')) processState = 'killed';
366
509
  }
367
510
  }
368
511
  if (processState === 'absent' && (scan.status === 'failed' || candidates.length > 0)) processState = 'unmeasured';
369
512
  }
370
513
  // ── ⓑ Pod Job (라벨로만) ───────────────────────────────────
371
514
  const targets = dryRun ? [] : contexts && contexts.length > 0 ? [...contexts] : deps.kubeContexts();
372
- const jobDeletes = targets.map((context) => deleteRunPodJobs(deps, runId, context));
515
+ const observationBudget: HarnessStopObservationBudget = { startedAt: null, budgetMs: STOP_POD_OBSERVATION_BUDGET_MS, observedPods: 0 };
516
+ const jobDeletes = targets.map((context) => deleteRunPodJobs(deps, runId, context, observationBudget));
373
517
  const jobsDeleted = jobDeletes.reduce((sum, job) => sum + job.deleted, 0);
374
518
  const result: HarnessStopResult = { runId, ...(given !== runId ? { givenRunId: given } : {}), process: processState, ...(record ? { pid: record.pid } : {}), candidates, scanned: scan.status === 'ok', pidRecordFound: record !== null, dryRun, jobsDeleted, jobDeletes, contexts: targets };
375
519
  debug.log('harness.stop', 'stopped', { runId, process: processState, jobsDeleted, contexts: targets.length });
@@ -0,0 +1,59 @@
1
+ import { parentPort } from 'node:worker_threads';
2
+ import { queryRunningRuns, type RunningRunsResult } from '../self-implement/running-runs.js';
3
+
4
+ /**
5
+ * HARNESS-PROGRESS-HANG — `harness progress` 하위 조회의 «전용 워커 엔트리».
6
+ * 이 모듈은 CLI 디스패치(`src/index.ts`·`bin/elanous.mjs`)를 거치지 않고 워커에 직접 적재되므로,
7
+ * 번들·컴파일 산출물에서도 `parentPort` 핸들러가 반드시 이 스레드에 등록된다.
8
+ * 그 전에는 워커가 `import.meta.url` 로 배포 엔트리를 재진입해 핸들러가 아예 안 올랐다.
9
+ */
10
+ export interface ProgressQueryWorkerRequest {
11
+ readonly kind?: 'query';
12
+ readonly caller: string;
13
+ readonly runIds?: readonly string[];
14
+ readonly timeBudgetMs?: number;
15
+ }
16
+
17
+ /** 상한 도달 뒤 부모가 보내는 정지 요청 — 워커는 «현재 행» 을 회신하고 정상 종료한다. */
18
+ export interface ProgressQueryWorkerAbortRequest {
19
+ readonly kind: 'abort';
20
+ }
21
+
22
+ export type ProgressQueryWorkerMessage = ProgressQueryWorkerRequest | ProgressQueryWorkerAbortRequest;
23
+
24
+ export interface ProgressQueryWorkerReply {
25
+ readonly ok: boolean;
26
+ readonly result?: RunningRunsResult;
27
+ readonly error?: string;
28
+ readonly stopped?: 'aborted';
29
+ }
30
+
31
+ /**
32
+ * 워커의 `parentPort` 핸들러를 등록한다.
33
+ * - `query`: 하위 조회를 실행해 결과를 회신한다.
34
+ * - `abort`: 이 스레드가 마지막으로 계산한 행(`lastResult`)을 «보존 행» 으로 회신한다 —
35
+ * 부모의 상한 뒤 유예 창 안에 도착하면 `progress-command-late` 관측으로 그대로 보존된다.
36
+ */
37
+ export function installProgressWorkerEntry(port: NonNullable<typeof parentPort> | null | undefined = parentPort): void {
38
+ if (!port) return;
39
+ let lastResult: RunningRunsResult | undefined;
40
+ port.on('message', (message: ProgressQueryWorkerMessage) => {
41
+ if (message.kind === 'abort') {
42
+ port.postMessage({ ok: true, result: lastResult, stopped: 'aborted' } satisfies ProgressQueryWorkerReply);
43
+ return;
44
+ }
45
+ try {
46
+ const result = queryRunningRuns({
47
+ caller: message.caller,
48
+ ...(message.timeBudgetMs === undefined ? {} : { timeBudgetMs: message.timeBudgetMs }),
49
+ ...(message.runIds === undefined ? {} : { runIds: message.runIds }),
50
+ });
51
+ lastResult = result;
52
+ port.postMessage({ ok: true, result } satisfies ProgressQueryWorkerReply);
53
+ } catch (error) {
54
+ port.postMessage({ ok: false, error: error instanceof Error ? error.message : String(error) } satisfies ProgressQueryWorkerReply);
55
+ }
56
+ });
57
+ }
58
+
59
+ installProgressWorkerEntry();
@@ -0,0 +1,11 @@
1
+ import { isMainThread } from 'node:worker_threads';
2
+
3
+ /**
4
+ * HARNESS-PROGRESS-HANG — `harness progress` 하위 조회는 «전용 워커 엔트리»(`./progress-worker-entry.ts`)
5
+ * 를 직접 적재한다. 그 엔트리는 CLI 디스패치를 거치지 않으므로 번들·컴파일 산출물에서도 `parentPort`
6
+ * 핸들러가 워커 스레드에 오른다. 이 판정은 배포 엔트리(`bin/elanous.mjs`)가 워커 문맥에서 재진입됐을 때
7
+ * 대시보드·provider 선택·명령 디스패치를 다시 걸지 않게 가드한다.
8
+ */
9
+ export function shouldRunCliEntry(): boolean {
10
+ return isMainThread;
11
+ }
package/src/index.ts CHANGED
@@ -4748,6 +4748,20 @@ selfCmd
4748
4748
  .option('--shard-position <n>', 'GATE-REMOTE-SHARD-PLAN — 조각 위치(1부터 정수). 원격 명령줄에 그대로 실린다')
4749
4749
  .option('--shard-plan <path>', 'GATE-REMOTE-SHARD-PLAN — 조각 계획 파일 경로. 주면 원격 명령줄에 --shard-plan 으로 실린다')
4750
4750
  .action(async (opts: { changed?: boolean; base?: string; pr?: string; shards?: string | boolean; shardConcurrency?: string; fixedShardDistribution?: boolean; includeImporters?: boolean; inherit?: boolean; remote?: string | boolean; local?: boolean; artifactDir?: string; orchestrationId?: string; shardId?: string; shardPosition?: string; shardPlan?: string }) => {
4751
+ const { observeSelfGateTrainMarker, refuseSeatSelfGateWithoutTrainMarker, writeSeatSelfGateRefusalArtifact } = require('./self-implement/gate-cli.js') as typeof import('./self-implement/gate-cli.js');
4752
+ const trainMarker = observeSelfGateTrainMarker();
4753
+ if (process.env.ELANOUS_TRACK) {
4754
+ const seatRefusal = refuseSeatSelfGateWithoutTrainMarker(trainMarker);
4755
+ if (seatRefusal) {
4756
+ if (opts.artifactDir !== undefined) {
4757
+ try { writeSeatSelfGateRefusalArtifact(process.cwd(), opts.artifactDir, trainMarker); }
4758
+ catch (error) { ui.error(`self gate artifact: ${error instanceof Error ? error.message : String(error)}`); }
4759
+ }
4760
+ ui.error(seatRefusal.message);
4761
+ process.exitCode = 2;
4762
+ return;
4763
+ }
4764
+ }
4751
4765
  if (!opts.changed && opts.shards === undefined) { ui.error('self gate requires --changed or --shards'); process.exitCode = 2; return; }
4752
4766
  if (opts.fixedShardDistribution && opts.shards === undefined) { ui.error('self gate: --fixed-shard-distribution requires --shards <n>'); process.exitCode = 2; return; }
4753
4767
  if (opts.shardConcurrency !== undefined && (!/^[1-4]$/.test(opts.shardConcurrency))) { ui.error('self gate: --shard-concurrency must be 1–4'); process.exitCode = 2; return; }
@@ -4770,7 +4784,7 @@ selfCmd
4770
4784
  ranLocal = true;
4771
4785
  try {
4772
4786
  const { runSelfGateCliAsync } = require('./self-implement/gate-cli.js') as typeof import('./self-implement/gate-cli.js');
4773
- const result = await runSelfGateCliAsync(process.cwd(), { base: opts.base, pr: opts.pr, shards, ...(opts.shardConcurrency !== undefined ? { shardConcurrency: Number(opts.shardConcurrency) } : {}), ...(opts.fixedShardDistribution ? { fixedShardDistribution: true } : {}), includeImporterTests: !!opts.includeImporters, noInherit: opts.inherit === false, ...(opts.artifactDir !== undefined ? { artifactDir: opts.artifactDir } : {}) });
4787
+ const result = await runSelfGateCliAsync(process.cwd(), { base: opts.base, pr: opts.pr, shards, ...(opts.shardConcurrency !== undefined ? { shardConcurrency: Number(opts.shardConcurrency) } : {}), ...(opts.fixedShardDistribution ? { fixedShardDistribution: true } : {}), includeImporterTests: !!opts.includeImporters, noInherit: opts.inherit === false, trainGate: trainMarker.received, ...(opts.artifactDir !== undefined ? { artifactDir: opts.artifactDir } : {}) });
4774
4788
  console.log(result.lines.join('\n'));
4775
4789
  return result.exitCode;
4776
4790
  } catch (error) {
@@ -4854,6 +4868,8 @@ selfCmd
4854
4868
  const fetched = remoteArtifacts && 'dir' in remoteArtifacts ? remoteArtifacts.fetch : undefined;
4855
4869
  try {
4856
4870
  if (fetched?.ok) {
4871
+ const { recordGateTrainMarker } = await import('./self-implement/gate-artifacts.js');
4872
+ recordGateTrainMarker(fetched.summaryPath, trainMarker.received);
4857
4873
  console.log(`artifacts: ${fetched.summaryPath} (junit ${fetched.junitFiles.length} · fetched from remote)`);
4858
4874
  if (fetched.remoteDirKept) console.log(`⚠ artifacts: 원격 산출 디렉토리를 못 지웠다 — ${(remoteArtifacts as { dir: string }).dir} (판정은 그대로다)`);
4859
4875
  }
@@ -4861,7 +4877,7 @@ selfCmd
4861
4877
  const reason = remoteArtifacts && 'unsupported' in remoteArtifacts ? 'remote-unsupported' as const : 'remote-fetch-failed' as const;
4862
4878
  if (reason === 'remote-fetch-failed') console.log(`⚠ artifacts: 원격 산출을 못 가져왔다 — ${fetched && !fetched.ok ? fetched.reason : 'no remote fetch ran'} (판정은 그대로다)`);
4863
4879
  const { writeRemoteUnavailableGateArtifacts } = await import('./self-implement/gate-artifacts.js');
4864
- const written = writeRemoteUnavailableGateArtifacts(opts.artifactDir, process.cwd(), opts.base, Number(process.exitCode ?? 0), reason);
4880
+ const written = writeRemoteUnavailableGateArtifacts(opts.artifactDir, process.cwd(), opts.base, Number(process.exitCode ?? 0), reason, undefined, undefined, trainMarker.received);
4865
4881
  console.log(`artifacts: ${written.summaryPath} (junit 0 · unavailable=${reason})`);
4866
4882
  }
4867
4883
  } catch (error) {
@@ -5614,7 +5630,7 @@ const selfOrchestrateCmd = selfCmd
5614
5630
  catch (e) { ui.error(`--pod-source: ${e instanceof Error ? e.message : String(e)}`); process.exit(2); }
5615
5631
  const outDir = join(elanousStateRoot(), 'pod-sources', runId);
5616
5632
  const baseRef = opts.base ?? 'origin/HEAD';
5617
- try { podSource = resolvePodSource(parsed, { base: baseRef, outDir }); }
5633
+ try { podSource = resolvePodSource(parsed, { base: baseRef, outDir, mirrorHead: image.imageCommit }); }
5618
5634
  catch (e) { ui.error(`--pod-source: ${e instanceof Error ? e.message : String(e)}`); process.exit(2); }
5619
5635
  debug.log('self-implement.pod', 'source', {
5620
5636
  kind: podSource.kind,
@@ -5626,7 +5642,7 @@ const selfOrchestrateCmd = selfCmd
5626
5642
  if (childFlags.childLlmProvider?.trim()) debug.log('self-implement.pod', 'child-provider-named', { provider: childFlags.childLlmProvider.trim(), model: childFlags.childLlmModel ?? null, podProvider });
5627
5643
  // BEDROCK-POD-PROVIDER-DROP — provider·account 는 한 곳(podLaunchProviderOptions)에서 — 손 나열이 bedrock 을 떨궈 codex(team)로 돌았다(10-11).
5628
5644
  const podProviderOptions = (await import('./task-orchestrator/surfaces/pod-child-providers.js')).podLaunchProviderOptions(podProvider, { explicitPodAccount, grokApiKeyOptIn });
5629
- const podBase = { hostSupervised: opts.supervise === true, ...podChildLlm, ...(remoteOnlyPool ? { imageCommit: image.imageCommit } : {}), ...podProviderOptions, ...(accountBroker ? { accountBroker, rotationAccounts } : {}), passEnv, ...(pool ? { pool } : {}), ...((opts as { podSkillEnv?: boolean }).podSkillEnv ? { skillEnv: true } : {}), ...(podSource ? { source: podSource } : {}), ...(repairBaseHead && podSource?.kind === 'pr' ? { repairCommitOnly: { pr: podSource.number, baseHead: repairBaseHead } } : {}) };
5645
+ const podBase = { hostSupervised: opts.supervise === true, ...podChildLlm, ...(remoteOnlyPool ? { imageCommit: image.imageCommit } : {}), ...podProviderOptions, ...(accountBroker ? { accountBroker, rotationAccounts } : {}), passEnv, warmReuseConfig: () => getUserConfig().pod?.warmReuse, warmReuseEvidence: () => undefined, ...(pool ? { pool } : {}), ...((opts as { podSkillEnv?: boolean }).podSkillEnv ? { skillEnv: true } : {}), ...(podSource ? { source: podSource } : {}), ...(repairBaseHead && podSource?.kind === 'pr' ? { repairCommitOnly: { pr: podSource.number, baseHead: repairBaseHead } } : {}) };
5630
5646
  if (benchArms) {
5631
5647
  const { benchPodSpawn } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
5632
5648
  podSpawn = benchPodSpawn(benchArms, podBase);
@@ -6922,6 +6938,21 @@ const agentCmd = program
6922
6938
  .alias('codex')
6923
6939
  .description(`Agent-mission CLI — 외부 에이전트 backend(${agentBackendHelpList}) 미션·리뷰 워치·셋업. \`codex\` 는 deprecated alias(하위호환).`);
6924
6940
 
6941
+ let agentMissionCliDepsForTesting: Partial<import('./agent-mission/mission-cli.js').MissionCliDeps> | undefined;
6942
+ let agentMissionLogSinkForTesting: ((surface: string) => Promise<boolean>) | undefined;
6943
+ /** 실제 agent-mission mission 진입점의 탐지·실행 순서를 검증한다. */
6944
+ export function setAgentMissionCliDepsForTesting(
6945
+ deps: Partial<import('./agent-mission/mission-cli.js').MissionCliDeps> | undefined,
6946
+ ): void {
6947
+ agentMissionCliDepsForTesting = deps;
6948
+ }
6949
+ /** 진입점 회귀 테스트에서 logs.db 쓰기를 차단한다. */
6950
+ export function setAgentMissionLogSinkForTesting(
6951
+ register: ((surface: string) => Promise<boolean>) | undefined,
6952
+ ): void {
6953
+ agentMissionLogSinkForTesting = register;
6954
+ }
6955
+
6925
6956
  // ★ 제1원칙 관측 — agent-mission 전 서브커맨드에 logs.db 싱크를 중앙 배선(preAction 훅)하고, 레거시
6926
6957
  // `codex` alias 진입이면 브레드크럼(명명 중립화 이행률 추적 → alias 제거 안전시점 판정 근거).
6927
6958
  // • 균일 커버리지: 훅은 mission/review-*/setup/models/config-migrate 모든 액션 앞에 1회 실행 →
@@ -6939,8 +6970,11 @@ const AGENT_MISSION_SURFACE_BY_SUB: Record<string, string> = {
6939
6970
  agentCmd.hook('preAction', async (_thisCommand, actionCommand) => {
6940
6971
  const surface = AGENT_MISSION_SURFACE_BY_SUB[actionCommand.name()] ?? 'agent-mission';
6941
6972
  try {
6942
- const { registerStandaloneLogSink } = await import('./domains/standalone-log-sink.js');
6943
- await registerStandaloneLogSink(surface);
6973
+ if (agentMissionLogSinkForTesting) await agentMissionLogSinkForTesting(surface);
6974
+ else {
6975
+ const { registerStandaloneLogSink } = await import('./domains/standalone-log-sink.js');
6976
+ await registerStandaloneLogSink(surface);
6977
+ }
6944
6978
  } catch { /* fail-open */ }
6945
6979
  try {
6946
6980
  const { isLegacyCodexInvocation, AGENT_ALIAS_LOG_CATEGORY } = await import('./agent-mission/legacy-alias.js');
@@ -7062,6 +7096,7 @@ agentCmd
7062
7096
  // ★ U4b — 액션 글루(backend 검증·mission-file/text·evidence·spec 빌드·통일 진입점 실행)는
7063
7097
  // runAgentMissionCliCommand(테스트 가능 seam)로 추출. 액션은 I/O(print/exit)만 담당.
7064
7098
  const { resolveBackend } = await import('./agent-mission/driver.js');
7099
+ const { detectAgentCli } = await import('./agent-mission/tool-install.js');
7065
7100
  const { runAgentMissionCliCommand } = await import('./agent-mission/mission-cli.js');
7066
7101
  const controller = new AbortController();
7067
7102
  const onSigint = (): void => { controller.abort(); };
@@ -7069,7 +7104,8 @@ agentCmd
7069
7104
  let outcome: Awaited<ReturnType<typeof runAgentMissionCliCommand>>;
7070
7105
  try {
7071
7106
  outcome = await runAgentMissionCliCommand(textParts, opts as import('./agent-mission/mission-cli.js').MissionCliOpts,
7072
- { resolveBackend, signal: controller.signal });
7107
+ { resolveBackend, detectAgentCli, onStatus: (line) => console.error(`[agent-mission] ${line}`), signal: controller.signal,
7108
+ ...agentMissionCliDepsForTesting });
7073
7109
  } finally {
7074
7110
  process.removeListener('SIGINT', onSigint);
7075
7111
  }
@@ -8764,6 +8800,15 @@ missionCmd
8764
8800
  persistMissionOutcome(setMissionMode(cfg.llm.missionRouting, mode));
8765
8801
  });
8766
8802
 
8803
+ // Stateless shell bridge for Codex/Claude agent missions. State is scoped to
8804
+ // the active Elanous instance; replies are persisted and mirrored to logs.db.
8805
+ if (!INDEX_FAST_ROOT) {
8806
+ const { registerMissionOutCommand } = require('./agent-mission/mission-out.js') as typeof import('./agent-mission/mission-out.js');
8807
+ registerMissionOutCommand(program, {
8808
+ emit: (event) => debug.log('mission.reply', 'reply', event),
8809
+ });
8810
+ }
8811
+
8767
8812
  registerTasksCommands(program);
8768
8813
  registerBriefCommands(program);
8769
8814
  registerLabelsCommands(program);
@@ -3,10 +3,14 @@ import { createHash, randomBytes } from 'node:crypto';
3
3
  import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
4
4
  import { basename, dirname, join, resolve } from 'node:path';
5
5
  import { elanousStateRoot } from '../autopilot/state-paths.js';
6
+ import { appendBoundaryResponseLine, HARNESS_BOUNDARY_RESPONSES_ENV } from '../harness/harness-space.js';
7
+ import { anonymousExport, suggestProjectForFolder } from '../project/project-store.js';
6
8
 
7
9
  export interface DevProjectDeps {
8
10
  git?: (dir: string, args: readonly string[]) => string | null;
9
11
  stateDir?: string;
12
+ /** TENANT-BOUNDARY (0.2.41): 회신 mailbox 경계 채널용 env — 생산은 process.env 기본값. */
13
+ env?: Record<string, string | undefined>;
10
14
  }
11
15
 
12
16
  interface DevProjectRegistry {
@@ -60,9 +64,30 @@ export function resolveDevProject(dir: string, deps: DevProjectDeps = {}): strin
60
64
  try {
61
65
  writeJsonAtomically(join(root, '.elanous', 'project.json'), { identityKey, devProject: id } satisfies DevProjectCache);
62
66
  } catch { /* cache only */ }
67
+
68
+ exportTenantBoundaryRecord(root, id, deps.env ?? process.env);
63
69
  return id;
64
70
  }
65
71
 
72
+ /**
73
+ * TENANT-BOUNDARY (0.2.41 · nfr:security): 고객 원장의 설치 밖 출구는 익명 내보내기 하나다.
74
+ * 경계 회신 mailbox(HARNESS_BOUNDARY_RESPONSES_ENV)가 열려 있을 때만, 고객 프로젝트 원장을
75
+ * `anonymousExport`(식별 필드 → 토큰)로 바꿔 한 줄(JSONL)로 남긴다. 원장 식별 원문은 절대
76
+ * 설치 밖으로 나가지 않는다. 채널이 없으면 아무 일도 일어나지 않고(기본 동작 보존),
77
+ * 채널 쓰기가 실패해도 id 해소를 막지 않는다(fail-open).
78
+ */
79
+ function exportTenantBoundaryRecord(root: string, devProject: string, env: Record<string, string | undefined>): void {
80
+ const mailbox = env[HARNESS_BOUNDARY_RESPONSES_ENV]?.trim();
81
+ if (!mailbox) return;
82
+ try {
83
+ const project = suggestProjectForFolder(root);
84
+ appendBoundaryResponseLine(env as NodeJS.ProcessEnv, {
85
+ devProject,
86
+ ...(project ? { project: anonymousExport(project) } : {}),
87
+ });
88
+ } catch { /* boundary export must never block id resolution */ }
89
+ }
90
+
66
91
  function runGit(dir: string, args: readonly string[]): string | null {
67
92
  try {
68
93
  return execFileSync('git', ['-C', dir, ...args], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
@@ -11,6 +11,8 @@ export interface SpawnElanousOptions {
11
11
  stateDir?: string;
12
12
  /** 실행할 elanous 진입 스크립트. 생략하면 이 트리의 bin/elanous.mjs. */
13
13
  bin?: string;
14
+ /** Installed command entry (for callers that must honor the user's installed CLI). */
15
+ executable?: string;
14
16
  cwd?: string;
15
17
  env?: NodeJS.ProcessEnv;
16
18
  }
@@ -26,20 +28,20 @@ export function elanousInvocation(args: readonly string[], opts: SpawnElanousOpt
26
28
  const root = opts.stateDir?.trim() || effectiveInstanceRoot();
27
29
  const base = opts.env ?? process.env;
28
30
  return {
29
- command: process.execPath,
30
- args: [opts.bin ?? DEFAULT_BIN, ...args],
31
+ command: opts.executable?.trim() || process.execPath,
32
+ args: opts.executable?.trim() ? [...args] : [opts.bin ?? DEFAULT_BIN, ...args],
31
33
  env: { ...base, ELANOUS_STATE_DIR: root, ELANOUS_STATE_DIR_SOURCE: stateDirSourceForChild(root, base) },
32
34
  };
33
35
  }
34
36
 
35
37
  export function spawnElanous(args: readonly string[], opts: SpawnElanousOptions & Omit<SpawnOptions, 'env' | 'cwd'> = {}): ChildProcess {
36
- const { stateDir: _s, bin: _b, env: _e, ...rest } = opts;
38
+ const { stateDir: _s, bin: _b, executable: _x, env: _e, ...rest } = opts;
37
39
  const inv = elanousInvocation(args, opts);
38
40
  return spawn(inv.command, inv.args, { ...rest, cwd: opts.cwd, env: inv.env });
39
41
  }
40
42
 
41
43
  export function spawnElanousSync(args: readonly string[], opts: SpawnElanousOptions & Omit<SpawnSyncOptions, 'env' | 'cwd'> = {}): SpawnSyncReturns<string | Buffer> {
42
- const { stateDir: _s, bin: _b, env: _e, ...rest } = opts;
44
+ const { stateDir: _s, bin: _b, executable: _x, env: _e, ...rest } = opts;
43
45
  const inv = elanousInvocation(args, opts);
44
46
  return spawnSync(inv.command, inv.args, { ...rest, cwd: opts.cwd, env: inv.env });
45
47
  }
@@ -49,7 +49,7 @@ const MODEL_ALIASES: Readonly<Record<string, string>> = {
49
49
  'pro': 'gemini-3.1-pro-preview',
50
50
  'gemini-pro': 'gemini-3.1-pro-preview',
51
51
  // OpenAI / Codex
52
- 'codex': 'gpt-6-sol', // ⭐ 2026-09-25: 운영 codex 기본(gpt-6-sol)과 맞춘다 — gpt-5.5 는 두 세대 낡았다
52
+ 'codex': 'gpt-6.1-terra',
53
53
  'gpt-5': 'gpt-5.5',
54
54
  'mini': 'gpt-5-mini',
55
55
  'nano': 'gpt-5-nano',
@@ -57,15 +57,16 @@ const MODEL_ALIASES: Readonly<Record<string, string>> = {
57
57
  // 🔑 왜 — `sol`·`luna` 라는 «같은 이름»이 두 세대에 걸쳐 있다. 세대를 안 쓰면
58
58
  // «어느 세대인지 말하지 않은 것»이고, 그때 골라야 할 것은 ***최신***이다.
59
59
  // (실제로 이 겹침 때문에 커뮤니티 조사기가 5.6 과 6 을 섞어 답한 일이 있었다.)
60
- // ⛔ `terra` 는 GPT-6 에 «없다» — 중간 등급이 접혔고 GPT-6 Sol 이 그 가격대를 흡수했다.
61
- // 그래서 `terra` 는 5.6 을 계속 가리킨다(은퇴가 아니라 «후속이 없는» 것이다).
60
+ // GPT-6.1 restores a Terra tier; unsuffixed aliases follow the current 6.1 generation.
62
61
  // 📏 세대 확인 = `curl /v1/models` ⊕ `codex debug models` (2026-09-23 둘 다 실측).
63
62
  'astra': 'gpt-6-astra',
64
- 'sol': 'gpt-6-sol',
63
+ 'sol': 'gpt-6.1-sol',
65
64
  'luna': 'gpt-6-luna',
66
- 'terra': 'gpt-5.6-terra', // ⛔ GPT-6 에 후속 없음
65
+ 'terra': 'gpt-6.1-terra',
67
66
  // 세대를 «명시»해 부르는 길 — 겹치는 이름을 또렷하게 가리킬 때.
68
67
  '6-sol': 'gpt-6-sol',
68
+ '6.1-sol': 'gpt-6.1-sol',
69
+ '6.1-terra': 'gpt-6.1-terra',
69
70
  '6-luna': 'gpt-6-luna',
70
71
  '5.6-sol': 'gpt-5.6-sol',
71
72
  '5.6-terra': 'gpt-5.6-terra',