elanous 0.2.41 → 0.2.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (589) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{GiOLWmt4MqDZePubBjA4Q → X1ucLw10Cds_h614NoEnh}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/{5159.115f1c2ca471386c.js → 1063.2fb8a9dc55c731f2.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +36 -0
  7. package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/{9048.212083de42d25be3.js → 1262.e804feb8fd1acb8c.js} +2 -2
  9. package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1455-530ca16c7e71baff.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/{4527.a69f2894d1bc9f4a.js → 1487.2f67b79444062da6.js} +1 -1
  13. package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +32 -0
  15. package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +286 -0
  21. package/apps/pwa/out/_next/static/chunks/2160.a097e7b138ae1c55.js +23 -0
  22. package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +34 -0
  25. package/apps/pwa/out/_next/static/chunks/2456.b6de0e1c05f28843.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/{530.d26346e18089640a.js → 2690.0521c738b7749931.js} +1 -1
  31. package/apps/pwa/out/_next/static/chunks/{4702.4a4adc1f16d7c93b.js → 2974.595d1e29d040cb6a.js} +1 -1
  32. package/apps/pwa/out/_next/static/chunks/{2263.e09b6edea33bad2d.js → 3207.a756c95e9ec8c3c8.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/{9541.eb8e2f8480c7feca.js → 3285.89ee2f298682f5e5.js} +2 -2
  34. package/apps/pwa/out/_next/static/chunks/{9507.7026657a2f47eb64.js → 3347.f846266b5e5f3ede.js} +16 -16
  35. package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +41 -0
  36. package/apps/pwa/out/_next/static/chunks/{1178.1aa9cad0e7695427.js → 3482.a9ae9d2ad6a5bd97.js} +1 -1
  37. package/apps/pwa/out/_next/static/chunks/3507.97e1977bc4d5fb0a.js +2 -0
  38. package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +24 -0
  40. package/apps/pwa/out/_next/static/chunks/3741.9cf76acaa2ee5298.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/{1661.0dd330f3d89f73f3.js → 3837.a210d7d0db8d8abd.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/{2fdf2931.b431eee4fb468bc3.js → 3d0154af.5331fec737ffe8c3.js} +1 -1
  45. package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4043.6b91203436c9c86b.js +309 -0
  47. package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +77 -0
  48. package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4276.336d76d858fcdf1b.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +148 -0
  54. package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +74 -0
  55. package/apps/pwa/out/_next/static/chunks/50061469.0326382241ef3b2d.js +122 -0
  56. package/apps/pwa/out/_next/static/chunks/{1115.434ae2ecb0ad986d.js → 5112.4b9f300124fab7b3.js} +3 -3
  57. package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +27 -0
  59. package/apps/pwa/out/_next/static/chunks/53c73f84.373b6160adfa89a4.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5431-72a1dbde59400691.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5885.0a3e52c8faccec98.js +287 -0
  69. package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6131.348b7d6bdcd267ce.js +226 -0
  72. package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +90 -0
  73. package/apps/pwa/out/_next/static/chunks/{2073.689dcb2680113d76.js → 6377.bc7df239edbff244.js} +1 -1
  74. package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/{1800.f7ff51dc4978a958.js → 6632.0eac1c554f8f2ef3.js} +1 -1
  77. package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +104 -0
  81. package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +94 -0
  82. package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/{2527-5c636a43c7cc5dde.js → 7279-c199ea83f34338fa.js} +1 -1
  85. package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/{385e4574.e9886ab32759eda3.js → 73d2eb0e.4966ad55293c801a.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{5471.1e611302ed3a7c53.js → 7411.9b4b8b747dc7b802.js} +2 -2
  90. package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +24 -0
  91. package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{2fe2c302.41b517f88d6fe502.js → 7a98bc80.fa935989e829f9c2.js} +1 -1
  97. package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8138.6c10b2a356d52fca.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{5574.f35accf4f132b29d.js → 8262.ddc03e06b733f184.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +8 -0
  102. package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +79 -0
  104. package/apps/pwa/out/_next/static/chunks/{8050-9b364bdef8f71927.js → 8546-6f03f8ea34dd61d9.js} +1 -1
  105. package/apps/pwa/out/_next/static/chunks/{5947-135e26537d80a6b9.js → 8673-bab689a55f7e13b9.js} +3 -3
  106. package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{5937.c2df9e3447e1f667.js → 9249.976f1e69a9d80754.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{1971-7efb628c471dc5a0.js → 9353-12bfff0c130104cf.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/{7191.fdc955f7d96064a4.js → 9415.69e4a21c60c7d2db.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/{1219.7e17964e0e7cd8e5.js → 9427.96aa912ddb5801e0.js} +16 -16
  118. package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9633.ce5bddc56784da72.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{5964-7e21164a8f2cf0ce.js → 9656-374232558fd528d0.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/{6552.a3840aa7da35ad68.js → 9832.f4a98c878ecf2c0a.js} +1 -1
  123. package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/9a852a62-6192a6ea9346ced3.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0e3d7b9421b79dac.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/term/page-bf067887b3307423.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/{a0a01613.6d1cca322238d7fe.js → b450776b.3db34d8d965f82d3.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{c0c1a699.0ba79f97005965d4.js → e8543907.5b040a5f22a0b0e5.js} +7 -7
  178. package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +22 -22
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +22 -22
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +22 -22
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +21 -21
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +21 -21
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +22 -22
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +21 -21
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +22 -22
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +22 -22
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +21 -21
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +22 -22
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -24
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +22 -22
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +22 -22
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +21 -21
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +22 -22
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -24
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -24
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +21 -21
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +21 -21
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +22 -22
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +22 -22
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +21 -21
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +21 -21
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +21 -21
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +22 -22
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +22 -22
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +21 -21
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +22 -22
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +22 -22
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +22 -22
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +22 -22
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +22 -22
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +21 -21
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +22 -22
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +22 -22
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +22 -22
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +22 -22
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +22 -22
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +22 -22
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +22 -22
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +22 -22
  278. package/docs/goal-context/04-mock-scenarios.md +13 -0
  279. package/graphs/catalog/catalog.yaml +1 -1
  280. package/graphs/heal/heal-loop.yaml +1 -0
  281. package/graphs/overlays/stop-heal-ladder.yaml +113 -0
  282. package/graphs/units/verbs/recipes.yaml +11 -11
  283. package/graphs/work/research-report.yaml +10 -2
  284. package/package.json +1 -1
  285. package/scripts/heal/run-role.ts +99 -5
  286. package/scripts/land-global-checks.ts +6 -1
  287. package/scripts/lib/decompose-ab.ts +1 -0
  288. package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
  289. package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
  290. package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
  291. package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
  292. package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
  293. package/scripts/lib/tui-regress-checks.ts +33 -13
  294. package/scripts/release-loop/gate-baseline-receipt.ts +47 -9
  295. package/scripts/release-loop/gate-image-pin.ts +81 -0
  296. package/scripts/release-loop/gate-node-sim.ts +207 -0
  297. package/scripts/release-loop/gate-node.ts +285 -46
  298. package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
  299. package/scripts/release-loop/gate-radius-live.ts +97 -13
  300. package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
  301. package/scripts/release-loop/gate-train-receipts.ts +122 -0
  302. package/scripts/release-loop/resume-release.ts +83 -8
  303. package/scripts/ux-sim.ts +18 -1
  304. package/scripts/warm-pool-provider-config.ts +263 -0
  305. package/skills/omni-crawl/SKILL.md +5 -2
  306. package/skills/omni-crawl/scripts/main.ts +84 -23
  307. package/src/acp/core-turn-bridge.ts +13 -0
  308. package/src/agent/registry.ts +2 -0
  309. package/src/agent/task-notification.ts +25 -5
  310. package/src/agent/types.ts +6 -0
  311. package/src/agent-mission/mission-cli.ts +24 -0
  312. package/src/agent-mission/mission-out.ts +595 -0
  313. package/src/agent-mission/tool-install.ts +88 -2
  314. package/src/agent-substrate/context-strategy.ts +4 -4
  315. package/src/agent-substrate/self-review-cli.ts +178 -13
  316. package/src/auto-research/research-turn.ts +123 -50
  317. package/src/autopilot/pr-manager.ts +38 -7
  318. package/src/autopilot/pty-control-loop.ts +2 -0
  319. package/src/capture/tui-self-report.ts +22 -6
  320. package/src/chat/index.ts +1 -1
  321. package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
  322. package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
  323. package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
  324. package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
  325. package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
  326. package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
  327. package/src/cli/pr-land-heavy-remote.ts +32 -0
  328. package/src/cli/pr-land-overlap-evidence.ts +100 -1
  329. package/src/cli/pr-land-pod-shadow-job.ts +60 -0
  330. package/src/cli/release-checklist-read-cli.ts +20 -10
  331. package/src/cli/research-cli.ts +4 -5
  332. package/src/cli/tasks-cli.ts +7 -0
  333. package/src/compact/auto.ts +8 -1
  334. package/src/control-plane/ledger.ts +52 -2
  335. package/src/control-plane/server.ts +16 -2
  336. package/src/core-turn/run-core-turn.ts +311 -90
  337. package/src/core-turn/run-goal-loop.ts +18 -0
  338. package/src/core-turn/types.ts +2 -0
  339. package/src/dashboard/classic-sidetab-mission-job.ts +58 -0
  340. package/src/dashboard/classic-sidetab-mission.ts +185 -0
  341. package/src/dashboard/index.ts +149 -15
  342. package/src/dashboard/input/agent-wake.ts +23 -1
  343. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +9 -0
  344. package/src/dashboard/mission-cli-consumer.ts +153 -0
  345. package/src/dashboard/seat-boot-preamble.ts +171 -1
  346. package/src/dashboard/side-basic-runtime.ts +54 -1
  347. package/src/dashboard/sidetab-runtime.ts +90 -1
  348. package/src/dashboard/skill-catalog-preamble.ts +101 -0
  349. package/src/dashboard/skill-detection-runtime.ts +55 -15
  350. package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
  351. package/src/dashboard/turn-preamble.ts +53 -15
  352. package/src/dashboard/turn-prompt-runtime.ts +4 -2
  353. package/src/graph-runner/graph-cli.ts +23 -7
  354. package/src/graph-runner/graph-tick.ts +10 -2
  355. package/src/graph-runner/runner.ts +1 -1
  356. package/src/grok/agent-search.ts +14 -4
  357. package/src/grok/credential.ts +28 -11
  358. package/src/harness/harness-pod-dispatch.ts +81 -15
  359. package/src/harness/harness-stop.ts +155 -11
  360. package/src/index.ts +34 -5
  361. package/src/instance/spawn-elanous.ts +6 -4
  362. package/src/llm.ts +166 -8
  363. package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
  364. package/src/loops/orchestrator/tick.ts +13 -0
  365. package/src/maturity/feature-maturity.ts +1 -1
  366. package/src/native-tool-catalog.ts +2 -2
  367. package/src/nexus/api/harness-traversal.ts +11 -0
  368. package/src/pr-tool/census.ts +3 -2
  369. package/src/pty-shell/tui-run-state.ts +188 -2
  370. package/src/release-loop/checklist-target-path-hint.ts +13 -0
  371. package/src/release-loop/checklist.ts +9 -1
  372. package/src/repl/index.ts +43 -2
  373. package/src/research/axis-fanout.ts +121 -16
  374. package/src/research/bloom-exemplars.ts +3 -1
  375. package/src/research/gap-followup.ts +13 -1
  376. package/src/research/plugin-discovery.ts +36 -14
  377. package/src/research-bridge/invoke.ts +22 -5
  378. package/src/research-bridge/types.ts +2 -0
  379. package/src/self-dev/decompose.ts +119 -5
  380. package/src/self-dev/launch-preflight-text.ts +5 -6
  381. package/src/self-dev/orchestrate.ts +12 -2
  382. package/src/self-dev/review-provider-fallback.ts +9 -2
  383. package/src/self-dev/run-supervisor.ts +42 -4
  384. package/src/self-dev/run-types.ts +4 -0
  385. package/src/self-implement/doctor-visit.ts +88 -0
  386. package/src/self-implement/goal-author.ts +326 -3
  387. package/src/self-implement/graph-overlay-yaml.ts +7 -0
  388. package/src/self-implement/headless-elanous-driver.ts +31 -2
  389. package/src/self-implement/heal-intake.ts +112 -4
  390. package/src/self-implement/heal-triage.ts +20 -0
  391. package/src/self-implement/host-regate.ts +27 -4
  392. package/src/self-implement/merge-train.ts +5 -0
  393. package/src/self-implement/orchestrator.ts +126 -11
  394. package/src/self-implement/regate-detail.ts +38 -1
  395. package/src/self-implement/rework-child-provider.ts +25 -0
  396. package/src/self-implement/run-chart.ts +119 -0
  397. package/src/self-implement/run-ledger.ts +112 -11
  398. package/src/self-implement/run-stop.ts +188 -4
  399. package/src/self-implement/stop-autoheal.ts +13 -0
  400. package/src/session/chat.ts +38 -4
  401. package/src/session-runtime/index.ts +98 -4
  402. package/src/session-runtime/tier-flip.ts +3 -3
  403. package/src/sidetab-core/model.ts +19 -5
  404. package/src/sidetab-core/visible-agent-mission.ts +186 -0
  405. package/src/skills/name-match.ts +20 -0
  406. package/src/skills/tools/agent.ts +30 -2
  407. package/src/skills/tools/omni-search.ts +67 -5
  408. package/src/task-agent/pod-distributor-entry.ts +3 -0
  409. package/src/task-agent/task-hand.ts +27 -0
  410. package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
  411. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
  412. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
  413. package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
  414. package/src/task-orchestrator/surfaces/pod-source-receive.ts +163 -13
  415. package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
  416. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +209 -39
  417. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
  418. package/src/task-orchestrator/surfaces/self-implement-pod.ts +165 -45
  419. package/src/tokens.ts +35 -2
  420. package/src/tool-runtime/agent-runtime.ts +1 -0
  421. package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
  422. package/src/tool-runtime/skill-exec-runtime.ts +33 -13
  423. package/src/tool-runtime/types.ts +1 -0
  424. package/src/tui/entry.ts +14 -4
  425. package/src/tui/sidetab/attach.ts +47 -0
  426. package/src/tui-client/local-chat-turn.ts +26 -13
  427. package/src/tui.ts +22 -0
  428. package/src/ux-sim/fake-kubectl.ts +37 -3
  429. package/src/ux-sim/fault-pool-cap.ts +11 -6
  430. package/src/ux-sim/mock-scenario-catalog.json +41 -0
  431. package/src/ux-sim/mock-scenario-catalog.ts +156 -0
  432. package/src/ux-sim/scenario.ts +116 -23
  433. package/src/version/packed-revision.json +1 -1
  434. package/src/voice/voice-tts-singleton.ts +18 -3
  435. package/src/web-search/grok.ts +5 -9
  436. package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +0 -36
  437. package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +0 -1
  438. package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +0 -287
  439. package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +0 -1
  440. package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +0 -90
  443. package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/1765.679b29625c8e88d4.js +0 -77
  445. package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +0 -1
  446. package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +0 -1
  447. package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +0 -1
  449. package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +0 -1
  450. package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +0 -1
  452. package/apps/pwa/out/_next/static/chunks/2743.5d3f76948be32b34.js +0 -41
  453. package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +0 -32
  454. package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +0 -1
  455. package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +0 -79
  456. package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +0 -1
  458. package/apps/pwa/out/_next/static/chunks/3230-49298c3b73ef2268.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +0 -74
  461. package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +0 -1
  463. package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +0 -1
  465. package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +0 -1
  467. package/apps/pwa/out/_next/static/chunks/4133.2056bb4d78f621af.js +0 -1
  468. package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +0 -148
  472. package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +0 -226
  473. package/apps/pwa/out/_next/static/chunks/4667.97e31aa38c95c475.js +0 -309
  474. package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +0 -1
  479. package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +0 -94
  481. package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +0 -8
  483. package/apps/pwa/out/_next/static/chunks/53aeb4ee-51c92f8d683f5220.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +0 -24
  487. package/apps/pwa/out/_next/static/chunks/5744.b9415e18ad623100.js +0 -23
  488. package/apps/pwa/out/_next/static/chunks/5892.2526d962339662d8.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +0 -286
  490. package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +0 -27
  494. package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +0 -24
  496. package/apps/pwa/out/_next/static/chunks/6874.d5cf7eb8edb2cabe.js +0 -2
  497. package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +0 -122
  499. package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/83184dcd-0ee6247ff41eb3f2.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +0 -104
  510. package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +0 -1
  517. package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +0 -34
  527. package/apps/pwa/out/_next/static/chunks/9834.63ab2bbc3153172e.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/9869.81a1e24ca682d5a0.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/addc2b32.8c4ff8f0aefe987d.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/app/botlab/page-14949db884bfa672.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-40f9e19149024298.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a142dfb0331a05f5.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/b2271e54.c1de3347976e90b0.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +0 -1
  588. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
  589. /package/apps/pwa/out/_next/static/{GiOLWmt4MqDZePubBjA4Q → X1ucLw10Cds_h614NoEnh}/_ssgManifest.js +0 -0
@@ -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>();
@@ -1,6 +1,6 @@
1
1
  import { classifyObservation } from '../design/behaviour-signal.js';
2
2
  import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, writeFileSync, type Dirent } from 'node:fs';
3
- import { spawn } from 'node:child_process';
3
+ import { execFileSync, spawn } from 'node:child_process';
4
4
  import { randomBytes } from 'node:crypto';
5
5
  import { dirname, isAbsolute, join, normalize, relative, resolve, sep } from 'node:path';
6
6
  import { isRepositoryImplementationCandidate, type CodebaseGrounding } from '../autopilot/codebase-grounding.js';
@@ -121,6 +121,12 @@ export interface GoalAuthorDeps {
121
121
  decomposeSteps?: (objective: string, opts?: { context?: string; runId?: string; goalId?: string }) => Promise<readonly string[]>;
122
122
  /** Optional launch preflight result supplied by the caller; authoring never reads the ledger or logs itself. */
123
123
  launchPreflight?: LaunchPreflightResult;
124
+ /**
125
+ * SELF-REVIEW-PRELAUNCH ⑤ — 완료 경계 증거 명령이 «현재 main» 에서 실행 가능한지 판정하는
126
+ * 읽기 전용 존재 심. 저작 코어(`authorGoal`)는 파일을 열지 않으므로 심이 없으면 판정을
127
+ * `not-applicable` 로 남기고, 생산 진입점(`writeAuthoredGoal`)이 repositoryRoot 기준 심을 공급한다.
128
+ */
129
+ selfReviewExistsOnMain?: (repositoryRelativePath: string) => boolean | undefined;
124
130
  /** Optional in-process notification for each authored-goal phase transition. */
125
131
  onProgress?: (phase: GoalAuthorPhase, event: 'start' | 'end') => void;
126
132
  /** AUTHOR-TIMEBOX: budget for the `ground` phase. Omitted means `GOAL_AUTHOR_GROUND_TIMEBOX_MS`. */
@@ -1013,7 +1019,7 @@ function targetPathsInLabelPiece(piece: string): string[] {
1013
1019
  return askPathTokens(piece).filter((path) => classifyTracedPathToken(path).kind === 'path');
1014
1020
  }
1015
1021
 
1016
- function declaredTargetPaths(document: string): string[] {
1022
+ export function declaredTargetPaths(document: string): string[] {
1017
1023
  return linesOutsideFencedCode(document).flatMap(({ text }) => {
1018
1024
  const match = TARGET_PATH_LABEL.exec(text.trim());
1019
1025
  return match ? match[1].split(/\s+[·,]\s*|[·,]\s+/).flatMap(targetPathsInLabelPiece) : [];
@@ -5804,6 +5810,278 @@ function acceptanceCriteria(
5804
5810
  return acceptance;
5805
5811
  }
5806
5812
 
5813
+ // ── SELF-REVIEW-PRELAUNCH — 발사 전 self-review 페이즈(다섯 검사 · 1회 재저작 · 잔여 needs-human) ─────────────
5814
+ /**
5815
+ * ⭐ 저작물이 «발사 전에» 자기를 검열한다 — ask 밖 목표·칸 밖 경로·미래 가정·mock 무대 누락·
5816
+ * main 에서 실행 불가능한 완료 경계 증거 명령을 lint·발사 흐름 «앞에서» 잡는다.
5817
+ * ⛔ 검사 대상은 «모델이 만든 목표 줄»(`- Checkable requested criterion:` · 분해 조각)뿐이다 —
5818
+ * 사람 ask(verbatim 울타리 안)와 저작기의 결정론 계약 줄(완료 경계 3행·보존·배선 줄)은 손대지 않는다.
5819
+ * ⭐ 걸리면 «1회» 재저작한다: ① 상 조각 재분해 ⊕ ② 줄 제거 ⊕ ③ FU(후속 조각) 화.
5820
+ * 그 뒤에도 남으면 «해당 조각만» needs-human verdict 로 남긴다(author.self-review 관측).
5821
+ */
5822
+ export const GOAL_AUTHOR_SELF_REVIEW_CHECKS = ['slice-difficulty', 'ask-scope', 'future-assumption', 'mock-stage', 'evidence-command'] as const;
5823
+ export type GoalSelfReviewCheck = (typeof GOAL_AUTHOR_SELF_REVIEW_CHECKS)[number];
5824
+ export type GoalSelfReviewVerdict = 'pass' | 'fixed' | 'needs-human' | 'not-applicable';
5825
+
5826
+ export interface GoalSelfReviewItem {
5827
+ readonly check: GoalSelfReviewCheck;
5828
+ readonly verdict: GoalSelfReviewVerdict;
5829
+ readonly detail: string;
5830
+ readonly slice?: string;
5831
+ readonly fix?: string;
5832
+ readonly judgment?: 'main-runnable' | 'main-not-runnable' | 'unknown';
5833
+ }
5834
+
5835
+ export interface GoalSelfReviewAttempt {
5836
+ readonly attempt: 1 | 2;
5837
+ readonly reauthored: boolean;
5838
+ readonly items: readonly GoalSelfReviewItem[];
5839
+ }
5840
+
5841
+ export interface GoalAuthorSelfReviewOutcome {
5842
+ readonly document: string;
5843
+ readonly reviews: readonly GoalSelfReviewAttempt[];
5844
+ }
5845
+
5846
+ export interface GoalAuthorSelfReviewInput {
5847
+ readonly ask: string;
5848
+ readonly document: string;
5849
+ readonly steps: readonly string[] | undefined;
5850
+ readonly checklist: readonly string[];
5851
+ readonly facts: CodebaseGrounding | null;
5852
+ readonly decomposeSteps?: GoalAuthorDeps['decomposeSteps'];
5853
+ readonly existsOnMain?: (repositoryRelativePath: string) => boolean | undefined;
5854
+ readonly runId?: string;
5855
+ readonly goalId?: string;
5856
+ }
5857
+
5858
+ const SLICE_DIFFICULTY_DECLARATION = /(?:난이도|difficulty)\s*[::]?\s*(하|중|상|low|medium|high)/iu;
5859
+ const SLICE_LANDABLE_DECLARATION = /(착지\s*가능|완료\s*경계|completion\s*boundary|landable)/iu;
5860
+ const SLICE_PREREQUISITE_DECLARATION = /(선행|depends\s*on|prerequisite|prereq)/iu;
5861
+ const SLICE_TIER_BY_DECLARATION: Record<string, '하' | '중' | '상'> = { 하: '하', 중: '중', 상: '상', low: '하', medium: '중', high: '상' };
5862
+ /** 미래 가정 — 현재 main 상태가 아니라 «앞으로 생길 것»을 전제하는 문면(제거하거나 FU 조각화). */
5863
+ const FUTURE_ASSUMPTION_DECLARATION = /나중에|향후|미래(?:에|의)|다음\s*(?:판|버전)|(?:착지|머지|반영|merge|land)(?:되|된|한다)?\s*(?:면|후|뒤|한\s*뒤)|after\s+#\d+|once\s+#\d+|#\d+\s+(?:lands|merges)|will\s+be\s+(?:added|landed|merged|available)|future\s+assumptions?/iu;
5864
+ /** ask 가 이름대지 않은 칸 id — ask 밖 목표의 결정론 표지(숫자로 시작하는 두번째 마디 `MS-02` 는 제외). */
5865
+ const OUT_OF_ASK_CELL_ID = /\b[A-Z][A-Z0-9]{1,}-[A-Z][A-Z0-9-]*\b/g;
5866
+
5867
+ function declaredSliceTier(step: string): '하' | '중' | '상' | null {
5868
+ const match = SLICE_DIFFICULTY_DECLARATION.exec(step);
5869
+ return match ? SLICE_TIER_BY_DECLARATION[match[1]!.toLowerCase()] ?? null : null;
5870
+ }
5871
+
5872
+ /** 칸 = ask ⊕ 접지 — 사람이 이름댔거나 접지가 Read 한 경로가 «칸 안»이다. */
5873
+ function inCellPathTokens(ask: string, facts: CodebaseGrounding | null): Set<string> {
5874
+ return new Set([
5875
+ ...declaredTargetPaths(ask),
5876
+ ...evidencePaths(ask),
5877
+ ...(facts?.files ?? []),
5878
+ ...(facts?.persistentEvidence ?? []).flatMap((entry) => evidencePaths(entry)),
5879
+ ]);
5880
+ }
5881
+
5882
+ function outOfCellReasons(criterion: string, ask: string, inCellPaths: ReadonlySet<string>): string[] {
5883
+ const reasons: string[] = [];
5884
+ const outPaths = evidencePaths(criterion).filter((path) => !inCellPaths.has(path) && !ask.includes(path));
5885
+ if (outPaths.length) reasons.push(`칸 밖 경로: ${outPaths.join(' · ')}`);
5886
+ const ids = [...criterion.matchAll(OUT_OF_ASK_CELL_ID)].map((match) => match[0]).filter((id) => !ask.includes(id));
5887
+ if (ids.length) reasons.push(`ask 밖 목표(칸 id): ${ids.join(' · ')}`);
5888
+ return reasons;
5889
+ }
5890
+
5891
+ /** ④ mock 무대 — 검증 계획(TDD) 의 무대 줄이 MS id·사건 주입·관측 줄을 갖췄나. */
5892
+ function mockStageSelfReviewItem(document: string): GoalSelfReviewItem {
5893
+ const start = document.indexOf(VERIFICATION_PLAN_HEADING);
5894
+ if (start === -1) return { check: 'mock-stage', verdict: 'not-applicable', detail: '검증 계획(TDD) 절이 없어 mock 무대 줄을 검사하지 않는다.' };
5895
+ const rest = document.slice(start + VERIFICATION_PLAN_HEADING.length);
5896
+ const nextHeading = rest.indexOf('\n## ');
5897
+ const section = nextHeading === -1 ? rest : rest.slice(0, nextHeading);
5898
+ const missing = [
5899
+ ...(/MS-\d+/u.test(section) ? [] : ['MS id']),
5900
+ ...(section.includes('사건 주입') ? [] : ['사건 주입 줄']),
5901
+ ...(section.includes('관측:') ? [] : ['관측 줄']),
5902
+ ];
5903
+ return missing.length
5904
+ ? { check: 'mock-stage', verdict: 'needs-human', detail: `mock 무대 줄 미비 — ${missing.join(' · ')} — 사람이 무대를 확정한다.` }
5905
+ : { check: 'mock-stage', verdict: 'pass', detail: 'mock 무대가 MS id·사건 주입·관측 줄을 갖췄다.' };
5906
+ }
5907
+
5908
+ /** ⑤ 완료 경계 증거 명령 — 경로 인자가 «현재 main» 에 있는지 판정한다(심이 없으면 판정을 남기지 못한다). */
5909
+ function evidenceCommandSelfReviewItem(document: string, existsOnMain: ((repositoryRelativePath: string) => boolean | undefined) | undefined): GoalSelfReviewItem {
5910
+ const command = inspectGoalDoneBoundary(document).values['완료 경계 증거 명령'];
5911
+ if (command === undefined) return { check: 'evidence-command', verdict: 'not-applicable', detail: '완료 경계 증거 명령이 없어 main 실행 가능 판정을 하지 않는다.' };
5912
+ if (existsOnMain === undefined) return { check: 'evidence-command', verdict: 'not-applicable', detail: 'main 존재 심(selfReviewExistsOnMain)이 없어 판정하지 못한다 — 생산 진입점이 심을 공급한다.', slice: command };
5913
+ const paths = evidencePaths(command);
5914
+ if (!paths.length) return { check: 'evidence-command', verdict: 'pass', judgment: 'main-runnable', detail: `증거 명령에 저장소 경로 인자가 없다 — 현재 main 에서 그대로 실행된다: ${command}` };
5915
+ const presence = paths.map((path) => [path, existsOnMain(path)] as const);
5916
+ const unknown = presence.filter(([, exists]) => exists === undefined).map(([path]) => path);
5917
+ if (unknown.length) return { check: 'evidence-command', verdict: 'needs-human', judgment: 'unknown', detail: `origin/main 에서 경로 존재를 잴 수 없음: ${unknown.join(' · ')} — main 실행 가능성을 확인할 수 없어 사람이 판정한다.`, slice: command };
5918
+ const missing = presence.filter(([, exists]) => exists === false).map(([path]) => path);
5919
+ return missing.length
5920
+ ? { check: 'evidence-command', verdict: 'needs-human', judgment: 'main-not-runnable', detail: `현재 main 에 없는 경로: ${missing.join(' · ')} — 신설 경로면 착지 뒤에 실행 가능하다.`, slice: command }
5921
+ : { check: 'evidence-command', verdict: 'pass', judgment: 'main-runnable', detail: `증거 명령의 모든 경로 인자가 현재 main 에 있다: ${paths.join(' · ')}` };
5922
+ }
5923
+
5924
+ interface SelfReviewPass {
5925
+ readonly items: readonly GoalSelfReviewItem[];
5926
+ readonly removeCriterionLines: readonly string[];
5927
+ readonly fuCriterionLines: readonly (readonly [line: string, fuLine: string])[];
5928
+ readonly fuStepLines: readonly (readonly [line: string, fuLine: string])[];
5929
+ readonly oversizeSteps: readonly string[];
5930
+ }
5931
+
5932
+ function passGoalSelfReview(input: {
5933
+ readonly document: string;
5934
+ readonly steps: readonly string[] | undefined;
5935
+ readonly modelCriteria: readonly string[];
5936
+ readonly ask: string;
5937
+ readonly inCellPaths: ReadonlySet<string>;
5938
+ readonly existsOnMain: ((repositoryRelativePath: string) => boolean | undefined) | undefined;
5939
+ }): SelfReviewPass {
5940
+ const items: GoalSelfReviewItem[] = [];
5941
+ const removeCriterionLines: string[] = [];
5942
+ const fuCriterionLines: Array<readonly [string, string]> = [];
5943
+ const fuStepLines: Array<readonly [string, string]> = [];
5944
+ const oversizeSteps: string[] = [];
5945
+
5946
+ // ① 조각 난이도 하·중·착지 가능·선행 명시 — 상이면 더 분해한다.
5947
+ if (input.steps === undefined || input.steps.length === 0) {
5948
+ items.push({ check: 'slice-difficulty', verdict: 'not-applicable', detail: '검토할 분해 조각이 없다 — 난이도·착지 가능·선행 명시를 검사하지 않는다.' });
5949
+ } else {
5950
+ for (const step of input.steps) {
5951
+ const tier = declaredSliceTier(step);
5952
+ const missing = [
5953
+ ...(tier === null ? ['난이도(하·중)'] : []),
5954
+ ...(SLICE_LANDABLE_DECLARATION.test(step) ? [] : ['착지 가능']),
5955
+ ...(SLICE_PREREQUISITE_DECLARATION.test(step) ? [] : ['선행']),
5956
+ ];
5957
+ if (tier === '상') {
5958
+ oversizeSteps.push(step);
5959
+ items.push({ check: 'slice-difficulty', verdict: 'needs-human', detail: `난이도 상 — 더 분해해야 한다 (미명시: ${missing.join(' · ')})`, slice: step });
5960
+ continue;
5961
+ }
5962
+ items.push(missing.length
5963
+ ? { check: 'slice-difficulty', verdict: 'needs-human', detail: `조각이 난이도 하·중·착지 가능·선행을 명시하지 않았다 — 미명시: ${missing.join(' · ')}`, slice: step }
5964
+ : { check: 'slice-difficulty', verdict: 'pass', detail: `난이도 ${tier} · 착지 가능 · 선행 명시 확인`, slice: step });
5965
+ }
5966
+ }
5967
+
5968
+ const documentLines = input.document.split('\n');
5969
+ const modelCriterionLines = input.modelCriteria
5970
+ .map((criterion) => ({ criterion, line: requestedCriterionLine(criterion) }))
5971
+ .filter(({ line }) => documentLines.includes(line));
5972
+
5973
+ // ② ask 밖 목표·칸 밖 경로 제거 — 칸 = ask ⊕ 접지.
5974
+ for (const { criterion, line } of modelCriterionLines) {
5975
+ const reasons = outOfCellReasons(criterion, input.ask, input.inCellPaths);
5976
+ if (!reasons.length) continue;
5977
+ items.push({ check: 'ask-scope', verdict: 'fixed', detail: `ask 밖 목표·칸 밖 경로 — ${reasons.join(' · ')}`, slice: criterion, fix: '1회 재저작에서 이 목표 줄을 문서에서 제거한다.' });
5978
+ removeCriterionLines.push(line);
5979
+ }
5980
+ if (!removeCriterionLines.length) items.push({ check: 'ask-scope', verdict: 'pass', detail: 'ask 밖 목표·칸 밖 경로가 없다.' });
5981
+
5982
+ // ③ 미래 가정 — 제거하거나 FU(후속 조각) 로 바꾼다.
5983
+ for (const { criterion, line } of modelCriterionLines) {
5984
+ if (removeCriterionLines.includes(line) || !FUTURE_ASSUMPTION_DECLARATION.test(criterion)) continue;
5985
+ items.push({ check: 'future-assumption', verdict: 'fixed', detail: '미래 가정 — 현재 main 상태가 아니라 앞으로 생길 것을 전제한다.', slice: criterion, fix: '1회 재저작에서 FU(후속 조각) 줄로 바꾼다.' });
5986
+ fuCriterionLines.push([line, `- FU(후속 조각): ${criterion}`]);
5987
+ }
5988
+ for (const step of input.steps ?? []) {
5989
+ // A declared step dependency is a present plan relationship, not an assumption
5990
+ // that an external future event will happen (e.g. shadow → live after step ① lands).
5991
+ if (SLICE_PREREQUISITE_DECLARATION.test(step) || !FUTURE_ASSUMPTION_DECLARATION.test(step)) continue;
5992
+ items.push({ check: 'future-assumption', verdict: 'fixed', detail: '미래 가정 조각 — 현재 main 상태가 아니라 앞으로 생길 것을 전제한다.', slice: step, fix: '1회 재저작에서 FU(후속 조각) 줄로 바꾼다.' });
5993
+ fuStepLines.push([`- ${step}`, `- FU(후속 조각): ${step}`]);
5994
+ }
5995
+ if (!fuCriterionLines.length && !fuStepLines.length) items.push({ check: 'future-assumption', verdict: 'pass', detail: '미래 가정이 없다.' });
5996
+
5997
+ items.push(mockStageSelfReviewItem(input.document));
5998
+ items.push(evidenceCommandSelfReviewItem(input.document, input.existsOnMain));
5999
+ return { items, removeCriterionLines, fuCriterionLines, fuStepLines, oversizeSteps };
6000
+ }
6001
+
6002
+ function renderGoalStepsSection(steps: readonly string[]): string {
6003
+ return ['## STEPS', ...(steps.length ? steps.map((step) => `- ${step}`) : ['- No externally injected steps.']), '', ''].join('\n');
6004
+ }
6005
+
6006
+ function replaceGoalStepsSection(document: string, steps: readonly string[]): string {
6007
+ const outside = linesOutsideFencedCode(document);
6008
+ const start = outside.find((line) => line.text === '## STEPS');
6009
+ const next = start && outside.find((line) => line.start > start.start && line.text === '## ACCEPTANCE CRITERIA');
6010
+ if (!start || !next) return document;
6011
+ return `${document.slice(0, start.start)}${renderGoalStepsSection(steps)}${document.slice(next.start)}`;
6012
+ }
6013
+
6014
+ function reviseGoalDocumentLines(document: string, revision: { remove: readonly string[]; fu: readonly (readonly [line: string, fuLine: string])[] }): string {
6015
+ const remove = new Set(revision.remove);
6016
+ const fu = new Map(revision.fu);
6017
+ return document.split('\n').flatMap((line) => {
6018
+ if (remove.has(line)) return [];
6019
+ const fuLine = fu.get(line);
6020
+ return fuLine ? [fuLine] : [line];
6021
+ }).join('\n');
6022
+ }
6023
+
6024
+ /**
6025
+ * 발사 전 self-review 엔진 — 1차 검사 → (결정론적 수정이 있으면) 1회 재저작 → 2차 검사.
6026
+ * 파일·원장·LLM 효과는 없다: 재분해는 주입된 `decomposeSteps` 심으로만, main 존재 판정은 주입된 심으로만.
6027
+ */
6028
+ export async function runGoalAuthorSelfReview(input: GoalAuthorSelfReviewInput): Promise<GoalAuthorSelfReviewOutcome> {
6029
+ const modelCriteria = withoutDedicatedSectionDuplicates(input.checklist, input.ask);
6030
+ const inCellPaths = inCellPathTokens(input.ask, input.facts);
6031
+ const first = passGoalSelfReview({ document: input.document, steps: input.steps, modelCriteria, ask: input.ask, inCellPaths, existsOnMain: input.existsOnMain });
6032
+ const canRedecompose = first.oversizeSteps.length > 0 && input.decomposeSteps !== undefined;
6033
+ const fixable = first.removeCriterionLines.length > 0 || first.fuCriterionLines.length > 0 || first.fuStepLines.length > 0 || canRedecompose;
6034
+ if (!fixable) return { document: input.document, reviews: [{ attempt: 1, reauthored: false, items: first.items }] };
6035
+
6036
+ // 1회 재저작 — ① 상 조각 재분해 ⊕ ② ask 밖 목표 제거 ⊕ ③ 미래 가정 FU 화.
6037
+ let document = input.document;
6038
+ let steps = input.steps;
6039
+ let stepsReauthored = false;
6040
+ if (canRedecompose) {
6041
+ const feedback = [
6042
+ 'SELF-REVIEW ①: 이전 분해 조각이 난이도 상이거나 하·중·착지 가능·선행을 명시하지 않았다.',
6043
+ `상 조각: ${first.oversizeSteps.join(' · ')}`,
6044
+ '전체 계획을 다시 내라 — 각 조각에 난이도(하|중)·착지 가능·선행을 명시하고, 상 조각은 하·중 조각으로 더 분해하라.',
6045
+ ].join('\n');
6046
+ const reDecomposed = await input.decomposeSteps!(input.ask, {
6047
+ context: feedback,
6048
+ ...(input.runId === undefined ? {} : { runId: input.runId }),
6049
+ ...(input.goalId === undefined ? {} : { goalId: input.goalId }),
6050
+ });
6051
+ if (reDecomposed.length) {
6052
+ const replacementSteps = [...reDecomposed];
6053
+ const replacementDocument = replaceGoalStepsSection(document, replacementSteps);
6054
+ if (replacementDocument !== document) {
6055
+ steps = replacementSteps;
6056
+ document = replacementDocument;
6057
+ stepsReauthored = true;
6058
+ }
6059
+ }
6060
+ }
6061
+ const oversizeStepLines = new Set(canRedecompose ? first.oversizeSteps.map((step) => `- ${step}`) : []);
6062
+ const fuStepLines = first.fuStepLines.filter(([line]) => !oversizeStepLines.has(line));
6063
+ document = reviseGoalDocumentLines(document, { remove: first.removeCriterionLines, fu: [...first.fuCriterionLines, ...fuStepLines] });
6064
+ const fuSteps = new Set(fuStepLines.map(([line]) => line.slice(2)));
6065
+ const second = passGoalSelfReview({
6066
+ document,
6067
+ steps: steps?.filter((step) => !fuSteps.has(step)),
6068
+ modelCriteria,
6069
+ ask: input.ask,
6070
+ inCellPaths,
6071
+ existsOnMain: input.existsOnMain,
6072
+ });
6073
+ const attempt1Items = first.items.map((item) => item.check === 'slice-difficulty' && item.verdict === 'needs-human' && item.slice !== undefined && first.oversizeSteps.includes(item.slice) && stepsReauthored
6074
+ ? { ...item, verdict: 'fixed' as const, fix: '1회 재저작에서 상 조각을 재분해로 대체했다.' }
6075
+ : item);
6076
+ return {
6077
+ document,
6078
+ reviews: [
6079
+ { attempt: 1, reauthored: true, items: attempt1Items },
6080
+ { attempt: 2, reauthored: true, items: second.items },
6081
+ ],
6082
+ };
6083
+ }
6084
+
5807
6085
  /** Compose one grounded goal artifact without filesystem, process, pipeline, or daemon effects. */
5808
6086
  export async function authorGoal(ask: string, deps: GoalAuthorDeps): Promise<AuthoredGoal> {
5809
6087
  if ('supersessionRootIntent' in deps) {
@@ -6397,7 +6675,7 @@ async function authorGoalWithSupersededRootIntent(
6397
6675
  ? tracedPathsSection(facts, ask, deps.repositoryRoot, narrative.tracedPathsUnavailableEvidence, authorRunId, deps.recordTracedPath)
6398
6676
  : [];
6399
6677
  if (goalType === 'implement') observeEmptyPersistentEvidence(facts, tracedPathsForDocument, authorRunId);
6400
- const document = [
6678
+ let document = [
6401
6679
  explicitGoalTitle ?? goalSummary(enhancement.original),
6402
6680
  `- GoalId: ${assignedGoalId}`,
6403
6681
  ...(deps.authoringLessonIds?.length ? [`- AuthoringLessons: ${deps.authoringLessonIds.join(', ')}`] : []),
@@ -6483,6 +6761,38 @@ async function authorGoalWithSupersededRootIntent(
6483
6761
  endAssembleSubphase();
6484
6762
  assembleCompleted = true;
6485
6763
  endGoalAuthorPhase('assemble', assembleStartedAt, authorRunId, deps.onProgress);
6764
+ // ⭐ SELF-REVIEW-PRELAUNCH — assemble 완료 뒤·발사(lint→return→파일 쓰기) 직전에 저작물을 검열한다.
6765
+ // ⛔ lite 저작은 assemble 단계 자체가 없다 — self-review 는 full 저작 경로에만 붙는다(의도적 경계).
6766
+ // 외부 페이즈 관측 계약(ground→enhance→assemble→lint)은 그대로 보존한다 — 검열 자국은
6767
+ // author.self-review 관측(attempt·항목별 verdict)으로만 남는다.
6768
+ try {
6769
+ const selfReview = await runGoalAuthorSelfReview({
6770
+ ask,
6771
+ document,
6772
+ steps: resolvedSteps,
6773
+ checklist: enhancement.checklist,
6774
+ facts,
6775
+ decomposeSteps: deps.decomposeSteps,
6776
+ existsOnMain: deps.selfReviewExistsOnMain,
6777
+ runId: authorRunId,
6778
+ goalId: assignedGoalId,
6779
+ });
6780
+ for (const review of selfReview.reviews) {
6781
+ try {
6782
+ observeGoalAuthor('goal-author', 'author.self-review', {
6783
+ authorRunId,
6784
+ goalId: assignedGoalId,
6785
+ attempt: review.attempt,
6786
+ reauthored: review.reauthored,
6787
+ items: review.items,
6788
+ });
6789
+ } catch { /* observation is fail-soft */ }
6790
+ }
6791
+ document = selfReview.document;
6792
+ } catch (error) {
6793
+ // 검열은 저작을 막지 않는다 — 실패는 관측으로 남기고 종전 문서를 그대로 발사한다.
6794
+ try { observeGoalAuthor('goal-author', 'author.self-review-failed', { authorRunId, error: error instanceof Error ? error.message : String(error) }); } catch { /* observation is fail-soft */ }
6795
+ }
6486
6796
  const lintStartedAt = startGoalAuthorPhase('lint', authorRunId, deps.onProgress);
6487
6797
  let lintPassed = false;
6488
6798
  try {
@@ -6688,6 +6998,19 @@ export async function writeAuthoredGoal(
6688
6998
  ...deps,
6689
6999
  repositoryRoot: deps.repositoryRoot ?? groundingRoot,
6690
7000
  };
7001
+ // ⭐ SELF-REVIEW-PRELAUNCH ⑤ — 완료 경계 증거 명령의 origin/main 실행 가능 판정 심(읽기 전용).
7002
+ // 현재 worktree 파일 존재를 main 증거로 오인하지 않는다. ref를 못 읽으면 unknown 으로 남긴다.
7003
+ resolvedDeps.selfReviewExistsOnMain = deps.selfReviewExistsOnMain
7004
+ ?? ((repositoryRelativePath: string) => {
7005
+ try {
7006
+ const entry = execFileSync('git', ['-C', resolvedDeps.repositoryRoot, 'ls-tree', '-r', '--name-only', 'origin/main', '--', repositoryRelativePath], {
7007
+ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'],
7008
+ });
7009
+ return entry.trim().length > 0;
7010
+ } catch {
7011
+ return undefined;
7012
+ }
7013
+ });
6691
7014
  const mandatoryGoalContextEvidence = goalContextEvidence(cwd);
6692
7015
  const authoringLessons = selectRelevantAuthoringLessons(cwd, ask, elanousStateRoot());
6693
7016
  observeGoalAuthor('goal-author', 'authoring-lessons', {
@@ -31,6 +31,8 @@ export interface GraphOverlaySpec {
31
31
  /** ⛔ 조건도 «값»이다 — 사람이 판단해 얹는 경로를 두지 않는다. */
32
32
  readonly appliesWhen: string;
33
33
  readonly patch: readonly OverlayPatchOp[];
34
+ /** Stop-reason vocabulary lives with heal declarations, not in TypeScript tables. */
35
+ readonly reasonMap?: Readonly<Record<string, string>>;
34
36
  }
35
37
 
36
38
  export interface OverlayParseResult {
@@ -93,6 +95,10 @@ function overlayFromRaw(raw: unknown, label: string): { overlay?: GraphOverlaySp
93
95
  if (!appliesWhen) errors.push({ path: `${label}/applies_when`, message: 'applies_when 이 없거나 문자열이 아니다' });
94
96
 
95
97
  const patch: OverlayPatchOp[] = [];
98
+ const reasonMapRaw = doc.reason_map;
99
+ const reasonMap = reasonMapRaw && typeof reasonMapRaw === 'object' && !Array.isArray(reasonMapRaw)
100
+ ? Object.fromEntries(Object.entries(reasonMapRaw as Record<string, unknown>).filter((entry): entry is [string, string] => typeof entry[1] === 'string'))
101
+ : undefined;
96
102
  const rawPatch = Array.isArray(doc.patch) ? doc.patch : [];
97
103
  if (rawPatch.length === 0) errors.push({ path: `${label}/patch`, message: 'patch 가 비었다 — 아무것도 안 바꾸는 오버레이다' });
98
104
  for (const [index, entry] of rawPatch.entries()) {
@@ -109,6 +115,7 @@ function overlayFromRaw(raw: unknown, label: string): { overlay?: GraphOverlaySp
109
115
  return {
110
116
  overlay: {
111
117
  overlayId: overlayId!, target: target!, stage: stage!, appliesWhen: appliesWhen!, patch,
118
+ ...(reasonMap && Object.keys(reasonMap).length ? { reasonMap } : {}),
112
119
  },
113
120
  errors,
114
121
  };
@@ -87,14 +87,14 @@ import type { ChannelBus } from '../terminal-matrix/channel-bus.js';
87
87
  import { federationObservation } from './orchestrator.js';
88
88
  // ⛔ 배달 상태는 「정하는 쪽」(orchestrator)이 소유한다 — 여기는 받아서 찍기만 한다.
89
89
  import type { SupervisorDeliveryLine, SupervisorDeliveryState } from './orchestrator.js';
90
- import type { RunShardIdentity } from './run-ledger.js';
90
+ import { runLedgerDir, type RunShardIdentity } from './run-ledger.js';
91
+ import { readRunChart, recordRunChartDecision, recordRunChartWaitHandoff, RUN_DOCTOR_HANDOFF_WAIT_THRESHOLD, RUN_DOCTOR_HANDOFF_INPUT_PREFIX } from './run-chart.js';
91
92
 
92
93
  const sleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
93
94
 
94
95
  // Boundary requests observed up to about 788 characters; preserve the complete request record.
95
96
  const HARNESS_BOUNDARY_REQUEST_STRING_MAX = 1024;
96
97
  const WAIT_SUPERVISION_PROGRESS_BATCH_SIZE = 5;
97
-
98
98
  /** Renders untrusted boundary metadata as one inert terminal line for the parent surface. */
99
99
  export function singleLineBoundarySurfaceValue(value: string): string {
100
100
  return value
@@ -1267,6 +1267,9 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1267
1267
  let sameCommandStallCount = 0;
1268
1268
  let pendingWaitSupervisionCount = 0;
1269
1269
  let pendingWaitLatestJudgment: string | undefined;
1270
+ let consecutiveWaitDecisionCount = 0;
1271
+ let waitStreakHandoffSent = false;
1272
+ let waitStreakIndex = 0;
1270
1273
  // Repetition identity is exact full instruction-text equality after the existing delivery trim;
1271
1274
  // the first occurrence omits the surface marker, and later occurrences are only annotated.
1272
1275
  const inputInstructionOccurrences = new Map<string, number>();
@@ -1699,6 +1702,8 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1699
1702
  descriptor: { controlStance: stance },
1700
1703
  });
1701
1704
  previousIntervention = intervention;
1705
+ const chartDir = runLedgerDir(opts.stateDir);
1706
+ const chartBeforeJudgment = readRunChart(runId, 'run-supervisor', chartDir);
1702
1707
  const controlObs: ControlObservation = {
1703
1708
  screen: rendered,
1704
1709
  state: curState,
@@ -1708,6 +1713,8 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1708
1713
  sameScreenMs: Math.max(0, nowMs - frameObs.screenSinceMs),
1709
1714
  stallRung: frameObs.stallRung,
1710
1715
  ...(roundContext ? { roundContext } : {}),
1716
+ runId,
1717
+ runChart: chartBeforeJudgment,
1711
1718
  };
1712
1719
  const controller = new AbortController();
1713
1720
  let rejectParentAbort: ((reason: Error) => void) | undefined;
@@ -1821,11 +1828,14 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1821
1828
  debug.log('self-implement', 'brain.suggestion', supervisionVerdictPayload);
1822
1829
  debug.log('self-implement', 'run-supervision.verdict', supervisionVerdictPayload);
1823
1830
  if (decision.action === 'wait') {
1831
+ consecutiveWaitDecisionCount += 1;
1824
1832
  pendingWaitSupervisionCount += 1;
1825
1833
  pendingWaitLatestJudgment = decision.action;
1826
1834
  if (pendingWaitSupervisionCount >= WAIT_SUPERVISION_PROGRESS_BATCH_SIZE) flushWaitSupervisionProgress();
1827
1835
  } else {
1828
1836
  flushWaitSupervisionProgress();
1837
+ consecutiveWaitDecisionCount = 0;
1838
+ waitStreakHandoffSent = false;
1829
1839
  const input = decision.action === 'input' ? decision.text.trim() : '';
1830
1840
  const inputInstructionOccurrence = input ? countInputInstructionOccurrence(input) : undefined;
1831
1841
  const delivery = input ? (opts.onSupervisorInput ? 'queued' : 'not-delivered') : undefined;
@@ -1858,6 +1868,25 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1858
1868
  }), 'supervision');
1859
1869
  });
1860
1870
  }
1871
+ const handoffNow = decision.action === 'wait'
1872
+ && consecutiveWaitDecisionCount >= RUN_DOCTOR_HANDOFF_WAIT_THRESHOLD && !waitStreakHandoffSent;
1873
+ const chartStopKey = handoffNow ? `${runId}:wait-streak:${waitStreakIndex + 1}` : `${runId}:supervisor:${i}`;
1874
+ const chartWrite = handoffNow
1875
+ ? recordRunChartWaitHandoff({ runId, stopKey: chartStopKey, waitCount: consecutiveWaitDecisionCount,
1876
+ readStopKeys: chartBeforeJudgment.map((cell) => cell.stopKey), dir: chartDir })
1877
+ : recordRunChartDecision({ runId, device: 'run-supervisor', stopKey: chartStopKey,
1878
+ observed: `${curState}; stallRung=${st?.rung ?? NO_STALL}`, verdict: decision.action,
1879
+ action: decision.action === 'input' ? decision.text.slice(0, 120) : decision.action,
1880
+ handoff: decision.action === 'no-progress' ? 'macrophage' : null,
1881
+ why: decision.action === 'no-progress' ? decision.reason : `supervisor ${decision.action}`,
1882
+ readStopKeys: chartBeforeJudgment.map((cell) => cell.stopKey), dir: chartDir });
1883
+ if (handoffNow && (chartWrite === 'recorded' || chartWrite === 'already-recorded')) {
1884
+ waitStreakHandoffSent = true; waitStreakIndex += 1;
1885
+ debug.log('run-supervisor', 'doctor-handoff', { runId, stopKey: chartStopKey, waitCount: consecutiveWaitDecisionCount, handoff: 'doctor' });
1886
+ opts.onSupervisorInput?.(`${RUN_DOCTOR_HANDOFF_INPUT_PREFIX} runId=${runId} stopKey=${chartStopKey} waitCount=${consecutiveWaitDecisionCount}`, (delivery, reason) => {
1887
+ try { debug.log('run-supervisor', 'doctor-handoff-delivery', { runId, stopKey: chartStopKey, delivery, ...(reason ? { reason } : {}) }); } catch { /* observation is fail-soft */ }
1888
+ });
1889
+ }
1861
1890
  debug.log('self-implement', 'brain.input-outcome', {
1862
1891
  ptyId: h.id, runId, step: i, axis: 'assist', action: decision.action,
1863
1892
  applied: autoAssist.assist, why: autoAssist.why,