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
@@ -10,13 +10,19 @@
10
10
  * ⭐ 이 스키마(`RunStopRecord`·`RUN_STOP_CLASSES`)는 STOP-AUTOHEAL 이 읽는다 — 칸 이름·닫힌 목록을 바꾸지 않는다(더하기만).
11
11
  */
12
12
  import { debug } from '../debug/log.js';
13
- import { appendRunLedgerEntry, type RunLedgerEntry, type RunLedgerWriter, type RunShardIdentity } from './run-ledger.js';
13
+ import { createHash } from 'node:crypto';
14
+ import { mkdirSync, writeFileSync } from 'node:fs';
15
+ import { dirname, join } from 'node:path';
16
+ import { appendRunLedgerEntry, runLedgerDir, runLedgerPath, type RunLedgerEntry, type RunLedgerWriter, type RunShardIdentity } from './run-ledger.js';
14
17
  import type { PodChildEvidence } from '../task-orchestrator/surfaces/self-implement.js';
18
+ import { defaultOverlaysDir, loadGraphOverlays } from './graph-overlay-yaml.js';
15
19
 
16
20
  /** 닫힌 목록 — 못 고르면 `unclassified`. */
17
21
  export const RUN_STOP_CLASSES = [
18
22
  'env-unrelated', 'main-sync', 'pod-died', 'pod-vanished', 'review-repeat',
19
- 'review-out-of-scope', 'scope-escape', 'evidence-uncovered', 'fabric', 'launch-failed', 'gate-failed', 'unclassified',
23
+ 'review-out-of-scope', 'review-budget-exhausted', 'scope-escape', 'evidence-uncovered', 'fabric', 'launch-failed', 'gate-failed',
24
+ 'implement-aborted', 'out-of-scope-held', 'provider-auth-missing', 'provider-unavailable',
25
+ 'merge-held-release-path', 'pr-guard-failed', 'gate-unmeasured', 'unclassified',
20
26
  ] as const;
21
27
  export type RunStopClass = typeof RUN_STOP_CLASSES[number];
22
28
 
@@ -35,6 +41,32 @@ export interface RunStopRecord {
35
41
  childEvidence?: PodChildEvidence;
36
42
  /** Exact structured Pod error code, when the host received one. */
37
43
  terminationReason?: 'pod-job-failed';
44
+ /** Safe terminal-attempt facts and a digest-addressed artifact; raw provider/child text is excluded. */
45
+ terminalEvidence?: RunStopTerminalEvidence;
46
+ }
47
+
48
+ export type RunStopReasonCode = 'tdd-evidence-missing' | 'goal-only-same-cell' | 'decomposition-401-invalid-api-key' | 'provider-credential-failure' | 'unknown';
49
+ export type RunStopFact = string | number | boolean | 'unknown';
50
+ export interface RunStopChildAttempt {
51
+ childRunId: RunStopFact;
52
+ job: RunStopFact;
53
+ attempt: RunStopFact;
54
+ stage: RunStopFact;
55
+ outcome: RunStopFact;
56
+ exitCode: RunStopFact;
57
+ reasonCode: RunStopReasonCode;
58
+ }
59
+ export interface RunStopTerminalEvidence {
60
+ childRunId: RunStopFact;
61
+ job: RunStopFact;
62
+ attempt: RunStopFact;
63
+ stage: RunStopFact;
64
+ node: RunStopFact;
65
+ outcome: RunStopFact;
66
+ exitCode: RunStopFact;
67
+ reasonCode: RunStopReasonCode;
68
+ childAttempts: RunStopChildAttempt[];
69
+ detailArtifact: { path: RunStopFact; byteLength: RunStopFact; sha256: RunStopFact };
38
70
  }
39
71
 
40
72
  export const RUN_STOP_EVENT = 'stop';
@@ -62,6 +94,127 @@ export interface RunStopInput {
62
94
  site?: string;
63
95
  childEvidence?: PodChildEvidence;
64
96
  terminationReason?: 'pod-job-failed';
97
+ terminalEvidence?: Omit<RunStopTerminalEvidence, 'detailArtifact'>;
98
+ /** Test seam; production persists only the sanitized structured artifact. */
99
+ writeEvidenceArtifact?: (path: string, bytes: Buffer) => void;
100
+ }
101
+
102
+ const UNKNOWN: RunStopFact = 'unknown';
103
+ const SAFE_TOKEN = /^[a-zA-Z0-9][a-zA-Z0-9._:/-]{0,159}$/u;
104
+ const RUN_STOP_REASON_CODES: readonly RunStopReasonCode[] = ['tdd-evidence-missing', 'goal-only-same-cell', 'decomposition-401-invalid-api-key', 'provider-credential-failure', 'unknown'];
105
+
106
+ function safeRunStopFact(value: unknown): RunStopFact {
107
+ if (typeof value === 'boolean') return value;
108
+ if (typeof value === 'number') return Number.isSafeInteger(value) ? value : UNKNOWN;
109
+ if (typeof value !== 'string' || !value.trim() || !SAFE_TOKEN.test(value.trim())) return UNKNOWN;
110
+ return value.trim();
111
+ }
112
+
113
+ function safeRunStopReasonCode(value: unknown): RunStopReasonCode {
114
+ return typeof value === 'string' && (RUN_STOP_REASON_CODES as readonly string[]).includes(value) ? value as RunStopReasonCode : 'unknown';
115
+ }
116
+
117
+ function writeTerminalEvidenceArtifact(input: RunStopInput, record: Omit<RunStopRecord, 'terminalEvidence'>): RunStopTerminalEvidence | undefined {
118
+ if (!input.terminalEvidence) return undefined;
119
+ const facts = input.terminalEvidence;
120
+ const safeEvidence = {
121
+ childRunId: safeRunStopFact(facts.childRunId), job: safeRunStopFact(facts.job), attempt: safeRunStopFact(facts.attempt),
122
+ stage: safeRunStopFact(facts.stage), node: safeRunStopFact(facts.node), outcome: safeRunStopFact(facts.outcome),
123
+ exitCode: safeRunStopFact(facts.exitCode), reasonCode: safeRunStopReasonCode(facts.reasonCode),
124
+ childAttempts: facts.childAttempts.slice(-8).map((item) => ({
125
+ childRunId: safeRunStopFact(item.childRunId), job: safeRunStopFact(item.job), attempt: safeRunStopFact(item.attempt),
126
+ stage: safeRunStopFact(item.stage), outcome: safeRunStopFact(item.outcome), exitCode: safeRunStopFact(item.exitCode),
127
+ reasonCode: safeRunStopReasonCode(item.reasonCode),
128
+ })),
129
+ };
130
+ const bytes = Buffer.from(`${JSON.stringify({ runId: input.runId, site: safeRunStopFact(input.site), class: record.class, terminalEvidence: safeEvidence }, null, 2)}\n`, 'utf8');
131
+ try {
132
+ // Validate the run id through the canonical ledger contract before using it in a path.
133
+ runLedgerPath(input.runId);
134
+ const path = join(runLedgerDir(), 'stop-cause-evidence', `${input.runId}.json`);
135
+ if (input.writeEvidenceArtifact) input.writeEvidenceArtifact(path, bytes);
136
+ else {
137
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
138
+ writeFileSync(path, bytes, { mode: 0o600 });
139
+ }
140
+ return { ...safeEvidence, detailArtifact: { path, byteLength: bytes.byteLength, sha256: createHash('sha256').update(bytes).digest('hex') } };
141
+ } catch {
142
+ return { ...safeEvidence, detailArtifact: { path: UNKNOWN, byteLength: UNKNOWN, sha256: UNKNOWN } };
143
+ }
144
+ }
145
+
146
+ /** Classify only named failure markers. Free-form strings are inspected, never copied to durable evidence. */
147
+ export function classifyRunStopReason(input: { detail?: unknown; terminationReason?: unknown; providerErrorCategory?: unknown; observedText?: readonly unknown[] }): RunStopReasonCode {
148
+ const text = [input.detail, ...(input.observedText ?? [])].filter((value): value is string => typeof value === 'string').join('\n').toLowerCase();
149
+ if (input.terminationReason === 'goal-only-rework-exhausted') return 'goal-only-same-cell';
150
+ if (/goal-only-rework-exhausted/u.test(text)) return 'goal-only-same-cell';
151
+ if (/tdd-evidence-missing/u.test(text)) return 'tdd-evidence-missing';
152
+ // Require a decomposition context as well as both credential markers; generic 401s are not this diagnosis.
153
+ if (/decompos.{0,256}\b401\b.{0,256}invalid api key|decompos.{0,256}invalid api key.{0,256}\b401\b|decomposition-401-invalid-api-key/u.test(text)) return 'decomposition-401-invalid-api-key';
154
+ if (input.providerErrorCategory === 'credential') return 'provider-credential-failure';
155
+ return 'unknown';
156
+ }
157
+
158
+ /** Extract child attempt metadata without carrying untrusted child/provider text into the stop artifact. */
159
+ export function runStopChildAttempts(entries: readonly RunLedgerEntry[], classify: (values: readonly unknown[]) => RunStopReasonCode = () => 'unknown'): RunStopChildAttempt[] {
160
+ const attempts: RunStopChildAttempt[] = [];
161
+ const attemptByJob = new Map<string, number>();
162
+ for (const entry of entries) {
163
+ const data = entry.data;
164
+ if (entry.event === 'pod-oom-retry-intent') {
165
+ if (typeof data.job === 'string' && Number.isSafeInteger(data.attempt) && typeof data.attempt === 'number') attemptByJob.set(data.job, data.attempt);
166
+ continue;
167
+ }
168
+ if (entry.event !== 'pod-child-evidence') continue;
169
+ const childRunId = safeRunStopFact(data.childRunId);
170
+ const childResult = data.childResult && typeof data.childResult === 'object' && !Array.isArray(data.childResult) ? data.childResult as Record<string, unknown> : {};
171
+ const pod = data.podTermination && typeof data.podTermination === 'object' && !Array.isArray(data.podTermination) ? data.podTermination as Record<string, unknown> : {};
172
+ const text = [childResult.error, data.childEvidence, entry.data].filter((value) => value !== undefined);
173
+ const stage = safeRunStopFact(childResult.stage);
174
+ const exitCode = safeRunStopFact(pod.exitCode);
175
+ const childOutcome = typeof childResult.ok === 'boolean' ? (childResult.ok ? 'completed' : 'failed')
176
+ : typeof exitCode === 'number' ? (exitCode === 0 ? 'completed' : 'failed') : UNKNOWN;
177
+ const job = safeRunStopFact(data.job);
178
+ attempts.push({ childRunId, job, attempt: typeof job === 'string' ? attemptByJob.get(job) ?? UNKNOWN : UNKNOWN,
179
+ stage, outcome: childOutcome, exitCode, reasonCode: classify(text) });
180
+ }
181
+ return attempts.slice(-8);
182
+ }
183
+
184
+ /** Join the final outcome to the latest recorded child attempt; missing fields stay explicit unknowns. */
185
+ export function buildRunStopTerminalEvidence(input: {
186
+ stage: unknown;
187
+ node: unknown;
188
+ outcome: unknown;
189
+ detail?: unknown;
190
+ terminationReason?: unknown;
191
+ providerErrorCategory?: unknown;
192
+ entries: readonly RunLedgerEntry[];
193
+ }): Omit<RunStopTerminalEvidence, 'detailArtifact'> {
194
+ const observedText = input.entries
195
+ .filter((entry) => entry.event === 'pod-child-evidence' || entry.event.includes('decomposition'))
196
+ .map((entry) => {
197
+ try { return `${entry.event} ${JSON.stringify(entry.data)}`.slice(0, 24_000); } catch { return ''; }
198
+ }).filter(Boolean);
199
+ const classify = (values: readonly unknown[]) => classifyRunStopReason({
200
+ observedText: values.map((value) => typeof value === 'string' ? value : (() => { try { return JSON.stringify(value); } catch { return ''; } })()),
201
+ });
202
+ const childAttempts = runStopChildAttempts(input.entries, classify);
203
+ const current = childAttempts.at(-1);
204
+ const classified = classifyRunStopReason({ detail: input.detail, terminationReason: input.terminationReason,
205
+ providerErrorCategory: input.providerErrorCategory, observedText: observedText.slice(-1) });
206
+ const reasonCode = classified !== 'unknown' ? classified : current?.reasonCode ?? 'unknown';
207
+ return {
208
+ childRunId: current?.childRunId ?? UNKNOWN,
209
+ job: current?.job ?? UNKNOWN,
210
+ attempt: current?.attempt ?? UNKNOWN,
211
+ stage: safeRunStopFact(input.stage),
212
+ node: safeRunStopFact(input.node),
213
+ outcome: safeRunStopFact(input.outcome),
214
+ exitCode: current?.exitCode ?? UNKNOWN,
215
+ reasonCode,
216
+ childAttempts,
217
+ };
65
218
  }
66
219
 
67
220
  export function isRunStopClass(value: unknown): value is RunStopClass {
@@ -79,9 +232,12 @@ export function boundRunStopCause(raw: string): string {
79
232
  /** 병합 보류 사유 → 닫힌 목록. 모르면 `unclassified`. */
80
233
  export function classifyMergeHoldStop(mergeReason: string | undefined): RunStopClass {
81
234
  const reason = mergeReason ?? '';
235
+ const graphClass = classifyStopReasonFromGraph(reason);
236
+ if (graphClass) return graphClass;
82
237
  if (reason.startsWith('main-sync') || reason === 'default-branch-unresolved') return 'main-sync';
83
238
  if (reason === 'required-evidence-uncovered') return 'evidence-uncovered';
84
- if (reason === 'review-must-fix' || reason === 'review-warn-with-must-fix' || reason.startsWith('review-budget')) return 'review-repeat';
239
+ if (reason.startsWith('review-budget')) return 'review-budget-exhausted';
240
+ if (reason === 'review-must-fix' || reason === 'review-warn-with-must-fix') return 'review-repeat';
85
241
  if (reason.startsWith('review-diff') || reason === 'no-real-review') return 'review-out-of-scope';
86
242
  return 'unclassified';
87
243
  }
@@ -96,6 +252,49 @@ export function classifyPodExitStop(reason: string | undefined, stage?: string):
96
252
  }
97
253
  }
98
254
 
255
+ /** Terminal implementation failures are classified only after the inner repair/round budget has ended. */
256
+ export function classifyTerminalHarnessFailure(input: {
257
+ stage: string;
258
+ cause?: string;
259
+ mergeReason?: string;
260
+ abandonedClassification?: string;
261
+ providerErrorCategory?: string;
262
+ supervisorVerdict?: string;
263
+ }): RunStopClass {
264
+ const graphClass = classifyStopReasonFromGraph(input.cause ?? input.mergeReason ?? '');
265
+ if (graphClass) return graphClass;
266
+ if (input.abandonedClassification === 'implement-aborted') return 'implement-aborted';
267
+ if (input.abandonedClassification === 'out-of-scope-held') return 'out-of-scope-held';
268
+ if (input.providerErrorCategory === 'credential' || input.providerErrorCategory === 'provider-auth-missing') return 'provider-auth-missing';
269
+ if (input.providerErrorCategory === 'provider-unavailable') return 'provider-unavailable';
270
+ if (input.mergeReason === 'release-path-hold') return 'merge-held-release-path';
271
+ if (input.mergeReason === 'pr-guard-failed') return 'pr-guard-failed';
272
+ if (input.mergeReason === 'gate-unmeasured') return 'gate-unmeasured';
273
+ if (input.mergeReason) return classifyMergeHoldStop(input.mergeReason);
274
+ if (input.providerErrorCategory === 'credential' || input.abandonedClassification === 'credential-failure') return 'launch-failed';
275
+ if (input.abandonedClassification === 'report-deficit') return 'pod-died';
276
+ if (input.stage === 'gate-failed') return 'gate-failed';
277
+ if (input.stage === 'review-blocked' || input.stage === 'no-changes' || input.supervisorVerdict === 'UNCONVERGEABLE') return 'review-repeat';
278
+ if (input.stage === 'merge-conflict') return 'main-sync';
279
+ if (input.stage === 'timed-out') return 'pod-died';
280
+ return 'unclassified';
281
+ }
282
+
283
+ /** Exact reason vocabulary declared by heal graph overlays; unknown phrases remain unclassified. */
284
+ export function classifyStopReasonFromGraph(reason: string): RunStopClass | undefined {
285
+ const normalized = reason.trim().toLowerCase();
286
+ if (!normalized) return undefined;
287
+ try {
288
+ for (const overlay of loadGraphOverlays(defaultOverlaysDir()).overlays) {
289
+ for (const [phrase, cls] of Object.entries(overlay.reasonMap ?? {})) {
290
+ const escaped = phrase.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
291
+ if (new RegExp(`(^|[^a-z0-9])${escaped}([^a-z0-9]|$)`).test(normalized) && isRunStopClass(cls)) return cls;
292
+ }
293
+ }
294
+ } catch { /* malformed or unavailable graph declarations are not classifier evidence */ }
295
+ return undefined;
296
+ }
297
+
99
298
  /** 이 프로세스에서 stop 을 이미 쓴 런 — 한 런이 두 자리(예: draft PR 실패 ⊕ aborted)에서 두 줄을 쓰지 않게. */
100
299
  const recordedThisProcess = new Set<string>();
101
300
  const RECORDED_MAX = 4096;
@@ -112,7 +311,7 @@ export function forgetRunStop(runId: string): void {
112
311
 
113
312
  /** 멈춘 런에 stop 한 줄을 더한다 — 기존 관측은 바꾸지 않는다. 쓴 줄을 돌려준다. */
114
313
  export function recordRunStop(input: RunStopInput, write: RunLedgerWriter = appendRunLedgerEntry): RunLedgerEntry {
115
- const record: RunStopRecord = {
314
+ const base: Omit<RunStopRecord, 'terminalEvidence'> = {
116
315
  class: isRunStopClass(input.class) ? input.class : 'unclassified',
117
316
  ...(input.site ? { site: input.site } : {}),
118
317
  cause: boundRunStopCause(input.cause),
@@ -121,6 +320,8 @@ export function recordRunStop(input: RunStopInput, write: RunLedgerWriter = appe
121
320
  ...(input.childEvidence ? { childEvidence: input.childEvidence } : {}),
122
321
  ...(input.terminationReason ? { terminationReason: input.terminationReason } : {}),
123
322
  };
323
+ const terminalEvidence = writeTerminalEvidenceArtifact(input, base);
324
+ const record: RunStopRecord = { ...base, ...(terminalEvidence ? { terminalEvidence } : {}) };
124
325
  const entry: RunLedgerEntry = {
125
326
  timestamp: new Date().toISOString(), runId: input.runId, event: RUN_STOP_EVENT,
126
327
  data: { ...record },
@@ -134,6 +335,7 @@ export function recordRunStop(input: RunStopInput, write: RunLedgerWriter = appe
134
335
  try { listener(entry); } catch { /* wake consumers cannot change run outcome */ }
135
336
  }
136
337
  try {
338
+ debug.log('self-implement.run-stop', 'cause-classified', { runId: input.runId, terminalEvidence });
137
339
  debug.log('self-implement.run-stop', 'recorded', { runId: input.runId, site: input.site ?? null, ...record, requestedClass: input.class ?? null });
138
340
  } catch { /* observation is fail-soft */ }
139
341
  return entry;
@@ -147,5 +349,6 @@ export function readRunStopRecord(entry: RunLedgerEntry): RunStopRecord | undefi
147
349
  return { class: isRunStopClass(data.class) ? data.class : 'unclassified', cause: data.cause, evidenceRef: data.evidenceRef, nextMove: data.nextMove,
148
350
  ...(typeof data.site === 'string' ? { site: data.site } : {}),
149
351
  ...(data.childEvidence ? { childEvidence: data.childEvidence } : {}),
150
- ...(data.terminationReason === 'pod-job-failed' ? { terminationReason: data.terminationReason } : {}) };
352
+ ...(data.terminationReason === 'pod-job-failed' ? { terminationReason: data.terminationReason } : {}),
353
+ ...(data.terminalEvidence && typeof data.terminalEvidence === 'object' ? { terminalEvidence: data.terminalEvidence as RunStopTerminalEvidence } : {}) };
151
354
  }
@@ -116,6 +116,8 @@ export interface RunningRunsResult {
116
116
  };
117
117
  /** Additive phase-store observability; queryRunningRuns always supplies this value. */
118
118
  readonly phases?: RunningRunsPhaseStoreObservation;
119
+ /** Present when a caller time budget stopped one observation stage before full coverage. */
120
+ readonly stalled?: { readonly stage: 'ledger-scan' | 'cross-directory-reconciliation' | 'pty-observation' | 'phase-observation' | 'launch-parent-classification'; readonly reason: 'deadline-exceeded' };
119
121
  }
120
122
 
121
123
  export interface QueriedRunningRunsResult extends RunningRunsResult {
@@ -263,7 +265,7 @@ export interface RunningRunsQueryObservation {
263
265
  }
264
266
 
265
267
  export interface RunningRunsQueryDeps {
266
- readonly queryLedgers?: (options: { includeTest?: boolean; ledgerDirectories?: readonly string[]; runIds?: readonly string[]; noCache?: boolean }) => FederatedUnfinishedRunLedgerQuery;
268
+ readonly queryLedgers?: (options: { includeTest?: boolean; ledgerDirectories?: readonly string[]; runIds?: readonly string[]; noCache?: boolean; deadlineAtMs?: number }) => FederatedUnfinishedRunLedgerQuery;
267
269
  readonly ledgerDirectories?: (options: { includeTest?: boolean }) => readonly string[];
268
270
  readonly ptyTargets?: (options: { includeTest?: boolean }) => readonly { name: string; dbPath: string }[];
269
271
  readonly readPtyRows?: typeof listPtyManifestRowsAt;
@@ -303,6 +305,7 @@ export function assessLingeringLaunchParents(
303
305
  isProcessAlive: (pid: number) => boolean,
304
306
  processStartTime: (pid: number) => number | null,
305
307
  ledgerObservation?: Pick<RunningRunsLedgerObservation, 'unreadableLedgerCount' | 'unreadableLedgerDirectoryCount' | 'unreadableLedgerDirectoryAccessCount' | 'indeterminateLedgerDirectoryCount'>,
308
+ deadlineAtMs?: number,
306
309
  ): LingeringLaunchParentAssessment {
307
310
  if (!ledgerObservation || hasUnreadableLedgerObservation(ledgerObservation)) return { observation: 'indeterminate' };
308
311
 
@@ -316,6 +319,7 @@ export function assessLingeringLaunchParents(
316
319
  let reusedPidCount = 0;
317
320
  try {
318
321
  for (const [runId, ledgerDirectory] of terminatedRunDirectories) {
322
+ if (deadlineAtMs !== undefined && Date.now() >= deadlineAtMs) return { observation: 'indeterminate' };
319
323
  const run = loadRun(runId, ledgerDirectory);
320
324
  const pid = run?.pid;
321
325
  if (typeof pid !== 'number' || !Number.isInteger(pid) || pid <= 0) {
@@ -454,7 +458,7 @@ export function distinctPhysicalLedgerDirectories(
454
458
  return distinct;
455
459
  }
456
460
 
457
- export function queryRunningRuns(options: { includeTest?: boolean; runIds?: readonly string[]; caller?: string; noCache?: boolean } = {}, deps: RunningRunsQueryDeps = {}): QueriedRunningRunsResult {
461
+ export function queryRunningRuns(options: { includeTest?: boolean; runIds?: readonly string[]; caller?: string; noCache?: boolean; timeBudgetMs?: number } = {}, deps: RunningRunsQueryDeps = {}): QueriedRunningRunsResult {
458
462
  const directoryFailures = new Map<string, ReturnType<typeof classifyFederatedLedgerDirectoryReadFailure>>();
459
463
  const queryLedgers = deps.queryLedgers ?? ((queryOptions: Parameters<typeof queryFederatedUnfinishedRunLedgers>[0]) => queryFederatedUnfinishedRunLedgers({
460
464
  ...queryOptions,
@@ -480,6 +484,9 @@ export function queryRunningRuns(options: { includeTest?: boolean; runIds?: read
480
484
  const processStartTime = deps.processStartedAt ?? processStartedAt;
481
485
  const observeQuery = deps.observeQuery ?? ((observation: RunningRunsQueryObservation) => debug.log('self-implement.running-runs', 'query', observation));
482
486
  const startedAt = Date.now();
487
+ const deadlineAtMs = options.timeBudgetMs === undefined ? undefined : startedAt + Math.max(0, options.timeBudgetMs);
488
+ let stalled: RunningRunsResult['stalled'];
489
+ const deadlineExceeded = (): boolean => deadlineAtMs !== undefined && Date.now() >= deadlineAtMs;
483
490
  // ID 조회 배선 — src/index.ts의 `self running-runs [runId]` 액션이 넘겨준 options.runIds 를 이 조회가 소비한다:
484
491
  // 정의된 runIds 는 연합 원장 질의 전달·엔트리·pty 관측을 모두 그 runId 들로 한정한다.
485
492
  const requestedRunIdSet = options.runIds === undefined ? undefined : new Set(options.runIds);
@@ -509,20 +516,25 @@ export function queryRunningRuns(options: { includeTest?: boolean; runIds?: read
509
516
  try {
510
517
  const requestedRunIds = options.runIds === undefined ? {} : { runIds: options.runIds };
511
518
  const cacheOption = options.noCache === undefined ? {} : { noCache: options.noCache };
519
+ const deadlineOption = deadlineAtMs === undefined ? {} : { deadlineAtMs };
512
520
  ledger = collectLedgerDirectories
513
- ? queryLedgers({ includeTest: options.includeTest, ledgerDirectories: collectedLedgerDirectories, ...requestedRunIds, ...cacheOption })
514
- : queryLedgers({ includeTest: options.includeTest, ...requestedRunIds, ...cacheOption });
521
+ ? queryLedgers({ includeTest: options.includeTest, ledgerDirectories: collectedLedgerDirectories, ...requestedRunIds, ...cacheOption, ...deadlineOption })
522
+ : queryLedgers({ includeTest: options.includeTest, ...requestedRunIds, ...cacheOption, ...deadlineOption });
515
523
  ledgerDirectoryCount = ledger.ledgerDirectories.length;
516
524
  ledgerEntryCount = ledger.entries.length;
517
525
  cacheHits = ledger.cacheHits ?? 0;
518
526
  cacheMisses = ledger.cacheMisses ?? 0;
527
+ if (ledger.timedOut) stalled = { stage: ledger.stalledStage ?? 'ledger-scan', reason: 'deadline-exceeded' };
519
528
  } finally {
520
529
  ledgerReadElapsedMs = Date.now() - ledgerReadStartedAt;
521
530
  }
522
531
  const screenProcessReadStartedAt = Date.now();
523
532
  let pty: FederatedPtyListing;
524
533
  try {
525
- pty = listPtyRefs(targets({ includeTest: options.includeTest }), readPtyRows);
534
+ if (deadlineExceeded()) {
535
+ stalled ??= { stage: 'pty-observation', reason: 'deadline-exceeded' };
536
+ pty = { refs: [], unreadable: ['<skipped:deadline-exceeded>'] };
537
+ } else pty = listPtyRefs(targets({ includeTest: options.includeTest }), readPtyRows);
526
538
  } finally {
527
539
  screenProcessReadElapsedMs = Date.now() - screenProcessReadStartedAt;
528
540
  }
@@ -538,7 +550,8 @@ export function queryRunningRuns(options: { includeTest?: boolean; runIds?: read
538
550
  let observedPhases: ObservedRunPhases = { events: [], targetCount: 0, unreadableTargets: [] };
539
551
  const stageStoreReadStartedAt = Date.now();
540
552
  try {
541
- observedPhases = readRunPhases({ includeTest: options.includeTest }, runIds);
553
+ if (deadlineExceeded()) stalled ??= { stage: 'phase-observation', reason: 'deadline-exceeded' };
554
+ else observedPhases = readRunPhases({ includeTest: options.includeTest }, runIds);
542
555
  } catch {
543
556
  observedPhases = { events: [], targetCount: 1, unreadableTargets: ['phase-query'] };
544
557
  } finally {
@@ -583,13 +596,23 @@ export function queryRunningRuns(options: { includeTest?: boolean; runIds?: read
583
596
  const launchParentClassificationStartedAt = Date.now();
584
597
  let lingeringLaunchParents: LingeringLaunchParentAssessment;
585
598
  try {
586
- lingeringLaunchParents = assessLingeringLaunchParents(
587
- scopedLedgerEntries, loadRun, isProcessAlive, processStartTime, ledger,
588
- );
599
+ if (deadlineExceeded()) {
600
+ stalled ??= { stage: 'launch-parent-classification', reason: 'deadline-exceeded' };
601
+ lingeringLaunchParents = { observation: 'indeterminate' };
602
+ } else {
603
+ lingeringLaunchParents = assessLingeringLaunchParents(
604
+ scopedLedgerEntries, loadRun, isProcessAlive, processStartTime, ledger, deadlineAtMs,
605
+ );
606
+ if (deadlineExceeded()) stalled ??= { stage: 'launch-parent-classification', reason: 'deadline-exceeded' };
607
+ }
589
608
  } finally {
590
609
  launchParentClassificationElapsedMs = Date.now() - launchParentClassificationStartedAt;
591
610
  }
592
- return { ...result, completeness, unreadable, count, observation, quantities: quantitySummary({ ...result, observation }), lingeringLaunchParents: lingeringLaunchParents!, ledger: { ledgerDirectories: ledger.ledgerDirectories, unreadableLedgerCount: ledger.unreadableLedgerCount, unreadableLedgerDirectoryCount: ledger.unreadableLedgerDirectoryCount, missingLedgerDirectoryCount: ledger.missingLedgerDirectoryCount, unreadableLedgerDirectoryAccessCount: ledger.unreadableLedgerDirectoryAccessCount, indeterminateLedgerDirectoryCount: ledger.indeterminateLedgerDirectoryCount, cacheHits, cacheMisses }, phases: phaseStoreObservation(observedPhases) };
611
+ const finalCompleteness = hasUnreadableLedgerObservation(ledger) || stalled ? 'partial' : 'complete';
612
+ const finalCount: RunningRunsCount = finalCompleteness === 'partial'
613
+ ? { count: null, lowerBound: result.counts.running + result.counts['probable-running'], unreadable }
614
+ : result.counts.running + result.counts['probable-running'];
615
+ return { ...result, completeness: finalCompleteness, unreadable, count: finalCount, observation, quantities: quantitySummary({ ...result, observation }), lingeringLaunchParents: lingeringLaunchParents!, ledger: { ledgerDirectories: ledger.ledgerDirectories, unreadableLedgerCount: ledger.unreadableLedgerCount, unreadableLedgerDirectoryCount: ledger.unreadableLedgerDirectoryCount, missingLedgerDirectoryCount: ledger.missingLedgerDirectoryCount, unreadableLedgerDirectoryAccessCount: ledger.unreadableLedgerDirectoryAccessCount, indeterminateLedgerDirectoryCount: ledger.indeterminateLedgerDirectoryCount, cacheHits, cacheMisses }, phases: phaseStoreObservation(observedPhases), ...(stalled ? { stalled } : {}) };
593
616
  } finally {
594
617
  try {
595
618
  observeQuery({
@@ -614,7 +637,7 @@ export function queryRunningRuns(options: { includeTest?: boolean; runIds?: read
614
637
 
615
638
  export function isPartialRunningRuns(result: RunningRunsResult): boolean {
616
639
  return (result.count !== undefined && typeof result.count !== 'number' && result.count.count === null)
617
- || result.completeness === 'partial' || hasUnreadableLedgerObservation(result.ledger) || (result.unreadable?.length ?? 0) > 0;
640
+ || result.completeness === 'partial' || result.stalled !== undefined || hasUnreadableLedgerObservation(result.ledger) || (result.unreadable?.length ?? 0) > 0;
618
641
  }
619
642
 
620
643
  function runningRunsLowerBound(result: RunningRunsResult): number {
@@ -670,7 +693,7 @@ function formatElapsed(ms: number): string {
670
693
  export function renderRunProgressTable(result: RunningRunsResult, nowMs: number = Date.now()): string {
671
694
  const partial = isPartialRunningRuns(result);
672
695
  const header = partial
673
- ? `부분 관측 — 최소 ${runningRunsLowerBound(result)} (읽지 못한 원장: ${runningRunsUnreadable(result).map((item) => `${item.dir}:${item.reason}`).join(',') || '목록 미관측'})`
696
+ ? `부분 관측 — 최소 ${runningRunsLowerBound(result)} (${result.stalled ? `중단 단계 ${result.stalled.stage} · 사유 ${result.stalled.reason}` : `읽지 못한 원장: ${runningRunsUnreadable(result).map((item) => `${item.dir}:${item.reason}`).join(',') || '목록 미관측'}`})`
674
697
  : `도는 런 ${result.counts.running + result.counts['probable-running']} (확인 ${result.counts.running} · 추정 ${result.counts['probable-running']})`;
675
698
  const rows = buildRunProgressRows(result, nowMs).map((row) => {
676
699
  const phaseUnreadable = row.phaseObservation === 'unreadable' || row.phaseObservation === 'partially-unreadable';
@@ -20,6 +20,7 @@ import { resolveObserveOnlyDecision } from './observe-only.js';
20
20
  import { getUserConfig } from '../user-config.js';
21
21
  import { resolveAutoReview } from './context-capsule.js';
22
22
  import { readDecomposeProposals } from '../self-dev/decompose-proposal.js';
23
+ import { tracedPathReferences } from './goal-author.js';
23
24
 
24
25
  /** self implement CLI 옵션(commander) — `--no-draft` 는 draft:false 로, `--max-wait` 는 문자열로 도착. */
25
26
  export interface SelfImplementCliOpts {
@@ -65,6 +66,12 @@ export interface SelfImplementCliDeps {
65
66
  resolveWantAutoReview?: (flag: boolean) => boolean | Promise<boolean>;
66
67
  /** reroute 실행(테스트 주입). 기본 executeSelfImplementReroute. */
67
68
  executeReroute?: typeof executeSelfImplementReroute;
69
+ /** Capability seam: false disables reason-repair reruns; omitted means available because this CLI has a production rerouter. */
70
+ reasonRepairExecutionAvailable?: boolean;
71
+ /** Supervisor side-effect seams for focused runtime tests. */
72
+ taskAgentShadow?: false;
73
+ taskAgentRejudge?: false;
74
+ sweepPendingMerges?: typeof import('./frozen-merges.js').sweepFrozenMerges;
68
75
  /** ⭐ 산출물의 «눈» 심(테스트 주입). 기본은 실제 브라우저 검증(`observeDeliverables`).
69
76
  * ⛔ 심이 «없으면» 이 배선을 시험으로 재현할 수 없고, 그러면 「손으로 돌려 봤다」만 남는다
70
77
  * — 그것은 「그때 됐다」이지 「앞으로도 된다」가 아니다(리뷰 #10556 must-fix). */
@@ -124,11 +131,25 @@ export interface SingleRunSuperviseOptions {
124
131
  type SelfImplementResultWithProposalMetadata = SelfImplementResult
125
132
  & Pick<SelfDevJobResult, 'decomposeProposal' | 'goalPlanRevision'>;
126
133
 
127
- export function singleRunAsJobResult(feature: string, r: SelfImplementResultWithProposalMetadata): SupervisorJobResult {
134
+ /**
135
+ * NEEDS-HUMAN-REASON-REPAIR — 실행 범위 가드가 «대상 밖»으로 잰 변경을 감독 판정 재료로 옮긴다.
136
+ * ⛔ 가드가 잰 이름만 쓴다 — 결과에 없으면 빈 배열이고, 「없다」를 지어내지 않는다.
137
+ */
138
+ function measuredOutsideTargetFiles(r: SelfImplementResult): string[] {
139
+ return [...new Set([
140
+ ...(r.outOfScopeEdits ?? []),
141
+ ...(r.scopeExpansion?.files.map((file) => file.path) ?? []),
142
+ ])];
143
+ }
144
+
145
+ export function singleRunAsJobResult(feature: string, r: SelfImplementResultWithProposalMetadata, includeDeclaredTargets = false): SupervisorJobResult {
146
+ const outsideTargetFiles = measuredOutsideTargetFiles(r);
147
+ const targetPaths = includeDeclaredTargets ? tracedPathReferences(feature).map(({ path }) => path) : [];
128
148
  return {
129
149
  taskId: r.runId,
130
150
  runId: r.runId,
131
151
  feature,
152
+ ...(targetPaths.length ? { targetPaths } : {}),
132
153
  status: r.ok ? 'done' : 'failed',
133
154
  stage: r.stage,
134
155
  ...(!r.ok && r.detail ? { error: { message: r.detail } } : {}),
@@ -145,6 +166,7 @@ export function singleRunAsJobResult(feature: string, r: SelfImplementResultWith
145
166
  ...(r.abandonedClassification?.classification
146
167
  ? { failureClassification: r.abandonedClassification.classification } : {}),
147
168
  ...(r.decomposeProposal ? { decomposeProposal: r.decomposeProposal } : {}),
169
+ ...(outsideTargetFiles.length > 0 ? { outsideTargetFiles } : {}),
148
170
  ...(r.rework ? { rework: r.rework } : {}),
149
171
  ...(r.review?.reviewed && r.review.mustFix?.length ? { reviewMustFix: r.review.mustFix } : {}),
150
172
  ...(r.goalPlanRevision ? { goalPlanRevision: r.goalPlanRevision } : {}),
@@ -268,10 +290,20 @@ export async function runSelfImplementCliCommand(
268
290
  }
269
291
  : undefined;
270
292
 
271
- const initialJob = singleRunAsJobResult(feature, result);
293
+ const reasonRepairEnabled = getUserConfig().tools.selfImplement.supervisor?.reasonRepair === true
294
+ && (deps.reasonRepairExecutionAvailable ?? true);
295
+ const initialJob = singleRunAsJobResult(feature, result, reasonRepairEnabled);
296
+ // NEEDS-HUMAN-REASON-REPAIR — 사유별 수복 골을 «실행하는» 경로인가.
297
+ // ⛔ 아래 rerun 이 invocation.repairGoals[taskId] 를 spec.input.text 로 그대로 실행하므로 «그렇다».
298
+ // ⇒ 그래서 이 감독 경로는 사유별 수복(needs-human 전 1회)을 연다.
299
+ const repairGoalExecution = true;
272
300
  await superviseRun({
273
301
  initial: [initialJob],
274
- repairGoalExecution: true,
302
+ ...(deps.taskAgentShadow === false ? { taskAgentShadow: false } : {}),
303
+ ...(deps.taskAgentRejudge === false ? { taskAgentRejudge: false } : {}),
304
+ ...(deps.sweepPendingMerges ? { sweepPendingMerges: deps.sweepPendingMerges } : {}),
305
+ repairGoalExecution,
306
+ needsHumanReasonRepairExecution: reasonRepairEnabled,
275
307
  limits,
276
308
  ...(deliverableEye ? { observeDeliverables: deliverableEye } : {}),
277
309
  ...(opts.supervise.onDecision ? { onDecision: opts.supervise.onDecision } : {}),
@@ -285,7 +317,7 @@ export async function runSelfImplementCliCommand(
285
317
  const next = await exec(repairGoal ? { ...spec, input: { ...spec.input, text: repairGoal } } : spec, pipelineDeps ? { pipelineDeps } : undefined);
286
318
  result = attachGoalPlanRevisionObservation(next.result, deps);
287
319
  exitCode = next.exitCode;
288
- return [{ ...singleRunAsJobResult(feature, result), taskId: initialJob.taskId }];
320
+ return [{ ...singleRunAsJobResult(feature, result, reasonRepairEnabled), taskId: initialJob.taskId }];
289
321
  },
290
322
  });
291
323
  }
@@ -0,0 +1,43 @@
1
+ /** Production STOP-AUTOHEAL actions. A missing prerequisite is a failed action, never a healed run. */
2
+ import { spawnSync } from 'node:child_process';
3
+ import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
4
+ import { runHostRegate, type HostRegateInput, type HostRegateResult } from './host-regate.js';
5
+ import type { AutohealActions, AutohealContext } from './stop-autoheal.js';
6
+
7
+ type PrHead = { headRefOid?: string; state?: string; isDraft?: boolean };
8
+ export interface OperationalAutohealDeps {
9
+ repoRoot: string;
10
+ readPr?: (number: number, repoRoot: string) => PrHead | null;
11
+ regate?: (input: HostRegateInput) => Promise<HostRegateResult>;
12
+ }
13
+
14
+ function prFromEvidence(ctx: AutohealContext): number | null {
15
+ const match = /^https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/([1-9]\d*)\/?$/.exec(ctx.record.evidenceRef);
16
+ return match ? Number(match[1]) : null;
17
+ }
18
+
19
+ function readPr(number: number, repoRoot: string): PrHead | null {
20
+ const result = spawnSync('gh', ['pr', 'view', String(number), '--json', 'headRefOid,state,isDraft'], {
21
+ cwd: repoRoot, encoding: 'utf8', timeout: 30_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER,
22
+ });
23
+ if (result.status !== 0) return null;
24
+ try { return JSON.parse(result.stdout) as PrHead; } catch { return null; }
25
+ }
26
+
27
+ /** Re-gate an existing PR in a clean checkout against current main; never merge from the healer. */
28
+ export function operationalAutohealActions(deps: OperationalAutohealDeps): AutohealActions {
29
+ return {
30
+ 'clean-workspace-regate': async (ctx) => {
31
+ const number = prFromEvidence(ctx);
32
+ if (!number) return { ok: false, detail: 'PR URL absent from stop evidence' };
33
+ const pr = (deps.readPr ?? readPr)(number, deps.repoRoot);
34
+ if (!pr?.headRefOid || pr.state !== 'OPEN' || typeof pr.isDraft !== 'boolean')
35
+ return { ok: false, detail: `PR #${number} is not an open PR with a measured head and draft state` };
36
+ const result = await (deps.regate ?? runHostRegate)({
37
+ prNumber: number, headCommit: pr.headRefOid, repoRoot: deps.repoRoot, verifyOnly: true,
38
+ ...(pr.isDraft ? { allowDraft: true } : {}),
39
+ });
40
+ return { ok: result.passed, detail: `PR #${number} head ${pr.headRefOid} clean regate ${result.status ?? (result.passed ? 'passed' : 'failed')}${result.failures.length ? `: ${result.failures.map((failure) => failure.step).join(',')}` : ''}` };
41
+ },
42
+ };
43
+ }
@@ -13,11 +13,12 @@
13
13
  * main-sync → rebase-regate 리베이스(MERGE-INTENT-RESOLVE 의도 해석) 뒤 재게이트
14
14
  * pod-died → resume-from-salvage `salvage/run-<6hex>/<leaf>` 가지에서 resume(DRAFT-NOT-ARCHIVE)
15
15
  * evidence-uncovered → derive-evidence-rejudge 런 출력·시험·배선에서 증거를 끌어내 1회 재판정
16
+ * review-budget-exhausted → needs-owner (code fallback; reauthor is an optional graph exit)
16
17
  * review-repeat · review-out-of-scope · scope-escape · fabric · launch-failed · gate-failed · unclassified → needs-owner(새 라운드 없음)
17
18
  *
18
19
  * 사다리의 «출처»: `graphs/overlays/stop-heal-ladder.yaml` 이 갈래마다 처방 노드(id = 처방 이름)를 선언한다.
19
20
  * 그 갈래에 얹힌 오버레이가 더한 노드 id 가 처방이다(source='graph'). 선언이 없거나 못 읽으면
20
- * 위 표(`AUTOHEAL_ACTION_BY_CLASS`)로 간다(source='code-default'). 둘이 같은 답을 내는지는 시험이 문다.
21
+ * 위 표(`AUTOHEAL_ACTION_BY_CLASS`)로 간다(source='code-default'). 선택된 노드가 실제 실행 가능한지는 별도 경계다.
21
22
  *
22
23
  * 모드 `tools.selfImplement.autoheal.mode` = `shadow`(기본: 할 일을 원장에만 적고 손대지 않는다) | `live`.
23
24
  * ⛔ live 에서도 행동은 주입 seam 으로만 한다 — seam 이 없는 행동은 `needs-owner`(action-unwired)로 떨어진다.
@@ -44,6 +45,12 @@ export type AutohealAction =
44
45
  | 'rebase-regate'
45
46
  | 'resume-from-salvage'
46
47
  | 'derive-evidence-rejudge'
48
+ | 'review-round-reauthor'
49
+ | 'reauthor-from-materialized'
50
+ | 'switch-provider'
51
+ | 'retry-provider'
52
+ | 'wait-release'
53
+ | 'remeasure-gate'
47
54
  | 'needs-owner';
48
55
 
49
56
  /** 닫힌 목록 전체를 덮는다 — 새 class 가 생기면 여기서 타입 오류가 난다. */
@@ -55,16 +62,26 @@ export const AUTOHEAL_ACTION_BY_CLASS: Readonly<Record<RunStopClass, AutohealAct
55
62
  'evidence-uncovered': 'derive-evidence-rejudge',
56
63
  'review-repeat': 'needs-owner',
57
64
  'review-out-of-scope': 'needs-owner',
65
+ // Reauthoring is an optional graph exit, not a code-level guarantee.
66
+ 'review-budget-exhausted': 'needs-owner',
58
67
  'scope-escape': 'needs-owner',
59
68
  fabric: 'needs-owner',
60
69
  'launch-failed': 'needs-owner',
61
70
  'gate-failed': 'needs-owner',
62
71
  unclassified: 'needs-owner',
72
+ 'implement-aborted': 'reauthor-from-materialized',
73
+ 'out-of-scope-held': 'reauthor-from-materialized',
74
+ 'provider-auth-missing': 'switch-provider',
75
+ 'provider-unavailable': 'retry-provider',
76
+ 'merge-held-release-path': 'wait-release',
77
+ 'pr-guard-failed': 'reauthor-from-materialized',
78
+ 'gate-unmeasured': 'remeasure-gate',
63
79
  };
64
80
 
65
81
  /** 처방 노드 id 로 인정하는 이름 — 오버레이가 더한 노드 중 이 넷만 처방으로 읽는다. */
66
82
  const HEAL_ACTION_NODE_IDS: ReadonlySet<string> = new Set<Exclude<AutohealAction, 'needs-owner'>>([
67
- 'clean-workspace-regate', 'rebase-regate', 'resume-from-salvage', 'derive-evidence-rejudge',
83
+ 'clean-workspace-regate', 'rebase-regate', 'resume-from-salvage', 'derive-evidence-rejudge', 'review-round-reauthor',
84
+ 'reauthor-from-materialized', 'switch-provider', 'retry-provider', 'wait-release', 'remeasure-gate',
68
85
  ]);
69
86
 
70
87
  /** 처방이 «어디서» 왔나 — `graph` = 그 갈래에 얹힌 오버레이가 더한 노드 · `code-default` = 위 표. */
@@ -75,6 +92,8 @@ export interface AutohealPick {
75
92
  source: AutohealActionSource;
76
93
  /** source='graph' 일 때 그 처방 노드를 더한 오버레이. */
77
94
  overlayId?: string;
95
+ /** Code fallback when an optional graph exit is not declared. */
96
+ fallbackReason?: string;
78
97
  }
79
98
 
80
99
  /** 사다리를 읽어 오는 자리 — 활성 템플릿 선언 ⊕ 오버레이 목록. 시험이 갈아 끼운다. */
@@ -93,7 +112,10 @@ function loadDefaultLadder(): AutohealLadder {
93
112
  * «조용히» 코드 표로 간다 — 그 사실은 `source` 가 말한다. 던지지 않는다.
94
113
  */
95
114
  export function pickAutohealAction(cls: RunStopClass, loadLadder: () => AutohealLadder = loadDefaultLadder): AutohealPick {
96
- const codeDefault: AutohealPick = { action: AUTOHEAL_ACTION_BY_CLASS[cls] ?? 'needs-owner', source: 'code-default' };
115
+ const codeDefault: AutohealPick = {
116
+ action: AUTOHEAL_ACTION_BY_CLASS[cls] ?? 'needs-owner', source: 'code-default',
117
+ ...(cls === 'review-budget-exhausted' ? { fallbackReason: 'declared-node-unavailable: review-round-reauthor' } : {}),
118
+ };
97
119
  try {
98
120
  const { template, overlays } = loadLadder();
99
121
  if (!template) return codeDefault;
@@ -297,8 +319,8 @@ export async function autohealFromStop(ctx: AutohealContext, deps: AutohealDeps
297
319
  }
298
320
  const mode = deps.mode ?? DEFAULT_AUTOHEAL_MODE;
299
321
  const cls = ctx.record.class;
300
- const { action, source, overlayId } = pickAutohealAction(cls, deps.loadLadder);
301
- const base = { runId: ctx.runId, class: cls, action, source, ...(overlayId ? { overlayId } : {}), mode };
322
+ const { action, source, overlayId, fallbackReason } = pickAutohealAction(cls, deps.loadLadder);
323
+ const base = { runId: ctx.runId, class: cls, action, source, ...(overlayId ? { overlayId } : {}), ...(fallbackReason ? { fallbackReason } : {}), mode };
302
324
 
303
325
  if (repeatedStop(deps.priorStops, ctx.record)) {
304
326
  // ⛔ 같은 골에서 같은 갈래의 멈춤이 반복되면 자동 재시도를 하지 않는다 — 사유를 골 되먹임 대상으로 넘긴다.
@@ -329,7 +351,7 @@ export async function autohealFromStop(ctx: AutohealContext, deps: AutohealDeps
329
351
  let detail: string | undefined;
330
352
  if (action === 'needs-owner') {
331
353
  outcome = 'needs-owner';
332
- reason = `stop ${cls}: ${ctx.record.cause}`;
354
+ reason = `${fallbackReason ? `${fallbackReason}; ` : ''}stop ${cls}: ${ctx.record.cause}`;
333
355
  } else if (mode === 'shadow') {
334
356
  outcome = 'would-act';
335
357
  } else {