elanous 0.2.41 → 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 (589) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{GiOLWmt4MqDZePubBjA4Q → X1ucLw10Cds_h614NoEnh}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/{5159.115f1c2ca471386c.js → 1063.2fb8a9dc55c731f2.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +36 -0
  7. package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/{9048.212083de42d25be3.js → 1262.e804feb8fd1acb8c.js} +2 -2
  9. package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1455-530ca16c7e71baff.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/{4527.a69f2894d1bc9f4a.js → 1487.2f67b79444062da6.js} +1 -1
  13. package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +32 -0
  15. package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +286 -0
  21. package/apps/pwa/out/_next/static/chunks/2160.a097e7b138ae1c55.js +23 -0
  22. package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +34 -0
  25. package/apps/pwa/out/_next/static/chunks/2456.b6de0e1c05f28843.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/{530.d26346e18089640a.js → 2690.0521c738b7749931.js} +1 -1
  31. package/apps/pwa/out/_next/static/chunks/{4702.4a4adc1f16d7c93b.js → 2974.595d1e29d040cb6a.js} +1 -1
  32. package/apps/pwa/out/_next/static/chunks/{2263.e09b6edea33bad2d.js → 3207.a756c95e9ec8c3c8.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/{9541.eb8e2f8480c7feca.js → 3285.89ee2f298682f5e5.js} +2 -2
  34. package/apps/pwa/out/_next/static/chunks/{9507.7026657a2f47eb64.js → 3347.f846266b5e5f3ede.js} +16 -16
  35. package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +41 -0
  36. package/apps/pwa/out/_next/static/chunks/{1178.1aa9cad0e7695427.js → 3482.a9ae9d2ad6a5bd97.js} +1 -1
  37. package/apps/pwa/out/_next/static/chunks/3507.97e1977bc4d5fb0a.js +2 -0
  38. package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +24 -0
  40. package/apps/pwa/out/_next/static/chunks/3741.9cf76acaa2ee5298.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/{1661.0dd330f3d89f73f3.js → 3837.a210d7d0db8d8abd.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/{2fdf2931.b431eee4fb468bc3.js → 3d0154af.5331fec737ffe8c3.js} +1 -1
  45. package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4043.6b91203436c9c86b.js +309 -0
  47. package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +77 -0
  48. package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4276.336d76d858fcdf1b.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +148 -0
  54. package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +74 -0
  55. package/apps/pwa/out/_next/static/chunks/50061469.0326382241ef3b2d.js +122 -0
  56. package/apps/pwa/out/_next/static/chunks/{1115.434ae2ecb0ad986d.js → 5112.4b9f300124fab7b3.js} +3 -3
  57. package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +27 -0
  59. package/apps/pwa/out/_next/static/chunks/53c73f84.373b6160adfa89a4.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5431-72a1dbde59400691.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5885.0a3e52c8faccec98.js +287 -0
  69. package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6131.348b7d6bdcd267ce.js +226 -0
  72. package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +90 -0
  73. package/apps/pwa/out/_next/static/chunks/{2073.689dcb2680113d76.js → 6377.bc7df239edbff244.js} +1 -1
  74. package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/{1800.f7ff51dc4978a958.js → 6632.0eac1c554f8f2ef3.js} +1 -1
  77. package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +104 -0
  81. package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +94 -0
  82. package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/{2527-5c636a43c7cc5dde.js → 7279-c199ea83f34338fa.js} +1 -1
  85. package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/{385e4574.e9886ab32759eda3.js → 73d2eb0e.4966ad55293c801a.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{5471.1e611302ed3a7c53.js → 7411.9b4b8b747dc7b802.js} +2 -2
  90. package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +24 -0
  91. package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{2fe2c302.41b517f88d6fe502.js → 7a98bc80.fa935989e829f9c2.js} +1 -1
  97. package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8138.6c10b2a356d52fca.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{5574.f35accf4f132b29d.js → 8262.ddc03e06b733f184.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +8 -0
  102. package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +79 -0
  104. package/apps/pwa/out/_next/static/chunks/{8050-9b364bdef8f71927.js → 8546-6f03f8ea34dd61d9.js} +1 -1
  105. package/apps/pwa/out/_next/static/chunks/{5947-135e26537d80a6b9.js → 8673-bab689a55f7e13b9.js} +3 -3
  106. package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{5937.c2df9e3447e1f667.js → 9249.976f1e69a9d80754.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{1971-7efb628c471dc5a0.js → 9353-12bfff0c130104cf.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/{7191.fdc955f7d96064a4.js → 9415.69e4a21c60c7d2db.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/{1219.7e17964e0e7cd8e5.js → 9427.96aa912ddb5801e0.js} +16 -16
  118. package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9633.ce5bddc56784da72.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{5964-7e21164a8f2cf0ce.js → 9656-374232558fd528d0.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/{6552.a3840aa7da35ad68.js → 9832.f4a98c878ecf2c0a.js} +1 -1
  123. package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/9a852a62-6192a6ea9346ced3.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0e3d7b9421b79dac.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/term/page-bf067887b3307423.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/{a0a01613.6d1cca322238d7fe.js → b450776b.3db34d8d965f82d3.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{c0c1a699.0ba79f97005965d4.js → e8543907.5b040a5f22a0b0e5.js} +7 -7
  178. package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +22 -22
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +22 -22
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +22 -22
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +21 -21
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +21 -21
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +22 -22
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +21 -21
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +22 -22
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +22 -22
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +21 -21
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +22 -22
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -24
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +22 -22
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +22 -22
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +21 -21
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +22 -22
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -24
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -24
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +21 -21
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +21 -21
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +22 -22
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +22 -22
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +21 -21
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +21 -21
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +21 -21
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +22 -22
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +22 -22
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +21 -21
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +22 -22
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +22 -22
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +22 -22
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +22 -22
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +22 -22
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +21 -21
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +22 -22
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +22 -22
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +22 -22
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +22 -22
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +22 -22
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +22 -22
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +22 -22
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +22 -22
  278. package/docs/goal-context/04-mock-scenarios.md +13 -0
  279. package/graphs/catalog/catalog.yaml +1 -1
  280. package/graphs/heal/heal-loop.yaml +1 -0
  281. package/graphs/overlays/stop-heal-ladder.yaml +113 -0
  282. package/graphs/units/verbs/recipes.yaml +11 -11
  283. package/graphs/work/research-report.yaml +10 -2
  284. package/package.json +1 -1
  285. package/scripts/heal/run-role.ts +99 -5
  286. package/scripts/land-global-checks.ts +6 -1
  287. package/scripts/lib/decompose-ab.ts +1 -0
  288. package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
  289. package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
  290. package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
  291. package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
  292. package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
  293. package/scripts/lib/tui-regress-checks.ts +33 -13
  294. package/scripts/release-loop/gate-baseline-receipt.ts +47 -9
  295. package/scripts/release-loop/gate-image-pin.ts +81 -0
  296. package/scripts/release-loop/gate-node-sim.ts +207 -0
  297. package/scripts/release-loop/gate-node.ts +285 -46
  298. package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
  299. package/scripts/release-loop/gate-radius-live.ts +97 -13
  300. package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
  301. package/scripts/release-loop/gate-train-receipts.ts +122 -0
  302. package/scripts/release-loop/resume-release.ts +83 -8
  303. package/scripts/ux-sim.ts +18 -1
  304. package/scripts/warm-pool-provider-config.ts +263 -0
  305. package/skills/omni-crawl/SKILL.md +5 -2
  306. package/skills/omni-crawl/scripts/main.ts +84 -23
  307. package/src/acp/core-turn-bridge.ts +13 -0
  308. package/src/agent/registry.ts +2 -0
  309. package/src/agent/task-notification.ts +25 -5
  310. package/src/agent/types.ts +6 -0
  311. package/src/agent-mission/mission-cli.ts +24 -0
  312. package/src/agent-mission/mission-out.ts +595 -0
  313. package/src/agent-mission/tool-install.ts +88 -2
  314. package/src/agent-substrate/context-strategy.ts +4 -4
  315. package/src/agent-substrate/self-review-cli.ts +178 -13
  316. package/src/auto-research/research-turn.ts +123 -50
  317. package/src/autopilot/pr-manager.ts +38 -7
  318. package/src/autopilot/pty-control-loop.ts +2 -0
  319. package/src/capture/tui-self-report.ts +22 -6
  320. package/src/chat/index.ts +1 -1
  321. package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
  322. package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
  323. package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
  324. package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
  325. package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
  326. package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
  327. package/src/cli/pr-land-heavy-remote.ts +32 -0
  328. package/src/cli/pr-land-overlap-evidence.ts +100 -1
  329. package/src/cli/pr-land-pod-shadow-job.ts +60 -0
  330. package/src/cli/release-checklist-read-cli.ts +20 -10
  331. package/src/cli/research-cli.ts +4 -5
  332. package/src/cli/tasks-cli.ts +7 -0
  333. package/src/compact/auto.ts +8 -1
  334. package/src/control-plane/ledger.ts +52 -2
  335. package/src/control-plane/server.ts +16 -2
  336. package/src/core-turn/run-core-turn.ts +311 -90
  337. package/src/core-turn/run-goal-loop.ts +18 -0
  338. package/src/core-turn/types.ts +2 -0
  339. package/src/dashboard/classic-sidetab-mission-job.ts +58 -0
  340. package/src/dashboard/classic-sidetab-mission.ts +185 -0
  341. package/src/dashboard/index.ts +149 -15
  342. package/src/dashboard/input/agent-wake.ts +23 -1
  343. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +9 -0
  344. package/src/dashboard/mission-cli-consumer.ts +153 -0
  345. package/src/dashboard/seat-boot-preamble.ts +171 -1
  346. package/src/dashboard/side-basic-runtime.ts +54 -1
  347. package/src/dashboard/sidetab-runtime.ts +90 -1
  348. package/src/dashboard/skill-catalog-preamble.ts +101 -0
  349. package/src/dashboard/skill-detection-runtime.ts +55 -15
  350. package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
  351. package/src/dashboard/turn-preamble.ts +53 -15
  352. package/src/dashboard/turn-prompt-runtime.ts +4 -2
  353. package/src/graph-runner/graph-cli.ts +23 -7
  354. package/src/graph-runner/graph-tick.ts +10 -2
  355. package/src/graph-runner/runner.ts +1 -1
  356. package/src/grok/agent-search.ts +14 -4
  357. package/src/grok/credential.ts +28 -11
  358. package/src/harness/harness-pod-dispatch.ts +81 -15
  359. package/src/harness/harness-stop.ts +155 -11
  360. package/src/index.ts +34 -5
  361. package/src/instance/spawn-elanous.ts +6 -4
  362. package/src/llm.ts +166 -8
  363. package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
  364. package/src/loops/orchestrator/tick.ts +13 -0
  365. package/src/maturity/feature-maturity.ts +1 -1
  366. package/src/native-tool-catalog.ts +2 -2
  367. package/src/nexus/api/harness-traversal.ts +11 -0
  368. package/src/pr-tool/census.ts +3 -2
  369. package/src/pty-shell/tui-run-state.ts +188 -2
  370. package/src/release-loop/checklist-target-path-hint.ts +13 -0
  371. package/src/release-loop/checklist.ts +9 -1
  372. package/src/repl/index.ts +43 -2
  373. package/src/research/axis-fanout.ts +121 -16
  374. package/src/research/bloom-exemplars.ts +3 -1
  375. package/src/research/gap-followup.ts +13 -1
  376. package/src/research/plugin-discovery.ts +36 -14
  377. package/src/research-bridge/invoke.ts +22 -5
  378. package/src/research-bridge/types.ts +2 -0
  379. package/src/self-dev/decompose.ts +119 -5
  380. package/src/self-dev/launch-preflight-text.ts +5 -6
  381. package/src/self-dev/orchestrate.ts +12 -2
  382. package/src/self-dev/review-provider-fallback.ts +9 -2
  383. package/src/self-dev/run-supervisor.ts +42 -4
  384. package/src/self-dev/run-types.ts +4 -0
  385. package/src/self-implement/doctor-visit.ts +88 -0
  386. package/src/self-implement/goal-author.ts +326 -3
  387. package/src/self-implement/graph-overlay-yaml.ts +7 -0
  388. package/src/self-implement/headless-elanous-driver.ts +31 -2
  389. package/src/self-implement/heal-intake.ts +112 -4
  390. package/src/self-implement/heal-triage.ts +20 -0
  391. package/src/self-implement/host-regate.ts +27 -4
  392. package/src/self-implement/merge-train.ts +5 -0
  393. package/src/self-implement/orchestrator.ts +126 -11
  394. package/src/self-implement/regate-detail.ts +38 -1
  395. package/src/self-implement/rework-child-provider.ts +25 -0
  396. package/src/self-implement/run-chart.ts +119 -0
  397. package/src/self-implement/run-ledger.ts +112 -11
  398. package/src/self-implement/run-stop.ts +188 -4
  399. package/src/self-implement/stop-autoheal.ts +13 -0
  400. package/src/session/chat.ts +38 -4
  401. package/src/session-runtime/index.ts +98 -4
  402. package/src/session-runtime/tier-flip.ts +3 -3
  403. package/src/sidetab-core/model.ts +19 -5
  404. package/src/sidetab-core/visible-agent-mission.ts +186 -0
  405. package/src/skills/name-match.ts +20 -0
  406. package/src/skills/tools/agent.ts +30 -2
  407. package/src/skills/tools/omni-search.ts +67 -5
  408. package/src/task-agent/pod-distributor-entry.ts +3 -0
  409. package/src/task-agent/task-hand.ts +27 -0
  410. package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
  411. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
  412. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
  413. package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
  414. package/src/task-orchestrator/surfaces/pod-source-receive.ts +163 -13
  415. package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
  416. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +209 -39
  417. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
  418. package/src/task-orchestrator/surfaces/self-implement-pod.ts +165 -45
  419. package/src/tokens.ts +35 -2
  420. package/src/tool-runtime/agent-runtime.ts +1 -0
  421. package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
  422. package/src/tool-runtime/skill-exec-runtime.ts +33 -13
  423. package/src/tool-runtime/types.ts +1 -0
  424. package/src/tui/entry.ts +14 -4
  425. package/src/tui/sidetab/attach.ts +47 -0
  426. package/src/tui-client/local-chat-turn.ts +26 -13
  427. package/src/tui.ts +22 -0
  428. package/src/ux-sim/fake-kubectl.ts +37 -3
  429. package/src/ux-sim/fault-pool-cap.ts +11 -6
  430. package/src/ux-sim/mock-scenario-catalog.json +41 -0
  431. package/src/ux-sim/mock-scenario-catalog.ts +156 -0
  432. package/src/ux-sim/scenario.ts +116 -23
  433. package/src/version/packed-revision.json +1 -1
  434. package/src/voice/voice-tts-singleton.ts +18 -3
  435. package/src/web-search/grok.ts +5 -9
  436. package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +0 -36
  437. package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +0 -1
  438. package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +0 -287
  439. package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +0 -1
  440. package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +0 -90
  443. package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/1765.679b29625c8e88d4.js +0 -77
  445. package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +0 -1
  446. package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +0 -1
  447. package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +0 -1
  449. package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +0 -1
  450. package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +0 -1
  452. package/apps/pwa/out/_next/static/chunks/2743.5d3f76948be32b34.js +0 -41
  453. package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +0 -32
  454. package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +0 -1
  455. package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +0 -79
  456. package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +0 -1
  458. package/apps/pwa/out/_next/static/chunks/3230-49298c3b73ef2268.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +0 -74
  461. package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +0 -1
  463. package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +0 -1
  465. package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +0 -1
  467. package/apps/pwa/out/_next/static/chunks/4133.2056bb4d78f621af.js +0 -1
  468. package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +0 -148
  472. package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +0 -226
  473. package/apps/pwa/out/_next/static/chunks/4667.97e31aa38c95c475.js +0 -309
  474. package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +0 -1
  479. package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +0 -94
  481. package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +0 -8
  483. package/apps/pwa/out/_next/static/chunks/53aeb4ee-51c92f8d683f5220.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +0 -24
  487. package/apps/pwa/out/_next/static/chunks/5744.b9415e18ad623100.js +0 -23
  488. package/apps/pwa/out/_next/static/chunks/5892.2526d962339662d8.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +0 -286
  490. package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +0 -27
  494. package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +0 -24
  496. package/apps/pwa/out/_next/static/chunks/6874.d5cf7eb8edb2cabe.js +0 -2
  497. package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +0 -122
  499. package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/83184dcd-0ee6247ff41eb3f2.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +0 -104
  510. package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +0 -1
  517. package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +0 -34
  527. package/apps/pwa/out/_next/static/chunks/9834.63ab2bbc3153172e.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/9869.81a1e24ca682d5a0.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/addc2b32.8c4ff8f0aefe987d.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/app/botlab/page-14949db884bfa672.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-40f9e19149024298.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a142dfb0331a05f5.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/b2271e54.c1de3347976e90b0.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +0 -1
  588. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
  589. /package/apps/pwa/out/_next/static/{GiOLWmt4MqDZePubBjA4Q → X1ucLw10Cds_h614NoEnh}/_ssgManifest.js +0 -0
@@ -79,6 +79,39 @@ export function recordPodSourceIoSummary(logs: string, job: string, runId: strin
79
79
  }
80
80
  }
81
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
+
82
115
  /** Select a timestamp for a DeadlineExceeded observation without making detector time look like Job completion.
83
116
  * `podFinishedAt` must come from readPodTermination for the same verified Job uid. */
84
117
  export function podJobFinishedTiming(input: { jobCreatedAt: string | null; jobCompletedAt: string | null;
@@ -102,6 +135,7 @@ import { POD_LAUNCH_FINISHED_EVENT, POD_LAUNCH_STARTED_EVENT, provenanceRowFromA
102
135
  import { podProvenanceMetadata, type PodProvenanceMetadata } from './pod-provenance.js';
103
136
  import { packageVersion } from '../../version/code-revision.js';
104
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';
105
139
  export { POD_CHILD_REQUESTS } from './pod-lease.js';
106
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';
107
141
  import { ACTUAL_SUBSTRATE_ENV, RUN_CONTRACT_ENV, carryRunContract, completionFloorFor } from '../../self-implement/graph-run-contract.js';
@@ -131,7 +165,7 @@ import { normalizeFallbackChain, type FallbackStep } from '../../oauth/fallback-
131
165
  import { goalTypeOf, type GoalType } from '../../../scripts/measure-pod-memory-by-goal.js';
132
166
  import { declaredGoalType, type GoalType as DeclaredGoalType } from '../../self-implement/goal-author.js';
133
167
  import { readPodMemoryAdvice, type PodMemoryAdvice } from '../../cli/pod-memory-advice.js';
134
- 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';
135
169
  import { worktreeAddTimeoutSec } from '../../git-fs/worktree.js';
136
170
  import { podChildProviderOf, podChildProviderRefusal, type PodChildProvider } from './pod-child-providers.js';
137
171
  import { BEDROCK_POD_EGRESS_LABEL, bedrockPodEnv, checkBedrockPodSecret, type BedrockPodSpec } from './pod-bedrock-child.js';
@@ -288,6 +322,8 @@ export interface PodSpawnOptions {
288
322
  readSkillEnv?: () => Record<string, string>;
289
323
  /** ☸️ 여러 클러스터 풀(pod-pool.ts) — Job 마다 우선순위 순 첫 빈 자리로. 없으면 현재 컨텍스트 하나. */
290
324
  pool?: PodPoolScheduler;
325
+ /** POD-DISTRIBUTOR-WIRE — replaceable admission seam; tasks-hand only in the first wire slice. */
326
+ podDistributorAdapter?: PodDistributorAdapter;
291
327
  /** ☸️ 원격 그라운딩 주소(P13) — 없으면 호스트 env ELANOUS_GROUNDING_URL → 설정 pod.groundingUrl. 셋 다 없으면 토큰을 안 만든다. */
292
328
  groundingUrl?: string;
293
329
  /** 시험 심 — 토큰 발급·회수. GitHub credential 토큰에는 호스트가 검증한 저장소를 서명한다. */
@@ -1606,7 +1642,26 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
1606
1642
  if (options.siWarmAttempt && !options.siWarmHostPostprocess) {
1607
1643
  throw new Error('si-v1 warm execution requires cold-path host postprocess parity');
1608
1644
  }
1609
- 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) {
1610
1665
  const done = (async (): Promise<SelfImplementJobDone> => {
1611
1666
  // POD-REUSE-REQUEST-CLEAN-FU — one fail-soft row per request decision. `runId` is the
1612
1667
  // ledger partition (warm child, then parent run, then the legacy spaceId fallback);
@@ -2087,11 +2142,15 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2087
2142
  if (input.signal?.aborted) return null;
2088
2143
  // The reason comes back inside this call, so a concurrent launch cannot overwrite it.
2089
2144
  const kind = podPlacementKind(oomRetried ? retryTier : memoryTier, selectedGoalType, requestKind);
2090
- const acquired = await options.pool.tryAcquire(unfitContexts, (reason) => {
2091
- stageReason['pool-slot'] = reason;
2092
- firstSlotReasonCode ??= slotReasonCode(reason);
2093
- },
2094
- { 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; } } } });
2095
2154
  if (acquired) {
2096
2155
  recordSlotObservation(attempt, 'admitted', firstSlotReasonCode ?? 'admitted');
2097
2156
  debug.log('self-implement.pod', 'pool-slot', { spaceId: input.spaceId, context: acquired.context, inflight: options.pool.snapshot(), ...(lastPlacement ? { placement: lastPlacement } : {}) });
@@ -2168,14 +2227,41 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2168
2227
  } catch (error) { debug.log('self-implement.pod', 'failure-capture-ledger-unavailable', { job: name, reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
2169
2228
  };
2170
2229
  let recorded = false;
2230
+ let jobApplied = false;
2171
2231
  let groundingMinted: string | null = null;
2172
2232
  try {
2173
2233
  if (!context) return { exitCode: 1, output: '', error: { code: 'pod-context', message: 'Pod Job context를 확인할 수 없다' } };
2174
- 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
+ };
2175
2253
  let repairResultAnnounced = false;
2176
2254
  let repairArtifactReady = false;
2177
2255
  let hostOriginCalls: number | null = 0;
2178
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
+ };
2179
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> } => {
2180
2266
  let full: ReturnType<Kubectl>;
2181
2267
  try {
@@ -2184,8 +2270,10 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2184
2270
  if (!full.stdout && unavailableEvent === 'failed-job-logs-unavailable') throw new Error('empty child logs');
2185
2271
  } catch (error) {
2186
2272
  debug.log('self-implement.pod', unavailableEvent, { job: name, reason: error instanceof Error ? error.message : String(error) });
2273
+ recordSourceAttemptOutcome(null, 'logs-unavailable', childId);
2187
2274
  return { status: 'unavailable', childLedgerIncomplete: false, samples: [] };
2188
2275
  }
2276
+ recordSourceAttemptOutcome(full.stdout, 'captured', childId);
2189
2277
  const via = /^ELANOUS_POD_SOURCE_VIA (image|mirror|github)\r?$/m.exec(full.stdout)?.[1];
2190
2278
  // #28246 names why the mirror was skipped on the line before `VIA github`; carry it on the same event.
2191
2279
  const mirrorSkip = /^ELANOUS_POD_SOURCE_MIRROR_SKIP (no-mount|rev-parse-failed|clone-failed)\r?$/m.exec(full.stdout)?.[1];
@@ -2308,13 +2396,22 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2308
2396
  /** 넘친 glm Pod 는 자식 인자도 OpenRouter GLM 으로 — Job 스크립트·리뷰어 고정·키 전달이 openrouter 갈래를 그대로 탄다. */
2309
2397
  const jobArgs = zaiRoute === 'openrouter' ? zaiOverflowChildArgs(args, ZAI_OPENROUTER_FALLBACK_MODEL) : args;
2310
2398
  const grok = options.provider === 'grok';
2311
- 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';
2312
2404
  const openGateway = options.provider === 'opengateway';
2313
2405
  const anthropic = options.provider === 'anthropic';
2314
2406
  const bedrockChild = options.provider === 'bedrock';
2315
2407
  const zaiChild = zaiRoute === 'zai';
2316
2408
  /** ZAI 로 입장한 자식도 플랜 한도 오류 뒤 OpenRouter 로 전환할 수 있다. 실행 중 폴백 자격을 발사 전에 확보한다. */
2317
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';
2318
2415
  /** API 키 자식 — codex 계정·자격 파일을 안 쓴다(키는 작업별 creds Secret 의 `env-<KEY>` · bedrock·glm 은 이름 있는 Secret 으로만). */
2319
2416
  const apiKeyChild = openrouter || openGateway || anthropic || bedrockChild || zaiChild;
2320
2417
  const plannedAccount = retryAccount ?? (grok ? 'grok' : openrouter ? 'openrouter' : openGateway ? 'opengateway' : anthropic ? 'anthropic' : bedrockChild ? 'bedrock' : zaiChild ? 'glm' : options.accountBroker?.() ?? options.account ?? 'team');
@@ -2358,7 +2455,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2358
2455
  }
2359
2456
  return credential;
2360
2457
  }) : undefined;
2361
- 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;
2362
2459
  if (openrouterCredentialRequired && !openrouterKey) throw new Error('pod: Pod 에 openrouter 키 없음 — 호스트 키 캐시 또는 OPENROUTER_API_KEY 필요');
2363
2460
  const openGatewayEnvKey = openGateway ? env.OPENGATEWAY_API_KEY?.trim() : undefined;
2364
2461
  const openGatewayCachedKey = openGateway ? (options.readKeyCache ?? defaultReadKeyCache)('OPENGATEWAY_API_KEY')?.trim() : undefined;
@@ -2441,7 +2538,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2441
2538
  }
2442
2539
  }
2443
2540
  // Grok 자격은 전용 Secret 키 하나로만 보낸다 — passEnv 의 API 키 중복 전달은 막는다.
2444
- 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'
2445
2542
  && key !== POD_GITHUB_CREDENTIAL_TOKEN_ENV && key !== POD_GITHUB_CREDENTIAL_URL_ENV
2446
2543
  && (!grok || !['XAI_API_KEY', 'GROK_API_KEY', 'GROK_CODE_XAI_API_KEY'].includes(key)));
2447
2544
  const skillEnvs: Record<string, string> = options.skillEnv
@@ -2618,8 +2715,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2618
2715
  authorChoice = { ...authorChoice, model: childModel, modelSource: 'fallback-child' };
2619
2716
  } else debug.log('self-implement.pod', 'role-llm-armed', { job: name, role: 'planning', model: authorChoice.model, source: authorChoice.modelSource, account: roleCodexAccount });
2620
2717
  }
2621
- 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);
2622
- 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);
2623
2719
  const hostFallbackNames = hostConfig.llm.fallbackChain;
2624
2720
  const zaiOverage = zaiLaunchOverage ?? zaiSettingsFromConfig(hostConfig.llm).overage;
2625
2721
  const normalizedFallback = normalizeFallbackChain(hostFallbackNames);
@@ -2876,22 +2972,6 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2876
2972
  slotId: env.ELANOUS_POD_SLOT_ID,
2877
2973
  work: !goalDoc && env.ELANOUS_POD_AUTHOR_ON_POD === '1' && !shard ? 'authoring' : (oomRetried ? retryTier : memoryTier) === 'lite' ? 'lite' : 'harness',
2878
2974
  };
2879
- // TA-POD-WARMBOOT-PARITY shadow only: read injected evidence, then keep the fresh-Job path.
2880
- // This boundary must not open host configuration or credential files for a warm decision.
2881
- if (workIdentity.taskCard) {
2882
- let stage: 'config' | 'evidence' | 'decision' = 'config';
2883
- try {
2884
- const config = options.warmReuseConfig?.();
2885
- stage = 'evidence';
2886
- const evidence = options.warmReuseEvidence?.();
2887
- stage = 'decision';
2888
- const decision = decideWarmReuse('ta', config, evidence);
2889
- debug.log('pod.warm', 'ta-shadow-observation', { ...decision, execution: 'fresh-job' });
2890
- } catch {
2891
- debug.log('pod.warm', 'ta-shadow-unavailable', { spaceId: input.spaceId,
2892
- reason: stage === 'decision' ? 'warm-decision-failed' : `injected-${stage}-failed`, execution: 'fresh-job' }, { level: 'warn' });
2893
- }
2894
- }
2895
2975
  // TA-POD-WARMBOOT-PARITY (GATE-WARM-BOOT parity · #27805): a commit-pinned source on a pool host — put that commit into
2896
2976
  // the host mirror first (once per host·commit in this process) so podSourceScript finds it instead of fetching
2897
2977
  // from GitHub. Best effort: a failed seed only logs; the Job is applied either way.
@@ -2968,6 +3048,19 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
2968
3048
  const a = kubectl(['apply', '-f', '-'], JSON.stringify(job));
2969
3049
  zaiPendingApply.delete(name); // apply 뒤엔 Job 라벨이 센다(성공) · 실패면 셀 것이 없다
2970
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
+ }
2971
3064
  releaseAdmission?.applied?.(name, context, namespace);
2972
3065
  try { appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-config-snapshot', data: {
2973
3066
  job: name, hash: configSnapshot.hash, keyCount: configSnapshot.keyCount,
@@ -3030,13 +3123,6 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
3030
3123
  }
3031
3124
  debug.log('self-implement.pod', 'source-delivered', { job: name, kind: 'bundle', headCommit: options.source.headCommit });
3032
3125
  }
3033
- // ☸️ P2: 비밀의 소유자 = Job — 호스트가 죽어도 Job 의 TTL 삭제와 함께 k8s 가 비밀을 거둔다(자격 사본이 클러스터에 남지 않는다).
3034
- const uid = kubectl(['-n', namespace, 'get', 'job', name, '-o', 'jsonpath={.metadata.uid}']).stdout.trim();
3035
- 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;
3036
- if (uid) {
3037
- const owned = kubectl(['-n', namespace, 'patch', 'secret', `${name}-creds`, '--type=merge', '-p', JSON.stringify({ metadata: { ownerReferences: [{ apiVersion: 'batch/v1', kind: 'Job', name, uid }] } })]);
3038
- if (owned.status !== 0) debug.log('self-implement.pod', 'secret-owner-failed', { job: name, stderr: owned.stderr.trim() }, { level: 'warn' });
3039
- }
3040
3126
  }
3041
3127
  try {
3042
3128
  appendRunLedgerEntry({ runId: ledgerRunId, timestamp: new Date((options.now ?? Date.now)()).toISOString(),
@@ -3216,11 +3302,11 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
3216
3302
  if (seen !== null) {
3217
3303
  releaseAdmission?.observed?.();
3218
3304
  state = seen === 0 ? 'complete' : 'failed';
3219
- // The child's own rc is the parent's exit code even when 0 — the condition path below yields none here.
3305
+ // The shared marker is authoritative while Pod status lags; preserve the child's rc, including 0, on the parent.
3220
3306
  containerExitCode = seen;
3221
3307
  if (seen !== 0) podTermination = readPodTermination({ kubectl, namespace, job: name, path: 'result-marker', jobUid: lifecycleJobUid });
3222
3308
  if (seen !== 0) captureFailedJob(liveChildRunId);
3223
- 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 });
3224
3310
  break;
3225
3311
  }
3226
3312
  }
@@ -3487,11 +3573,24 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
3487
3573
  };
3488
3574
  }
3489
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
+ };
3490
3579
  // POD-NORESULT: a terminal Job without a parsed disposition is incomplete even when the Job condition says Complete.
3491
3580
  const noResultCandidate = !podVanished && !disposition && !oomKilled && failedReason !== 'DeadlineExceeded' &&
3492
3581
  (state === 'complete' || (state === 'failed' && containerExitCode !== 0));
3493
3582
  if (noResultCandidate) {
3494
- 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
+ }
3495
3594
  catch { /* ledger not returned: do not invent a stage */ }
3496
3595
  noResultDiagnostic ??= 'child terminal result missing; last ledger stage=unknown; round=unknown; mustFix=unknown';
3497
3596
  }
@@ -3503,20 +3602,41 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
3503
3602
  const missingStage = noResultDiagnostic?.includes('stage=unknown') ?? false;
3504
3603
  if (shouldCaptureFailureLog || missingStage) {
3505
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
+ };
3506
3626
  if ('tail' in logRead) {
3507
3627
  noResultLogEvidence = missingStage
3508
- ? { stderr: logRead.tail.join('\n'), logTail: logRead.tail, logTailLines: logRead.tail.length }
3509
- : { 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 };
3510
3630
  debug.log('self-implement.pod', missingStage ? 'no-result-log-tail' : 'failed-pod-log-tail', {
3511
- 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,
3512
3632
  }, { compact: { stringMax: 500 } });
3513
3633
  } else {
3514
3634
  const unavailable = `log-unavailable: ${logRead.unavailable}`;
3515
3635
  noResultLogEvidence = missingStage
3516
- ? { stderr: unavailable }
3517
- : { podLogUnavailable: logRead.unavailable };
3636
+ ? { stderr: unavailable, observation }
3637
+ : { podLogUnavailable: logRead.unavailable, observation };
3518
3638
  debug.log('self-implement.pod', missingStage ? 'no-result-log-tail' : 'failed-pod-log-tail', {
3519
- job: name, childRunId: liveChildRunId, diagnostic: noResultDiagnostic,
3639
+ job: name, childRunId: liveChildRunId, diagnostic: noResultDiagnostic, ...observation,
3520
3640
  logUnavailable: missingStage ? unavailable : logRead.unavailable,
3521
3641
  }, { level: 'warn' });
3522
3642
  }
package/src/tokens.ts CHANGED
@@ -33,7 +33,32 @@ export function estimateTokens(text: string): number {
33
33
  return Math.ceil(ascii / 4 + wide / 2);
34
34
  }
35
35
 
36
- export interface MessageLike { role: string; content: string | unknown[] }
36
+ export interface MessageLike {
37
+ role: string;
38
+ content: string | unknown[];
39
+ /** Opaque reasoning replayed by the Codex Responses adapter. */
40
+ codexReasoningItems?: unknown[];
41
+ }
42
+
43
+ function estimateStructuredTokens(value: unknown, ancestors = new Set<object>()): number {
44
+ if (typeof value === 'string') return estimateTokens(value);
45
+ if (value === null || typeof value !== 'object') return 1;
46
+ if (ancestors.has(value)) return 200; // malformed cyclic extension: conservative block floor
47
+ ancestors.add(value);
48
+ let total = 2; // JSON brackets/braces
49
+ if (Array.isArray(value)) {
50
+ total += Math.ceil(value.length / 4); // commas
51
+ for (const item of value) total += estimateStructuredTokens(item, ancestors);
52
+ } else {
53
+ const entries = Object.entries(value);
54
+ total += Math.ceil(entries.length / 4); // commas
55
+ for (const [key, item] of entries) {
56
+ total += estimateTokens(key) + 1 + estimateStructuredTokens(item, ancestors);
57
+ }
58
+ }
59
+ ancestors.delete(value);
60
+ return total;
61
+ }
37
62
 
38
63
  export function estimateMessagesTokens(messages: MessageLike[]): number {
39
64
  let total = 0;
@@ -44,7 +69,12 @@ export function estimateMessagesTokens(messages: MessageLike[]): number {
44
69
  for (const block of m.content) {
45
70
  if (!block || typeof block !== 'object') continue;
46
71
  const obj = block as Record<string, unknown>;
47
- if (typeof obj.text === 'string') {
72
+ if (obj.type === 'tool_use' || obj.type === 'tool_result') {
73
+ // These payloads are replayed as structured JSON; fixed block cost
74
+ // misses large args/results. Retain the old 200-token floor for
75
+ // tiny blocks so many small calls cannot under-trigger compaction.
76
+ total += Math.max(200, estimateStructuredTokens(obj));
77
+ } else if (typeof obj.text === 'string') {
48
78
  total += estimateTokens(obj.text);
49
79
  } else if (typeof obj.content === 'string') {
50
80
  // Wave 2 (2026-05-04) · tool_result block content matters
@@ -58,6 +88,9 @@ export function estimateMessagesTokens(messages: MessageLike[]): number {
58
88
  }
59
89
  }
60
90
  }
91
+ if (m.role === 'assistant' && m.codexReasoningItems?.length) {
92
+ total += estimateStructuredTokens(m.codexReasoningItems);
93
+ }
61
94
  }
62
95
  return total;
63
96
  }
@@ -10,6 +10,7 @@ export const agentRuntime: ToolRuntime<Record<string, unknown>, AgentToolResult>
10
10
  spec: buildAgentTool(),
11
11
  async run(req, ctx) {
12
12
  return await dispatchAgent(req, {
13
+ ...(ctx.parentSessionId ? { parentSessionId: ctx.parentSessionId } : {}),
13
14
  ...(ctx.agentCwd ? { cwd: ctx.agentCwd } : {}),
14
15
  hostTools: ctx.agentHostTools,
15
16
  dispatchTool: ctx.agentDispatchTool,
@@ -15,6 +15,7 @@ import { join } from 'node:path';
15
15
  import { readdir, readFile } from 'node:fs/promises';
16
16
  import { defaultSkillDirs } from '../user-config.js';
17
17
  import { SKILLS_LIST_DESCRIPTION } from '../onboarding/entry-hints.js';
18
+ import { normalizeSkillName } from '../skills/name-match.js';
18
19
  import type { LLMToolSpec } from '../llm.js';
19
20
  import type { ToolRuntime } from './types.js';
20
21
 
@@ -69,6 +70,7 @@ export async function dispatchElanousSkillsList(
69
70
  const skillsDir = dirs[0] ?? ''; // 단일 경로 계약 보존(첫 dir)·전체는 skillsDirs
70
71
  const label = dirs.join(', '); // 표시용(다중 루트면 콤마 결합)
71
72
  const query = (args.query ?? '').toLowerCase();
73
+ const normalizedQuery = normalizeSkillName(query);
72
74
  const seen = new Set<string>();
73
75
  const entries: ElanousSkillsListEntry[] = [];
74
76
  const errors: string[] = [];
@@ -91,7 +93,9 @@ export async function dispatchElanousSkillsList(
91
93
  }
92
94
  }
93
95
  let filtered = entries;
94
- if (query.length > 0) filtered = entries.filter((e) => e.name.toLowerCase().includes(query));
96
+ if (query.length > 0) filtered = entries.filter((e) =>
97
+ e.name.toLowerCase().includes(query)
98
+ || (normalizedQuery.length > 0 && normalizeSkillName(e.name).includes(normalizedQuery)));
95
99
  filtered.sort((a, b) => a.name.localeCompare(b.name));
96
100
  // 모든 dir 열거 실패(산출 0)면 실패 보고(단일 dir 부재 계약 보존).
97
101
  if (entries.length === 0 && errors.length > 0 && errors.length === dirs.length) {
@@ -3,6 +3,8 @@ import * as harnessSkillExec from '../harness/skill-exec.js';
3
3
  import { invokeResearch } from '../research-bridge/invoke.js';
4
4
  import * as skillIndex from '../skills/index.js';
5
5
  import type { SkillIndexEntry } from '../skills/index.js';
6
+ import { dirname } from 'node:path';
7
+ import { resolveSkillName } from '../skills/name-match.js';
6
8
  import { getUserConfig } from '../user-config.js';
7
9
  import type { LLMToolSpec } from '../llm.js';
8
10
  import type { ToolRuntime } from './types.js';
@@ -17,7 +19,7 @@ export interface SkillExecRunOptions {
17
19
  }
18
20
 
19
21
  export interface SkillExecArgs {
20
- /** Exact name of the skill to execute. */
22
+ /** Installed skill name; spaces/punctuation may be omitted if the match is unique. */
21
23
  skill: string;
22
24
  /** Task text passed verbatim to the named skill. */
23
25
  task: string;
@@ -33,6 +35,8 @@ export interface SkillExecResult extends Record<string, unknown> {
33
35
 
34
36
  export interface SkillExecDiscoveryDeps {
35
37
  discoverPlugin?: (gap: string, deps?: { signal?: AbortSignal }) => Promise<{ card: string }>;
38
+ /** Test seam for the bounded plugin-discovery follow-up. */
39
+ discoveryTimeoutMs?: number;
36
40
  }
37
41
 
38
42
  export type SkillExecIndexProvider = () => readonly SkillIndexEntry[];
@@ -71,13 +75,13 @@ function obtainSkillIndex(): readonly SkillIndexEntry[] {
71
75
  export function buildSkillExecTool(): LLMToolSpec {
72
76
  return {
73
77
  name: 'skill_exec',
74
- description: 'Execute one explicitly named allowlisted skill with the supplied task. If you do not know the exact skill name, call elanous_skills_list first. Does not infer a skill name.',
78
+ description: 'Execute one explicitly named allowlisted skill with the supplied task. Names may omit spaces or punctuation (for example, "krflow" resolves to "kr-flow") only when the installed match is unique. Call elanous_skills_list when uncertain.',
75
79
  parameters: {
76
80
  type: 'object',
77
81
  properties: {
78
82
  skill: {
79
83
  type: 'string',
80
- description: 'Exact name of the skill to execute.',
84
+ description: 'Installed skill name; spaces and punctuation may be omitted when the match is unique.',
81
85
  },
82
86
  task: {
83
87
  type: 'string',
@@ -95,9 +99,19 @@ export async function dispatchSkillExec(
95
99
  deps: SkillExecDiscoveryDeps = {},
96
100
  options: SkillExecRunOptions = {},
97
101
  ): Promise<SkillExecResult> {
98
- const { skill, task } = args;
102
+ const { skill: requestedSkill, task } = args;
103
+ if (requestedSkill !== requestedSkill.trim()) {
104
+ return { skill: requestedSkill, ok: false, output: REJECT_OUTPUT(requestedSkill) };
105
+ }
99
106
  const extra = getUserConfig().skillRouter.harnessExecAllowlist;
100
107
  const index = obtainSkillIndex();
108
+ const resolution = resolveSkillName(requestedSkill, index);
109
+ const skill = resolution.entry?.name ?? requestedSkill;
110
+ if (resolution.ambiguous.length > 0) {
111
+ const candidates = resolution.ambiguous.map((entry) => entry.name).sort().join(', ');
112
+ return { skill: requestedSkill, ok: false, output: `스킬 이름이 여러 항목과 일치합니다: ${candidates}. elanous_skills_list에서 정확한 이름을 골라 다시 호출하세요.` };
113
+ }
114
+ const selected = resolution.entry;
101
115
  const allowlist = harnessSkillExec.resolveHarnessExecAllowlist(
102
116
  extra,
103
117
  (rejected, reason) => observe('allowlist-reject', { skill: rejected, reason }),
@@ -163,13 +177,18 @@ export async function dispatchSkillExec(
163
177
  let interruption: 'skill-exec-timeout' | 'skill-exec-cancelled' | undefined;
164
178
  try {
165
179
  const outcome = await Promise.race([
166
- invokeResearch(task, { skill, signal: child.signal, onProgress: (delta) => {
167
- progressChunks += 1;
168
- progressBytes += delta.length;
169
- if (progressChunks === 1 || progressChunks % 32 === 0) {
170
- observe('progress', { skill, progressChunks, progressBytes });
171
- }
172
- } }).then((value) => ({ result: value })),
180
+ invokeResearch(task, {
181
+ skill,
182
+ ...(selected ? { skillRootDir: dirname(selected.skillDir) } : {}),
183
+ signal: child.signal,
184
+ onProgress: (delta) => {
185
+ progressChunks += 1;
186
+ progressBytes += delta.length;
187
+ if (progressChunks === 1 || progressChunks % 32 === 0) {
188
+ observe('progress', { skill, progressChunks, progressBytes });
189
+ }
190
+ },
191
+ }).then((value) => ({ result: value })),
173
192
  interrupted.then((reason) => ({ interruption: reason })),
174
193
  ]);
175
194
  settled = true;
@@ -195,10 +214,11 @@ export async function dispatchSkillExec(
195
214
  // A low-quality research result is a capability gap. Keep the original failure,
196
215
  // and attach a bounded discovery card rather than silently switching tools.
197
216
  let discoveryCard: string | undefined;
198
- if (!result.ok && /\b(?:no data|no evidence|missing|unavailable|not found|empty)\b|(?:자료가 없|데이터가 없|자료 부족|미확인|찾지 못)/i
217
+ const localSkillMissing = /not found under (?:~\/\.claude\/skills|\/)/i.test(result.error ?? '');
218
+ if (!result.ok && !localSkillMissing && /\b(?:no data|no evidence|missing|unavailable|not found|empty)\b|(?:자료가 없|데이터가 없|자료 부족|미확인|찾지 못)/i
199
219
  .test(`${result.output} ${result.error ?? ''}`)) {
200
220
  const controller = new AbortController();
201
- const timer = setTimeout(() => controller.abort(new Error('plugin discovery time budget exhausted')), 10_000);
221
+ const timer = setTimeout(() => controller.abort(new Error('plugin discovery time budget exhausted')), deps.discoveryTimeoutMs ?? 10_000);
202
222
  try {
203
223
  const discovery = deps.discoverPlugin ?? (await import('../research/plugin-discovery.js')).discoverResearchPlugin;
204
224
  const found = await discovery(task, { signal: controller.signal });
@@ -56,6 +56,7 @@ export interface ToolRuntimeContext {
56
56
  * supported (e.g. streaming fetch, long-running agent calls). */
57
57
  signal?: AbortSignal;
58
58
  /** Parent catalog and dispatcher inherited by an Agent runtime's child. */
59
+ parentSessionId?: string;
59
60
  agentHostTools?: LLMToolSpec[];
60
61
  /** Host-selected working directory for an Agent spawned through MCP. */
61
62
  agentCwd?: string;