elanous 0.2.19 → 0.2.21

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 (509) 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/MObU8ujkMciAKr6ljAV05/_buildManifest.js +1 -0
  4. package/apps/pwa/out/_next/static/chunks/088d8e8a.8069543d082bec12.js +160 -0
  5. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +148 -0
  6. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +32 -0
  7. package/apps/pwa/out/_next/static/chunks/119fc678.6f591cdb84ca5791.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +309 -0
  9. package/apps/pwa/out/_next/static/chunks/{4323.c5dfb6f503304775.js → 1268.0840ff91e083fcbd.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1307-c97eba9fb72a9a5e.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +122 -0
  12. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +149 -0
  13. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +79 -0
  14. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +24 -0
  16. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +27 -0
  21. package/apps/pwa/out/_next/static/chunks/1948.5f35b39eef222a94.js +5 -0
  22. package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/{2977-e38442e86289f1d3.js → 211-9c9090c59e2c5907.js} +1 -1
  26. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +36 -0
  31. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +286 -0
  32. package/apps/pwa/out/_next/static/chunks/2489-ff55a35b202c0f94.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +94 -0
  45. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/3522-1de1319d028ac89c.js +25 -0
  49. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +74 -0
  54. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +34 -0
  59. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +115 -0
  61. package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/4588.ad3364cb7fb97ada.js +86 -0
  63. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +77 -0
  66. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +90 -0
  70. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/5977-59fedea50d13c762.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +8 -0
  75. package/apps/pwa/out/_next/static/chunks/{4847.56f5bc454fbcc827.js → 6110.1297d4093fdfbb0d.js} +2 -2
  76. package/apps/pwa/out/_next/static/chunks/6158.566c890adc06a459.js +2 -0
  77. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +64 -0
  78. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +287 -0
  80. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +226 -0
  81. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6767.8e6c5f6e744fcd9f.js +38 -0
  83. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7175-350f4ce2873bc038.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +41 -0
  91. package/apps/pwa/out/_next/static/chunks/{1470.98a6ab61ccb4131c.js → 726.83532d69452ee24b.js} +1 -1
  92. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/{6062-73e68343a9814f6a.js → 7327-2d69fb321ba73389.js} +1 -1
  94. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +24 -0
  95. package/apps/pwa/out/_next/static/chunks/7630.2b9a68659053ff4e.js +193 -0
  96. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/7899.597af4a9996c907f.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/79b78388.663188133449d707.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8194.484f51e273d9abd2.js +217 -0
  105. package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +104 -0
  109. package/apps/pwa/out/_next/static/chunks/8857-f1762140ef9a96b1.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/88729267.9c6c000157c83f2f.js +62 -0
  111. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +93 -0
  113. package/apps/pwa/out/_next/static/chunks/9070.067c106528ec1ae6.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9247-7581825d511a64c0.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{7647.2fcd30d894d5ee30.js → 935.4ddaa99fc1d1126c.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +23 -0
  118. package/apps/pwa/out/_next/static/chunks/9497-b0e758d1cd4ae8d7.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +62 -0
  120. package/apps/pwa/out/_next/static/chunks/9832.2ab2e818013574c7.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/a9f2b54d-40c16bd0efdb04b8.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-937c92292a4ab4f0.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d781be3e3a9cfd74.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-b0a80997903852d8.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-2b1263165630d9c8.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea998f7f5d156bea.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-33c328b64ca508f8.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-e2d6bed48ac20120.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-111cabe4d1fd69ae.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-544dd4bd4847eeb7.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-3ee191319bf97d87.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e4bcb2c503dab04b.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-300897dcbbd5ed76.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-a449f1ed472b81c2.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-9045094d6d3b5cd0.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-c06673596849ef45.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-103fa3191c1b2e08.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-9f81233f29dcd409.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/{page-b70cd005d9169e25.js → page-be8b4615c919e36c.js} +1 -1
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-c685b104e0dfa609.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-8d693331cfbb6add.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-cef4f30a4c22fae1.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66ea1b54fc83fa15.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-7a12f61be4a579d1.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-c85b0589591a99c9.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-725a4da02dd129eb.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-8cc707bd09a497d9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-90b55be1f15ce0e8.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cb16606e08be65db.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-16dc64b74ed6a40a.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-21bec4afeb2f0917.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-dc39ee7a36d26385.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-84ae759f76053672.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-3db58ddb61fe2be9.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c5315e30f3528dc4.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-2fe368efb6de3b6a.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8d04132dd0ac5e10.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-f23484de467c9ea3.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-c69762987b751174.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-5456692bda39aafb.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d75f7cd65845ce98.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-5603f5e568b25ce3.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-d2cc0f4e89f42028.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-a6eb73b8a4840f1c.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-c0a3f4d10edb83fa.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6c0b88068c143f15.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-7f8d7fcdf058a845.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-22163556cd38bc88.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-141436fd26dd56fc.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/d70879db.c66c56a95a91efc6.js +66 -0
  174. package/apps/pwa/out/_next/static/chunks/{8046cadf-211ca3c0e00f2b72.js → f6231284-45726550aba08fca.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/{2ea96958.e8c7e112de50b067.js → f6b7c9ba.64a895b8b2fedbdc.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/f8626309.a4e5d362b1d55e59.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/framework-5c169757551134ed.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +1 -0
  183. package/apps/pwa/out/_next/static/css/{d3427996da11e480.css → b9d8151e48998417.css} +1 -1
  184. package/apps/pwa/out/_next/static/css/e81df11490b4413b.css +1 -0
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +24 -24
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +23 -23
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -23
  222. package/apps/pwa/out/live-run/index.html +1 -0
  223. package/apps/pwa/out/live-run/index.txt +35 -0
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/graphs/demo/editor-recipes.yaml +22 -0
  279. package/graphs/drafts/recipes.yaml +4 -4
  280. package/graphs/implement-loop.yaml +277 -5
  281. package/graphs/retro/daily.yaml +25 -0
  282. package/graphs/retro/recipes.yaml +24 -0
  283. package/package.json +1 -1
  284. package/scripts/ask-marker-check.ts +3 -1
  285. package/scripts/coord-channel-watch.sh +31 -4
  286. package/scripts/docs-lint.ts +4 -1
  287. package/scripts/land-global-checks.ts +89 -0
  288. package/scripts/lib/pch-regress-map.ts +2 -1
  289. package/scripts/marketing/generate-ax-brief.ts +18 -1
  290. package/scripts/measure-nl-routing-corpus.ts +11 -3
  291. package/scripts/release-loop/gate-node.ts +296 -25
  292. package/scripts/release-loop/gate-timing.ts +116 -7
  293. package/scripts/release-loop/preflight.ts +6 -4
  294. package/scripts/release-loop/publish-window.ts +141 -0
  295. package/scripts/release-loop/release-docs.ts +1 -4
  296. package/scripts/release-loop/release-universe.ts +38 -0
  297. package/scripts/release-loop/resume-release.ts +4 -1
  298. package/scripts/release-loop/shard-plan.ts +50 -5
  299. package/scripts/release-loop/unattended-release.ts +10 -2
  300. package/scripts/release-story/draft.ts +5 -1
  301. package/scripts/retro/shadow-compare.ts +71 -0
  302. package/scripts/rhythm/daily.ts +8 -2
  303. package/src/agent-mission/driver.ts +34 -6
  304. package/src/autopilot/build/llm-conflict-merge.ts +132 -7
  305. package/src/autopilot/build/merge-intent.ts +135 -7
  306. package/src/away/release-watch.ts +20 -3
  307. package/src/browser-cdp/client.ts +10 -5
  308. package/src/cli/config-drift.ts +513 -0
  309. package/src/cli/log-event-names.ts +4 -0
  310. package/src/cli/ops-cli.ts +11 -0
  311. package/src/cli/ops-overview-cli.ts +50 -0
  312. package/src/cli/pod-cli.ts +1 -0
  313. package/src/cli/pr-cli.ts +20 -0
  314. package/src/cli/release-cli.ts +20 -5
  315. package/src/cli/retro-cli.ts +78 -0
  316. package/src/cli/tasks-cli.ts +200 -8
  317. package/src/dashboard/index.ts +40 -4
  318. package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -4
  319. package/src/dashboard/slash-runtime/help-from-registry.ts +57 -31
  320. package/src/domains/outbound-log-probe.ts +6 -1
  321. package/src/esc-abort-gate.ts +3 -1
  322. package/src/graph-runner/graph-cli.ts +57 -0
  323. package/src/graph-runner/graph-run-api.ts +218 -0
  324. package/src/graph-runner/runner.ts +11 -1
  325. package/src/graph-wizard/archetypes.ts +88 -0
  326. package/src/graph-wizard/generate.ts +545 -0
  327. package/src/graph-wizard/saved-steps.ts +120 -0
  328. package/src/graph-wizard/steps.ts +193 -0
  329. package/src/harness/harness-cli-command.ts +482 -59
  330. package/src/harness/harness-queue.ts +315 -25
  331. package/src/harness/harness-salvage-cli.ts +62 -0
  332. package/src/hq/fence-outcomes.ts +63 -0
  333. package/src/hq/fence-wrapper.ts +33 -0
  334. package/src/hq/hq.ts +11 -1
  335. package/src/index.ts +76 -10
  336. package/src/intake-plane/digest.ts +18 -11
  337. package/src/maturity/feature-maturity.ts +4 -3
  338. package/src/nexus/api/draft-metrics.ts +114 -0
  339. package/src/nexus/api/graph-kinds.ts +10 -4
  340. package/src/nexus/api/graph-wizard-api.ts +53 -0
  341. package/src/nexus/api/graphs-api.ts +220 -10
  342. package/src/nexus/api/harness-traversal.ts +205 -0
  343. package/src/nexus/api/http-server.ts +69 -3
  344. package/src/nexus/api/loop-edges.ts +4 -2
  345. package/src/nexus/api/ops-api.ts +22 -7
  346. package/src/nexus/api/ops-board-route.ts +48 -0
  347. package/src/nexus/outbound/router.ts +28 -8
  348. package/src/onboarding/entry-hints.ts +5 -0
  349. package/src/onboarding/first-run.ts +3 -0
  350. package/src/onboarding.ts +24 -6
  351. package/src/ops/overview-collect.ts +345 -0
  352. package/src/ops/overview-seat-era.ts +90 -0
  353. package/src/ops/overview.ts +223 -0
  354. package/src/release-loop/feature-store.ts +14 -11
  355. package/src/release-loop/gate-shards.ts +163 -0
  356. package/src/release-loop/release-schedule.ts +6 -2
  357. package/src/retro/daily.ts +372 -0
  358. package/src/seat-loop/op-decide.ts +173 -0
  359. package/src/seat-loop/seat-loop.ts +60 -3
  360. package/src/seat-loop/seat-report.ts +58 -3
  361. package/src/self-dev/ask-launch-flow.ts +9 -6
  362. package/src/self-dev/ask-launch-io.ts +52 -2
  363. package/src/self-dev/ask-path-candidates.ts +40 -2
  364. package/src/self-dev/draft-sweep.ts +371 -16
  365. package/src/self-dev/draft-triage-rules.ts +19 -4
  366. package/src/self-dev/graph-journey-nodes.ts +157 -0
  367. package/src/self-dev/graph-journey-route.ts +105 -0
  368. package/src/self-dev/launch-preflight.ts +43 -3
  369. package/src/self-dev/pr-preview.ts +84 -16
  370. package/src/self-dev/release-path-guard.ts +7 -4
  371. package/src/self-implement/blocked-draft-policy.ts +101 -0
  372. package/src/self-implement/execution-clarification.ts +11 -0
  373. package/src/self-implement/frozen-merges.ts +23 -0
  374. package/src/self-implement/gate-env-retry.ts +83 -0
  375. package/src/self-implement/goal-author.ts +14 -0
  376. package/src/self-implement/heal-intake.ts +3 -0
  377. package/src/self-implement/orchestrator.ts +234 -6
  378. package/src/self-implement/run-stop.ts +123 -0
  379. package/src/self-implement/run-ttl.ts +258 -0
  380. package/src/self-implement/salvage-retention.ts +123 -0
  381. package/src/self-implement/seams.ts +7 -0
  382. package/src/self-implement/self-implement-cli.ts +2 -0
  383. package/src/self-implement/self-implement-runtime.ts +12 -0
  384. package/src/self-implement/sibling-resync.ts +223 -0
  385. package/src/self-implement/stop-autoheal.ts +204 -0
  386. package/src/session-runtime/index.ts +5 -3
  387. package/src/shell-env-bootstrap.ts +17 -3
  388. package/src/task-agent/board.ts +1 -1
  389. package/src/task-agent/card-evidence.ts +105 -10
  390. package/src/task-agent/judge.ts +7 -0
  391. package/src/task-agent/live-moves.ts +120 -20
  392. package/src/task-agent/mission.ts +1 -1
  393. package/src/task-agent/parent-host.ts +315 -0
  394. package/src/task-agent/shadow.ts +10 -1
  395. package/src/task-agent/task-hand.ts +16 -4
  396. package/src/task-orchestrator/surfaces/pod-command-job.ts +60 -11
  397. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +4 -0
  398. package/src/task-orchestrator/surfaces/pod-gate-deps.ts +123 -0
  399. package/src/task-orchestrator/surfaces/pod-install-slots.ts +89 -0
  400. package/src/task-orchestrator/surfaces/pod-lease.ts +93 -10
  401. package/src/task-orchestrator/surfaces/pod-pool.ts +147 -34
  402. package/src/task-orchestrator/surfaces/self-implement-pod.ts +58 -9
  403. package/src/telegram-commands.ts +41 -0
  404. package/src/testing/real-cli-spawn.ts +106 -0
  405. package/src/tool-runtime/browser-runtime.ts +87 -3
  406. package/src/tool-runtime/index.ts +1 -0
  407. package/src/user-config.ts +76 -7
  408. package/src/version/packed-revision.json +1 -1
  409. package/apps/pwa/out/_next/static/J5H7BvqgSI8DUjtRRcA_S/_buildManifest.js +0 -1
  410. package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +0 -1
  411. package/apps/pwa/out/_next/static/chunks/1157-cba0e8553d35a980.js +0 -1
  412. package/apps/pwa/out/_next/static/chunks/171-23a877ed11720de9.js +0 -1
  413. package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +0 -1
  414. package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +0 -1
  415. package/apps/pwa/out/_next/static/chunks/2336-e830c777eb6bce04.js +0 -1
  416. package/apps/pwa/out/_next/static/chunks/2375-e061bb24cd2b5cde.js +0 -1
  417. package/apps/pwa/out/_next/static/chunks/2415.ed6428ff334c7ce2.js +0 -1
  418. package/apps/pwa/out/_next/static/chunks/3094.67339318c7f72a3a.js +0 -2
  419. package/apps/pwa/out/_next/static/chunks/338-ceb956612dcfaa86.js +0 -1
  420. package/apps/pwa/out/_next/static/chunks/3395-835e4ceaa6335ba4.js +0 -1
  421. package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +0 -5
  422. package/apps/pwa/out/_next/static/chunks/3441-be82e3595aef3a20.js +0 -1
  423. package/apps/pwa/out/_next/static/chunks/3689-89905039bf3e7257.js +0 -1
  424. package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +0 -1
  425. package/apps/pwa/out/_next/static/chunks/3822-6f268bc26c6a84ac.js +0 -1
  426. package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +0 -1
  427. package/apps/pwa/out/_next/static/chunks/4457-d7df81c90f9d0268.js +0 -1
  428. package/apps/pwa/out/_next/static/chunks/4551-77dadae76f6cbace.js +0 -1
  429. package/apps/pwa/out/_next/static/chunks/4978.6fd93b974441e87f.js +0 -1
  430. package/apps/pwa/out/_next/static/chunks/5012-f746f6549b869f91.js +0 -1
  431. package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +0 -1
  432. package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +0 -1
  433. package/apps/pwa/out/_next/static/chunks/62-5bfed1e23790b745.js +0 -1
  434. package/apps/pwa/out/_next/static/chunks/6320-9bc8561fde416e07.js +0 -1
  435. package/apps/pwa/out/_next/static/chunks/649-ca96d1c5d09e02b8.js +0 -1
  436. package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +0 -1
  437. package/apps/pwa/out/_next/static/chunks/6726-85a7db59b288c53f.js +0 -1
  438. package/apps/pwa/out/_next/static/chunks/6735-33267c4630d0d963.js +0 -1
  439. package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +0 -1
  440. package/apps/pwa/out/_next/static/chunks/7633-141682015873beb6.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +0 -1
  443. package/apps/pwa/out/_next/static/chunks/8067-143791231c99bd02.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +0 -1
  445. package/apps/pwa/out/_next/static/chunks/8430-a10cfba8ef282d4e.js +0 -1
  446. package/apps/pwa/out/_next/static/chunks/8870-9614a213b990b10b.js +0 -25
  447. package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/9454-12c2f30dea62291c.js +0 -1
  449. package/apps/pwa/out/_next/static/chunks/976-4a9b4ebdca7c739a.js +0 -1
  450. package/apps/pwa/out/_next/static/chunks/9989-15cdf568bafa9fc8.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/ae787e4c-e5b1ef00b2dbceca.js +0 -1
  452. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +0 -1
  453. package/apps/pwa/out/_next/static/chunks/app/approvals/page-deef5ee191830f14.js +0 -1
  454. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-b193da485f9a14b2.js +0 -1
  455. package/apps/pwa/out/_next/static/chunks/app/board/page-b6e1a79df0e214f4.js +0 -1
  456. package/apps/pwa/out/_next/static/chunks/app/botlab/page-e84df4d907f703c7.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/app/bots/page-a5fb9a5db89ae4ea.js +0 -1
  458. package/apps/pwa/out/_next/static/chunks/app/ceo/page-1499f481d7fc52d6.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/app/chat/page-c7cf753aeb648790.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/app/consult/page-4118469e514e10fd.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/app/control/page-e968f7630654332a.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/app/decisions/page-505915052f947022.js +0 -1
  463. package/apps/pwa/out/_next/static/chunks/app/design-check/page-c2f962fb4a3b06c6.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/app/editor/page-7b5ed0bd8a589ec4.js +0 -1
  465. package/apps/pwa/out/_next/static/chunks/app/exec/page-cf8193250dd42dd4.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/app/field/page-cf3f5dfa35dea8e9.js +0 -1
  467. package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +0 -1
  468. package/apps/pwa/out/_next/static/chunks/app/inside/page-5b29d9b06ceadade.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/app/intake/page-a15e7fcc283e9ca7.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/app/layout-d2915e7b70ff3d0e.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/app/loops/page-2595f0eba29f57e1.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/app/market/page-c776322454156e36.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-77bbd17f4435aa10.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/app/morning/page-049689e611ecc936.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/app/not-found-85954a4fb09c44eb.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/app/observatory/page-e773e552e1068ee6.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5633c4bfa7684b4a.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d829b92bd01b4994.js +0 -1
  479. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-061c317fc771becf.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3a45ece8865ed4b6.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/app/page-0be990618c0d56bd.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/app/reflection/page-bfea4865dc244b73.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-0d6ba8e337741484.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/app/sessions/page-76a88b55d816482e.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-bba1542df59f61ce.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/app/settings/page-4185c95689bb372e.js +0 -1
  487. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-b699e1a8d5d34b8b.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/app/setup/page-c225e338c31bf274.js +0 -1
  490. package/apps/pwa/out/_next/static/chunks/app/share/page-449353f70507ca1f.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/app/showroom/page-90b889714102476d.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f1ee7fbeb7f96ddc.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/app/term/page-d59a95e1434dfaa0.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/app/today/page-71491a23414d1a47.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/app/trace/page-de7112bdb65fa4fe.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/app/vault/page-feb4d0d88079660d.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-f17d887b40dd6b1d.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/app/workflows/page-8da77be2192bcd5d.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/app/workspace/page-72c3b9a5e9582b29.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c3afe4c8d0c48c39.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/main-app-b9308f2d8a931531.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/webpack-6f35f9d892fa630b.js +0 -1
  507. package/apps/pwa/out/_next/static/css/85f53c6f35d11382.css +0 -1
  508. /package/apps/pwa/out/_next/static/{J5H7BvqgSI8DUjtRRcA_S → MObU8ujkMciAKr6ljAV05}/_ssgManifest.js +0 -0
  509. /package/skills/project-onboarding/{skill.md → SKILL.md} +0 -0
@@ -64,12 +64,16 @@ import { GoalRunStore, insertGoalRunRecord, type GoalPriorRuns } from './goal-ru
64
64
  import { writeGoalRunRecordFragment } from './goal-execution-records.js';
65
65
  import { getUserConfig } from '../user-config.js';
66
66
  import { appendRunLedgerEntry, loadRunLedger, parseRunShardIdentity, queryRunChain, type RunChainShardSibling, type RunLedgerEntry, type RunLedgerWriter, type RunOriginData, type RunShardIdentity } from './run-ledger.js';
67
+ import { classifyMergeHoldStop, forgetRunStop, readRunStopRecord, recordRunStop, runStopRecorded } from './run-stop.js';
68
+ import { autohealFromStop, parseAutohealMode, type AutohealActions, type AutohealResult } from './stop-autoheal.js';
67
69
  import { emitSessionEvent, type SessionEventInput } from '../context-bus/session-events.js';
68
70
  import { decideLineageSupersede, lineageSupersedeCloseComment, type LineageSupersedeOpenDraft } from './lineage-supersede.js';
69
71
  import { basename, isAbsolute, join, relative, resolve, sep } from 'node:path';
70
72
  import { homedir } from 'node:os';
71
73
  import { enqueueControlMemo, readSoftStopRequestStatus, type SoftStopRequestRead } from '../harness/control-inbox.js';
72
74
  import { debug } from '../debug/log.js';
75
+ import { enterJourneyNode, exitJourneyNode, journeyJoinFields, withJourneyNode } from '../self-dev/graph-journey-nodes.js';
76
+ import { classifyGateEnvDeficit, DEFAULT_GATE_ENV_RETRY, GATE_ENV_DEFICIT_HARVESTABLE_MARK, type GateEnvDeficitKind } from './gate-env-retry.js';
73
77
  import { recordFailureEvent } from './heal-intake.js';
74
78
  import { classifyReworkCapExhaustion, type ReworkCapHealDecision } from './heal-triage.js';
75
79
  import { releasePathHold, releasePathHoldComment, RELEASE_PATH_LABEL } from '../self-dev/release-path-guard.js';
@@ -210,7 +214,7 @@ import { hasModuleLoadFailure, type GateTestFailure } from './gate-baseline.js';
210
214
  import { commitWorktree, defaultBranchRef, preservationHasChanges } from './seams.js';
211
215
  import { detectUncommittedWork } from './uncommitted-work.js';
212
216
  import { spawnSync } from 'node:child_process';
213
- import { blockedDraftDisposition } from './blocked-draft-policy.js';
217
+ import { blockedDraftDisposition, decideDraftOnStop, nextMoveFor, parseDraftOnStopMode, salvageBranchForRun, type DraftOnStopMode } from './blocked-draft-policy.js';
214
218
  import { formatLlmMergeOutcome } from '../autopilot/build/llm-conflict-merge.js';
215
219
  import { FOUND_CITED_PATH_REFUTATION_QUOTE, MISSING_CITED_PATH_REFUTATION_QUOTE, MUST_FIX_REFUTATION_ACKNOWLEDGEMENT_WITH_REASON, REFUTATION_QUOTE_GRAMMAR, observeMustFixCitedPaths, parseMustFixRefutationAcknowledgement, parseMustFixRefutations, renderMustFixCitedPathFacts, snapshotMustFixFindings, stableMustFixId, type ReflectEvidenceFacts, type ReflectGateFacts, type MustFixCitedPathFact, type MustFixFinding, type MustFixRecurrenceHistory, type MustFixRefutation, type MustFixRefutationKind } from './reflect-mustfix.js';
216
220
  import type { IngestionEntry } from '../agent-substrate/execution/ingestion-policy.js';
@@ -762,7 +766,8 @@ function changedFileIsInsideDeclaredTarget(changedFile: string, declaredPath: st
762
766
  const file = normalizeDeclaredScopePath(changedFile);
763
767
  const target = normalizeDeclaredScopePath(declaredPath);
764
768
  if (!file || !target) return false;
765
- return file === target || file.startsWith(`${target}/`);
769
+ return file === target || file.startsWith(`${target}/`)
770
+ || (target.endsWith('.ts') && !target.endsWith('.test.ts') && file === `${target.slice(0, -3)}.test.ts`);
766
771
  }
767
772
 
768
773
  function parseDeclaredTargetPathsFromAsk(askText: string): { readable: boolean; paths: readonly string[] } {
@@ -930,6 +935,12 @@ export type ImplementTerminalStatus = {
930
935
  export interface SelfImplementSeams {
931
936
  /** Run-observer ledger sink. Tests inject an in-memory sink to avoid touching user state. */
932
937
  writeRunLedger?: RunLedgerWriter;
938
+ /** STOP-AUTOHEAL — heal action seams (live mode only runs actions given here; missing = needs-owner). */
939
+ stopAutohealActions?: AutohealActions;
940
+ /** STOP-AUTOHEAL — one-attempt guard reader. Default: real run ledger, or none when `writeRunLedger` is injected. */
941
+ stopAutohealLoadLedger?: (runId: string) => readonly RunLedgerEntry[] | null;
942
+ /** STOP-AUTOHEAL — observes each dispatcher result (tests). */
943
+ onStopAutoheal?: (result: AutohealResult) => void;
933
944
  /** Optional context-journal sink for isolated runs. */
934
945
  emitContextEvent?: (input: SessionEventInput) => void;
935
946
  /** Registers this run as an ephemeral loop-agent asset; failures are observed but never affect execution. */
@@ -965,6 +976,8 @@ export interface SelfImplementSeams {
965
976
  readSoftStopRequestStatus?: (spaceId: string) => SoftStopRequestRead;
966
977
  /** Parent harness space whose durable stop marker is read. Tests inject this; production uses `getHarnessSpace()`. */
967
978
  parentSoftStopSpaceId?: string;
979
+ /** Real, created worktree's soft-stop target; observation only, never guesses a space. */
980
+ onSoftStopSpaceReady?: (spaceId: string) => void;
968
981
  /** disposable worktree 생성 → 경로·브랜치 ⊕ **어디서 갈랐나**(관측용).
969
982
  * ⚠️ 관측 3필드는 **선택**이다 — 시임은 주입점이고, 테스트 더블에게 git SHA 를 지어내라고
970
983
  * 요구하면 계약이 아니라 부담이 된다. 실 시임(`defaultSeams`)은 항상 채운다.
@@ -1028,6 +1041,11 @@ export interface SelfImplementSeams {
1028
1041
  reviewBaselineObservationSource?: (cwd: string, base: string) => Promise<string | undefined>;
1029
1042
  /** ④ gate — cwd 에서 bun test/build. postsync=정합 후 재게이트(merge-base 실행 범위). */
1030
1043
  gate: (cwd: string, ctx?: { runId?: string; mode?: 'postsync'; round?: number }) => Promise<SelfImplementGateResult>;
1044
+ /**
1045
+ * GATE-ENV-RETRY — 환경 결손 gate 실패에 «게이트만» 다시 도는 정책. 생략 시 기본(2회 · 20초).
1046
+ * `attempts: 0` 이면 재시도하지 않는다. 시험은 `sleep` 으로 대기를 주입한다.
1047
+ */
1048
+ gateEnvRetry?: { attempts?: number; delayMs?: number; sleep?: (ms: number) => Promise<void> };
1031
1049
  /** Gate가 실행된 worktree HEAD가 local origin/main보다 뒤처진 커밋 수. 실패는 undefined(unknown)로 정직하게 남긴다. */
1032
1050
  gateWorktreeBehindMain?: (cwd: string) => Promise<number | undefined>;
1033
1051
  /** 변경 파일 목록 — 게이트 «라우터»가 「코드가 바뀌었나」를 판정하는 입력.
@@ -1068,6 +1086,8 @@ export interface SelfImplementSeams {
1068
1086
  headCommit?: (cwd: string) => string | undefined;
1069
1087
  /** `commit` pins the pushed state; without it the worktree HEAD is pushed. */
1070
1088
  preserveBlockedBranch?: (ctx: { cwd: string; branch: string; title: string; commit?: string }) => boolean | Promise<boolean>;
1089
+ /** DRAFT-NOT-ARCHIVE — `tools.selfImplement.draftOnStop` 읽기 seam. 생략하면 user-config(실패·부재 = 'always' · 종전). */
1090
+ draftOnStopMode?: () => DraftOnStopMode;
1071
1091
  /** Hard-cap salvage evidence: a clean worktree and commits ahead of origin/main. */
1072
1092
  readReworkSalvageEvidence?: (cwd: string) => Promise<ReworkSalvageEvidence>;
1073
1093
  /** Starts exactly one detached `elanous dev --file <goal> --base <branch>` follow-up. */
@@ -1092,6 +1112,8 @@ export interface SelfImplementSeams {
1092
1112
  mergePr?: (opts: { number: number; cwd: string; matchHeadCommit?: string }) => Promise<{ merged: boolean; baseRefName?: string; mergeCommit?: string; detail?: string }>;
1093
1113
  /** Only successful merges trigger this injected, fail-closed draft inventory and mutation seam. */
1094
1114
  supersedeDraftsOnMerge?: (number: number, cwd: string) => Promise<void>;
1115
+ /** SIBLING-RESYNC-ON-MERGE — after a successful merge, tell open sibling PRs on the same paths to rebase + regate now. Failure is observation-only. */
1116
+ resyncSiblingsOnMerge?: (number: number, cwd: string) => Promise<void>;
1095
1117
  /** Post-merge cleanup is opt-in and injectable so tests never touch the filesystem. */
1096
1118
  postMergeCleanup?: {
1097
1119
  enabled: boolean;
@@ -3479,6 +3501,28 @@ function runOriginData(env: NodeJS.ProcessEnv = process.env): RunOriginData {
3479
3501
  };
3480
3502
  }
3481
3503
 
3504
+ /**
3505
+ * STOP-AUTOHEAL — a recorded stop goes straight to the dispatcher (shadow by default:
3506
+ * `tools.selfImplement.autoheal.mode`). Never throws and never changes the run outcome.
3507
+ */
3508
+ async function autohealRecordedStop(stopEntry: RunLedgerEntry, s: SelfImplementSeams | undefined): Promise<void> {
3509
+ try {
3510
+ const record = readRunStopRecord(stopEntry);
3511
+ if (!record) return;
3512
+ const mode = parseAutohealMode((await import('../user-config.js')).getUserConfig().tools.selfImplement.autoheal?.mode);
3513
+ const loadLedger = s?.stopAutohealLoadLedger ?? (s?.writeRunLedger ? () => null : undefined);
3514
+ const result = await autohealFromStop({ runId: stopEntry.runId, ...(stopEntry.goalId ? { goalId: stopEntry.goalId } : {}), record }, {
3515
+ mode,
3516
+ ...(s?.stopAutohealActions ? { actions: s.stopAutohealActions } : {}),
3517
+ ...(loadLedger ? { loadLedger } : {}),
3518
+ ...(s?.writeRunLedger ? { writeLedger: s.writeRunLedger } : {}),
3519
+ });
3520
+ s?.onStopAutoheal?.(result);
3521
+ } catch (error) {
3522
+ try { debug.log('self-implement.autoheal', 'dispatch-failed', { runId: stopEntry.runId, error: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
3523
+ }
3524
+ }
3525
+
3482
3526
  export async function runSelfImplement(opts: SelfImplementOptions): Promise<SelfImplementResult> {
3483
3527
  if (opts.childLlm && (typeof opts.childLlm.provider !== 'string' || !opts.childLlm.provider.trim() || typeof opts.childLlm.model !== 'string' || !opts.childLlm.model.trim())) {
3484
3528
  throw new Error('childLlm.provider and childLlm.model must both be non-empty');
@@ -3500,6 +3544,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
3500
3544
  const attemptOrdinal = incrementRunAttemptOrdinal(runId);
3501
3545
  const shardIdentity = parseRunShardIdentity(opts.feature);
3502
3546
  const observeOuter = makeRunObserver(runId, opts.goalId, debug.log.bind(debug), opts.seams.writeRunLedger, shardIdentity);
3547
+ forgetRunStop(runId); // STOP-RECORD: one stop per run «attempt» — a rerun with the same id may record again
3503
3548
  try {
3504
3549
  // 10-05 PODPROVIDER: record which child provider this run uses — «default» when the launch named none.
3505
3550
  const launch = opts.launch ?? resolveLaunchStamp();
@@ -3763,6 +3808,8 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
3763
3808
  const attemptOrdinal = readRunAttemptOrdinal(runId);
3764
3809
  const identified = {
3765
3810
  ...graphIdentity,
3811
+ // HARNESS-FULL-GRAPH — 앞단 여정 걸음(runId 없음)과 이 런의 걸음을 잇는 조인 키.
3812
+ ...journeyJoinFields(),
3766
3813
  ...data,
3767
3814
  attemptOrdinal,
3768
3815
  };
@@ -4108,6 +4155,21 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
4108
4155
  observeOuter('credential-failure-observed', { count: credentialFailureCount, ...lastCredentialFailure });
4109
4156
  }
4110
4157
  terminalResult = withEvidenceCoverage(addressedResult);
4158
+ // runSelfImplement is the terminal caller: retain every existing PR/ledger/log observation and append one stop fact.
4159
+ if ((addressedResult.stage === 'aborted' || (addressedResult.mergeReason && addressedResult.mergeReason !== 'auto')) && !runStopRecorded(runId)) {
4160
+ const reason = addressedResult.mergeReason;
4161
+ const aborted = addressedResult.stage === 'aborted';
4162
+ let stopEntry: RunLedgerEntry | undefined;
4163
+ try {
4164
+ stopEntry = recordRunStop({ runId, ...(opts.goalId ? { goalId: opts.goalId } : {}), shardIdentity,
4165
+ site: aborted ? 'implement-aborted' : 'merge-hold',
4166
+ class: aborted ? 'unclassified' : classifyMergeHoldStop(reason), cause: aborted ? 'implement aborted' : `merge held: ${reason}`,
4167
+ evidenceRef: addressedResult.prUrl ?? `run-ledger:${runId}:${aborted ? 'implemented' : 'merge-decision'}`,
4168
+ nextMove: aborted ? 'Inspect preserved worktree and child summary' : 'Review merge decision and PR before landing',
4169
+ }, opts.seams.writeRunLedger ?? appendRunLedgerEntry);
4170
+ } catch { /* stop observation cannot change the run outcome */ }
4171
+ if (stopEntry) await autohealRecordedStop(stopEntry, opts.seams);
4172
+ }
4111
4173
  observeDeclaredScopeDiff(observeOuter, {
4112
4174
  goalFile: opts.goalFile,
4113
4175
  changedFiles: opts.goalFile && addressedResult.worktreePath
@@ -4962,6 +5024,9 @@ async function runSelfImplementInner(
4962
5024
  // 그래서 getHarnessSpace() 만 보면 운영에서 늘 undefined 이고 정지 확인이 «한 번도» 안 돈다(#20040 착지 직후 실측).
4963
5025
  // `self send <space> --stop` 이 겨냥하는 것은 자식의 공간 = 워크트리 이름이다(아래 activeChildInboxId 와 같은 식 · dev-cli.ts recordRestart 폴백과 같다).
4964
5026
  const parentSoftStopSpaceId = s.parentSoftStopSpaceId || getHarnessSpace()?.id || normalizeSpaceId(basename(wt.path)) || undefined;
5027
+ if (parentSoftStopSpaceId) {
5028
+ try { s.onSoftStopSpaceReady?.(parentSoftStopSpaceId); } catch { /* UI registration must not break execution */ }
5029
+ }
4965
5030
  const readParentSoftStop = s.readSoftStopRequestStatus ?? readSoftStopRequestStatus;
4966
5031
  const honorParentSoftStop = (
4967
5032
  beforeNode: 'gate' | 'review' | 'rework' | 'open-pr',
@@ -5134,6 +5199,8 @@ async function runSelfImplementInner(
5134
5199
  limitationCount: number;
5135
5200
  } | undefined;
5136
5201
  let gate!: SelfImplementGateResult;
5202
+ /** GATE-ENV-RETRY: 재시도 뒤에도 남은 환경 결손의 종류. 정의되면 이 라운드의 gate 실패는 «수확 대기»로 끝난다. */
5203
+ let gateEnvDeficitKind: GateEnvDeficitKind | undefined;
5137
5204
  let review: SelfImplementReview | undefined;
5138
5205
  /** Review-budget leftovers and the body that carried them, so a later merge drafts from the same text. */
5139
5206
  let preparedReviewBudgetPrBody: string | undefined;
@@ -5556,6 +5623,15 @@ async function runSelfImplementInner(
5556
5623
  });
5557
5624
  };
5558
5625
  const podReviewBlockedDraft = process.env.ELANOUS_SUBSTRATE === 'pod';
5626
+ /** DRAFT-NOT-ARCHIVE: 멈춤 산출을 PR 대신 수확 가지로 보냈으면 그 가지 — hard-cap 재발사의 base 가 된다. */
5627
+ let salvagedStopBranch: string | undefined;
5628
+ const readDraftOnStopMode = (): DraftOnStopMode => {
5629
+ try {
5630
+ return s.draftOnStopMode ? s.draftOnStopMode() : parseDraftOnStopMode(getUserConfig().tools?.selfImplement?.draftOnStop).mode;
5631
+ } catch {
5632
+ return 'always';
5633
+ }
5634
+ };
5559
5635
  let blockedDraftNoChanges = false;
5560
5636
  let blockedDraftPrFailure: string | undefined;
5561
5637
  const reviewBlockedResult = (pr: { url: string; number: number } | undefined) => ({
@@ -5768,6 +5844,72 @@ async function runSelfImplementInner(
5768
5844
  progress(stage, '보존할 변경이 없어 draft PR을 열지 않음');
5769
5845
  return undefined;
5770
5846
  }
5847
+ // DRAFT-NOT-ARCHIVE (RFC R1): harvestable 멈춤은 draft PR 대신 수확 가지 ⊕ 런 원장(사유·다음 수).
5848
+ // ⛔ Pod review-blocked 는 결과 stage 가 PR 유무로 갈리므로 이 조각에서는 건드리지 않는다.
5849
+ const draftOnStopMode = readDraftOnStopMode();
5850
+ let launchSeat: string | undefined;
5851
+ try { launchSeat = (opts.launch ?? resolveLaunchStamp()).actor; } catch { launchSeat = undefined; }
5852
+ const draftOnStop = decideDraftOnStop({ mode: draftOnStopMode, classification: classificationRecord.classification, seat: launchSeat });
5853
+ const stopCard = {
5854
+ stage,
5855
+ mode: draftOnStop.mode,
5856
+ stopClass: draftOnStop.stopClass,
5857
+ classification: classificationRecord.classification,
5858
+ reason: reason.slice(0, 240),
5859
+ nextMove: nextMoveFor(classificationRecord.classification),
5860
+ branch: wt.branch,
5861
+ };
5862
+ if (draftOnStop.action === 'salvage-branch' && !(stage === 'review-blocked' && podReviewBlockedDraft)) {
5863
+ const salvageBranch = salvageBranchForRun(runId, wt.branch);
5864
+ let artifactPath: string | undefined;
5865
+ let artifactError: string | undefined;
5866
+ try {
5867
+ artifactPath = persistFullPrBody(s.persistPrBodyArtifact, {
5868
+ origin: 'self-implement-draft-not-archive',
5869
+ body: assembled.body,
5870
+ originalChars: assembled.originalChars,
5871
+ });
5872
+ } catch (persistenceError) {
5873
+ artifactError = persistenceError instanceof Error ? persistenceError.message : String(persistenceError);
5874
+ }
5875
+ let salvageError: string | undefined;
5876
+ try {
5877
+ if (s.preserveBlockedBranch) {
5878
+ if (!await s.preserveBlockedBranch({ cwd: wt.path, branch: salvageBranch, title: prTitle(opts.feature) })) throw new Error('수확 가지 push가 성공하지 않았음');
5879
+ } else {
5880
+ if (!existsSync(wt.path)) throw new Error(`worktree not found: ${wt.path}`);
5881
+ const commit = commitWorktree(wt.path, prTitle(opts.feature));
5882
+ if (!commit.ok && !/nothing to commit/.test(commit.out)) throw new Error(`로컬 커밋 실패: ${commit.out}`);
5883
+ const push = runGitCommand(wt.path, ['push', 'origin', `HEAD:refs/heads/${salvageBranch}`]);
5884
+ if (push.status !== 0) throw new Error(push.stderr || push.stdout || 'git push failed');
5885
+ }
5886
+ } catch (error) {
5887
+ salvageError = safeErrorDescription(error);
5888
+ }
5889
+ const artifactFields = { ...(artifactPath ? { prBodyArtifactPath: artifactPath } : {}), ...(artifactError ? { prBodyArtifactError: artifactError } : {}) };
5890
+ if (salvageError === undefined) {
5891
+ salvagedStopBranch = salvageBranch;
5892
+ observe('salvaged', { ...stopCard, salvageBranch, ...artifactFields }, { category: 'self-implement.draft-not-archive' });
5893
+ observe('rework-blocked-draft-pr', { ...observation, skipped: 'draft-not-archive', salvageBranch, nextMove: stopCard.nextMove, ...artifactFields });
5894
+ progress(stage, `멈춤 — draft PR 없이 수확 가지로 보존: ${salvageBranch} · 사유: ${stopCard.reason.slice(0, 160)} · 다음 수: ${stopCard.nextMove}${artifactPath ? ` · 판정 본문: ${artifactPath}` : ''}`);
5895
+ return undefined;
5896
+ }
5897
+ // 수확 가지를 못 남기면 산출을 잃지 않도록 종전대로 draft PR 로 간다.
5898
+ observe('salvage-failed', { ...stopCard, salvageBranch, error: salvageError, fallback: 'open-draft', ...artifactFields }, { category: 'self-implement.draft-not-archive', level: 'warn' });
5899
+ } else if (draftOnStop.mode === 'needs-owner-only') {
5900
+ const ownerLabel = draftOnStop.action === 'open-draft' ? draftOnStop.ownerLabel : undefined;
5901
+ // 자리를 모르면 «모름»으로 남긴다(⛔ OP 로 추측하지 않는다).
5902
+ observe(draftOnStop.stopClass === 'landable' ? 'landable-draft' : 'needs-owner-draft', { ...stopCard, ownerSeat: ownerLabel ? ownerLabel.slice('elanous:seat-'.length) : 'unknown', ...(ownerLabel ? { ownerLabel } : {}) }, { category: 'self-implement.draft-not-archive' });
5903
+ }
5904
+ // 'always' 는 종전 라벨 그대로 · needs-owner-only 의 needs-owner 는 `elanous:needs-owner` ⊕ (아는 경우만) 자리 라벨.
5905
+ // landable(승인된 산출)은 자리 라벨만 — 다음 수가 `pr land` 라 needs-owner 가 아니다.
5906
+ const needsOwnerDraft = draftOnStop.mode === 'needs-owner-only' && draftOnStop.stopClass === 'needs-owner';
5907
+ const seatLabelled = draftOnStop.mode === 'needs-owner-only' && draftOnStop.stopClass !== 'harvestable';
5908
+ const draftLabels = [
5909
+ ...(stage === 'review-blocked' ? ['review-blocked'] : []),
5910
+ ...(seatLabelled && draftOnStop.action === 'open-draft' && draftOnStop.ownerLabel ? [draftOnStop.ownerLabel] : []),
5911
+ ...(needsOwnerDraft ? ['elanous:needs-owner'] : []),
5912
+ ];
5771
5913
  // Pod review-blocked: a failed commit or PR still pushes the branch, and the result detail says what survived.
5772
5914
  const preserveReviewBlockedBranch = async (cause: string, commitFirst: boolean, suffix = ''): Promise<undefined> => {
5773
5915
  let pushed = false;
@@ -5817,7 +5959,7 @@ async function runSelfImplementInner(
5817
5959
  head: wt.branch,
5818
5960
  ...(opts.base ? { base: opts.base } : {}),
5819
5961
  draft: true,
5820
- ...(stage === 'review-blocked' ? { labels: ['review-blocked'] } : {}),
5962
+ ...(draftLabels.length > 0 ? { labels: draftLabels } : {}),
5821
5963
  cwd: wt.path,
5822
5964
  }), T.pr, 'pr');
5823
5965
  } catch (error) {
@@ -5839,6 +5981,17 @@ async function runSelfImplementInner(
5839
5981
  ...(artifactPath ? { prBodyArtifactPath: artifactPath } : {}),
5840
5982
  ...(artifactError ? { prBodyArtifactError: artifactError } : {}),
5841
5983
  }, { level: 'warn' });
5984
+ // STOP-RECORD: a failed blocked-draft PR open (e.g. same-branch rerun with a PR already open) left no stop reason.
5985
+ let draftStopEntry: RunLedgerEntry | undefined;
5986
+ try {
5987
+ const prExists = /already exists|pull request for branch/i.test(prError);
5988
+ draftStopEntry = recordRunStop({ runId, ...(opts.goalId ? { goalId: opts.goalId } : {}), site: 'draft-pr-open-failed', class: 'unclassified',
5989
+ cause: prExists ? 'draft PR open failed: a PR already exists for this branch' : `draft PR open failed: ${prError}`,
5990
+ evidenceRef: artifactPath ?? `branch:${wt.branch}`,
5991
+ nextMove: prExists ? '기존 PR 갱신 (update the existing PR for this branch)' : 'Retry draft PR open from the preserved branch',
5992
+ }, s.writeRunLedger ?? appendRunLedgerEntry);
5993
+ } catch { /* stop observation cannot change the run outcome */ }
5994
+ if (draftStopEntry) await autohealRecordedStop(draftStopEntry, s);
5842
5995
  if (stage === 'review-blocked' && podReviewBlockedDraft) {
5843
5996
  return preserveReviewBlockedBranch(`draft PR 생성 실패: ${prError}`, true,
5844
5997
  `; ${artifactPath ? `판정 본문: ${artifactPath}` : `판정 본문 보존 실패: ${artifactError ?? 'unknown error'}`}`);
@@ -5873,6 +6026,13 @@ async function runSelfImplementInner(
5873
6026
  observe('pr.comment.seam-missing', { number: pr.number, salvageAction: action }, { level: 'warn' });
5874
6027
  return;
5875
6028
  }
6029
+ // QUIET-PR-COMMENTS: a parked outcome is history of this run, not a new notification — fold it into the
6030
+ // single edited status comment (an edit mails nobody). Without the status seams it stays a separate comment.
6031
+ if (s.findPrComment && s.editPrComment) {
6032
+ bufferPrComment(round, 'author', `Rework salvage status: ${action}.`, reason ? [`reason: ${reason}`] : []);
6033
+ await flushPrComments(pr);
6034
+ return;
6035
+ }
5876
6036
  const body = [
5877
6037
  formatPrComment({ role: 'author', round, run: runId }),
5878
6038
  `Rework salvage status: ${action}.`,
@@ -6046,7 +6206,7 @@ async function runSelfImplementInner(
6046
6206
  observe('rework-salvage', { action: 'launching', ...launchObservation });
6047
6207
  try {
6048
6208
  if (!s.launchReworkSalvage) throw new Error('launch seam unavailable');
6049
- await s.launchReworkSalvage({ goalFile: opts.goalFile!, base: wt.branch, salvageAttempt: (opts.salvageAttempt ?? 0) + 1 });
6209
+ await s.launchReworkSalvage({ goalFile: opts.goalFile!, base: salvagedStopBranch ?? wt.branch, salvageAttempt: (opts.salvageAttempt ?? 0) + 1 });
6050
6210
  observe('rework-salvage', { action: 'launched', ...launchObservation });
6051
6211
  await postSalvageStatus(pr, 'launched', environmentReason ?? (hardCapBlockedExtend ? 'hard-cap-extend' : undefined));
6052
6212
  return 'launched';
@@ -6843,7 +7003,7 @@ async function runSelfImplementInner(
6843
7003
  { label: 'Stay in scope', description: 'Do not accept out-of-scope changes.', recommended: true },
6844
7004
  { label: 'Expand scope', description: 'Accept the changed files outside the target paths.' },
6845
7005
  ],
6846
- }, { runId }, { writeRunLedger: s.writeRunLedger });
7006
+ }, { runId, outsideFiles: scope.outsideNames, outsideCount: scope.outsideCount, declaredPaths: declaredPathsFromGoalDocumentText(goalDocument!).paths }, { writeRunLedger: s.writeRunLedger });
6847
7007
  if ('parked' in result || 'deferred' in result || result.choice !== 'Expand scope') {
6848
7008
  finalizeSupervisorDeliveries('execution-scope-not-approved');
6849
7009
  observe('execution-scope-held', { outsideCount: scope.outsideCount, disposition: 'parked' in result ? 'parked' : 'in-scope-only' });
@@ -6875,6 +7035,31 @@ async function runSelfImplementInner(
6875
7035
  }
6876
7036
  onNodeEntry(node('gate'), round);
6877
7037
  gate = await stepTimeout(s.gate(wt.path, { runId, round }), T.gate, 'gate');
7038
+ // ⭐ GATE-ENV-RETRY — 「잰 쪽」이 넘어진 실패(시험 결과 미수신·index.lock·OOM·측정 불가·네트워크)는
7039
+ // 구현을 버리지 않고 짧게 쉰 뒤 gate «만» 다시 돈다. ⛔ 도입 실패·자식 책임은 판정자가 거짓을 낸다.
7040
+ gateEnvDeficitKind = undefined;
7041
+ let envVerdict = classifyGateEnvDeficit(gate);
7042
+ const envRetryAttempts = Math.max(0, s.gateEnvRetry?.attempts ?? DEFAULT_GATE_ENV_RETRY.attempts);
7043
+ const envRetryDelayMs = Math.max(0, s.gateEnvRetry?.delayMs ?? DEFAULT_GATE_ENV_RETRY.delayMs);
7044
+ const envRetrySleep = s.gateEnvRetry?.sleep ?? ((ms: number) => new Promise<void>((done) => setTimeout(done, ms)));
7045
+ for (let attempt = 1; envVerdict.envDeficit && attempt <= envRetryAttempts; attempt++) {
7046
+ const kind = envVerdict.kind;
7047
+ debug.log('self-implement.gate-env-retry', 'retry-scheduled', { runId, round, attempt, attempts: envRetryAttempts, kind, delayMs: envRetryDelayMs });
7048
+ observe('gate-env-retry', { round, attempt, attempts: envRetryAttempts, kind, delayMs: envRetryDelayMs }, { level: 'warn' });
7049
+ progress('gating', `gate 환경 결손(${kind}) — 구현 유지 · ${Math.round(envRetryDelayMs / 1000)}초 뒤 gate 만 재측정 (${attempt}/${envRetryAttempts})`);
7050
+ await envRetrySleep(envRetryDelayMs);
7051
+ gate = await stepTimeout(s.gate(wt.path, { runId, round }), T.gate, 'gate');
7052
+ envVerdict = classifyGateEnvDeficit(gate);
7053
+ debug.log('self-implement.gate-env-retry', 'retry-result', {
7054
+ runId, round, attempt, kind, passed: gate.passed,
7055
+ stillEnvDeficit: envVerdict.envDeficit,
7056
+ ...(envVerdict.envDeficit ? { nextKind: envVerdict.kind } : { verdict: envVerdict.reason }),
7057
+ });
7058
+ }
7059
+ if (envVerdict.envDeficit) {
7060
+ gateEnvDeficitKind = envVerdict.kind;
7061
+ debug.log('self-implement.gate-env-retry', 'exhausted', { runId, round, attempts: envRetryAttempts, kind: envVerdict.kind });
7062
+ }
6878
7063
  } else {
6879
7064
  observe('gate-skipped-by-graph', { ...graphAuthorityFields(graphAuthority, graphTemplate), round, reason: gateRoute.reason, changedFileCount: gateRouteFiles?.length ?? null });
6880
7065
  gate = {
@@ -6961,6 +7146,26 @@ async function runSelfImplementInner(
6961
7146
  // 타임아웃«뿐» — 도입 0 · 미분류 0 · 자식 책임 없음. 재작업으로 보내지 않고 리뷰로 진행한다.
6962
7147
  // 게이트를 통과로 접지하지 않는다(allowsBaselineOnlyFailure 는 그대로 timedOut===0 을 요구).
6963
7148
  // 이 런의 병합은 뒤에서 GATE_TIMEOUT_UNMEASURED_MERGE_REASON 으로 hitl 에 고정한다.
7149
+ if (gateEnvDeficitKind !== undefined) {
7150
+ // ⭐ GATE-ENV-RETRY — 재측정 뒤에도 환경 결손이면 구현을 «버리지 않는다».
7151
+ // 브랜치·draft PR 을 남기고 `harvestable` 로 끝낸다(재작업은 이 신호를 못 바꾼다).
7152
+ const envKind = gateEnvDeficitKind;
7153
+ finalizeSupervisorDeliveries('gate-env-deficit-harvestable');
7154
+ const reason = `gate failed on an environment deficit (${envKind}) after gate-only retries; ${GATE_ENV_DEFICIT_HARVESTABLE_MARK} — implementation kept without rework`;
7155
+ bufferPrComment(round, 'reviewer', `Round ${round}: ${reason}.`, [
7156
+ `Gate: ${gate.log?.trim() || '(gate log unavailable)'}`,
7157
+ ]);
7158
+ observe('gate-env-deficit-harvestable', {
7159
+ round, kind: envKind,
7160
+ ...(facts ? { introduced: facts.introduced, preexisting: facts.preexisting, unknown: facts.unknown } : {}),
7161
+ ...(facts?.unknownReason !== undefined ? { unknownReason: facts.unknownReason } : {}),
7162
+ reason,
7163
+ }, { level: 'warn' });
7164
+ debug.log('self-implement.gate-env-retry', 'harvestable', { runId, round, kind: envKind, branch: wt.branch });
7165
+ progress('gate-failed', `중단 — 환경 결손(${envKind})이 재측정 뒤에도 남음 · 구현 유지 · 수확 대기`);
7166
+ const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', reason, gate, salvageStatusExpected: false });
7167
+ return { ok: false, stage: 'gate-failed', node: 'rework', ...resolveRunOutcome({ termination: 'abandoned' }), harvestable: true, sessionId, worktreePath: wt.path, branch: wt.branch, gate, quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: reason };
7168
+ }
6964
7169
  if (isTimeoutOnlyUnmeasuredGate(facts)) {
6965
7170
  observe('gate-timeout-only-continued-to-review', {
6966
7171
  round,
@@ -7537,6 +7742,16 @@ async function runSelfImplementInner(
7537
7742
  sync.status,
7538
7743
  );
7539
7744
  observe('gate.postsync', postSyncGateObservation(regate, wt.branch, hasModuleLoadFailure, sync.status));
7745
+ // MERGE-INTENT-RESOLVE — join the resolver's sibling-intent decisions with the regate verdict (OP metric).
7746
+ if (sync.intentResolve?.length) {
7747
+ debug.log('self-implement.main-sync', 'intent-resolve', {
7748
+ phase: 'regate', runId, branch: wt.branch, mergeTarget,
7749
+ adopted: [...new Set(sync.intentResolve.map((entry) => entry.adopted))],
7750
+ siblingIntentAdopted: sync.intentResolve.some((entry) => entry.adopted === 'sibling-intent'),
7751
+ files: sync.intentResolve,
7752
+ regatePassed: regate.passed,
7753
+ });
7754
+ }
7540
7755
  if (timeoutOnlyPostSync) {
7541
7756
  const facts = regate.reflectGateFacts!;
7542
7757
  observe('post-sync-gate-timeout-only-continued', {
@@ -7860,6 +8075,12 @@ async function runSelfImplementInner(
7860
8075
  } catch (error) {
7861
8076
  observe('draft-supersede-on-merge-failed', { number: pr.number, error: safeErrorDescription(error) }, { level: 'warn' });
7862
8077
  }
8078
+ // Runs after supersede: a sibling the merge already closed is no longer open, so it gets no resync.
8079
+ try {
8080
+ await s.resyncSiblingsOnMerge?.(pr.number, wt.path);
8081
+ } catch (error) {
8082
+ observe('sibling-resync-on-merge-failed', { number: pr.number, error: safeErrorDescription(error) }, { level: 'warn' });
8083
+ }
7863
8084
  const directory = releaseNotesDir(elanousStateRoot());
7864
8085
  const fragment: ReleaseNoteFragment = {
7865
8086
  pr: pr.number,
@@ -7875,7 +8096,14 @@ async function runSelfImplementInner(
7875
8096
  }
7876
8097
  const defaultBranch = resolveDefaultBranchTarget(s.defaultBranchRef ?? defaultBranchRef, wt.path).target ?? undefined;
7877
8098
  progress('merged', formatAutoMergeSuccessMessage({ prNumber: pr.number, mergedBase, defaultBranch }));
7878
- await runPostMergeCleanup(s.postMergeCleanup, wt.path, wt.branch, opts.goalFile, mergedBase && defaultBranch && displayBranchName(mergedBase) === displayBranchName(defaultBranch) ? defaultBranch : undefined, observe);
8099
+ // HARNESS-FULL-GRAPH — 회수도 그래프 노드(cleanup)다. 결과 = completed | preserved | failed.
8100
+ let cleanupOutcome = 'completed';
8101
+ enterJourneyNode('cleanup', { provenance: 'post-merge', runId });
8102
+ await withJourneyNode('cleanup', { provenance: 'post-merge', runId }, () => runPostMergeCleanup(s.postMergeCleanup, wt.path, wt.branch, opts.goalFile, mergedBase && defaultBranch && displayBranchName(mergedBase) === displayBranchName(defaultBranch) ? defaultBranch : undefined, (event, data) => {
8103
+ if (event.startsWith('post-merge-cleanup-')) cleanupOutcome = event.slice('post-merge-cleanup-'.length);
8104
+ observe(event, data);
8105
+ }));
8106
+ exitJourneyNode('cleanup', { provenance: 'post-merge', runId, outcome: cleanupOutcome });
7879
8107
  const mergedLedger = (() => {
7880
8108
  try { return loadRunLedger(runId); } catch { return null; }
7881
8109
  })();
@@ -0,0 +1,123 @@
1
+ /**
2
+ * STOP-RECORD (0.2.20 P0) — 런이 «멈춘» 자리마다 런 원장에 `event='stop'` 한 줄을 «더한다».
3
+ *
4
+ * 멈추는 자리 넷이 이 함수 하나를 부른다:
5
+ * ① 병합 보류(`mergeReason !== 'auto'`) · ② implement aborted — `orchestrator.ts` `runSelfImplement`
6
+ * ③ Pod exit 비0 — `harness-cli-command.ts` `onPod`
7
+ * ④ 발사 직후 자식 비0 종료(launch-failed) — `tasks-cli.ts` `defaultTaskLauncher`
8
+ *
9
+ * ⛔ 보존 계약: 기존 PR 본문·런 원장 항목·logs.db 사건(exit-classified 등)은 손대지 않고 «더하기»만 한다.
10
+ * ⭐ 이 스키마(`RunStopRecord`·`RUN_STOP_CLASSES`)는 STOP-AUTOHEAL 이 읽는다 — 칸 이름·닫힌 목록을 바꾸지 않는다(더하기만).
11
+ */
12
+ import { debug } from '../debug/log.js';
13
+ import { appendRunLedgerEntry, type RunLedgerEntry, type RunLedgerWriter, type RunShardIdentity } from './run-ledger.js';
14
+
15
+ /** 닫힌 목록 — 못 고르면 `unclassified`. */
16
+ export const RUN_STOP_CLASSES = [
17
+ 'env-unrelated', 'main-sync', 'pod-died', 'review-repeat',
18
+ 'review-out-of-scope', 'evidence-uncovered', 'fabric', 'launch-failed', 'unclassified',
19
+ ] as const;
20
+ export type RunStopClass = typeof RUN_STOP_CLASSES[number];
21
+
22
+ /** 런 원장 `event='stop'` 줄의 `data` 모양(STOP-AUTOHEAL 이 소비한다). */
23
+ export interface RunStopRecord {
24
+ class: RunStopClass;
25
+ /** 한 줄 · ≤120자 · 결정 라벨(원 로그 꼬리 금지). */
26
+ cause: string;
27
+ /** 근거 위치 — PR URL · `run-ledger:<runId>:<event>` · 파일 경로. */
28
+ evidenceRef: string;
29
+ /** 다음 한 수(사람·힐러가 읽는다). */
30
+ nextMove: string;
31
+ }
32
+
33
+ export const RUN_STOP_EVENT = 'stop';
34
+ export const RUN_STOP_CAUSE_MAX = 120;
35
+
36
+ export interface RunStopInput {
37
+ runId: string;
38
+ goalId?: string;
39
+ shardIdentity?: RunShardIdentity;
40
+ /** 닫힌 목록 밖이거나 비면 `unclassified`. */
41
+ class?: string;
42
+ cause: string;
43
+ evidenceRef: string;
44
+ nextMove: string;
45
+ /** 관측용 — 어느 자리가 불렀나(merge-hold · implement-aborted · draft-pr-open-failed · pod-exit · launch-failed). */
46
+ site?: string;
47
+ }
48
+
49
+ export function isRunStopClass(value: unknown): value is RunStopClass {
50
+ return typeof value === 'string' && (RUN_STOP_CLASSES as readonly string[]).includes(value);
51
+ }
52
+
53
+ /** 원 로그 꼬리가 아니라 «한 줄»로 — 첫 비어 있지 않은 줄 · ANSI 제거 · 공백 접기 · ≤120자(코드 포인트). */
54
+ export function boundRunStopCause(raw: string): string {
55
+ // eslint-disable-next-line no-control-regex
56
+ const plain = raw.replace(/\x1b\[[0-9;?]*[ -/]*[@-~]/g, '').replace(/[\x00-\x08\x0b-\x1f\x7f]/g, (c) => (c === '\r' ? '\n' : ' '));
57
+ const first = plain.split('\n').map((line) => line.replace(/\s+/g, ' ').trim()).find((line) => line.length > 0) ?? '';
58
+ return Array.from(first).slice(0, RUN_STOP_CAUSE_MAX).join('') || 'stop reason unclassified';
59
+ }
60
+
61
+ /** 병합 보류 사유 → 닫힌 목록. 모르면 `unclassified`. */
62
+ export function classifyMergeHoldStop(mergeReason: string | undefined): RunStopClass {
63
+ const reason = mergeReason ?? '';
64
+ if (reason.startsWith('main-sync') || reason === 'default-branch-unresolved') return 'main-sync';
65
+ if (reason === 'required-evidence-uncovered') return 'evidence-uncovered';
66
+ if (reason === 'review-must-fix' || reason.startsWith('review-budget')) return 'review-repeat';
67
+ if (reason.startsWith('review-diff') || reason === 'no-real-review') return 'review-out-of-scope';
68
+ return 'unclassified';
69
+ }
70
+
71
+ /** Pod exit 분류 사유 → 닫힌 목록. */
72
+ export function classifyPodExitStop(reason: string | undefined): RunStopClass {
73
+ switch (reason) {
74
+ case 'pod-failure': case 'pod-error': case 'OOMKilled': case 'ENOBUFS': case 'signal': return 'pod-died';
75
+ case 'no-launch': return 'launch-failed';
76
+ default: return 'unclassified';
77
+ }
78
+ }
79
+
80
+ /** 이 프로세스에서 stop 을 이미 쓴 런 — 한 런이 두 자리(예: draft PR 실패 ⊕ aborted)에서 두 줄을 쓰지 않게. */
81
+ const recordedThisProcess = new Set<string>();
82
+ const RECORDED_MAX = 4096;
83
+
84
+ /** 이 프로세스가 그 런에 stop 을 이미 썼나(원장 재독 없이 · 같은 프로세스 안 중복 방지용). */
85
+ export function runStopRecorded(runId: string): boolean {
86
+ return recordedThisProcess.has(runId);
87
+ }
88
+
89
+ /** 런 시작 때 부른다 — 같은 runId 로 다시 도는 런(재시도·시험)이 지난 판의 표시에 막히지 않게. */
90
+ export function forgetRunStop(runId: string): void {
91
+ recordedThisProcess.delete(runId);
92
+ }
93
+
94
+ /** 멈춘 런에 stop 한 줄을 더한다 — 기존 관측은 바꾸지 않는다. 쓴 줄을 돌려준다. */
95
+ export function recordRunStop(input: RunStopInput, write: RunLedgerWriter = appendRunLedgerEntry): RunLedgerEntry {
96
+ const record: RunStopRecord = {
97
+ class: isRunStopClass(input.class) ? input.class : 'unclassified',
98
+ cause: boundRunStopCause(input.cause),
99
+ evidenceRef: input.evidenceRef,
100
+ nextMove: input.nextMove,
101
+ };
102
+ const entry: RunLedgerEntry = {
103
+ timestamp: new Date().toISOString(), runId: input.runId, event: RUN_STOP_EVENT,
104
+ data: { ...record },
105
+ ...(input.goalId ? { goalId: input.goalId } : {}),
106
+ ...input.shardIdentity,
107
+ };
108
+ write(entry);
109
+ if (recordedThisProcess.size >= RECORDED_MAX) recordedThisProcess.clear();
110
+ recordedThisProcess.add(input.runId);
111
+ try {
112
+ debug.log('self-implement.run-stop', 'recorded', { runId: input.runId, site: input.site ?? null, ...record, requestedClass: input.class ?? null });
113
+ } catch { /* observation is fail-soft */ }
114
+ return entry;
115
+ }
116
+
117
+ /** 원장 항목이 stop 줄이면 그 레코드를 돌려준다(STOP-AUTOHEAL 소비용). */
118
+ export function readRunStopRecord(entry: RunLedgerEntry): RunStopRecord | undefined {
119
+ if (entry.event !== RUN_STOP_EVENT) return undefined;
120
+ const data = entry.data as Partial<RunStopRecord>;
121
+ if (typeof data.cause !== 'string' || typeof data.evidenceRef !== 'string' || typeof data.nextMove !== 'string') return undefined;
122
+ return { class: isRunStopClass(data.class) ? data.class : 'unclassified', cause: data.cause, evidenceRef: data.evidenceRef, nextMove: data.nextMove };
123
+ }