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
@@ -7,6 +7,8 @@ import { authorRepairGoal } from '../harness/helper-repair.js';
7
7
  export type { SupervisorStopReason } from './run-types.js';
8
8
  export { SUPERVISOR_STOP_REASONS } from './run-types.js';
9
9
  import { recordSelfDevRunSupervisorStop, selfDevRunsDir } from './run-store.js';
10
+ import { readRunChart, recordRunChartDecision } from '../self-implement/run-chart.js';
11
+ import { runLedgerDir } from '../self-implement/run-ledger.js';
10
12
  import { debug } from '../debug/log.js';
11
13
  import { sweepFrozenMerges } from '../self-implement/frozen-merges.js';
12
14
  import { selectKnowhowPack } from '../self-implement/knowhow-pack.js';
@@ -43,6 +45,11 @@ export interface SupervisorRound {
43
45
  mainSyncRelaunchFeatures?: string[];
44
46
  /** PR 없는 미분류 실패에 대해 실제 분해 실행기로 수복한 원래 골. 새 taskId에도 한 번 상한을 지킨다. */
45
47
  selfHealDecomposeFeatures?: string[];
48
+ /**
49
+ * NEEDS-HUMAN-REASON-REPAIR — 사유별 자가 수복 1회의 소진 기억(사유 → 그때 수복한 골 전문).
50
+ * 사유가 다르면 다른 시도다. 옛 원장엔 이 칸이 없다 = 「안 쟀다」이지 「시도했다」가 아니다.
51
+ */
52
+ selfHealRepairFeatures?: Partial<Record<NeedsHumanRepairReason, string[]>>;
46
53
  /**
47
54
  * Tasks of this round that ended `status=failed` without a PR. Omitted when there are none — and on older
48
55
  * history, which never measured it, so the no-PR streak guard reads it as «not measured» and stays off.
@@ -137,7 +144,96 @@ export interface SupervisorDecision {
137
144
  };
138
145
  oscillation?: { taskIds: string[]; helper: 'review-oscillation'; signature: string; repairGoals?: Record<string, string>; heldTaskIds?: string[] };
139
146
  pendingDecision?: 'attempt-care-escalation';
140
- selfHeal?: { reason: 'supervisor-unclassified-decompose'; attempt: 1; taskIds: string[] };
147
+ selfHeal?: { reason: SelfHealReason; attempt: 1; taskIds: string[]; repairGoals?: Record<string, string> };
148
+ }
149
+
150
+ /**
151
+ * NEEDS-HUMAN-REASON-REPAIR — needs-human 으로 접히기 «전»에 한 번 수복해 볼 사유.
152
+ * 각 사유의 수복은 다르다: 없는 경로 → 재접지 · 범위 확장 → 좁히기 · 시간 초과 → 좁은 시험 · 조각 없음 → 조각 재걸기.
153
+ */
154
+ export type NeedsHumanRepairReason = 'missing-path' | 'scope-expansion' | 'step-timeout' | 'no-piece';
155
+
156
+ /** 선행 0.2.38 의 분해 수복 사유까지 포함한 자가 수복 사유 전체. */
157
+ export type SelfHealReason = 'supervisor-unclassified-decompose' | `supervisor-${NeedsHumanRepairReason}`;
158
+
159
+ const NEEDS_HUMAN_REPAIR_REASONS: readonly NeedsHumanRepairReason[] = ['missing-path', 'scope-expansion', 'step-timeout', 'no-piece'];
160
+
161
+ /** 파일 부재의 두 코드 — 없는 경로(ENOENT)와 중간 성분이 파일인 경로(ENOTDIR). */
162
+ const MISSING_PATH_ERROR_CODES: ReadonlySet<string> = new Set(['ENOENT', 'ENOTDIR']);
163
+
164
+ const NEEDS_HUMAN_REPAIR_INSTRUCTION: Record<NeedsHumanRepairReason, string> = {
165
+ 'missing-path': '없는 경로를 다시 접지한다 — 저장소에 있는 파일이나 골에 명시된 대상 경로만 고르고, 새 파일은 골이 신설을 요구할 때만 만든다',
166
+ 'scope-expansion': '범위 확장을 좁힌다 — 대상 경로 밖으로 나간 변경을 되돌리고 골의 대상·완료 경계 안에서만 구현한다',
167
+ 'step-timeout': '단계 예산을 넘겼다 — 좁은 시험 하나로 판정선을 먼저 세우고 나머지 실행은 그 뒤로 미룬다',
168
+ 'no-piece': '조각 없이 실패했다 — 같은 골을 다시 걸되 완료 경계를 한 조각 분량으로 잘라 건다',
169
+ };
170
+
171
+ function normalizedRepairPath(path: string): string {
172
+ return path.replace(/^\.\//u, '').replace(/[),.;:]+$/u, '');
173
+ }
174
+
175
+ /** 경로가 범위 집합 안인가 — 정확 일치 · 디렉터리 접두 · (언급이 파일 이름뿐이면) 파일 이름 일치. */
176
+ function pathWithinScope(path: string, scope: readonly string[]): boolean {
177
+ const p = normalizedRepairPath(path);
178
+ return scope.some((raw) => {
179
+ const s = normalizedRepairPath(raw);
180
+ if (s === p) return true;
181
+ if (s.endsWith('/') ? p.startsWith(s) : p.startsWith(`${s}/`)) return true;
182
+ return !p.includes('/') && s.split('/').at(-1) === p;
183
+ });
184
+ }
185
+
186
+ /**
187
+ * 범위 확장 — «밖»이라고 잰 변경 전부.
188
+ * ⛔ 대상 경로를 모르면 `changedFiles` 로는 «밖»을 단정하지 않는다(둘 다 쟀을 때만).
189
+ * 다만 실행 범위 가드가 «대상 밖»으로 직접 잰 값(`outsideTargetFiles`)은 그 자체가 측정이다.
190
+ */
191
+ function expandedBeyondTargetPaths(result: SupervisorJobResult): string[] {
192
+ const measured = result.outsideTargetFiles ?? [];
193
+ const changed = result.changedFiles;
194
+ const targets = result.targetPaths;
195
+ const byScope = changed !== undefined && targets !== undefined && targets.length > 0
196
+ ? changed.filter((file) => !pathWithinScope(file, targets))
197
+ : [];
198
+ return [...new Set([...measured, ...byScope])];
199
+ }
200
+
201
+ /**
202
+ * needs-human 앞의 수복 사유 discriminator — 결과에 이미 실리는 판정 재료만 본다:
203
+ * 단계(`timed-out`) · 오류 코드(ENOENT/ENOTDIR) · 변경 파일 vs 골 대상 경로 · 분해 제안 조각 수.
204
+ * PR 이 있는 결과(사람이 볼 PR)와 재시도 재료가 있는 결과는 여기 대상이 아니다(undefined).
205
+ */
206
+ export function needsHumanRepairReason(result: SupervisorJobResult): NeedsHumanRepairReason | undefined {
207
+ if (result.status !== 'failed' || result.prNumber !== undefined || result.prUrl) return undefined;
208
+ if (result.stage === 'timed-out') return 'step-timeout';
209
+ if (result.error?.code !== undefined && MISSING_PATH_ERROR_CODES.has(result.error.code)) return 'missing-path';
210
+ if (expandedBeyondTargetPaths(result).length > 0) return 'scope-expansion';
211
+ if ((result.decomposeProposal?.pieces.length ?? 0) < 2) return 'no-piece';
212
+ return undefined;
213
+ }
214
+
215
+ /** 사유별 수복 골 원문 — 사유의 수복 지시 + 골의 대상 경로 + 관측된 원인 + 원래 골. */
216
+ export function needsHumanRepairGoal(result: SupervisorJobResult, reason: NeedsHumanRepairReason): string {
217
+ const outside = expandedBeyondTargetPaths(result);
218
+ const repairTargets = result.targetPaths?.length ? result.targetPaths : undefined;
219
+ return [
220
+ ...(repairTargets?.length ? [`대상 경로: ${repairTargets.join(', ')}`] : []),
221
+ `[supervisor-needs-human-repair:${reason}] ${NEEDS_HUMAN_REPAIR_INSTRUCTION[reason]}`,
222
+ ...(outside.length ? [`대상 경로 밖 변경: ${outside.join(', ')}`] : []),
223
+ ...(result.error?.message ? [`이전 실패: ${result.error.message.slice(0, 200)}`] : []),
224
+ result.feature,
225
+ ].join('\n');
226
+ }
227
+
228
+ /** 수복 사유가 붙은 자가 수복인가 — 선행 분해 수복('supervisor-unclassified-decompose')과 갈라낸다. */
229
+ function needsHumanRepairDecisionReason(reason: SelfHealReason): NeedsHumanRepairReason | undefined {
230
+ return NEEDS_HUMAN_REPAIR_REASONS.find((candidate) => reason === `supervisor-${candidate}`);
231
+ }
232
+
233
+ /** 사유별 소진 기억에 이 조각이 이미 있는가 — 새 taskId 여도 골 전문으로 짝을 맞춘다. */
234
+ function needsHumanRepairSpent(history: readonly SupervisorRound[], reason: NeedsHumanRepairReason, feature: string): boolean {
235
+ const key = resumeKey(feature);
236
+ return history.some((entry) => (entry.selfHealRepairFeatures?.[reason] ?? []).some((spent) => resumeKey(spent) === key));
141
237
  }
142
238
 
143
239
  export interface SupervisorLimits {
@@ -245,6 +341,11 @@ export type SupervisorJobResult = SelfDevJobResult & {
245
341
  reviewReason?: string;
246
342
  salvage?: 'launched' | 'parked';
247
343
  next?: SupervisorNext;
344
+ /**
345
+ * NEEDS-HUMAN-REASON-REPAIR — 실행 범위 가드가 «대상 경로 밖»으로 직접 잰 변경.
346
+ * 골이 대상 경로를 안 선언했어도 이 값은 측정이다 — `changedFiles` 와 달리 «밖»을 단정할 수 있다.
347
+ */
348
+ outsideTargetFiles?: readonly string[];
248
349
  };
249
350
 
250
351
  export function aggregateReviewTrend(results: readonly SelfDevJobResult[]): ReviewRework['trend'] | undefined {
@@ -348,7 +449,7 @@ function mustFixScopeDecision(
348
449
  return { byTask, ...(split.length ? { split } : {}), ...(askOwner.length ? { askOwner } : {}) };
349
450
  }
350
451
 
351
- export function decideNextRun(input: {
452
+ type DecideNextRunInput = {
352
453
  results: readonly SupervisorJobResult[];
353
454
  history?: readonly SupervisorRound[];
354
455
  limits?: SupervisorLimits;
@@ -360,9 +461,15 @@ export function decideNextRun(input: {
360
461
  reviewMustFixTrend?: ReviewRework['trend'];
361
462
  /** True: the rerun consumes the authored goal. False: it cannot, so oscillation stops for a human. Undefined: pure decision. */
362
463
  repairGoalExecution?: boolean;
464
+ /** Separate opt-in for needs-human reason repairs; omitted keeps the new repair execution disabled. */
465
+ needsHumanReasonRepairExecution?: boolean;
363
466
  /** 분해 제안을 실제 조각 실행으로 승격할 수 있는 supervisor 경로에만 true. */
364
467
  decompositionExecution?: boolean;
365
- }): SupervisorDecision {
468
+ /** Chart context available to the outer-supervisor judgment; pulled from this same run only. */
469
+ runChart?: readonly { device: string; stopKey: string; observed: string; verdict: string; action: string; handoff: string | null; why: string; readStopKeys: readonly string[] }[];
470
+ };
471
+
472
+ function decideNextRunCore(input: DecideNextRunInput): SupervisorDecision {
366
473
  const results = [...input.results];
367
474
  const history = [...(input.history ?? [])];
368
475
  const maxRounds = input.limits?.maxRounds ?? DEFAULT_MAX_ROUNDS;
@@ -550,7 +657,52 @@ export function decideNextRun(input: {
550
657
  why: `supervisor-unclassified-decompose (attempt: 1/1) — PR 없는 미분류 조각 ${taskIds.length}개를 실증된 분해 제안으로 한 번 재걸기`,
551
658
  };
552
659
  }
660
+ // NEEDS-HUMAN-REASON-REPAIR — 사람에게 접기 «전»에 사유별로 한 번 수복한다. 수복 골은 rerun 이 그대로 실행한다.
661
+ // ⛔ 실행기가 선언되지 않았으면(repairGoalExecution !== true) 수복 대신 지금처럼 사람에게 간다.
662
+ if (input.repairGoalExecution === true && input.needsHumanReasonRepairExecution === true && round + 1 <= maxRounds) {
663
+ const repairable = activeResults.flatMap((result) => {
664
+ if (!t.needsHuman.includes(result.taskId)) return [];
665
+ if (!t.classifications.some((classification) => classification.taskId === result.taskId && classification.kind === 'unclassified')) return [];
666
+ const reason = needsHumanRepairReason(result);
667
+ if (reason === undefined || (result.targetPaths?.length ?? 0) === 0) return [];
668
+ return needsHumanRepairSpent(history, reason, result.feature) ? [] : [{ result, reason }];
669
+ });
670
+ const first = repairable[0];
671
+ const single = first !== undefined && repairable.length === 1 && t.needsHuman.every((id) => id === first.result.taskId)
672
+ ? first : undefined;
673
+ if (single) {
674
+ const taskIds = [single.result.taskId];
675
+ return {
676
+ ...base,
677
+ action: 'relaunch',
678
+ needsHuman: t.needsHuman.filter((id) => !taskIds.includes(id)),
679
+ selfHeal: {
680
+ reason: `supervisor-${single.reason}`,
681
+ attempt: 1,
682
+ taskIds,
683
+ repairGoals: { [single.result.taskId]: needsHumanRepairGoal(single.result, single.reason) },
684
+ },
685
+ why: `supervisor-${single.reason} (attempt: 1/1) — ${NEEDS_HUMAN_REPAIR_INSTRUCTION[single.reason]}`,
686
+ };
687
+ }
688
+ }
553
689
  if (t.needsHuman.length > 0) {
690
+ // 이미 한 번 수복했는데 같은 사유로 다시 섰다 — 사유·시도를 원문으로 남기고 사람에게 넘긴다.
691
+ const exhausted = activeResults.flatMap((result) => {
692
+ if (!t.needsHuman.includes(result.taskId)) return [];
693
+ const reason = needsHumanRepairReason(result);
694
+ if (reason === undefined || !needsHumanRepairSpent(history, reason, result.feature)) return [];
695
+ return [{ result, reason }];
696
+ });
697
+ if (exhausted.length > 0) {
698
+ return {
699
+ ...base,
700
+ action: 'stop',
701
+ stopReason: 'needs-human',
702
+ why: withGoalPlanRevisionObservation(`${exhausted.map(({ result, reason }) =>
703
+ `supervisor-${reason} (attempt: 1/1) — ${NEEDS_HUMAN_REPAIR_INSTRUCTION[reason]} 을 한 번 시도했으나 같은 조각이 다시 실패했다(${result.taskId})`).join(' · ')} · 사람이 볼 것 ${t.needsHuman.length}`),
704
+ };
705
+ }
554
706
  return {
555
707
  ...base,
556
708
  action: 'stop',
@@ -777,6 +929,26 @@ export function decideNextRun(input: {
777
929
  };
778
930
  }
779
931
 
932
+ /** Consume an unread doctor→reauthor chart handoff before returning a terminal exit. */
933
+ export function decideNextRun(input: DecideNextRunInput): SupervisorDecision {
934
+ const decision = decideNextRunCore(input);
935
+ if (decision.action !== 'stop' || decision.stopReason === 'max-rounds') return decision;
936
+ const pendingReauthor = [...(input.runChart ?? [])].reverse().find((cell) => cell.handoff === 'reauthor'
937
+ && !input.runChart?.some((later) => later.device === 'outer-supervisor' && later.readStopKeys.includes(cell.stopKey)));
938
+ if (!pendingReauthor) return decision;
939
+ const eligible = input.results.filter((result) => decision.needsHuman.includes(result.taskId)
940
+ && result.status === 'failed' && result.feature.trim() && result.prNumber === undefined && !result.prUrl);
941
+ if (eligible.length === 0 || decision.round > (input.limits?.maxRounds ?? DEFAULT_MAX_ROUNDS)) return decision;
942
+ const taskIds = eligible.map((result) => result.taskId);
943
+ return { ...decision, action: 'relaunch', stopReason: undefined,
944
+ rerunnable: [...new Set([...decision.rerunnable, ...taskIds])],
945
+ needsHuman: decision.needsHuman.filter((taskId) => !taskIds.includes(taskId)),
946
+ classifications: decision.classifications.map((classification) => taskIds.includes(classification.taskId)
947
+ ? { ...classification, action: 'rerun' as const } : classification),
948
+ why: `run-chart handoff=reauthor consumed (${pendingReauthor.stopKey}) — needs-human 조각 ${taskIds.length}개를 재발사`,
949
+ };
950
+ }
951
+
780
952
  export function appendRound(
781
953
  history: readonly SupervisorRound[],
782
954
  results: readonly SupervisorJobResult[],
@@ -802,6 +974,9 @@ export function appendRound(
802
974
  if (result.durationMs === undefined) { unknownTimeTaskIds.add(result.taskId); continue; }
803
975
  lostTimeMsByTask[result.taskId] = (lostTimeMsByTask[result.taskId] ?? 0) + result.durationMs;
804
976
  }
977
+ const selfHealRepairReason = decision?.action !== 'stop' && decision?.selfHeal
978
+ ? needsHumanRepairDecisionReason(decision.selfHeal.reason)
979
+ : undefined;
805
980
  return [...history, {
806
981
  round: history.length,
807
982
  landed: countLanded(results),
@@ -826,6 +1001,15 @@ export function appendRound(
826
1001
  return feature === undefined ? [] : [feature];
827
1002
  }),
828
1003
  } : {}),
1004
+ // NEEDS-HUMAN-REASON-REPAIR — 사유별 수복 1회 소진을 회차 원장에 남긴다(사유가 다르면 다른 시도).
1005
+ ...(selfHealRepairReason !== undefined && decision?.selfHeal ? {
1006
+ selfHealRepairFeatures: {
1007
+ [selfHealRepairReason]: decision.selfHeal.taskIds.flatMap((id) => {
1008
+ const feature = results.find((result) => result.taskId === id)?.feature;
1009
+ return feature === undefined ? [] : [feature];
1010
+ }),
1011
+ },
1012
+ } : {}),
829
1013
  ...(decision?.action === 'add-repair-task' && decision.oscillation ? (() => {
830
1014
  // Each repaired task is recorded under its original goal feature and, when a rerun runs the authored goal as
831
1015
  // the piece's new feature (orchestrate), under that repair text too — so the repair's own oscillation stops.
@@ -1048,6 +1232,7 @@ export interface SuperviseRunOptions {
1048
1232
  sweepPendingMerges?: typeof sweepFrozenMerges;
1049
1233
  /** True only when rerun consumes `invocation.repairGoals`; omitted or false → a review oscillation stops for a human. */
1050
1234
  repairGoalExecution?: boolean;
1235
+ needsHumanReasonRepairExecution?: boolean;
1051
1236
  /**
1052
1237
  * TASK-AGENT-SHADOW — 멈춤이 확정되면 판단부를 그림자로 부른다(기본 `recordTaskAgentShadowMove`).
1053
1238
  * `false` 면 끈다. 던져도 런의 결말은 바뀌지 않는다(fail-soft).
@@ -1097,6 +1282,7 @@ export async function rejudgeTerminalTaskCard(runId: string | null, deps: {
1097
1282
  export async function superviseRun(opts: SuperviseRunOptions): Promise<SupervisorJobResult[]> {
1098
1283
  let results = [...opts.initial];
1099
1284
  let history: SupervisorRound[] = [];
1285
+ const maxRounds = opts.limits?.maxRounds ?? DEFAULT_MAX_ROUNDS;
1100
1286
 
1101
1287
  for (;;) {
1102
1288
  try {
@@ -1138,21 +1324,49 @@ export async function superviseRun(opts: SuperviseRunOptions): Promise<Superviso
1138
1324
  const allUnreviewedAreNoDiff = unreviewed.length > 0
1139
1325
  && unreviewed.every((result) => result.reviewReason === 'no-diff');
1140
1326
 
1327
+ const chartRunId = opts.runStore?.runId ?? results.find((result) => result.runId?.trim())?.runId ?? null;
1328
+ const chartDir = opts.runStore?.dir ?? runLedgerDir();
1329
+ const chartBeforeJudgment = chartRunId ? readRunChart(chartRunId, 'outer-supervisor', chartDir) : [];
1330
+
1141
1331
  let decision = decideNextRun({
1142
1332
  results,
1143
1333
  history,
1144
1334
  decompositionExecution: opts.promoteDecomposition !== undefined,
1145
1335
  // Undeclared = cannot run the repair goal: an add-repair-task would otherwise be a same-strategy relaunch.
1146
1336
  repairGoalExecution: opts.repairGoalExecution === true,
1337
+ ...(opts.needsHumanReasonRepairExecution === undefined ? {} : { needsHumanReasonRepairExecution: opts.needsHumanReasonRepairExecution }),
1147
1338
  ...(aggregateReviewTrend(results) ? { reviewMustFixTrend: aggregateReviewTrend(results) } : {}),
1148
1339
  ...(opts.limits ? { limits: opts.limits } : {}),
1149
1340
  ...(observed.deployFindings ? { deployFindings: observed.deployFindings } : {}),
1150
1341
  deliverableObservation: observed.state,
1342
+ runChart: chartBeforeJudgment,
1151
1343
  ...(unreviewed.length > 0 ? {
1152
1344
  reviewed: false,
1153
1345
  ...(allUnreviewedAreNoDiff ? { reviewReason: 'no-diff' } : {}),
1154
1346
  } : {}),
1155
1347
  });
1348
+ if (chartRunId) {
1349
+ recordRunChartDecision({ runId: chartRunId, device: 'outer-supervisor',
1350
+ stopKey: `${chartRunId}:outer-supervisor:${history.length + 1}`, observed: `results=${results.length}`,
1351
+ verdict: decision.action, action: decision.action === 'stop' ? decision.stopReason ?? 'stop' : 'relaunch',
1352
+ handoff: decision.action === 'stop' ? 'human' : 'macrophage', why: decision.why,
1353
+ readStopKeys: chartBeforeJudgment.map((cell) => cell.stopKey), dir: chartDir });
1354
+ }
1355
+
1356
+ const reasonRepairSkipped = decision.action !== 'stop' || decision.stopReason !== 'needs-human' || history.length + 1 > maxRounds
1357
+ ? [] : results.flatMap((result) => {
1358
+ if (!decision.needsHuman.includes(result.taskId) || needsHumanRepairReason(result) === undefined) return [];
1359
+ if (!decision.classifications.some((classification) => classification.taskId === result.taskId && classification.kind === 'unclassified')) return [];
1360
+ const repairReason = needsHumanRepairReason(result)!;
1361
+ if (needsHumanRepairSpent(history, repairReason, result.feature)) return [];
1362
+ const reason = opts.repairGoalExecution !== true || opts.needsHumanReasonRepairExecution !== true
1363
+ ? 'disabled' : 'no-target-paths';
1364
+ if (reason === 'no-target-paths' && (result.targetPaths?.length ?? 0) > 0) return [];
1365
+ return [{ taskId: result.taskId, reason }];
1366
+ });
1367
+ for (const skipped of reasonRepairSkipped) {
1368
+ try { opts.observe?.('supervisor.reason-repair-skipped', skipped); } catch { /* fail-soft */ }
1369
+ }
1156
1370
 
1157
1371
  // The supervisor consumes knowhow when it judges a failed piece. Keep the child prompt untouched.
1158
1372
  const failedPiece = results.find((result) => result.status === 'failed' && result.feature.trim());
@@ -1166,7 +1380,7 @@ export async function superviseRun(opts: SuperviseRunOptions): Promise<Superviso
1166
1380
  }
1167
1381
  }
1168
1382
 
1169
- const runId = opts.runStore?.runId ?? results.find((result) => result.runId?.trim())?.runId ?? null;
1383
+ const runId = chartRunId;
1170
1384
 
1171
1385
  let decomposePromotion: DecomposePromotionObservation = decision.decomposable.length === 0
1172
1386
  ? { attempted: false, reason: 'no-decomposable-decision' }
@@ -1188,7 +1402,13 @@ export async function superviseRun(opts: SuperviseRunOptions): Promise<Superviso
1188
1402
  decomposePromotion = { attempted: true, reason: `shim-failed: ${String(error)}` };
1189
1403
  }
1190
1404
  }
1191
- if (decision.selfHeal) {
1405
+ if (decision.selfHeal && needsHumanRepairDecisionReason(decision.selfHeal.reason) !== undefined) {
1406
+ // NEEDS-HUMAN-REASON-REPAIR — 수복 시도는 rerun 이 사유별 수복 골로 실행한다(아래 repairGoals).
1407
+ // 여기서는 «한 번 시도했다»를 관측하고 relaunch 를 유지한다 — 실패는 다음 라운드 판정이 사유·시도 원문으로 접는다.
1408
+ try { opts.observe?.('supervisor-self-heal', { runId, reason: decision.selfHeal.reason,
1409
+ attempt: decision.selfHeal.attempt, taskIds: decision.selfHeal.taskIds,
1410
+ outcome: 'relaunching', repairGoalTasks: Object.keys(decision.selfHeal.repairGoals ?? {}) }); } catch { /* fail-open */ }
1411
+ } else if (decision.selfHeal) {
1192
1412
  const promoted = decomposePromotion.attempted && (decomposePromotion.pieceCount ?? 0) >= 2;
1193
1413
  try { opts.observe?.('supervisor-self-heal', { runId, reason: decision.selfHeal.reason,
1194
1414
  attempt: decision.selfHeal.attempt, taskIds: decision.selfHeal.taskIds,
@@ -1309,7 +1529,7 @@ export async function superviseRun(opts: SuperviseRunOptions): Promise<Superviso
1309
1529
  // but their results stay in the round so the human hand-off (and the final review-oscillating stop) keeps them.
1310
1530
  const held = decision.oscillation?.heldTaskIds ?? [];
1311
1531
  const heldResults = results.filter((result) => held.includes(result.taskId));
1312
- const repairGoals = { ...decision.relaunchGoals, ...decision.oscillation?.repairGoals };
1532
+ const repairGoals = { ...decision.relaunchGoals, ...decision.selfHeal?.repairGoals, ...decision.oscillation?.repairGoals };
1313
1533
  const rerunResults = await opts.rerun(held.length ? results.filter((result) => !held.includes(result.taskId)) : results,
1314
1534
  { relaunch: true, ...(Object.keys(repairGoals).length > 0 ? { repairGoals } : {}) });
1315
1535
  results = [...rerunResults, ...heldResults.filter((heldResult) => !rerunResults.some((result) => result.taskId === heldResult.taskId))];
@@ -27,6 +27,10 @@ export interface SelfDevGoal {
27
27
  kind?: JobKind;
28
28
  /** Decomposition intent; deliberately distinct from executable `kind`. */
29
29
  goalType?: SelfDevGoalType;
30
+ /** Required for default-LLM decomposition slices; included in the child task prompt. */
31
+ completionBoundary?: string;
32
+ /** Existing simulation evidence required to make a decomposed slice independently reviewable. */
33
+ mockScenario?: { id: string; injection: string; observation: string };
30
34
  /** Feature/goal text → `elanous self implement <feature>` for dev jobs. */
31
35
  feature: string;
32
36
  /** Pod lease predecessor goal ID or PR number. */
@@ -114,6 +118,9 @@ export interface SelfDevJobResult {
114
118
  completionDisposition?: string;
115
119
  /** Abandoned-run classification from the child. Independent of completionDisposition. */
116
120
  failureClassification?: AbandonedClassification;
121
+ /** Basis and explicit terminal reason are kept separate from the classification label. */
122
+ classificationBasis?: string;
123
+ terminationReason?: string;
117
124
  /** Provider failure evidence from the child result; absent when unobserved. */
118
125
  providerErrors?: { count: number; provider: string; category: 'quota' | 'credential' | 'request' | 'other' };
119
126
  /** Stable child run identity used to join its run-ledger proposal. */
@@ -1,6 +1,7 @@
1
1
  import { spawnSync } from 'node:child_process';
2
2
  import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
3
3
  import { debug } from '../debug/log.js';
4
+ import { readRunChart, recordRunChartDecision } from './run-chart.js';
4
5
  import { selectKnowhowPack } from './knowhow-pack.js';
5
6
  import { loadReviewRoundBrief, type ReviewRoundBrief } from './review-round-brief.js';
6
7
  import { findIncidentPrecedents, type IncidentPrecedent } from '../harness/harness-incidents.js';
@@ -15,6 +16,8 @@ import {
15
16
  type RunLedgerCheckedAppendOutcome,
16
17
  type RunLedgerLookupOptions,
17
18
  } from './run-ledger.js';
19
+ import { pickAutohealAction, type AutohealAction } from './stop-autoheal.js';
20
+ import { RUN_STOP_CLASSES, type RunStopClass } from './run-stop.js';
18
21
  /** 사고 원장 루트 기본값 — 운영/시험 우주 상태 디렉터리(없으면 빈 선례 · fail-soft). */
19
22
  export function doctorVisitIncidentRoot(): string {
20
23
  return elanousStateRoot();
@@ -250,6 +253,91 @@ export function recordParentNeedsOwnerVisit(input: {
250
253
 
251
254
  export type ReadDoctorVisitsOptions = RunLedgerLookupOptions;
252
255
 
256
+ export interface RunDoctorHandoffResult {
257
+ status: 'acted' | 'already-acted' | 'needs-human' | 'missing-handoff';
258
+ action?: AutohealAction;
259
+ outcome?: string;
260
+ stopKey: string;
261
+ }
262
+
263
+ /** Consume one persisted run-supervisor handoff through PR1's graph-aware stop prescription. */
264
+ export async function runDoctorHandoff(input: {
265
+ runId: string;
266
+ stopKey: string;
267
+ dir?: string;
268
+ dispatch: (action: AutohealAction, handoff: Record<string, unknown>) => Promise<{ outcome: string; detail?: string }> | { outcome: string; detail?: string };
269
+ }): Promise<RunDoctorHandoffResult> {
270
+ const entries = loadRunLedger(input.runId, input.dir);
271
+ if (entries === null) return { status: 'missing-handoff', stopKey: input.stopKey };
272
+ const latestHandoff = [...entries].reverse().find((entry) => entry.event === 'run-chart-cell'
273
+ && entry.data.device === 'run-supervisor' && entry.data.handoff === 'run-doctor');
274
+ const handoff = latestHandoff?.data.stopKey === input.stopKey ? latestHandoff : undefined;
275
+ if (!handoff) return { status: 'missing-handoff', stopKey: input.stopKey };
276
+ const prior = entries.filter((entry) => entry.event === 'doctor-rx' && entry.data.stopKey === input.stopKey);
277
+ const completed = prior.find((entry) => entry.data.status === 'completed' || entry.data.status === 'needs-human');
278
+ if (completed) return { status: completed.data.status === 'completed' ? 'already-acted' : 'needs-human',
279
+ ...(typeof completed.data.action === 'string' ? { action: completed.data.action as AutohealAction } : {}),
280
+ ...(typeof completed.data.outcome === 'string' ? { outcome: completed.data.outcome } : {}), stopKey: input.stopKey };
281
+ if (prior.some((entry) => entry.data.status === 'started')) {
282
+ const outcome = 'needs-human: prior doctor action started without a recorded result';
283
+ return { status: 'needs-human', outcome, stopKey: input.stopKey };
284
+ }
285
+
286
+ const chartBefore = readRunChart(input.runId, 'run-doctor', input.dir ?? runLedgerDir());
287
+ const rawClass = handoff.data.failureClass ?? (handoff.data.verdict === 'wait' ? 'implement-aborted' : undefined);
288
+ const failureClass = typeof rawClass === 'string' && (RUN_STOP_CLASSES as readonly string[]).includes(rawClass)
289
+ ? rawClass as RunStopClass : 'unclassified';
290
+ const prescription = pickAutohealAction(failureClass);
291
+ const visitAppend = appendRunLedgerEntryChecked(input.runId, (current) => {
292
+ if (current === null) return { append: false, result: false };
293
+ if (current.some((entry) => entry.event === 'doctor-visit' && entry.data.stopKey === input.stopKey)) return { append: false, result: true };
294
+ return { append: true, entry: { timestamp: new Date().toISOString(), runId: input.runId,
295
+ event: 'doctor-visit', data: { from: 'supervisor', symptom: 'no-progress', stopKey: input.stopKey,
296
+ evidence: `consecutive wait decisions=${String(handoff.data.waitCount ?? 'unknown')}`, prescription: prescription.action } } };
297
+ }, input.dir);
298
+ if (!visitAppend.appended && visitAppend.result !== true) return { status: 'missing-handoff', stopKey: input.stopKey };
299
+ const claim = appendRunLedgerEntryChecked(input.runId, (current) => {
300
+ if (current === null) return { append: false, result: 'missing-ledger' as const };
301
+ const priorAction = current.find((entry) => entry.event === 'doctor-rx' && entry.data.stopKey === input.stopKey);
302
+ if (priorAction) return { append: false, result: priorAction.data.status === 'completed' ? 'completed' as const
303
+ : priorAction.data.status === 'needs-human' ? 'needs-human' as const : 'in-progress' as const };
304
+ return { append: true, entry: { timestamp: new Date().toISOString(), runId: input.runId, event: 'doctor-rx',
305
+ data: { device: 'run-doctor', stopKey: input.stopKey, status: 'started', action: prescription.action,
306
+ source: prescription.source, ...(prescription.overlayId ? { overlayId: prescription.overlayId } : {}), executed: false } } };
307
+ }, input.dir);
308
+ if (!claim.appended) {
309
+ if (claim.result === 'completed') return { status: 'already-acted', action: prescription.action, stopKey: input.stopKey };
310
+ return { status: 'needs-human', action: prescription.action,
311
+ outcome: claim.result === 'needs-human' ? 'needs-human: prior action requires a person'
312
+ : claim.result === 'missing-ledger' ? 'needs-human: run ledger missing' : 'needs-human: doctor action already in progress',
313
+ stopKey: input.stopKey };
314
+ }
315
+
316
+ let outcome: string;
317
+ let detail: string | undefined;
318
+ try {
319
+ const result = await input.dispatch(prescription.action, handoff.data);
320
+ outcome = result.outcome;
321
+ detail = result.detail;
322
+ } catch (error) {
323
+ outcome = 'needs-human';
324
+ detail = error instanceof Error ? error.message : String(error);
325
+ }
326
+ const needsHuman = outcome === 'needs-human' || outcome.startsWith('needs-human:');
327
+ appendRunLedgerEntry({ timestamp: new Date().toISOString(), runId: input.runId, event: 'doctor-rx',
328
+ data: { device: 'run-doctor', stopKey: input.stopKey, status: needsHuman ? 'needs-human' : 'completed',
329
+ action: prescription.action, source: prescription.source, outcome, executed: !needsHuman,
330
+ ...(detail ? { detail: detail.slice(0, 300) } : {}) } }, input.dir);
331
+ recordRunChartDecision({ runId: input.runId, device: 'run-doctor', stopKey: input.stopKey,
332
+ observed: String(handoff.data.observed ?? 'supervisor handoff'), verdict: needsHuman ? 'needs-human' : 'acted',
333
+ action: prescription.action, handoff: needsHuman ? 'outer-supervisor'
334
+ : prescription.action === 'reauthor-from-materialized' ? 'reauthor' : null,
335
+ why: detail ?? outcome, readStopKeys: chartBefore.map((cell) => cell.stopKey), dir: input.dir ?? runLedgerDir() });
336
+ debug.log('run-doctor', 'action', { runId: input.runId, stopKey: input.stopKey, action: prescription.action,
337
+ source: prescription.source, outcome, executed: !needsHuman });
338
+ return { status: needsHuman ? 'needs-human' : 'acted', action: prescription.action, outcome, stopKey: input.stopKey };
339
+ }
340
+
253
341
  /** Project logged review briefs into status without changing the run-ledger schema. Keep the latest observation per PR. */
254
342
  export function doctorReviewVisits(events: readonly { timestamp?: string; sequence?: number; runId?: string; key?: string; evidence?: string }[]): (Omit<DoctorVisit, 'runId'> & { runId?: string })[] {
255
343
  const seenPrs = new Set<string>();
@@ -78,6 +78,8 @@ export interface GateArtifactSummary extends GateArtifactCounts {
78
78
  head40: string | null;
79
79
  base40: string | null;
80
80
  envKey: string;
81
+ /** Seat self-gate marker observed at process entry (true only for ELANOUS_TRAIN_GATE=1). */
82
+ trainGate?: boolean;
81
83
  shards: number;
82
84
  cohort: string[];
83
85
  shardsDetail: GateArtifactShard[];
@@ -128,6 +130,7 @@ export interface GateArtifactInput {
128
130
  head40: string | null;
129
131
  base40: string | null;
130
132
  envKey: string;
133
+ trainGate?: boolean;
131
134
  testFiles: readonly string[];
132
135
  verdict: string | null;
133
136
  verdictLine?: string;
@@ -218,6 +221,7 @@ export function writeGateArtifacts(input: GateArtifactInput): { summaryPath: str
218
221
  head40: input.head40,
219
222
  base40: input.base40,
220
223
  envKey: input.envKey,
224
+ ...(input.trainGate !== undefined ? { trainGate: input.trainGate } : {}),
221
225
  shards: input.sharded ? input.sharded.shards.length : 0,
222
226
  cohort: sorted(input.testFiles),
223
227
  shardsDetail,
@@ -251,12 +255,14 @@ export function writeRemoteUnavailableGateArtifacts(
251
255
  reason: 'remote-unsupported' | 'remote-fetch-failed',
252
256
  resolveRev: RevResolver = defaultRevResolver(cwd),
253
257
  envKey: () => string = defaultGateEnvKey,
258
+ trainGate?: boolean,
254
259
  ): { summaryPath: string; junitFiles: string[] } {
255
260
  return writeGateArtifacts({
256
261
  dir: resolveArtifactDir(dir, cwd),
257
262
  head40: resolveRev('HEAD'),
258
263
  base40: baseRef ? resolveRev(baseRef) : null,
259
264
  envKey: envKey(),
265
+ trainGate,
260
266
  testFiles: [],
261
267
  verdict: null,
262
268
  exitCode,
@@ -266,6 +272,13 @@ export function writeRemoteUnavailableGateArtifacts(
266
272
  });
267
273
  }
268
274
 
275
+ /** The local train wrapper owns the receipt marker, including when artifacts came from a remote host. */
276
+ export function recordGateTrainMarker(summaryPath: string, trainGate: boolean): void {
277
+ const summary = JSON.parse(readFileSync(summaryPath, 'utf8')) as Record<string, unknown>;
278
+ summary.trainGate = trainGate;
279
+ writeFileSync(summaryPath, `${JSON.stringify(summary, null, 2)}\n`);
280
+ }
281
+
269
282
  // ── 원격 산출 회수 (SIDE-VERIFY-GATE-SHARDS ②) ──────────────────────────────
270
283
  // 원격 run 은 `$W` 임시 트리에서 돌고 끝나면 trap 이 `$W` 를 지운다(gate-remote.ts remoteScript). 그래서 원격 쪽
271
284
  // `--artifact-dir` 는 `$W` «밖»의 호스트 디스크 경로(/var/tmp/elanous-gate-artifacts-<nonce>)로 준다 — run 이 끝나도 남고, 회수