elanous 0.2.13 → 0.2.15

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 (524) 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/LZcstaO9_NXypPFmujolv/_buildManifest.js +1 -0
  4. package/apps/pwa/out/_next/static/chunks/{7334.a6679d9168f37aa8.js → 1268.0840ff91e083fcbd.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1307-33ffcc49ab45123b.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/{9656-c1540088f5859c80.js → 1844-9ec4b1d12f6e80eb.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1866-e7a6999f25548b30.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/{390.c373e31b3b9d0c41.js → 1948.15f356b15a625597.js} +2 -2
  10. package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/224-798346143007ff65.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/2699-63b73fa4d3bcf6ff.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/2957-96ffab3d521fb08f.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/4144-a0041c8dc3be57ac.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/4554-3565eea1f1495ba7.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/{4685-c3c1c625b71accd1.js → 4614-21403aac730d4586.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/{8039-df92e08fede5de8f.js → 4795-f372490b178583fc.js} +1 -1
  24. package/apps/pwa/out/_next/static/chunks/5135-44008fe8b1f2aa41.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/5233-bf28bd6bd7a32099.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/5360-be1f1d8f9fcc9755.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/5977-c952712c87a1f757.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/5994-ae92c0de046ab9ba.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{1452.93700483b9d4fc61.js → 6110.1297d4093fdfbb0d.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/6158.9c0449a9a8d0064b.js +2 -0
  31. package/apps/pwa/out/_next/static/chunks/6877-7c6208705c284124.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/{1829-b453a1b22d3999bb.js → 7327-2d69fb321ba73389.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/7395-164e238f471b5d7b.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/7787-02a1c0b04e25e811.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/8827-e2f5b09a8d37e83b.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/8868-10a3a4440fb0ccd8.js +25 -0
  42. package/apps/pwa/out/_next/static/chunks/{8421-1c4acfb1395a0edf.js → 8949-ecb4128a0858b911.js} +1 -1
  43. package/apps/pwa/out/_next/static/chunks/899-46946fe8363e1262.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/9070.067c106528ec1ae6.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/9103-7a3ae7f60af3b99f.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/{3869-3cd46526879f454c.js → 9247-29d889b809288e65.js} +1 -1
  47. package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/{79f8be9e-957d68913b590b08.js → a9f2b54d-7865aba0f4d2ee49.js} +1 -1
  49. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/app/approvals/page-0e2c57fe6add4b2a.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-e05a77df7e005b04.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/app/board/page-f544338193a9a762.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/app/botlab/page-5491c115b1f9a923.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/app/bots/page-b8c49f6b4fa2df91.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/app/ceo/page-96398e364fbd4548.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/app/chat/page-976813c91d7394ea.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/app/consult/page-28b9448091776c06.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/app/control/page-1d4901eb7c2d8822.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/app/design-check/page-72d3e7ff35a8c954.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/app/editor/page-60c7a8e1a4fe62ce.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/app/exec/page-2a52b316cb143d9c.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/app/field/page-c3ce483c8d5db370.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/app/inside/page-13c7b53e0c2519a9.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/app/intake/page-96f074f6538e8a2c.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/app/layout-e97be5334d83a9f5.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/app/live/page-65e484302921a932.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/app/loops/page-34d08facaf08f556.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/app/market/page-955ec2da3be4c560.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-9f88fbc15d9058d1.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/app/morning/page-c1343f9499d86f3f.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/app/not-found-8739a2e0ae793130.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/app/observatory/page-c9fc5706b8abaa11.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-d23b12bb92242558.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-8d47f45a0dc044ac.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-c7fea475488201a8.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/app/outputs/page-e2ee2896811e98d0.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/app/page-83b19dae8619de05.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/app/reflection/page-5efbf81124c474ae.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f1a1fc0a82738c.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/app/sessions/page-da6c08aae0f92768.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-06ee266953d9c879.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/app/settings/page-153c2b3bcc89e8de.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-87a11e6a05f15199.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/app/setup/page-7d4182964407c09c.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/app/share/page-0d6d23b40263a7ea.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/app/showroom/page-7e8c39241f8eb6d0.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/app/tasks/page-008c1a96618a4887.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/app/term/{page-63d14a4d8fe1e1c1.js → page-f5597e894c02cd33.js} +1 -1
  91. package/apps/pwa/out/_next/static/chunks/app/today/page-0337fdf7fb5e37b6.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/app/trace/page-73735b64bfe1ae67.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/app/vault/page-8fcec4c9ea2e7f70.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-f7e631e9b4daf66e.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/app/workflows/page-4881b8f9f63694b4.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/app/workspace/page-9817c7f9007466cc.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-97f9f43172a3a90e.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{5cd7e3a9-404fd6b8d0ecd44c.js → f6231284-45726550aba08fca.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/{f48170cc-d05d28bf87a43bf4.js → f6b7c9ba.64a895b8b2fedbdc.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/framework-5c169757551134ed.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/webpack-539cde99554be20f.js +1 -0
  106. package/apps/pwa/out/_next/static/css/1f7c958c41ffa3b9.css +1 -0
  107. package/apps/pwa/out/approvals/index.html +1 -1
  108. package/apps/pwa/out/approvals/index.txt +23 -23
  109. package/apps/pwa/out/autopilot/index.html +1 -1
  110. package/apps/pwa/out/autopilot/index.txt +23 -23
  111. package/apps/pwa/out/board/index.html +1 -1
  112. package/apps/pwa/out/board/index.txt +23 -23
  113. package/apps/pwa/out/botlab/index.html +1 -1
  114. package/apps/pwa/out/botlab/index.txt +22 -22
  115. package/apps/pwa/out/bots/index.html +1 -1
  116. package/apps/pwa/out/bots/index.txt +22 -22
  117. package/apps/pwa/out/ceo/index.html +1 -0
  118. package/apps/pwa/out/ceo/index.txt +33 -0
  119. package/apps/pwa/out/chat/index.html +1 -1
  120. package/apps/pwa/out/chat/index.txt +22 -22
  121. package/apps/pwa/out/consult/index.html +1 -1
  122. package/apps/pwa/out/consult/index.txt +23 -23
  123. package/apps/pwa/out/control/index.html +1 -1
  124. package/apps/pwa/out/control/index.txt +23 -23
  125. package/apps/pwa/out/design-check/index.html +1 -1
  126. package/apps/pwa/out/design-check/index.txt +23 -23
  127. package/apps/pwa/out/editor/index.html +1 -1
  128. package/apps/pwa/out/editor/index.txt +23 -23
  129. package/apps/pwa/out/exec/index.html +1 -1
  130. package/apps/pwa/out/exec/index.txt +23 -23
  131. package/apps/pwa/out/field/index.html +1 -1
  132. package/apps/pwa/out/field/index.txt +23 -23
  133. package/apps/pwa/out/healthz +1 -1
  134. package/apps/pwa/out/index.html +1 -1
  135. package/apps/pwa/out/index.txt +22 -22
  136. package/apps/pwa/out/inside/index.html +1 -1
  137. package/apps/pwa/out/inside/index.txt +22 -22
  138. package/apps/pwa/out/intake/index.html +1 -1
  139. package/apps/pwa/out/intake/index.txt +23 -23
  140. package/apps/pwa/out/live/index.html +1 -1
  141. package/apps/pwa/out/live/index.txt +23 -23
  142. package/apps/pwa/out/loops/index.html +1 -0
  143. package/apps/pwa/out/loops/index.txt +30 -0
  144. package/apps/pwa/out/market/index.html +1 -1
  145. package/apps/pwa/out/market/index.txt +22 -22
  146. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  147. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  148. package/apps/pwa/out/morning/index.html +1 -1
  149. package/apps/pwa/out/morning/index.txt +23 -23
  150. package/apps/pwa/out/observatory/index.html +1 -1
  151. package/apps/pwa/out/observatory/index.txt +23 -23
  152. package/apps/pwa/out/ops/checklist/index.html +1 -1
  153. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  154. package/apps/pwa/out/ops/release/index.html +1 -1
  155. package/apps/pwa/out/ops/release/index.txt +22 -22
  156. package/apps/pwa/out/ops/seats/index.html +1 -1
  157. package/apps/pwa/out/ops/seats/index.txt +22 -22
  158. package/apps/pwa/out/outputs/index.html +1 -1
  159. package/apps/pwa/out/outputs/index.txt +22 -22
  160. package/apps/pwa/out/reflection/index.html +1 -1
  161. package/apps/pwa/out/reflection/index.txt +23 -23
  162. package/apps/pwa/out/scheduler/index.html +1 -1
  163. package/apps/pwa/out/scheduler/index.txt +23 -23
  164. package/apps/pwa/out/sessions/index.html +1 -1
  165. package/apps/pwa/out/sessions/index.txt +22 -22
  166. package/apps/pwa/out/settings/devices/index.html +1 -1
  167. package/apps/pwa/out/settings/devices/index.txt +23 -23
  168. package/apps/pwa/out/settings/index.html +1 -1
  169. package/apps/pwa/out/settings/index.txt +23 -23
  170. package/apps/pwa/out/setup/done/index.html +1 -1
  171. package/apps/pwa/out/setup/done/index.txt +23 -23
  172. package/apps/pwa/out/setup/index.html +1 -1
  173. package/apps/pwa/out/setup/index.txt +23 -23
  174. package/apps/pwa/out/share/index.html +1 -1
  175. package/apps/pwa/out/share/index.txt +23 -23
  176. package/apps/pwa/out/showroom/index.html +1 -1
  177. package/apps/pwa/out/showroom/index.txt +22 -22
  178. package/apps/pwa/out/tasks/index.html +1 -1
  179. package/apps/pwa/out/tasks/index.txt +23 -23
  180. package/apps/pwa/out/term/index.html +1 -1
  181. package/apps/pwa/out/term/index.txt +23 -23
  182. package/apps/pwa/out/today/index.html +1 -1
  183. package/apps/pwa/out/today/index.txt +23 -23
  184. package/apps/pwa/out/trace/index.html +1 -1
  185. package/apps/pwa/out/trace/index.txt +23 -23
  186. package/apps/pwa/out/vault/index.html +1 -1
  187. package/apps/pwa/out/vault/index.txt +23 -23
  188. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  189. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  190. package/apps/pwa/out/workflows/index.html +1 -1
  191. package/apps/pwa/out/workflows/index.txt +23 -23
  192. package/apps/pwa/out/workspace/index.html +1 -1
  193. package/apps/pwa/out/workspace/index.txt +23 -23
  194. package/apps/pwa/out/worktrees/index.html +1 -1
  195. package/apps/pwa/out/worktrees/index.txt +23 -23
  196. package/graphs/heal/heal-loop.yaml +1 -1
  197. package/graphs/implement-loop.yaml +1 -1
  198. package/graphs/orchestrator/orchestrator.yaml +59 -0
  199. package/graphs/orchestrator/recipes.yaml +18 -0
  200. package/graphs/release/recipes.yaml +6 -0
  201. package/graphs/release/release-loop.yaml +6 -1
  202. package/graphs/rhythm/daily.yaml +38 -0
  203. package/graphs/rhythm/recipes.yaml +18 -0
  204. package/graphs/rhythm/weekly.yaml +39 -0
  205. package/graphs/video/recipes.yaml +3 -0
  206. package/graphs/video/youtube-summary.yaml +17 -0
  207. package/package.json +1 -1
  208. package/scripts/audit-test-state-writes.ts +72 -17
  209. package/scripts/brand/check.ts +188 -0
  210. package/scripts/ci-typecheck-changed.ts +50 -18
  211. package/scripts/coord-post.sh +11 -1
  212. package/scripts/docs/generate-graph-anatomy.ts +315 -0
  213. package/scripts/docs-cli-check.ts +23 -6
  214. package/scripts/expose-rubric-check.ts +118 -0
  215. package/scripts/expose-rubric-suggest.ts +169 -0
  216. package/scripts/heal/run-role.ts +14 -0
  217. package/scripts/hq/standby-verify.ts +11 -7
  218. package/scripts/lecture-note/node.ts +31 -11
  219. package/scripts/lessons/handbook-page.ts +112 -0
  220. package/scripts/marketing/generate-ax-brief.ts +140 -0
  221. package/scripts/marketing/generate-feature-map.ts +118 -0
  222. package/scripts/release-loop/checklist-gate-node.ts +53 -14
  223. package/scripts/release-loop/gate-node.ts +89 -14
  224. package/scripts/release-loop/publish-node.ts +14 -1
  225. package/scripts/release-loop/unattended-release.ts +23 -1
  226. package/scripts/release-loop/vault-note-node.ts +428 -0
  227. package/scripts/release-story/draft.ts +220 -0
  228. package/scripts/rhythm/daily.ts +570 -0
  229. package/scripts/rhythm/weekly.ts +315 -0
  230. package/scripts/skills/public-check.ts +169 -0
  231. package/scripts/smart-merge/resync-shadow.ts +147 -0
  232. package/scripts/test-deterministic.ts +4 -8
  233. package/scripts/test-diet/effectiveness.ts +195 -0
  234. package/scripts/test-diet/lib.ts +16 -8
  235. package/scripts/test-diet/node.ts +77 -9
  236. package/scripts/ux/demo-rehearsal.ts +2 -2
  237. package/scripts/ux/lib/rehearsal-verdict.ts +1 -0
  238. package/scripts/video/youtube-summary.ts +133 -0
  239. package/skills/diagram-master/SKILL.md +42 -49
  240. package/skills/diagram-master/references/pyproject.toml +4 -1
  241. package/skills/diagram-master/references/routing-guide.md +4 -2
  242. package/skills/grill-me/SKILL.md +1 -0
  243. package/skills/youtube-master/SKILL.md +13 -13
  244. package/skills/youtube-master/package-lock.json +0 -545
  245. package/skills/youtube-master/package.json +2 -5
  246. package/skills/youtube-master/scripts/main.ts +2 -2
  247. package/skills/youtube-master/scripts/transcribe-local.ts +1 -1
  248. package/skills/youtube-master/src/util.ts +30 -7
  249. package/src/agent-env/profile.ts +161 -0
  250. package/src/agent-mission/driver.ts +3 -3
  251. package/src/agent-substrate/pr-reviewer.ts +2 -0
  252. package/src/ask-user-question/pending-questions.ts +5 -0
  253. package/src/auth/github-app-token.ts +112 -13
  254. package/src/autopilot/build/llm-conflict-merge.ts +73 -10
  255. package/src/autopilot/build/merge-intent.ts +53 -0
  256. package/src/briefing/brief-items.ts +121 -0
  257. package/src/chat/index.ts +2 -0
  258. package/src/claims/claims-ledger.ts +232 -0
  259. package/src/claims/claims-render.ts +166 -0
  260. package/src/cli/agent-env-cli.ts +21 -0
  261. package/src/cli/claims-cli.ts +94 -0
  262. package/src/cli/decisions-cli.ts +44 -3
  263. package/src/cli/docs-cli.ts +2 -0
  264. package/src/cli/doctor-cli.ts +23 -1
  265. package/src/cli/doctor-node-modules.ts +147 -0
  266. package/src/cli/flow-cli.ts +11 -0
  267. package/src/cli/freeze-cli.ts +45 -0
  268. package/src/cli/intake-cli.ts +46 -17
  269. package/src/cli/lesson-cli.ts +108 -0
  270. package/src/cli/logs-cli.ts +104 -2
  271. package/src/cli/logs-model-input.ts +131 -0
  272. package/src/cli/pod-cli.ts +2 -0
  273. package/src/cli/pr-cli.ts +29 -1
  274. package/src/cli/private-ledger-commands.ts +54 -4
  275. package/src/cli/pty-drive-verdict.ts +11 -2
  276. package/src/cli/release-cli.ts +190 -33
  277. package/src/cli/rfc-status.ts +91 -0
  278. package/src/cli/seat-requests-cli.ts +52 -0
  279. package/src/connectors/linear.ts +5 -3
  280. package/src/context-bus/condense.ts +15 -20
  281. package/src/context-bus/context-now-public.ts +96 -0
  282. package/src/context-bus/context-now-surfaces.ts +55 -2
  283. package/src/context-bus/context-now.ts +6 -3
  284. package/src/context-bus/coord-events.ts +6 -4
  285. package/src/context-bus/long-term-memory.ts +92 -11
  286. package/src/dashboard/index.ts +75 -22
  287. package/src/dashboard/slash-runtime/chat-persona.ts +66 -0
  288. package/src/dashboard/slash-runtime/dashboard-handlers.ts +99 -0
  289. package/src/dashboard/slash-runtime/loops-table.ts +77 -0
  290. package/src/decisions/decision-cards.ts +33 -7
  291. package/src/decisions/decision-ledger.ts +40 -1
  292. package/src/decisions/proact-meter.ts +286 -0
  293. package/src/decisions/proact1-lite.ts +86 -0
  294. package/src/decisions/web-push-decision-cards.ts +1 -1
  295. package/src/discord/sprint21-runtime.ts +16 -0
  296. package/src/discord-self-message.ts +8 -0
  297. package/src/discord-slash-wire.ts +31 -2
  298. package/src/domains/alert-audit.ts +271 -0
  299. package/src/domains/core-tools.ts +4 -3
  300. package/src/domains/ops-facts-tool.ts +31 -1
  301. package/src/domains/outbound-alert.ts +1 -1
  302. package/src/elanous-config-dir.ts +29 -4
  303. package/src/execution-loop/launch-gate.ts +29 -14
  304. package/src/flow/cards.ts +239 -0
  305. package/src/graph-runner/graph-tick.ts +4 -0
  306. package/src/graph-runner/runner.ts +30 -5
  307. package/src/harness/harness-cli-command.ts +259 -38
  308. package/src/harness/harness-incidents.ts +45 -12
  309. package/src/harness/harness-pod-dispatch.ts +102 -11
  310. package/src/harness/harness-queue-child.ts +3 -3
  311. package/src/harness/harness-queue.ts +583 -65
  312. package/src/harness/helper-repair.ts +87 -0
  313. package/src/harness/helper-scan.ts +151 -0
  314. package/src/harness/launch-stamp.ts +236 -0
  315. package/src/harness/ledger-write-guard-child.fixture.ts +12 -0
  316. package/src/harness/ledger-write-guard.ts +35 -0
  317. package/src/harness/model-input-observation.ts +37 -0
  318. package/src/harness/pod-memory-policy.ts +15 -0
  319. package/src/harness/repository-name.ts +55 -0
  320. package/src/hq/fence-audit.ts +90 -0
  321. package/src/hq/hq.ts +63 -5
  322. package/src/hq/lease.ts +4 -4
  323. package/src/hq/move-plan.ts +126 -0
  324. package/src/hq/promote.ts +332 -0
  325. package/src/index.ts +159 -27
  326. package/src/intake-plane/check.ts +63 -0
  327. package/src/intake-plane/digest.ts +37 -15
  328. package/src/intake-plane/front-classifier.ts +6 -0
  329. package/src/intake-plane/items.ts +3 -2
  330. package/src/intake-plane/lens.ts +177 -0
  331. package/src/intake-plane/linear-wish.ts +39 -11
  332. package/src/intake-plane/route.ts +145 -1
  333. package/src/intake-plane/wish-benchmark-ledger.ts +129 -0
  334. package/src/intake-plane/wish-card.ts +53 -2
  335. package/src/intake-plane/wish-folder.ts +5 -2
  336. package/src/intake-plane/wish-reply.ts +72 -0
  337. package/src/launch-head/seat-goal-queue-lock.fixture.ts +15 -0
  338. package/src/launch-head/seat-goal-queue.ts +198 -0
  339. package/src/lessons/lesson-import.ts +106 -0
  340. package/src/lessons/lesson-ledger.ts +206 -0
  341. package/src/loops/activity.ts +203 -0
  342. package/src/loops/budget.ts +63 -0
  343. package/src/loops/checker.ts +5 -3
  344. package/src/loops/contract/examples/orchestrator.loop.yaml +1 -1
  345. package/src/loops/loop-cli.ts +36 -4
  346. package/src/loops/neighbors.ts +40 -0
  347. package/src/loops/observe.ts +10 -0
  348. package/src/loops/orchestrator/author-depth.ts +220 -0
  349. package/src/loops/orchestrator/author-input-check.ts +82 -0
  350. package/src/loops/orchestrator/author-ledger.ts +232 -0
  351. package/src/loops/orchestrator/finish-rate.ts +175 -0
  352. package/src/loops/orchestrator/overlap.ts +51 -12
  353. package/src/loops/orchestrator/resync-shadow.ts +227 -0
  354. package/src/loops/orchestrator/seat-share.ts +56 -0
  355. package/src/loops/orchestrator/tick.ts +309 -0
  356. package/src/loops/orchestrator/traffic.ts +134 -13
  357. package/src/loops/registry.ts +535 -9
  358. package/src/loops/status-rows.ts +118 -0
  359. package/src/loops/verdict.ts +17 -5
  360. package/src/maturity/bot-slash-catalog.ts +66 -0
  361. package/src/maturity/feature-maturity.ts +9 -5
  362. package/src/maturity/tui-slash-availability.ts +31 -0
  363. package/src/mss/logging/log-store.ts +35 -4
  364. package/src/nexus/api/dashboard.ts +6 -1
  365. package/src/nexus/api/http-server.ts +33 -3
  366. package/src/nexus/api/loop-edges.ts +173 -0
  367. package/src/nexus/api/merge-approvals-gate.ts +1 -1
  368. package/src/nexus/api/schedules-read.ts +18 -1
  369. package/src/nexus/api/seat-requests.ts +79 -56
  370. package/src/nexus/api/task-cards-api.ts +44 -5
  371. package/src/nexus/api/workflows.ts +2 -1
  372. package/src/prompt-enhance/enhance.ts +6 -1
  373. package/src/release-loop/auto-start.ts +51 -0
  374. package/src/release-loop/checklist.ts +22 -4
  375. package/src/release-loop/feature-store.ts +71 -32
  376. package/src/release-loop/landing-freeze.ts +121 -0
  377. package/src/release-loop/merged-pr-checklist.ts +125 -0
  378. package/src/release-loop/placement.ts +302 -0
  379. package/src/release-loop/release-schedule.ts +3 -1
  380. package/src/seat-dispatch/ceo-commands.ts +2 -2
  381. package/src/seat-dispatch/seat-ask.ts +16 -3
  382. package/src/seat-dispatch/seat-questions.ts +58 -0
  383. package/src/seat-dispatch/seat-request-eligibility.ts +19 -0
  384. package/src/seat-dispatch/seat-request-ledger.ts +133 -0
  385. package/src/seat-loop/seat-loop.ts +531 -40
  386. package/src/self-dev/dev-pipeline.ts +14 -6
  387. package/src/self-dev/draft-sweep.ts +162 -6
  388. package/src/self-dev/draft-triage-rules.ts +25 -8
  389. package/src/self-dev/orchestrate.ts +15 -1
  390. package/src/self-dev/review-provider-fallback.ts +6 -1
  391. package/src/self-dev/run-store.ts +73 -1
  392. package/src/self-dev/run-supervisor.ts +57 -2
  393. package/src/self-dev/self-orchestrate-runtime.ts +5 -1
  394. package/src/self-implement/budget-gate.ts +29 -0
  395. package/src/self-implement/expose-gate.ts +47 -0
  396. package/src/self-implement/frozen-merges.ts +295 -0
  397. package/src/self-implement/gate-cli.ts +10 -4
  398. package/src/self-implement/gate-scope.ts +46 -9
  399. package/src/self-implement/goal-archive.ts +222 -0
  400. package/src/self-implement/goal-author.ts +43 -5
  401. package/src/self-implement/goal-clarification-escalation.ts +5 -0
  402. package/src/self-implement/goal-lookup.ts +147 -0
  403. package/src/self-implement/heal-intake.ts +197 -0
  404. package/src/self-implement/host-regate.ts +32 -2
  405. package/src/self-implement/l8-merge-queue.ts +132 -0
  406. package/src/self-implement/orchestrator.ts +299 -48
  407. package/src/self-implement/pipeline-shape.ts +1 -1
  408. package/src/self-implement/revert-guard.ts +97 -0
  409. package/src/self-implement/run-ledger.ts +3 -1
  410. package/src/self-implement/run-status-mapping.ts +2 -0
  411. package/src/self-implement/seams.ts +29 -9
  412. package/src/self-implement/self-implement-cli.ts +1 -0
  413. package/src/self-implement/speed-claims.ts +338 -0
  414. package/src/session/index.ts +2 -0
  415. package/src/steward/triage.ts +74 -3
  416. package/src/steward/working-backwards.ts +4 -1
  417. package/src/task-cards/card-cli.ts +10 -2
  418. package/src/task-cards/card-store.ts +10 -6
  419. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +63 -48
  420. package/src/task-orchestrator/surfaces/pod-command-job.ts +84 -9
  421. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +48 -0
  422. package/src/task-orchestrator/surfaces/pod-lease.ts +5 -2
  423. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +46 -6
  424. package/src/task-orchestrator/surfaces/pod-pool.ts +60 -8
  425. package/src/task-orchestrator/surfaces/self-implement-pod.ts +224 -49
  426. package/src/task-orchestrator/surfaces/self-implement.ts +5 -1
  427. package/src/telegram-commands.ts +27 -3
  428. package/src/telegram-loops-command.ts +44 -0
  429. package/src/telegram.ts +25 -4
  430. package/src/user-config.ts +146 -18
  431. package/src/version/packed-revision.json +1 -1
  432. package/src/workflow-runtime/nodes/bash.ts +9 -1
  433. package/src/workflow-runtime/storage.ts +31 -13
  434. package/apps/pwa/out/_next/static/D51l8jUBplJrIpWvENsDK/_buildManifest.js +0 -1
  435. package/apps/pwa/out/_next/static/chunks/1159-0c5ef8bc21cb6afb.js +0 -1
  436. package/apps/pwa/out/_next/static/chunks/1394-931c9827067b2276.js +0 -1
  437. package/apps/pwa/out/_next/static/chunks/2176-c379e3ebce874151.js +0 -1
  438. package/apps/pwa/out/_next/static/chunks/2426.8c6ee0c668d53def.js +0 -1
  439. package/apps/pwa/out/_next/static/chunks/3170-7ec60a56fa0e4728.js +0 -1
  440. package/apps/pwa/out/_next/static/chunks/3278-ae6ef084769f6195.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/3454-988a53dac60a1763.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/3638-aa80b4641ea439db.js +0 -1
  443. package/apps/pwa/out/_next/static/chunks/3735-fe3402553ac1c9c6.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/3992-fe5c06d6b31f8b25.js +0 -25
  445. package/apps/pwa/out/_next/static/chunks/4215-c9d91dd644ec1719.js +0 -1
  446. package/apps/pwa/out/_next/static/chunks/4508-5d0161d1e724d735.js +0 -1
  447. package/apps/pwa/out/_next/static/chunks/4733-623a79345b171e1c.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/4883.3bd969ea1d3aaaff.js +0 -2
  449. package/apps/pwa/out/_next/static/chunks/5250-c78ca295585bbf95.js +0 -1
  450. package/apps/pwa/out/_next/static/chunks/5532.6899a12958a89b72.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/5845-e6c003ce8d5fd36a.js +0 -1
  452. package/apps/pwa/out/_next/static/chunks/5978-b27004c677119115.js +0 -1
  453. package/apps/pwa/out/_next/static/chunks/6048-4c5c33579bc4ef78.js +0 -1
  454. package/apps/pwa/out/_next/static/chunks/6303-422dbf0f67c72aac.js +0 -1
  455. package/apps/pwa/out/_next/static/chunks/6511-ff8360be3d65aaa4.js +0 -1
  456. package/apps/pwa/out/_next/static/chunks/6588-ba380869b67c4fa7.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/6751-bb3595948b2e311b.js +0 -1
  458. package/apps/pwa/out/_next/static/chunks/7274-19b7279f18b47ab3.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/7551-a0e0707b79164ddd.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/7758-85c2b53f731da024.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/7777-79f845045aa1ed86.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/8025-cc24ee5d8f2fb6f8.js +0 -1
  463. package/apps/pwa/out/_next/static/chunks/8206-c6684dcde12be721.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/8605-9da4678f8a310d18.js +0 -1
  465. package/apps/pwa/out/_next/static/chunks/8725.bf46bb1395dd0fa2.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/8734-252d511cd276c0dc.js +0 -1
  467. package/apps/pwa/out/_next/static/chunks/8834-ca1cb09c1cb1a6bf.js +0 -1
  468. package/apps/pwa/out/_next/static/chunks/9269.d2a4795bc6812717.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/9538-2816b90923606459.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/9906-e7b8b5310a169dfe.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d16993889b125c42.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/app/approvals/page-e5b4e1b256f41076.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-e49b9b76c565a0b1.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/app/board/page-b4f032c893b21cc9.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/app/botlab/page-f14987d5850a31e0.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/app/bots/page-b433308aad13ceb6.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/app/chat/page-4c1dbb21861beab2.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/app/consult/page-c85b816e3b269dbb.js +0 -1
  479. package/apps/pwa/out/_next/static/chunks/app/control/page-f6bc66b919b2ea7d.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/app/design-check/page-60603c1e056c9b25.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/app/editor/page-a0ea8f5a2341ee6b.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/app/exec/page-45c5bf04b4a605e6.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/app/field/page-36c6c4183353ac9e.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d16993889b125c42.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/app/inside/page-cb2eb0fd809980da.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/app/intake/page-31012264da8a341f.js +0 -1
  487. package/apps/pwa/out/_next/static/chunks/app/layout-50309aeb0bdd554a.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/app/live/page-bc00e964e855f4df.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/app/market/page-0696ee3fac9fe56c.js +0 -1
  490. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66c27608f651b866.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/app/morning/page-6ddd2109b7fc3a80.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/app/not-found-4e50b7298c1f69a5.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/app/observatory/page-7a2bf830038a2264.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1f327f18694fabca.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-e5cef2fe6e4028df.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cf596128d2b420ba.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/app/outputs/page-f672536f14f0969f.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/app/page-b52365662232db89.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/app/reflection/page-e7a6c80f288b1948.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-29a709616df9b050.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/app/sessions/page-fee842d7c2151129.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-78b40a344ed22f24.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/app/settings/page-75d199f448171014.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-a011dd5b0bff29c5.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d16993889b125c42.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/app/setup/page-d92e32d51ab5157e.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/app/share/page-5f21aed6932ef375.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/app/showroom/page-1e1a53946804debf.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/app/tasks/page-a1833cd43d832601.js +0 -1
  510. package/apps/pwa/out/_next/static/chunks/app/today/page-2a511d320f762e06.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/app/trace/page-1c3e03f88dac1e21.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/app/vault/page-c4d5289c2ea97a89.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b91f8952deaeaf27.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/app/workflows/page-71b43a2588489987.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/app/workspace/page-2b256feed331546f.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-505bb96d69a8622c.js +0 -1
  517. package/apps/pwa/out/_next/static/chunks/framework-172630e6aa5e2d7f.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/main-app-f0fe2d7477845181.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/main-fc98ac70b44eccb0.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/pages/_app-5bd7f10271f72413.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/pages/_error-97d0d85ea05fef9b.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/webpack-9e4d02d567b98240.js +0 -1
  523. package/apps/pwa/out/_next/static/css/128fb7fb670b2fbf.css +0 -1
  524. /package/apps/pwa/out/_next/static/{D51l8jUBplJrIpWvENsDK → LZcstaO9_NXypPFmujolv}/_ssgManifest.js +0 -0
@@ -2,14 +2,16 @@ import { execFileSync } from 'node:child_process';
2
2
  import { dlopen, FFIType } from 'bun:ffi';
3
3
  import { createHash } from 'node:crypto';
4
4
  import { existsSync, readFileSync } from 'node:fs';
5
- import { constants as osConstants } from 'node:os';
6
- import { resolve, sep } from 'node:path';
5
+ import { constants as osConstants, hostname } from 'node:os';
6
+ import { basename, dirname, resolve, sep } from 'node:path';
7
7
  import { findGitDir } from '../git-fs/locate.js';
8
8
  import { LogStore, logsDbPath } from '../mss/logging/log-store.js';
9
9
  import { loadSelfDevRun } from '../self-dev/run-store.js';
10
10
  import { normalizeRunId } from './harness-space.js';
11
- import { effectiveInstanceRoot } from '../instance/resolve.js';
12
- import { detectBursts, formatIncidentBurstWarning, readRunExits, recentBurst, recordRunExit } from './harness-incidents.js';
11
+ import { effectiveInstanceRoot, prodInstanceRoot } from '../instance/resolve.js';
12
+ import { lookupGoal, type GoalLookupOptions, type GoalLookupResult } from '../self-implement/goal-lookup.js';
13
+ import { archiveGoals, type GoalArchiveOptions } from '../self-implement/goal-archive.js';
14
+ import { detectBursts, formatIncidentBurstWarning, incidentLastLines, readRunExits, recentBurst, recordRunExit } from './harness-incidents.js';
13
15
  import { Command, Option } from 'commander';
14
16
  import { runGitCommand } from '../git-fs/runner.js';
15
17
  import { GOAL_TYPES, lintGoalFile, parseGoalId, parseGoalType, tracedPathReferences, type GoalType } from '../self-implement/goal-author.js';
@@ -19,7 +21,7 @@ import { resolveChildLlmEffort, resolveImplementationChildModel } from '../self-
19
21
  import { resolveHarnessTarget } from '../self-implement/harness-target-options.js';
20
22
  import { queryRunningRuns } from '../self-implement/running-runs.js';
21
23
  import { DevPipelineError } from '../self-dev/dev-pipeline.js';
22
- import { runDraftSweep, type DraftSweepAdapters, type DraftSweepResult, type SweepDraft, type SweepMergedPr } from '../self-dev/draft-sweep.js';
24
+ import { runDraftSweep, sweepFailureReason, type DraftSweepAdapters, type DraftSweepResult, type SweepDraft, type SweepMergedPr, type SweepReviewGate } from '../self-dev/draft-sweep.js';
23
25
  import { debug } from '../debug/log.js';
24
26
  import { dispatchTask, type DispatchTaskInput, type DispatchTaskDeps } from '../execution-loop/dispatch-task.js';
25
27
  import { launchRequestId, preLaunchGate, type PreLaunchGateDeps } from '../execution-loop/launch-gate.js';
@@ -28,8 +30,10 @@ import { CODEX_PROVIDER, GROK_PROVIDER, decideBudget, decideLaunchBudget, readBu
28
30
  import { DEFAULT_FALLBACK_CHAIN } from '../oauth/fallback-chain.js';
29
31
  import { installDeliverableVerifyCliCommand, type InstallDeliverableVerifyCliDeps } from './deliverable-verify-cli.js';
30
32
  import { getUserConfig } from '../user-config.js';
33
+ import { resolveRepositoryName } from './repository-name.js';
31
34
  import { installHarnessCliSinkHook } from './harness-cli-sink.js';
32
- import { addHarnessQueue, listHarnessQueue, reconcileHarnessQueue, removeHarnessQueue, tickHarnessQueue, type HarnessQueueDeps } from './harness-queue.js';
35
+ import { addHarnessQueue, listHarnessQueue, queueSeatForCwd, reconcileHarnessQueue, removeHarnessQueue, tickHarnessQueue, type HarnessQueueDeps, type QueueSeat } from './harness-queue.js';
36
+ import { parseDoorSince, queryLaunchDoors, renderLaunchDoors, type DoorTable } from './launch-stamp.js';
33
37
  import { resolveHarnessSubstrate, type ResolvedHarnessSubstrate } from './harness-substrate-default.js';
34
38
  import { runHarnessPlanRfc } from './harness-plan-rfc.js';
35
39
  import { classifyGarbage, isGarbageProcessTarget, type GarbageProcess } from './process-garbage.js';
@@ -92,6 +96,7 @@ export class HarnessCliInputError extends Error {
92
96
  }
93
97
 
94
98
  export interface HarnessAskSayOptions {
99
+ seat?: QueueSeat;
95
100
  json?: boolean;
96
101
  base?: string;
97
102
  target?: string;
@@ -253,6 +258,7 @@ function registerHarnessAskSayOptions(command: Command): Command {
253
258
  .option('--target <path>', 'self: harness가 작업할 레포 또는 디렉터리(self-mission 전용)')
254
259
  .option('--yes', 'git 아닌 프로젝트에 git init 및 첫 커밋을 만들도록 동의')
255
260
  .option('--correlation <id>', '요청과 런을 잇는 불투명 correlation 값')
261
+ .addOption(new Option('--seat <seat>', '런 귀속 자리 (OP|TC|MK|UX)').choices(['OP', 'TC', 'MK', 'UX']))
256
262
  .addOption(new Option('--goal-type <type>', `골 종류 (${GOAL_TYPES.join('|')})`).choices([...GOAL_TYPES]))
257
263
  .option('--force-preflight', '전제 검사 막힘을 명시 요청으로 우회(관측에 남음)')
258
264
  .option('--force-gate', '같은 골 실행 중 막힘을 명시 요청으로 우회(관측에 남음; 예산 막힘은 우회 불가)')
@@ -284,6 +290,7 @@ function registerHarnessMissionOptions(command: Command): Command {
284
290
  function normalizeHarnessCommonOptions(opts: HarnessAskSayOptions): HarnessAskSayOptions {
285
291
  return {
286
292
  ...(opts.json ? { json: true } : {}),
293
+ ...(opts.seat !== undefined ? { seat: opts.seat } : {}),
287
294
  ...(opts.base !== undefined ? { base: opts.base } : {}),
288
295
  ...(opts.target !== undefined ? { target: opts.target } : {}),
289
296
  ...(opts.yes === true ? { yes: true } : {}),
@@ -328,7 +335,7 @@ function assertHarnessChildLlmModel(opts: HarnessAskSayChildLlmOptions): void {
328
335
  }
329
336
 
330
337
  /** Shared post-parse gate: validate child model before any ask/say early return (including `--dry-run`). */
331
- type HarnessSubstrateOpts = { substrate?: 'local' | 'pod'; podPool?: string; podMemory?: string; after?: string; autoMerge?: boolean; base?: string; json?: boolean; target?: string; source?: string };
338
+ type HarnessSubstrateOpts = { substrate?: 'local' | 'pod'; podPool?: string; podMemory?: 'lite' | 'standard' | 'high'; after?: string; autoMerge?: boolean; base?: string; json?: boolean; target?: string; source?: string; seat?: QueueSeat };
332
339
  function resolveLaunchSubstrate(opts: HarnessSubstrateOpts): ResolvedHarnessSubstrate {
333
340
  const resolved = resolveHarnessSubstrate({ flag: opts, config: getUserConfig(), env: process.env });
334
341
  debug.log('harness.substrate', 'resolved', resolved);
@@ -338,7 +345,17 @@ function resolveLaunchSubstrate(opts: HarnessSubstrateOpts): ResolvedHarnessSubs
338
345
  return resolved;
339
346
  }
340
347
  type PodExit = { status: number | null; signal?: string | null };
341
- type PodExitReason = 'signal' | 'human-stop' | 'supervisor' | 'no-launch' | 'unknown';
348
+ type PodExitReason = 'signal' | 'human-stop' | 'supervisor' | 'no-launch' | 'unknown'
349
+ | 'pod-error' | 'launch-gate-blocked' | 'ENOBUFS' | 'OOMKilled';
350
+
351
+ function unknownPodExitTailReason(output: string): PodExitReason | undefined {
352
+ const tail = output.slice(-16_000);
353
+ if (/\bOOMKilled\b/i.test(tail)) return 'OOMKilled';
354
+ if (/\bENOBUFS\b/i.test(tail)) return 'ENOBUFS';
355
+ if (/launch gate[^\r\n]*blocked|blocked[^\r\n]*launch gate/i.test(tail)) return 'launch-gate-blocked';
356
+ if (/\bpod-error\b/i.test(tail)) return 'pod-error';
357
+ return undefined;
358
+ }
342
359
  /** GitHub lists at most this many files for one pull request; a list that reaches it is not provably complete. */
343
360
  export const GITHUB_PR_FILES_LIST_CAP = 3000;
344
361
  const STOPPING_SUPERVISOR_VERDICTS = new Set(['UNCONVERGEABLE', 'CONTRACT-CONFLICT']);
@@ -441,34 +458,47 @@ export function classifyHarnessPodExit(
441
458
  try { applied = (deps.hasJobApplied ?? hasHarnessPodJobApplied)(runId, output); } catch { /* unknown */ }
442
459
  const noLaunch = ledgerReadable && !ledger?.some((entry) => LAUNCH_EVIDENCE_EVENTS.has(entry.event))
443
460
  && applied === false && !pr;
444
- reason = noLaunch ? 'no-launch' : 'unknown';
461
+ reason = noLaunch ? 'no-launch' : unknownPodExitTailReason(output) ?? 'unknown';
445
462
  line = noLaunch
446
463
  ? 'Pod 실행에 닿지 못했다 — 풀·컨텍스트·SSH 연결을 확인하거나 `--substrate local` 로 명시하라'
447
- : 'Pod 실행 여부 또는 종료 이유를 확인하지 못했다';
464
+ : reason === 'unknown' ? 'Pod 실행 여부 또는 종료 이유를 확인하지 못했다'
465
+ : `Pod 종료 출력에서 확인한 원인: ${reason}`;
448
466
  }
449
467
  try { debug.log('harness.pod', 'exit-classified', { runId, reason, status: exit.status, signal: signal ?? null }); } catch { /* observation is fail-soft */ }
450
468
  return { reason, lines: [line, ...(pr ? [`PR 이 남아 있다: ${pr}`] : [])] };
451
469
  }
452
470
 
453
471
  /** The classified status is the same exit handed to the launcher; ledger failure is never an exit failure. */
454
- export function recordClassifiedHarnessPodExit(runId: string | undefined, reason: string, status: number): void {
472
+ export function recordClassifiedHarnessPodExit(runId: string | undefined, reason: string, status: number,
473
+ context: { entrance?: string; seat?: string; output?: string } = {}): void {
455
474
  if (!runId) return;
456
475
  try {
457
476
  const signal = status > 128
458
477
  ? Object.entries(osConstants.signals).find(([, number]) => number === status - 128)?.[0] ?? null : null;
459
- recordRunExit({ runId, reason, status, signal, at: new Date().toISOString() }, effectiveInstanceRoot());
478
+ const cwd = process.cwd();
479
+ const seat = context.seat ?? process.env.ELANOUS_HARNESS_SEAT;
480
+ recordRunExit({ runId, reason, status, signal, at: new Date().toISOString(),
481
+ ...(context.entrance ? { entrance: context.entrance } : {}),
482
+ ...(['OP', 'TC', 'MK', 'UX'].includes(seat ?? '') ? { seat } : {}),
483
+ cwd: `${basename(dirname(cwd))}/${basename(cwd)}`, hostname: hostname().split('.')[0]!, pid: process.pid,
484
+ ...(context.output ? { lastLines: incidentLastLines(context.output) } : {}),
485
+ }, effectiveInstanceRoot());
460
486
  } catch { /* incident writes cannot change Pod output or exit */ }
461
487
  }
462
488
 
463
489
  /** Every Pod launch entrance (harness ask/say · dev ask --substrate pod) warns once after a recent burst; it never blocks the launch. */
464
490
  export function warnRecentIncidentBurst(
465
491
  root: string = effectiveInstanceRoot(), now: Date = new Date(), write: (line: string) => void = (line) => console.error(line),
492
+ context: { seat?: string; entrance?: string } = {},
466
493
  ): boolean {
467
494
  try {
468
- const burst = recentBurst(root, now);
495
+ const seat = context.seat ?? process.env.ELANOUS_HARNESS_SEAT;
496
+ const burst = recentBurst(root, now, { entrance: context.entrance,
497
+ ...(['OP', 'TC', 'MK', 'UX'].includes(seat ?? '') ? { seat } : {}) });
469
498
  if (!burst) return false;
470
499
  write(formatIncidentBurstWarning(burst));
471
- try { debug.log('harness.incident', 'burst', { reason: burst.reason, count: burst.count }); } catch { /* observation is fail-soft */ }
500
+ try { debug.log('harness.incident', 'burst', { reason: burst.reason, count: burst.count,
501
+ ...(burst.seat ? { seat: burst.seat } : {}), ...(burst.entrance ? { entrance: burst.entrance } : {}) }); } catch { /* observation is fail-soft */ }
472
502
  return true;
473
503
  } catch { return false; /* incident reads cannot block a launch */ }
474
504
  }
@@ -524,9 +554,23 @@ function hasHarnessPodJobApplied(runId: string | undefined, output: string): boo
524
554
  } finally { store.close(); }
525
555
  }
526
556
 
557
+ /** 10-05 PODPROVIDER — say which child provider a local run will use (an unnamed choice follows config). */
558
+ function announceLocalChildProvider(opts: unknown): void {
559
+ const child = opts as HarnessAskSayChildLlmOptions;
560
+ if (!child.childLlmProvider?.trim()) return;
561
+ console.error(`child provider 요청 = ${child.childLlmProvider.trim()}${child.childLlmModel?.trim() ? `/${child.childLlmModel.trim()}` : ''} (local)`);
562
+ }
563
+
564
+ /** `harness.authorOnPod` — 명시 true 만 켠다. 읽기 실패는 끔(호스트 저작)으로 둔다. */
565
+ function harnessAuthorOnPod(): boolean {
566
+ try { return getUserConfig().harness?.authorOnPod === true; }
567
+ catch { return false; }
568
+ }
569
+
527
570
  /** ⭐ 런 계약의 실행 칸 = pod — 호스트는 그래프를 안 돌리고 Pod 로 보낸다(harness-pod-dispatch.ts). */
528
571
  async function onPod(opts: unknown, entrance: 'cli-harness-ask' | 'cli-harness-say', input: string, pool: string,
529
- recordDispatch: (input: DispatchTaskInput, deps?: DispatchTaskDeps) => ReturnType<typeof dispatchTask> = dispatchTask): Promise<void> {
572
+ recordDispatch: (input: DispatchTaskInput, deps?: DispatchTaskDeps) => ReturnType<typeof dispatchTask> = dispatchTask,
573
+ authorOnPod = false): Promise<void> {
530
574
  const o = opts as HarnessSubstrateOpts;
531
575
  if (o.target !== undefined) {
532
576
  debug.log('harness.pod', 'target-refused', { target: o.target });
@@ -540,7 +584,8 @@ async function onPod(opts: unknown, entrance: 'cli-harness-ask' | 'cli-harness-s
540
584
  process.exitCode = 2;
541
585
  return;
542
586
  }
543
- warnRecentIncidentBurst();
587
+ warnRecentIncidentBurst(effectiveInstanceRoot(), new Date(), (line) => console.error(line),
588
+ { entrance, seat: o.seat });
544
589
  let dispatchRecorded = false;
545
590
  try {
546
591
  const goalText = entrance === 'cli-harness-ask' ? readFileSync(input, 'utf8') : input;
@@ -559,14 +604,21 @@ async function onPod(opts: unknown, entrance: 'cli-harness-ask' | 'cli-harness-s
559
604
  const { dispatchHarnessOnPod } = await import('./harness-pod-dispatch.js');
560
605
  let output = '';
561
606
  let runId: string | undefined;
562
- const status = await dispatchHarnessOnPod({ entrance, input, podPool: pool, ...(dispatchRecorded ? { dispatchRecorded: true } : {}), ...(o.podMemory ? { podMemory: o.podMemory } : {}), ...(o.after ? { after: o.after } : {}), ...(o.autoMerge === false ? { autoMerge: false } : {}), ...(o.base ? { base: o.base } : {}), ...(o.json ? { json: true } : {}), ...(o.source ? { source: o.source } : {}) },
607
+ const child = opts as HarnessAskSayChildLlmOptions;
608
+ // 10-05 PODPROVIDER: say which child provider the Pod will use when the launch named one.
609
+ if (child.childLlmProvider?.trim()) console.error(`child provider 요청 = ${child.childLlmProvider.trim()}${child.childLlmModel?.trim() ? `/${child.childLlmModel.trim()}` : ''} (pod · 자격 없으면 발사 전 거부)`);
610
+ const status = await dispatchHarnessOnPod({ entrance, input, podPool: pool, ...(authorOnPod && entrance === 'cli-harness-say' ? { authorOnPod: true } : {}),
611
+ ...(child.childLlmProvider?.trim() ? { childLlmProvider: child.childLlmProvider.trim() } : {}),
612
+ ...(child.childLlmModel?.trim() ? { childLlmModel: child.childLlmModel.trim() } : {}),
613
+ ...(child.childLlmEffort?.trim() ? { childLlmEffort: child.childLlmEffort.trim() } : {}), ...(dispatchRecorded ? { dispatchRecorded: true } : {}), ...(o.podMemory ? { podMemory: o.podMemory } : {}), ...((opts as HarnessAskSayChildLlmOptions).goalType ? { goalType: (opts as HarnessAskSayChildLlmOptions).goalType } : {}), ...(o.after ? { after: o.after } : {}), ...(o.autoMerge === false ? { autoMerge: false } : {}), ...(o.base ? { base: o.base } : {}), ...(o.json ? { json: true } : {}), ...(o.source ? { source: o.source } : {}), ...(o.seat ? { seat: o.seat } : {}) },
563
614
  { onOutput: (text) => {
564
615
  runId ??= harnessPodRunId(output + text);
565
616
  output = (output + text).slice(-16_000);
566
617
  } });
567
618
  if (status !== 0) {
568
619
  const classified = classifyHarnessPodExit({ status }, output, { ...(runId ? { runId } : {}) });
569
- recordClassifiedHarnessPodExit(runId ?? harnessPodRunId(output), classified.reason, status);
620
+ recordClassifiedHarnessPodExit(runId ?? harnessPodRunId(output), classified.reason, status,
621
+ { entrance, seat: o.seat, output });
570
622
  for (const line of classified.lines) console.error(line);
571
623
  process.exitCode = status;
572
624
  }
@@ -634,7 +686,7 @@ async function dispatchHarnessAskSay(
634
686
  readonly wouldStart: string;
635
687
  readonly goalPath?: string;
636
688
  },
637
- dispatch: (resolved: ResolvedHarnessSubstrate) => Promise<void>,
689
+ dispatch: (resolved: ResolvedHarnessSubstrate, stampedOpts: HarnessAskSayChildLlmOptions & HarnessDryRunOpts) => Promise<void>,
638
690
  gate: PreLaunchGateDeps & { readBudget?: () => Promise<BudgetDecision | 'unknown'> } = {},
639
691
  ): Promise<void> {
640
692
  await runInjectedHarnessHandler(async () => {
@@ -644,6 +696,25 @@ async function dispatchHarnessAskSay(
644
696
  printHarnessLaunchDryRun(dryRunPreview);
645
697
  return;
646
698
  }
699
+ // Resolve the launch directory once; descendants and the checkpoint retain the same identity.
700
+ const queued = process.env.ELANOUS_HARNESS_QUEUE_LAUNCH && process.env.ELANOUS_HARNESS_SEAT;
701
+ const queueSeat = queued === 'OP' || queued === 'TC' || queued === 'MK' || queued === 'UX' ? queued : undefined;
702
+ const assigned = opts.seat ?? queueSeat ?? queueSeatForCwd(process.cwd(), getUserConfig().loops?.orchestrator?.seatTrees);
703
+ const inheritedSeat = process.env.ELANOUS_HARNESS_SEAT;
704
+ const podSeat = resolved.substrate === 'pod' && ['OP', 'TC', 'MK', 'UX'].includes(inheritedSeat ?? '')
705
+ ? inheritedSeat as QueueSeat : undefined;
706
+ const stampedSeat = resolved.substrate === 'pod' ? opts.seat ?? queueSeat ?? podSeat ?? assigned : assigned;
707
+ const stampedOpts = stampedSeat ? { ...opts, seat: stampedSeat } : opts;
708
+ const launch = async () => {
709
+ const previous = process.env.ELANOUS_HARNESS_SEAT;
710
+ if (stampedSeat) process.env.ELANOUS_HARNESS_SEAT = stampedSeat;
711
+ else delete process.env.ELANOUS_HARNESS_SEAT;
712
+ try { await dispatch(resolved, stampedOpts); }
713
+ finally {
714
+ if (previous === undefined) delete process.env.ELANOUS_HARNESS_SEAT;
715
+ else process.env.ELANOUS_HARNESS_SEAT = previous;
716
+ }
717
+ };
647
718
  // Without a GoalId, match the request to a live run's exact verbatim original ask; still check budget.
648
719
  let identity = dryRunPreview.input;
649
720
  let goalId: string | null = null;
@@ -658,7 +729,7 @@ async function dispatchHarnessAskSay(
658
729
  // CLI wiring tests time out on them. Gate tests inject deps or opt in with ELANOUS_LAUNCH_GATE_LIVE=1.
659
730
  if (process.env.NODE_ENV === 'test' && Object.keys(gate).length === 0 && process.env.ELANOUS_LAUNCH_GATE_LIVE !== '1') {
660
731
  try { debug.log('execution-loop.launch-gate', 'skipped-test-env', { goalId }); } catch { /* observation is fail-soft */ }
661
- await dispatch(resolved);
732
+ await launch();
662
733
  return;
663
734
  }
664
735
  const budget = await (gate.readBudget ?? (() => readHarnessLaunchBudget(opts)))();
@@ -673,7 +744,7 @@ async function dispatchHarnessAskSay(
673
744
  ...(decision.budget === 'unknown' ? ['budget unknown'] : decision.budget.action === 'next-provider' ? [decision.budget.reasons.join(' · ') || 'next-provider'] : []),
674
745
  ];
675
746
  if (warnings.length > 0) console.error(`⚠️ launch gate: ${warnings.join(' · ').split(/\r?\n/, 1)[0]}`);
676
- await dispatch(resolved);
747
+ await launch();
677
748
  });
678
749
  }
679
750
 
@@ -1582,6 +1653,12 @@ export async function runHarnessBudget(opts: { json?: boolean } = {}, io: {
1582
1653
 
1583
1654
  const DRAFT_SWEEP_REPOSITORY = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
1584
1655
 
1656
+ /** A review body still names a must-fix. «must-fix 0» and «must-fix: 0» are a cleared list, not a remaining one. */
1657
+ function mustFixRemains(text: string): boolean {
1658
+ if (!/(?:^|\n)\s*(?:[-*]\s*)?(?:must-fix|must fix)\b/i.test(text)) return false;
1659
+ return !/(?:^|\n)\s*(?:[-*]\s*)?(?:must-fix|must fix)\s*[:=]?\s*0\b/i.test(text);
1660
+ }
1661
+
1585
1662
  type GithubPull = {
1586
1663
  number: number;
1587
1664
  title: string;
@@ -1606,6 +1683,30 @@ const executeGh: GhExecute = (args) => execFileSync('gh', args, {
1606
1683
  stdio: ['ignore', 'pipe', 'pipe'], env: process.env,
1607
1684
  });
1608
1685
 
1686
+ /** Merge-time adapter: reuse the sweep's GitHub inventory and worktree liveness without a second triage implementation. */
1687
+ export async function supersedeMergedGoalDrafts(
1688
+ number: number, cwd: string,
1689
+ execute: GhExecute = executeGh, git: DraftSweepGitExecute = runGitCommand,
1690
+ ): Promise<void> {
1691
+ const remote = git(cwd, ['config', '--get', 'remote.origin.url']);
1692
+ const repository = remote.status === 0 ? githubRemoteRepository(remote.stdout) : undefined;
1693
+ if (!repository) throw new Error('Merge repository unavailable');
1694
+ // The PR can change between open and merge; never authorize a close using locally reconstructed metadata.
1695
+ const pr = ghJson<GithubPull>(['api', `repos/${repository}/pulls/${number}`], execute);
1696
+ if (!pr || pr.number !== number || pr.state !== 'closed' || !pr.merged_at || !pr.title?.trim()
1697
+ || !pr.head?.ref?.trim() || !pr.created_at || !Array.isArray(pr.labels)
1698
+ || !Number.isFinite(Date.parse(pr.created_at)) || !Number.isFinite(Date.parse(pr.merged_at))
1699
+ || Date.parse(pr.merged_at) < Date.parse(pr.created_at)) {
1700
+ throw new Error('Merged PR metadata unavailable');
1701
+ }
1702
+ const merged: SweepMergedPr & { createdAt: string; mergedAt: string } = {
1703
+ number: pr.number, title: pr.title, body: pr.body ?? undefined, branch: pr.head.ref,
1704
+ createdAt: pr.created_at, mergedAt: pr.merged_at,
1705
+ };
1706
+ const { supersedeDraftsOnMerge } = await import('../self-dev/draft-sweep.js');
1707
+ await supersedeDraftsOnMerge({ repository, merged, adapters: githubDraftSweepAdapters(execute, git, cwd) });
1708
+ }
1709
+
1609
1710
  function ghJson<T>(args: string[], execute: GhExecute): T {
1610
1711
  return JSON.parse(execute(args)) as T;
1611
1712
  }
@@ -1670,7 +1771,7 @@ function githubRemoteRepository(url: string): string | undefined {
1670
1771
  return match?.[1];
1671
1772
  }
1672
1773
 
1673
- export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: DraftSweepGitExecute = runGitCommand): DraftSweepAdapters {
1774
+ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: DraftSweepGitExecute = runGitCommand, cwd = process.cwd()): DraftSweepAdapters {
1674
1775
  const inventory = async (repository: string, state: 'open' | 'closed'): Promise<GithubPull[]> => {
1675
1776
  // ⛔ A large repository has tens of thousands of closed PRs (2026-09-28: 21k → «exceeded pagination limit», no sweep at all).
1676
1777
  // Merged twins only matter after the oldest open draft was opened, so the closed listing stops at that time.
@@ -1741,6 +1842,36 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
1741
1842
  }
1742
1843
  return undefined;
1743
1844
  };
1845
+ const reviewGateForDraft = (draft: SweepDraft, repository: string): SweepReviewGate | undefined => {
1846
+ const head = ghJson<{ head?: { sha?: string } }>(['api', `repos/${repository}/pulls/${draft.number}`], execute);
1847
+ const sha = head?.head?.sha;
1848
+ if (!sha) return undefined;
1849
+ const comments: string[] = [];
1850
+ for (let page = 1; page <= 100; page++) {
1851
+ const batch = ghJson<Array<{ body?: string }>>(['api', `repos/${repository}/issues/${draft.number}/comments?per_page=100&page=${page}`], execute);
1852
+ if (!Array.isArray(batch) || batch.length > 100) throw new Error('Incomplete review comment inventory');
1853
+ comments.push(...batch.map((comment) => comment.body ?? ''));
1854
+ if (batch.length < 100) break;
1855
+ if (page === 100) throw new Error('Review comment inventory exceeded pagination limit');
1856
+ }
1857
+ const reviews = ghJson<Array<{ state?: string; body?: string }>>(['api', `repos/${repository}/pulls/${draft.number}/reviews?per_page=100`], execute);
1858
+ if (!Array.isArray(reviews) || reviews.length > 100) throw new Error('Incomplete review inventory');
1859
+ const text = [...comments, ...reviews.map((review) => review.body ?? '')].join('\n');
1860
+ const status = ghJson<{ state?: string }>(['api', `repos/${repository}/commits/${sha}/status`], execute);
1861
+ const checkRuns = ghJson<{ check_runs?: Array<{ conclusion?: string | null }> }>(
1862
+ ['api', `repos/${repository}/commits/${sha}/check-runs?per_page=100`], execute);
1863
+ if (!checkRuns || !Array.isArray(checkRuns.check_runs)) throw new Error('Incomplete check-run inventory');
1864
+ const conclusions = checkRuns.check_runs.map((run) => run.conclusion ?? null);
1865
+ const gatePass = (status?.state === 'success' || status?.state === undefined)
1866
+ && conclusions.length > 0 && conclusions.every((conclusion) => conclusion === 'success' || conclusion === 'skipped' || conclusion === 'neutral');
1867
+ const gateFail = status?.state === 'failure' || status?.state === 'error'
1868
+ || conclusions.some((conclusion) => conclusion === 'failure' || conclusion === 'cancelled' || conclusion === 'timed_out' || conclusion === 'action_required');
1869
+ return {
1870
+ ...(reviews.some((review) => review.state === 'APPROVED') || /(?:^|\n)\s*VERDICT:\s*PASS\b/i.test(text) ? { review: 'pass' as const } : {}),
1871
+ ...(mustFixRemains(text) ? { mustFix: true } : {}),
1872
+ ...(gatePass && !gateFail ? { gate: 'pass' as const } : gateFail ? { gate: 'fail' as const } : {}),
1873
+ };
1874
+ };
1744
1875
  const landingCommentsFor = (repository: string, number: number): string[] => {
1745
1876
  const comments: string[] = [];
1746
1877
  for (let page = 1; page <= 100; page++) {
@@ -1763,6 +1894,7 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
1763
1894
  return draftSweepRunStatus(ledgerMatches, running, repository, draft.number);
1764
1895
  };
1765
1896
  return {
1897
+ getPrFiles: async (repository, number) => filesFor(repository, number),
1766
1898
  listDrafts: async (page, perPage, repository): Promise<SweepDraft[]> =>
1767
1899
  (await listed(open, repository, 'open')).filter((pr) => pr.draft)
1768
1900
  .slice((page - 1) * perPage, page * perPage)
@@ -1811,7 +1943,6 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
1811
1943
  } finally { store.close(); }
1812
1944
  },
1813
1945
  listLiveBranches: async (repository) => {
1814
- const cwd = process.cwd();
1815
1946
  const remote = git(cwd, ['config', '--get', 'remote.origin.url']);
1816
1947
  if (remote.status !== 0 || githubRemoteRepository(remote.stdout)?.toLowerCase() !== repository.toLowerCase()) {
1817
1948
  return undefined;
@@ -1829,6 +1960,7 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
1829
1960
  execute(['pr', 'close', String(number), '--repo', repository, '--comment', comment]);
1830
1961
  },
1831
1962
  getClaimOwner: async (repository, number) => claimCommentOwner(repository, number, execute),
1963
+ getReviewGate: async (draft, repository) => reviewGateForDraft(draft, repository),
1832
1964
  };
1833
1965
  }
1834
1966
 
@@ -1863,7 +1995,10 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
1863
1995
  .action(async (number: string, opts: { owner?: string; note?: string; release?: boolean; repo?: string }) => {
1864
1996
  try {
1865
1997
  const execute = deps.execute ?? executeGh;
1866
- const repository = opts.repo ?? deps.repository?.() ?? execute(['repo', 'view', '--json', 'nameWithOwner', '--jq', '.nameWithOwner']).trim();
1998
+ const repository = resolveRepositoryName({
1999
+ repo: opts.repo ?? deps.repository?.(),
2000
+ executeGh: (args) => execute(args),
2001
+ });
1867
2002
  if (!DRAFT_SWEEP_REPOSITORY.test(repository) || repository.includes('..')) throw new HarnessCliInputError(`invalid --repo (expected owner/name): ${repository}`);
1868
2003
  if (!/^[1-9]\d*$/.test(number) || !Number.isSafeInteger(Number(number))) throw new HarnessCliInputError(`invalid PR number: ${number}`);
1869
2004
  const owner = opts.owner?.trim();
@@ -1900,26 +2035,86 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
1900
2035
  .action(async (opts: { apply?: boolean; json?: boolean; repo?: string }) => {
1901
2036
  try {
1902
2037
  const write = deps.write ?? console.log;
1903
- const repository = opts.repo ?? deps.repository?.() ?? execFileSync('gh', ['repo', 'view', '--json', 'nameWithOwner', '--jq', '.nameWithOwner'],
1904
- { encoding: 'utf8', timeout: 30_000, stdio: ['ignore', 'pipe', 'pipe'], env: process.env }).trim();
2038
+ const execute = deps.execute ?? executeGh;
2039
+ const repository = resolveRepositoryName({
2040
+ repo: opts.repo ?? deps.repository?.(),
2041
+ executeGh: (args) => execute(args),
2042
+ });
1905
2043
  if (!DRAFT_SWEEP_REPOSITORY.test(repository) || repository.includes('..')) {
1906
2044
  throw new HarnessCliInputError(`invalid --repo (expected owner/name): ${repository}`);
1907
2045
  }
1908
2046
  const result: DraftSweepResult = await runDraftSweep({ repository, apply: opts.apply === true, adapters: deps.adapters ?? githubDraftSweepAdapters(deps.execute) });
1909
- if (opts.json) write(JSON.stringify(result));
2047
+ const reason = result.error ? sweepFailureReason(result.error) : undefined;
2048
+ if (opts.json) write(JSON.stringify(reason ? { ...result, error: reason } : result));
1910
2049
  else {
1911
- write(`draft sweep ${result.repository}: ${result.complete ? 'complete' : `incomplete (${result.error})`} · ${result.apply ? 'apply' : 'dry-run'}`);
1912
- for (const entry of result.entries) write(`#${entry.number} ${entry.action}: ${entry.reason}${entry.statusLabel ? ` → ${entry.statusLabel}` : ''}${entry.error ? ` ERROR: ${entry.error}` : ''}`);
1913
- if (result.complete) write(`못 본 초안 ${result.unobserved ?? 0} · 이번에 닫음 ${result.closed ?? 0}${result.apply ? '' : '(dry-run)'} · 처리 중 ${result.claimed ?? 0} · 표식 만료 ${result.claimExpired ?? 0}`);
2050
+ write(`draft sweep ${result.repository}: ${result.complete ? 'complete' : `incomplete (${reason})`} · ${result.apply ? 'apply' : 'dry-run'}`);
2051
+ for (const entry of result.entries) write(`#${entry.number} ${entry.action}: ${entry.reason}${entry.statusLabel ? ` → ${entry.statusLabel}` : ''}${entry.error ? ` ERROR: ${sweepFailureReason(entry.error)}` : ''}`);
2052
+ if (result.complete) {
2053
+ const daily = result.daily
2054
+ ? ` · 24h 넘음 ${result.daily.over24h} · 정리 대상 ${result.daily.closable} · 수확 대기 ${result.daily.harvestable} · 막힘 ${result.daily.blocked}`
2055
+ : '';
2056
+ write(`못 본 초안 ${result.unobserved ?? 0} · 이번에 닫음 ${result.closed ?? 0}${result.apply ? '' : '(dry-run)'} · 처리 중 ${result.claimed ?? 0} · 표식 만료 ${result.claimExpired ?? 0}${daily}`);
2057
+ }
2058
+ if (reason) write(reason);
1914
2059
  }
1915
2060
  if (!result.complete || result.entries.some((entry) => entry.error)) process.exitCode = 1;
1916
2061
  } catch (error) {
1917
2062
  console.error(humanErrorLine(error));
2063
+ try { debug.log('drafts.cleanup', 'failed', { reason: sweepFailureReason(error) }); } catch { /* observation is fail-soft */ }
1918
2064
  process.exitCode = 1;
1919
2065
  }
1920
2066
  });
1921
2067
  }
1922
2068
 
2069
+ function renderHarnessGoal(result: GoalLookupResult, universe: '운영' | '시험'): string {
2070
+ const matchedRun = result.runState?.results.find((entry) => entry.runId === result.runId);
2071
+ return [
2072
+ `골: ${result.goalBody?.split(/\r?\n/, 1)[0] || '골 문서에 없음'}`,
2073
+ `runId: ${result.runId ?? '원장에 없음'}`,
2074
+ `칸 id: ${result.kanId ?? '기록 없음'}`,
2075
+ `PR: ${result.record?.prNumber != null ? `#${result.record.prNumber}` : '기록 없음'}`,
2076
+ `stage/결과: ${result.record?.stage ?? '기록 없음'} / ${result.record?.outcome ?? '기록 없음'}`,
2077
+ `종결 사유: ${result.runState?.supervisorStopReason ?? matchedRun?.error?.message ?? '기록 없음'}`,
2078
+ `찾은 우주: ${universe}`,
2079
+ `원장: ${result.runState ? '찾음' : '원장에 없음'}`,
2080
+ `골 문서: ${result.goalFile ? '찾음' : '골 문서에 없음'}`,
2081
+ ].join('\n');
2082
+ }
2083
+
2084
+ function installHarnessGoalCommand(harnessCmd: Command, options?: GoalLookupOptions, archiveOptions?: GoalArchiveOptions): Command {
2085
+ const goal = harnessCmd.command('goal').usage('<reference> | archive [--before <date>] [--apply]')
2086
+ .description('골 문서와 실행 결과를 조회하거나 보관한다');
2087
+ goal.command('archive')
2088
+ .description('종료된 골 문서를 미리 보거나 상태 루트에 보관한다 — 저장소는 건드리지 않고 지울 목록(filesForPr)만 낸다')
2089
+ .option('--before <date>', '완료 시각이 이 YYYY-MM-DD 이전인 골만')
2090
+ .option('--apply', '상태 루트에 보관 복사·색인 (저장소 삭제·스테이지·커밋 없음 · 지우기는 filesForPr 로 사람이 PR)')
2091
+ .option('--trust-doc-record', '런 원장이 없을 때 문서에 적힌 종료 실행 기록을 신뢰')
2092
+ .action((opts: { before?: string; apply?: boolean; trustDocRecord?: boolean }) => {
2093
+ try {
2094
+ const result = archiveGoals({ ...archiveOptions, before: opts.before, apply: opts.apply, trustDocRecord: opts.trustDocRecord });
2095
+ console.log(JSON.stringify(result));
2096
+ } catch (error) {
2097
+ console.error(humanErrorLine(error));
2098
+ process.exitCode = 1;
2099
+ }
2100
+ });
2101
+ goal.command('show <reference>', { isDefault: true })
2102
+ .description('PR 번호 또는 runId 로 골 문서와 실행 결과를 조회한다 (읽기 전용)')
2103
+ .option('--json', 'GoalLookupResult 그대로 출력')
2104
+ .action((reference: string, opts: { json?: boolean }) => {
2105
+ try {
2106
+ const result = lookupGoal(reference, options);
2107
+ const universe = effectiveInstanceRoot() === prodInstanceRoot() ? '운영' : '시험';
2108
+ console.log(opts.json ? JSON.stringify(result) : renderHarnessGoal(result, universe));
2109
+ if (!result.goalFile || !result.runState) process.exitCode = 1;
2110
+ } catch (error) {
2111
+ console.error(humanErrorLine(error));
2112
+ process.exitCode = 1;
2113
+ }
2114
+ });
2115
+ return goal;
2116
+ }
2117
+
1923
2118
  function installHarnessBudgetCommand(harnessCmd: Command): Command {
1924
2119
  return harnessCmd
1925
2120
  .command('budget')
@@ -2106,6 +2301,8 @@ export interface HarnessCliCommandDeps {
2106
2301
  processObservation?: HarnessProcessObservationDeps;
2107
2302
  draftSweep?: HarnessDraftSweepDeps;
2108
2303
  queue?: HarnessQueueDeps;
2304
+ goalLookup?: GoalLookupOptions;
2305
+ goalArchive?: GoalArchiveOptions;
2109
2306
  ask?: HarnessAskHandler;
2110
2307
  say?: HarnessSayHandler;
2111
2308
  /** Observe-only Pod host dispatch seam. */
@@ -2124,6 +2321,27 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
2124
2321
  .command('harness')
2125
2322
  .description('dev-harness worktree 수명 — 워크트리 생성(worktree add)·조회(worktrees)·정리(clean)·프로세스 관찰(processes)');
2126
2323
  installHarnessCliSinkHook(harnessCmd, deps.registerSink, deps.resolveSurface);
2324
+ harnessCmd.command('doors').description('기간 안 런을 입구×대기열 경유 표로 읽는다')
2325
+ .option('--since <window>', '조회 창 (30m · 12h · 1d, 기본 1d)', '1d')
2326
+ .option('--json', '구조화 출력')
2327
+ .action((opts: { since?: string; json?: boolean }) => {
2328
+ const parsed = parseDoorSince(opts.since);
2329
+ if ('error' in parsed) {
2330
+ console.error(`❌ ${parsed.error}`);
2331
+ process.exitCode = 2;
2332
+ return;
2333
+ }
2334
+ let table: DoorTable;
2335
+ try {
2336
+ table = queryLaunchDoors({ sinceMs: parsed.sinceMs });
2337
+ } catch (error) {
2338
+ console.error(`❌ doors: ${error instanceof Error ? error.message : String(error)}`);
2339
+ process.exitCode = 1;
2340
+ return;
2341
+ }
2342
+ if (opts.json) console.log(JSON.stringify(table));
2343
+ else console.log(renderLaunchDoors(table));
2344
+ });
2127
2345
  harnessCmd.command('incidents').description('최근 하니스 Pod 종료 사고 원장을 읽는다')
2128
2346
  .option('--since <minutes>', '최근 몇 분의 종료를 볼지 (기본 15분)', '15')
2129
2347
  .option('--json', '구조화 출력')
@@ -2146,8 +2364,8 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
2146
2364
  const bursts = detectBursts(rows).filter((burst) => Date.parse(burst.lastAt) >= now - since * 60_000 && Date.parse(burst.lastAt) <= now);
2147
2365
  if (opts.json) console.log(JSON.stringify({ rows: selected, bursts }));
2148
2366
  else {
2149
- for (const row of selected) console.log(`${row.at} run ${row.runId} · ${row.reason} · status=${row.status} signal=${row.signal ?? '-'}`);
2150
- for (const burst of bursts) console.log(`${burst.firstAt}–${burst.lastAt} 묶음 ${burst.reason} ×${burst.count} · ${burst.runIds.join(', ')}`);
2367
+ for (const row of selected) console.log(`${row.at} run ${row.runId} · seat=${row.seat ?? '-'} entrance=${row.entrance ?? '-'} reason=${row.reason} · status=${row.status} signal=${row.signal ?? '-'}`);
2368
+ for (const burst of bursts) console.log(`${burst.firstAt}–${burst.lastAt} 묶음 ${burst.reason} ×${burst.count} · seat=${burst.seat ?? '-'} entrance=${burst.entrance ?? '-'} · ${burst.runIds.join(', ')}`);
2151
2369
  }
2152
2370
  } catch (error) {
2153
2371
  console.error(humanErrorLine(error));
@@ -2157,6 +2375,7 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
2157
2375
  installDeliverableVerifyCliCommand(harnessCmd, deps.deliverableVerify);
2158
2376
  installHarnessProcessObservationCommand(harnessCmd, deps.processObservation);
2159
2377
  installHarnessBudgetCommand(harnessCmd);
2378
+ installHarnessGoalCommand(harnessCmd, deps.goalLookup, deps.goalArchive);
2160
2379
  installHarnessDraftSweepCommand(harnessCmd, deps.draftSweep);
2161
2380
  const queue = harnessCmd.command('queue').description('자리별 영속 발사 대기열');
2162
2381
  const queueDeps = deps.queue ?? {};
@@ -2169,7 +2388,7 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
2169
2388
  console.log(`${row.id} ${row.seat} ${row.kind} queued`);
2170
2389
  }));
2171
2390
  queue.command('list').description('대기·발사 원장 조회').action(() => queueAction(async () => {
2172
- for (const row of listHarnessQueue(queueDeps)) console.log(`${row.id} ${row.seat} ${row.status} ${row.kind} ${row.input}`);
2391
+ for (const row of listHarnessQueue(queueDeps)) console.log(`${row.id} ${row.seat} ${row.status} ${row.kind} ${row.input}${row.waitingReason ? ` · ${row.waitingReason}` : ''}`);
2173
2392
  }));
2174
2393
  queue.command('remove <id>').description('대기 중 또는 종료 확인된 항목 제거').action((id: string) => queueAction(async () => {
2175
2394
  if (!await removeHarnessQueue(id, queueDeps)) throw new Error(`queue item active or not found: ${id}`);
@@ -2178,7 +2397,7 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
2178
2397
  queue.command('reconcile <id>').description('불확정 발사를 확인하고 종료 또는 미발사 증거가 있으면 예약 해소').action((id: string) => queueAction(async () => {
2179
2398
  console.log(`${id} ${await reconcileHarnessQueue(id, queueDeps)}`);
2180
2399
  }));
2181
- queue.command('tick').description('맨 앞 한 건의 자리 몫과 Pod 풀 여유를 확인하고 발사').action(() => queueAction(async () => {
2400
+ queue.command('tick').description('자리별 맨 앞 한 건을 라운드로빈으로 돌며 자리 몫·Pod 풀 여유·마무리 관문을 확인하고 한 건 발사').action(() => queueAction(async () => {
2182
2401
  const result = await tickHarnessQueue(queueDeps);
2183
2402
  console.log(`${result.outcome}${result.item ? ` ${result.item.id}` : ''}: ${result.reason}`);
2184
2403
  }));
@@ -2197,13 +2416,13 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
2197
2416
  ...(opts.goalType !== undefined ? { goalType: opts.goalType } : {}),
2198
2417
  ...(opts.target !== undefined ? { target: opts.target } : {}),
2199
2418
  },
2200
- (resolved) => {
2419
+ (resolved, stampedOpts) => {
2201
2420
  if (resolved.substrate !== 'pod' && (opts as { source?: string }).source !== undefined) {
2202
2421
  console.error('`--source` 는 `--substrate pod` 와 함께');
2203
2422
  process.exitCode = 2;
2204
2423
  return Promise.resolve();
2205
2424
  }
2206
- return resolved.substrate === 'pod' ? onPod(opts, 'cli-harness-ask', goalPath, resolved.pool!, deps.podDispatchTask) : ask(goalPath, normalizeHarnessAskSayOptions(opts));
2425
+ return resolved.substrate === 'pod' ? onPod(stampedOpts, 'cli-harness-ask', goalPath, resolved.pool!, deps.podDispatchTask) : (announceLocalChildProvider(stampedOpts), ask(goalPath, normalizeHarnessAskSayOptions(stampedOpts)));
2207
2426
  },
2208
2427
  deps.launchGate,
2209
2428
  );
@@ -2222,13 +2441,15 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
2222
2441
  wouldStart: '골 문서 · 워크트리 · 브랜치 · 자식 · 파이프라인',
2223
2442
  ...(opts.target !== undefined ? { target: opts.target } : {}),
2224
2443
  },
2225
- (resolved) => {
2444
+ (resolved, stampedOpts) => {
2226
2445
  if (resolved.substrate !== 'pod' && (opts as { source?: string }).source !== undefined) {
2227
2446
  console.error('`--source` 는 `--substrate pod` 와 함께');
2228
2447
  process.exitCode = 2;
2229
2448
  return Promise.resolve();
2230
2449
  }
2231
- return resolved.substrate === 'pod' ? onPod(opts, 'cli-harness-say', sentence.join(' '), resolved.pool!, deps.podDispatchTask) : say(sentence, normalizeHarnessAskSayOptions(opts));
2450
+ return resolved.substrate === 'pod'
2451
+ ? onPod(stampedOpts, 'cli-harness-say', sentence.join(' '), resolved.pool!, deps.podDispatchTask, harnessAuthorOnPod())
2452
+ : (announceLocalChildProvider(stampedOpts), say(sentence, normalizeHarnessAskSayOptions(stampedOpts)));
2232
2453
  },
2233
2454
  deps.launchGate,
2234
2455
  );