elanous 0.2.27 → 0.2.28

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 (285) 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/chunks/{1454-a9c338f5bb556f42.js → 1454-29d1d773d5996a49.js} +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{599-a914cc0468f56143.js → 599-56f2c0a5cc4a7295.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/app/approvals/page-5ab1e47978577c5e.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/app/autopilot/{page-07110da72c45e68f.js → page-24453f6a302816b4.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/app/board/{page-d2d76d4a7eae91bd.js → page-6c131d30bb1cf871.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/app/botlab/page-fa46d4588e8442c2.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/app/bots/{page-e5a9302c105725a3.js → page-dc0772b11861af51.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/app/ceo/page-66ad46ed0279feb9.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/app/chat/page-5159dc8752c6cd29.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/app/consult/page-c5a2478861c08b87.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/app/control/page-f722a9dec084e08b.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/app/decisions/{page-6a16a48d1aa6e91f.js → page-256ffd365d32e100.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e0de78ae7b99f01c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/app/editor/page-cfbdc44b708d9801.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/app/exec/{page-39f82acf619cca23.js → page-4c741eb760f2f77c.js} +1 -1
  18. package/apps/pwa/out/_next/static/chunks/app/field/{page-7c2c8f81b185f9c0.js → page-e9ba98f5f1440a21.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/app/inside/{page-ae7aff07e32676bb.js → page-dafc901bb1b72b5f.js} +1 -1
  20. package/apps/pwa/out/_next/static/chunks/app/intake/{page-482c60c1bc540d0a.js → page-2f6f303fa114ec24.js} +1 -1
  21. package/apps/pwa/out/_next/static/chunks/app/{layout-7cb996c1aa08b6f5.js → layout-1634081c5272006c.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/app/live/{page-623e08fe4477d606.js → page-ced0bcfc6542b3fc.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/app/live-run/{page-db460cd8aecb8490.js → page-bb1f05cd51c38944.js} +1 -1
  24. package/apps/pwa/out/_next/static/chunks/app/loops/{page-ff27902d0b11ef4f.js → page-646b50f63b6fe732.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/app/market/page-db069b48a59c8c00.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/{page-1917ea87ea71ab6b.js → page-f736324afa2117c1.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/app/morning/{page-25a302273b054fd7.js → page-6f131b51193a36f9.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/app/{not-found-670510eda8b9443f.js → not-found-435f5e2faf02bc01.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/app/observatory/page-497e0eedf20e7890.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-a8d28fdf995e16ea.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-4bb7556e2e97a750.js → page-8966452228753c5e.js} +1 -1
  32. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fd5d18656cb432b6.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5663779cb1a37609.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/app/{page-4eb96fc7241c2456.js → page-66a67eb19ebd976b.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/app/reflection/page-3b492aa78cf3c4a6.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/app/scheduler/{page-0d64ff212dc55d03.js → page-c71267e7681da982.js} +1 -1
  37. package/apps/pwa/out/_next/static/chunks/app/sessions/{page-7f096248993fc2d4.js → page-a21d1e1797172692.js} +1 -1
  38. package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-e47fc72049149a38.js → page-cb249e81ed339318.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/app/settings/{page-f7d808e31e005895.js → page-781cfc5114e097da.js} +1 -1
  40. package/apps/pwa/out/_next/static/chunks/app/setup/done/{page-5c2b24b5496dad73.js → page-478157214db6a023.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/app/setup/{page-76cdb531668b5191.js → page-86141f12cf090b7f.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/app/share/page-7256c73bb1c36751.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/app/showroom/page-5c738ca7adef3de5.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/app/tasks/page-0138c8091ec17224.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/app/term/page-cc2f24f16d85e735.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/app/today/{page-dab163b338e3b966.js → page-979d318a534e92da.js} +1 -1
  47. package/apps/pwa/out/_next/static/chunks/app/trace/page-182d394f7e6e096b.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/app/vault/{page-0260ffc7eda50db1.js → page-21050928a697ed7a.js} +1 -1
  49. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-44b9d807005a9030.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/app/workflows/{page-99c4e6c7345a9156.js → page-601fb77340e63c9a.js} +1 -1
  51. package/apps/pwa/out/_next/static/chunks/app/workspace/page-75d3fb5d47af0edf.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-11bf9e5725a72c22.js +1 -0
  53. package/apps/pwa/out/approvals/index.html +1 -1
  54. package/apps/pwa/out/approvals/index.txt +13 -13
  55. package/apps/pwa/out/autopilot/index.html +1 -1
  56. package/apps/pwa/out/autopilot/index.txt +13 -13
  57. package/apps/pwa/out/board/index.html +1 -1
  58. package/apps/pwa/out/board/index.txt +13 -13
  59. package/apps/pwa/out/botlab/index.html +1 -1
  60. package/apps/pwa/out/botlab/index.txt +13 -13
  61. package/apps/pwa/out/bots/index.html +1 -1
  62. package/apps/pwa/out/bots/index.txt +13 -13
  63. package/apps/pwa/out/ceo/index.html +1 -1
  64. package/apps/pwa/out/ceo/index.txt +13 -13
  65. package/apps/pwa/out/chat/index.html +1 -1
  66. package/apps/pwa/out/chat/index.txt +13 -13
  67. package/apps/pwa/out/consult/index.html +1 -1
  68. package/apps/pwa/out/consult/index.txt +13 -13
  69. package/apps/pwa/out/control/index.html +1 -1
  70. package/apps/pwa/out/control/index.txt +13 -13
  71. package/apps/pwa/out/decisions/index.html +1 -1
  72. package/apps/pwa/out/decisions/index.txt +13 -13
  73. package/apps/pwa/out/design-check/index.html +1 -1
  74. package/apps/pwa/out/design-check/index.txt +13 -13
  75. package/apps/pwa/out/editor/index.html +1 -1
  76. package/apps/pwa/out/editor/index.txt +13 -13
  77. package/apps/pwa/out/exec/index.html +1 -1
  78. package/apps/pwa/out/exec/index.txt +13 -13
  79. package/apps/pwa/out/field/index.html +1 -1
  80. package/apps/pwa/out/field/index.txt +13 -13
  81. package/apps/pwa/out/healthz +1 -1
  82. package/apps/pwa/out/index.html +1 -1
  83. package/apps/pwa/out/index.txt +13 -13
  84. package/apps/pwa/out/inside/index.html +1 -1
  85. package/apps/pwa/out/inside/index.txt +13 -13
  86. package/apps/pwa/out/intake/index.html +1 -1
  87. package/apps/pwa/out/intake/index.txt +13 -13
  88. package/apps/pwa/out/live/index.html +1 -1
  89. package/apps/pwa/out/live/index.txt +13 -13
  90. package/apps/pwa/out/live-run/index.html +1 -1
  91. package/apps/pwa/out/live-run/index.txt +13 -13
  92. package/apps/pwa/out/loops/index.html +1 -1
  93. package/apps/pwa/out/loops/index.txt +13 -13
  94. package/apps/pwa/out/market/index.html +1 -1
  95. package/apps/pwa/out/market/index.txt +13 -13
  96. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  97. package/apps/pwa/out/missions/placeholder/index.txt +13 -13
  98. package/apps/pwa/out/morning/index.html +1 -1
  99. package/apps/pwa/out/morning/index.txt +13 -13
  100. package/apps/pwa/out/observatory/index.html +1 -1
  101. package/apps/pwa/out/observatory/index.txt +13 -13
  102. package/apps/pwa/out/ops/checklist/index.html +1 -1
  103. package/apps/pwa/out/ops/checklist/index.txt +13 -13
  104. package/apps/pwa/out/ops/release/index.html +1 -1
  105. package/apps/pwa/out/ops/release/index.txt +13 -13
  106. package/apps/pwa/out/ops/seats/index.html +1 -1
  107. package/apps/pwa/out/ops/seats/index.txt +13 -13
  108. package/apps/pwa/out/outputs/index.html +1 -1
  109. package/apps/pwa/out/outputs/index.txt +13 -13
  110. package/apps/pwa/out/reflection/index.html +1 -1
  111. package/apps/pwa/out/reflection/index.txt +14 -14
  112. package/apps/pwa/out/scheduler/index.html +1 -1
  113. package/apps/pwa/out/scheduler/index.txt +13 -13
  114. package/apps/pwa/out/sessions/index.html +1 -1
  115. package/apps/pwa/out/sessions/index.txt +13 -13
  116. package/apps/pwa/out/settings/devices/index.html +1 -1
  117. package/apps/pwa/out/settings/devices/index.txt +13 -13
  118. package/apps/pwa/out/settings/index.html +1 -1
  119. package/apps/pwa/out/settings/index.txt +13 -13
  120. package/apps/pwa/out/setup/done/index.html +1 -1
  121. package/apps/pwa/out/setup/done/index.txt +13 -13
  122. package/apps/pwa/out/setup/index.html +1 -1
  123. package/apps/pwa/out/setup/index.txt +13 -13
  124. package/apps/pwa/out/share/index.html +1 -1
  125. package/apps/pwa/out/share/index.txt +13 -13
  126. package/apps/pwa/out/showroom/index.html +1 -1
  127. package/apps/pwa/out/showroom/index.txt +13 -13
  128. package/apps/pwa/out/tasks/index.html +1 -1
  129. package/apps/pwa/out/tasks/index.txt +13 -13
  130. package/apps/pwa/out/term/index.html +1 -1
  131. package/apps/pwa/out/term/index.txt +13 -13
  132. package/apps/pwa/out/today/index.html +1 -1
  133. package/apps/pwa/out/today/index.txt +13 -13
  134. package/apps/pwa/out/trace/index.html +1 -1
  135. package/apps/pwa/out/trace/index.txt +13 -13
  136. package/apps/pwa/out/vault/index.html +1 -1
  137. package/apps/pwa/out/vault/index.txt +13 -13
  138. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  139. package/apps/pwa/out/workflows/chat-ui/index.txt +13 -13
  140. package/apps/pwa/out/workflows/index.html +1 -1
  141. package/apps/pwa/out/workflows/index.txt +13 -13
  142. package/apps/pwa/out/workspace/index.html +1 -1
  143. package/apps/pwa/out/workspace/index.txt +13 -13
  144. package/apps/pwa/out/worktrees/index.html +1 -1
  145. package/apps/pwa/out/worktrees/index.txt +13 -13
  146. package/graphs/implement-loop.yaml +38 -1
  147. package/graphs/steward/recipes.yaml +6 -0
  148. package/graphs/steward/release-day.yaml +23 -0
  149. package/graphs/steward/steward.yaml +9 -1
  150. package/graphs/work/code-pr.yaml +23 -0
  151. package/package.json +1 -1
  152. package/scripts/browser-observe-cycle.ts +76 -2
  153. package/scripts/ci-typecheck-changed.ts +50 -17
  154. package/scripts/detect-test-interference.ts +31 -1
  155. package/scripts/release-loop/docs-node.ts +51 -22
  156. package/scripts/release-loop/gate-node.ts +37 -4
  157. package/scripts/release-loop/node-verdict.ts +3 -1
  158. package/scripts/release-loop/publish-node.ts +3 -0
  159. package/scripts/release-loop/tui-node-checks.ts +5 -2
  160. package/scripts/skills/public-check.ts +5 -2
  161. package/scripts/test-deterministic.ts +520 -37
  162. package/scripts/ux-sim.ts +7 -1
  163. package/scripts/verify-kpack6-live.ts +230 -0
  164. package/src/acp/codex-plugins.ts +17 -0
  165. package/src/agent/task-notification.ts +2 -1
  166. package/src/agent-mission/in-agent-plugin.ts +8 -3
  167. package/src/agent-substrate/self-review-cli.ts +34 -10
  168. package/src/briefing/brief-items.ts +151 -35
  169. package/src/budget/llm-cost.ts +25 -2
  170. package/src/budget/usage-outcomes.ts +32 -0
  171. package/src/claims/claims-ledger.ts +23 -0
  172. package/src/claims/claims-render.ts +22 -2
  173. package/src/cli/brief-cli.ts +131 -10
  174. package/src/cli/claims-cli.ts +24 -4
  175. package/src/cli/msg-cli.ts +165 -9
  176. package/src/cli/plugin-cli.ts +11 -3
  177. package/src/cli/pr-cli.ts +80 -18
  178. package/src/cli/pr-land-refusal.ts +20 -0
  179. package/src/cli/release-cli.ts +2 -0
  180. package/src/cli/rfc-cli.ts +24 -0
  181. package/src/cli/tailscale-serve.ts +5 -8
  182. package/src/cli/tasks-cli.ts +393 -26
  183. package/src/cli/usage-cli.ts +9 -4
  184. package/src/dashboard/first-screen-band.ts +63 -13
  185. package/src/dashboard/index.ts +8 -3
  186. package/src/dashboard/skill-detection-runtime.ts +24 -4
  187. package/src/domains/morning-report.ts +3 -1
  188. package/src/github/pr-labels.ts +10 -4
  189. package/src/graph-runner/runner.ts +101 -14
  190. package/src/harness/harness-clean.ts +21 -3
  191. package/src/harness/harness-cli-command.ts +22 -6
  192. package/src/harness/harness-pod-dispatch.ts +11 -4
  193. package/src/hq/seats.ts +17 -3
  194. package/src/index.ts +34 -5
  195. package/src/intelligence-map/model-bench-scores.ts +102 -0
  196. package/src/loops/orchestrator/inbox.ts +73 -0
  197. package/src/loops/orchestrator/resync-shadow.ts +100 -12
  198. package/src/loops/orchestrator/tick.ts +73 -2
  199. package/src/maturity/feature-maturity.ts +1 -1
  200. package/src/msg/msg-sse-server.ts +141 -0
  201. package/src/msg/msg-store.ts +84 -14
  202. package/src/patents/ledger.ts +128 -0
  203. package/src/plugins/install/market-fetch.ts +32 -1
  204. package/src/pod-lease/admission.ts +116 -41
  205. package/src/release-loop/checklist.ts +11 -0
  206. package/src/release-loop/merged-pr-checklist.ts +24 -5
  207. package/src/release-loop/rubric.ts +70 -0
  208. package/src/rfc-registry/registry.ts +88 -0
  209. package/src/seat-dispatch/seat-request-ledger.ts +4 -0
  210. package/src/seat-loop/knowhow-lint.ts +233 -0
  211. package/src/seat-loop/seat-pack.ts +16 -4
  212. package/src/seat-loop/traffic-signal.ts +7 -0
  213. package/src/self-dev/ask-launch-flow.ts +48 -8
  214. package/src/self-dev/ask-path-candidates.ts +69 -14
  215. package/src/self-dev/decompose-proposal.ts +43 -1
  216. package/src/self-dev/graph-journey-nodes.ts +2 -0
  217. package/src/self-dev/launch-preflight-text.ts +5 -1
  218. package/src/self-dev/launch-preflight.ts +143 -10
  219. package/src/self-implement/gate-cli.ts +6 -2
  220. package/src/self-implement/goal-author.ts +2 -1
  221. package/src/self-implement/goal-new-paths.ts +4 -5
  222. package/src/self-implement/graph-authority.ts +17 -3
  223. package/src/self-implement/graph-yaml.ts +15 -7
  224. package/src/self-implement/headless-elanous-driver.ts +16 -1
  225. package/src/self-implement/host-regate.ts +44 -9
  226. package/src/self-implement/orchestrator.ts +3 -10
  227. package/src/self-implement/rework-policy.ts +80 -2
  228. package/src/self-implement/speed-claims.ts +145 -6
  229. package/src/skills/tools/persistent-grounding.ts +59 -4
  230. package/src/skills/tools/shell.ts +79 -1
  231. package/src/steward/rejudge-tick.ts +12 -1
  232. package/src/steward/release-day.ts +158 -0
  233. package/src/steward/resync-tick.ts +123 -0
  234. package/src/task-agent/actions.ts +1 -0
  235. package/src/task-agent/adopt-pr.ts +140 -0
  236. package/src/task-agent/board.ts +11 -1
  237. package/src/task-agent/card-evidence.ts +37 -5
  238. package/src/task-agent/cover.ts +84 -17
  239. package/src/task-agent/failure-notify.ts +61 -0
  240. package/src/task-agent/green-sweep.ts +170 -0
  241. package/src/task-agent/land-worktree.ts +52 -5
  242. package/src/task-agent/live-move-history.ts +1 -0
  243. package/src/task-agent/live-moves.ts +43 -12
  244. package/src/task-agent/parent-host.ts +1 -1
  245. package/src/task-agent/postland-card.ts +139 -0
  246. package/src/task-agent/rejudge-on-head.ts +106 -7
  247. package/src/task-agent/remote-rejudge-bind.ts +62 -0
  248. package/src/task-agent/repair-branch-cas.ts +182 -0
  249. package/src/task-agent/repair-cycle.ts +275 -0
  250. package/src/task-agent/repair-next-move.ts +31 -0
  251. package/src/task-agent/repair-review.ts +24 -0
  252. package/src/task-agent/repair-worker.ts +87 -0
  253. package/src/task-agent/review-result-capture.ts +2 -1
  254. package/src/task-agent/shadow.ts +13 -7
  255. package/src/task-agent/task-hand.ts +115 -6
  256. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +96 -0
  257. package/src/task-orchestrator/surfaces/self-implement-pod.ts +70 -12
  258. package/src/telegram.ts +30 -1
  259. package/src/user-config.ts +8 -1
  260. package/src/ux-sim/fault-sqlite-busy.ts +50 -0
  261. package/src/version/packed-revision.json +1 -1
  262. package/apps/pwa/out/_next/static/chunks/app/approvals/page-a1ce306364f08da9.js +0 -1
  263. package/apps/pwa/out/_next/static/chunks/app/botlab/page-30007380f2e2a3c1.js +0 -1
  264. package/apps/pwa/out/_next/static/chunks/app/ceo/page-b93c04b5311c97ec.js +0 -1
  265. package/apps/pwa/out/_next/static/chunks/app/chat/page-718a49e86bf25f9c.js +0 -1
  266. package/apps/pwa/out/_next/static/chunks/app/consult/page-20662900d6b4b455.js +0 -1
  267. package/apps/pwa/out/_next/static/chunks/app/control/page-f707a509515ac50c.js +0 -1
  268. package/apps/pwa/out/_next/static/chunks/app/design-check/page-fcb06e305f515527.js +0 -1
  269. package/apps/pwa/out/_next/static/chunks/app/editor/page-6acf5ec4e6c6d1af.js +0 -1
  270. package/apps/pwa/out/_next/static/chunks/app/market/page-8397a5c6ca569bf4.js +0 -1
  271. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d73c3f1e00d93986.js +0 -1
  272. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-65caacf54389081e.js +0 -1
  273. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-77e04b4f8762c666.js +0 -1
  274. package/apps/pwa/out/_next/static/chunks/app/outputs/page-15c0a4095baddfba.js +0 -1
  275. package/apps/pwa/out/_next/static/chunks/app/reflection/page-63e272a4cd3b6634.js +0 -1
  276. package/apps/pwa/out/_next/static/chunks/app/share/page-e2b63345bba1a11f.js +0 -1
  277. package/apps/pwa/out/_next/static/chunks/app/showroom/page-d376e0c83edc041a.js +0 -1
  278. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d6db55fe2c04d128.js +0 -1
  279. package/apps/pwa/out/_next/static/chunks/app/term/page-87b88f551f421d8b.js +0 -1
  280. package/apps/pwa/out/_next/static/chunks/app/trace/page-08019efef111ed2e.js +0 -1
  281. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-980ce6fe36ad95eb.js +0 -1
  282. package/apps/pwa/out/_next/static/chunks/app/workspace/page-0ab42e0f05823013.js +0 -1
  283. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ad9220422d20ba33.js +0 -1
  284. /package/apps/pwa/out/_next/static/{Ev2jivDMTSoEc-5rIXdcy → y1ltt7oCZxVpC6zVPhZ2O}/_buildManifest.js +0 -0
  285. /package/apps/pwa/out/_next/static/{Ev2jivDMTSoEc-5rIXdcy → y1ltt7oCZxVpC6zVPhZ2O}/_ssgManifest.js +0 -0
@@ -6,7 +6,8 @@ import { existsSync, readFileSync } from 'node:fs';
6
6
  import { elanousStateRoot } from '../autopilot/state-paths.js';
7
7
  import { userConfigPath } from '../user-config.js';
8
8
  import { debug, redactSecretText } from '../debug/log.js';
9
- import { addMarket, ensureInternalMarketIndex, listMarkets, MarketFetchError, updateMarket } from '../plugins/install/market-fetch.js';
9
+ import { addMarket, codexPluginPackagePath, ensureInternalMarketIndex, listMarkets, MarketFetchError, updateMarket } from '../plugins/install/market-fetch.js';
10
+ import { readCodexPluginList } from '../acp/codex-plugins.js';
10
11
  import { emitDecision } from '../live/detail-switch.js';
11
12
  import { OFFICIAL_INDEX_KEYS } from '../market/official-keys.js';
12
13
  import { installPlugin, listInstalledPlugins, PluginInstallError, removePlugin, type InstallEvent } from '../plugins/install/plugin-install.js';
@@ -118,15 +119,22 @@ export function registerPluginCommands(program: Command): void {
118
119
  }
119
120
  });
120
121
  plugin.command('add <spec>').description('Install a local path, pinned git plugin or signed market plugin')
122
+ .option('--from-codex', 'Import an installed Codex plugin by name@marketplace')
121
123
  .option('--yes', 'Accept requested capabilities')
122
124
  .option('--json', 'NDJSON progress events')
123
125
  .option('--allow-unsigned', 'Allow unsigned marketplace indices')
124
126
  .option('--refresh', 'Refresh the signed marketplace index before installing')
125
- .action(async (spec: string, opts: { yes?: boolean; json?: boolean; allowUnsigned?: boolean; refresh?: boolean }) => {
127
+ .action(async (spec: string, opts: { yes?: boolean; json?: boolean; allowUnsigned?: boolean; refresh?: boolean; fromCodex?: boolean }) => {
126
128
  try {
127
129
  const root = elanousStateRoot();
128
130
  const nodeCount = { value: 0 };
129
- await installPlugin(spec, {
131
+ let source = spec;
132
+ if (opts.fromCodex) {
133
+ const match = /^([a-z0-9][a-z0-9-]{1,39})@([a-z0-9][a-z0-9-]{1,39})$/.exec(spec);
134
+ if (!match) throw new PluginInstallError('io', 'Codex import requires name@marketplace');
135
+ source = codexPluginPackagePath(await readCodexPluginList(), match[1]!, match[2]!);
136
+ }
137
+ await installPlugin(source, {
130
138
  root, marketDir: join(root, 'plugins', 'markets'), trustedKeys: keys(),
131
139
  yes: opts.yes, allowUnsigned: opts.allowUnsigned, refresh: opts.refresh,
132
140
  onEvent: event => outputEvent(event, !!opts.json, nodeCount),
package/src/cli/pr-cli.ts CHANGED
@@ -58,7 +58,9 @@ import { parseReleaseNoteSection } from '../release-loop/release-note.js';
58
58
  import { landingFreezeMessage } from '../release-loop/landing-freeze.js';
59
59
  import { admitLandingMerge } from '../self-implement/frozen-merges.js';
60
60
  import { verifyAncestorAutoPass, verifyOverlapEvidence } from './pr-land-overlap-evidence.js';
61
+ import { observePrLandRefusal } from './pr-land-refusal.js';
61
62
  import { taskAgentStatePath } from '../task-agent/task-hand.js';
63
+ import { PR_LABEL_NAMES } from '../github/pr-labels.js';
62
64
  import { enqueueL8ShadowQueue, runL8ShadowQueue, shadowPrNumber, statusL8ShadowQueue, type L8ShadowQueueDeps } from '../self-implement/l8-merge-queue.js';
63
65
 
64
66
  export { branchLineageSlug, findSiblingPrs };
@@ -1143,8 +1145,36 @@ export function runPrGranularity(opts: PrGranularityOpts = {}, deps: PrLandDeps
1143
1145
  const GITHUB_MERGEABLE = new Set(['MERGEABLE', 'CONFLICTING', 'UNKNOWN']);
1144
1146
  const GITHUB_MERGE_STATE = new Set(['BEHIND', 'BLOCKED', 'CLEAN', 'DIRTY', 'DRAFT', 'HAS_HOOKS', 'UNKNOWN', 'UNSTABLE']);
1145
1147
 
1148
+ /** Read-only identity check shared by pinned landing and its dry-run. Later landing gates still run only on a real landing. */
1149
+ function inspectPinnedPr(run: CmdRunner, cwd: string, pr: number, expectedHead: string) {
1150
+ const viewed = run('gh', ['pr', 'view', String(pr), '--json', 'headRefOid,headRefName,state,isDraft,url'], { cwd });
1151
+ let value: { headRefOid?: string; headRefName?: string; state?: string; isDraft?: boolean; url?: string } = {};
1152
+ try {
1153
+ if (viewed.ok) {
1154
+ const parsed: unknown = JSON.parse(viewed.out);
1155
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) value = parsed as typeof value;
1156
+ }
1157
+ } catch { /* unreadable is not approval */ }
1158
+ const local = run('git', ['rev-parse', 'HEAD'], { cwd });
1159
+ const dirty = run('git', ['status', '--porcelain'], { cwd });
1160
+ const reasons: string[] = [];
1161
+ if (value.state !== 'OPEN') reasons.push('PR is not OPEN or its state is unavailable');
1162
+ if (value.isDraft !== false) reasons.push(value.isDraft === true ? 'PR is draft' : 'PR ready status is unavailable');
1163
+ if (value.headRefOid?.toLowerCase() !== expectedHead.toLowerCase()) reasons.push('PR head differs from --expected-head or is unavailable');
1164
+ if (!value.url?.endsWith(`/pull/${pr}`) || !value.headRefName) reasons.push('PR identity or head branch is unavailable');
1165
+ if (!local.ok || local.out.trim().toLowerCase() !== expectedHead.toLowerCase()) reasons.push('local HEAD differs from --expected-head or is unavailable');
1166
+ if (!dirty.ok || dirty.out.trim()) reasons.push(dirty.ok ? 'local worktree is dirty' : 'local worktree status is unavailable');
1167
+ return { ok: reasons.length === 0, reasons, branch: value.headRefName, url: value.url };
1168
+ }
1169
+
1146
1170
  export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): Promise<number> {
1147
1171
  const out = deps.out ?? liveOut;
1172
+ // First slice: observe pinned identity/branch, overlap decision, and GitHub merge refusals.
1173
+ // Option syntax and prerequisite gate errors do not describe a merge recovery edge.
1174
+ const refuse = (message: string, context: { isDraft?: boolean } = {}): void => {
1175
+ out.error(message);
1176
+ observePrLandRefusal(message, context);
1177
+ };
1148
1178
  if (opts.title !== undefined && opts.titleFile !== undefined) {
1149
1179
  out.error('✗ title: --title과 --title-file은 함께 사용할 수 없습니다.');
1150
1180
  return 1;
@@ -1248,6 +1278,31 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1248
1278
  out.log('- Mutations (ready/edit/create/merge, git commit/push, worktree): NOT RUN');
1249
1279
  return 0;
1250
1280
  }
1281
+ if (opts.dryRun && pinned) {
1282
+ const pr = Number(opts.pr);
1283
+ if (!/^[1-9]\d*$/.test(opts.pr ?? '') || !Number.isSafeInteger(pr) || !/^[a-f0-9]{40}$/i.test(opts.expectedHead ?? '')) {
1284
+ out.error('✗ expected-head: --pr and --expected-head (full SHA) are required together without --hold');
1285
+ return 1;
1286
+ }
1287
+ if (opts.hold) {
1288
+ out.error('✗ dry-run: --hold 는 머리 고정 읽기 전용 예행과 함께 사용할 수 없습니다.');
1289
+ return 1;
1290
+ }
1291
+ if (opts.overlapEvidence !== undefined) {
1292
+ out.error('✗ dry-run: --overlap-evidence 는 머리 고정 읽기 전용 예행에서 사용할 수 없습니다.');
1293
+ return 1;
1294
+ }
1295
+ const inspected = inspectPinnedPr(run, cwd, pr, opts.expectedHead!);
1296
+ const branch = (deps.currentBranch ?? liveCurrentBranch)(cwd);
1297
+ const reasons = [...inspected.reasons];
1298
+ if (!branch || branch !== inspected.branch) reasons.push('current branch differs from the PR head branch or is unavailable');
1299
+ out.log(`[dry-run] pinned PR #${pr} · expected head ${opts.expectedHead}`);
1300
+ for (const reason of reasons) out.log(`[dry-run] ✗ preflight: ${reason}`);
1301
+ if (reasons.includes('PR is draft')) out.log(`[dry-run] 선행: eln gh pr ready ${pr}`);
1302
+ if (reasons.length === 0) out.log('[dry-run] ✓ preflight: PR OPEN non-draft, matching PR/local HEAD and branch, clean worktree');
1303
+ out.log('[dry-run] Remaining landing gates, freeze, overlap and merge: UNMEASURED; no PR or git state changed.');
1304
+ return reasons.length === 0 ? 0 : 1;
1305
+ }
1251
1306
  if (opts.overlapEvidence !== undefined && (!pinned || !opts.overlapEvidence.trim())) {
1252
1307
  out.error('✗ overlap-evidence: --overlap-evidence <file> 는 --pr ⊕ --expected-head 머리 고정 착지에서만 쓴다.');
1253
1308
  return 1;
@@ -1256,30 +1311,26 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1256
1311
  let pinnedUrl: string | undefined;
1257
1312
  if (pinned) {
1258
1313
  const pr = Number(opts.pr);
1259
- if (!/^[1-9]\d*$/.test(opts.pr ?? '') || !Number.isSafeInteger(pr) || !/^[a-f0-9]{40}$/i.test(opts.expectedHead ?? '') || opts.hold || opts.dryRun) {
1260
- out.error('✗ expected-head: --pr and --expected-head (full SHA) are required together without --hold/--dry-run');
1314
+ if (!/^[1-9]\d*$/.test(opts.pr ?? '') || !Number.isSafeInteger(pr) || !/^[a-f0-9]{40}$/i.test(opts.expectedHead ?? '') || opts.hold) {
1315
+ out.error('✗ expected-head: --pr and --expected-head (full SHA) are required together without --hold');
1261
1316
  return 1;
1262
1317
  }
1263
- const viewed = run('gh', ['pr', 'view', String(pr), '--json', 'headRefOid,headRefName,state,isDraft,url'], { cwd });
1264
- let value: { headRefOid?: string; headRefName?: string; state?: string; isDraft?: boolean; url?: string } = {};
1265
- try { if (viewed.ok) value = JSON.parse(viewed.out) as typeof value; } catch { /* unreadable is not approval */ }
1266
- const local = run('git', ['rev-parse', 'HEAD'], { cwd });
1267
- const dirty = run('git', ['status', '--porcelain'], { cwd });
1268
- if (value.state !== 'OPEN' || value.isDraft !== false || value.headRefOid?.toLowerCase() !== opts.expectedHead!.toLowerCase()
1269
- || !value.url?.endsWith(`/pull/${pr}`) || !value.headRefName || !local.ok || local.out.trim().toLowerCase() !== opts.expectedHead!.toLowerCase()
1270
- || !dirty.ok || dirty.out.trim()) {
1271
- out.error('✗ expected-head: PR OPEN non-draft, matching local HEAD and clean worktree required');
1318
+ const inspected = inspectPinnedPr(run, cwd, pr, opts.expectedHead!);
1319
+ if (!inspected.ok) {
1320
+ refuse('✗ expected-head: PR OPEN non-draft, matching local HEAD and clean worktree required', {
1321
+ isDraft: inspected.reasons.includes('PR is draft'),
1322
+ });
1272
1323
  return 1;
1273
1324
  }
1274
- pinnedBranch = value.headRefName;
1275
- pinnedUrl = value.url;
1325
+ pinnedBranch = inspected.branch;
1326
+ pinnedUrl = inspected.url;
1276
1327
  }
1277
1328
  const resolveBase = deps.resolveBase ?? resolveDeliverableBase;
1278
1329
  const branch = (deps.currentBranch ?? liveCurrentBranch)(cwd);
1279
1330
  if (!branch || (pinned && branch !== pinnedBranch)) {
1280
1331
  const detail = pinned ? 'PR head branch와 현재 브랜치가 다릅니다.' : '현재 브랜치를 해석하지 못했습니다.';
1281
1332
  record('branch', false);
1282
- out.error(`✗ branch: ${detail}`);
1333
+ refuse(`✗ branch: ${detail}`);
1283
1334
  return 1;
1284
1335
  }
1285
1336
  record('branch', true);
@@ -1664,6 +1715,7 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1664
1715
  const hold = !!opts.hold || overlapDecision?.outcome === 'user-hold';
1665
1716
  // TA-LAND-OVERLAP — 비대화형 «승인 불가»만 증거로 대신한다(사람의 hold 는 증거로 뒤집지 않는다) · 증거가 없거나 어긋나면 종전 거부 그대로.
1666
1717
  let overlapEvidenceAccepted = false;
1718
+ let ancestorResyncNeeded = false;
1667
1719
  if (pinned && overlapDecision?.outcome === 'unavailable' && opts.overlapEvidence !== undefined) {
1668
1720
  const ref = resolveRemoteBranchRef(run, cwd, base);
1669
1721
  const verdict = verifyOverlapEvidence({
@@ -1678,7 +1730,7 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1678
1730
  ? `✓ overlap-evidence: base-advanced-disjoint — gate base ${verdict.gateBase.slice(0, 12)} ⊂ head ${opts.expectedHead!.slice(0, 12)} · ${ref.remote}/${ref.branch} ${verdict.baseTip.slice(0, 12)} 까지 ${verdict.windowCommits}개 커밋이 PR 파일을 안 건드린다 · review pass|warn must-fix 0 (${verdict.reviewResult})`
1679
1731
  : `✓ overlap-evidence: ${ref.remote}/${ref.branch} ${verdict.baseTip.slice(0, 12)} ⊂ head ${opts.expectedHead!.slice(0, 12)} · gate passed on that base · review pass must-fix 0 (${verdict.reviewResult})`);
1680
1732
  }
1681
- else out.error(`✗ overlap-evidence: ${verdict.reason}`);
1733
+ else refuse(`✗ overlap-evidence: ${verdict.reason}`);
1682
1734
  } else if (pinned && overlapDecision?.outcome === 'unavailable') {
1683
1735
  // 증거 파일이 없을 때 — 겹친 착지가 전부 머리의 조상이고 표준 자리의 리뷰가 pass|warn ⊕ must-fix 0 이면 통과(아니면 종전 거부).
1684
1736
  const verdict = verifyAncestorAutoPass({
@@ -1690,9 +1742,19 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1690
1742
  if (verdict.ok) {
1691
1743
  out.log(`✓ overlap-evidence: already-ancestor-auto — 겹친 최근 착지 ${overlappingLandings.length}개가 전부 head ${opts.expectedHead!.slice(0, 12)} 의 조상 · review pass|warn must-fix 0 (${verdict.reviewResult})`);
1692
1744
  }
1693
- else out.error(`✗ ancestor-auto: ${verdict.reason}`);
1745
+ else {
1746
+ refuse(`✗ ancestor-auto: ${verdict.reason}`);
1747
+ ancestorResyncNeeded = verdict.reason.startsWith('ancestor-auto-not-ancestor:');
1748
+ }
1694
1749
  }
1695
1750
  if (pinned && overlapDecision && overlapDecision.outcome !== 'user-merge' && !overlapEvidenceAccepted) {
1751
+ // A clean GitHub PR can still be behind a recently landed overlapping head. Preserve the cue
1752
+ // across hosts; the current steward tick acts only if it can also prove local run ownership.
1753
+ if (ancestorResyncNeeded && !opts.dryRun) {
1754
+ const marked = run('gh', ['pr', 'edit', String(opts.pr), '--add-label', PR_LABEL_NAMES.needsRebase], { cwd });
1755
+ record('resync-marker', marked.ok, { pr: Number(opts.pr), reason: 'ancestor-auto-not-ancestor' });
1756
+ if (!marked.ok) out.error('⚠ resync-marker: needs-rebase 라벨을 남기지 못했습니다');
1757
+ }
1696
1758
  out.error('✗ expected-head: overlap merge approval unavailable for the reviewed head');
1697
1759
  return 1;
1698
1760
  }
@@ -1753,7 +1815,7 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1753
1815
  if (opts.hold) {
1754
1816
  out.log(`[dry-run] ${existing.url ? '기존 PR을 갱신' : 'PR을 생성'}하고 --hold 로 병합하지 않고 멈춥니다.`);
1755
1817
  } else {
1756
- out.log(`[dry-run] ${existing.url ? '기존 PR을 갱신하고 ready 상태를 보장' : 'PR을 생성하고 ready 상태를 보장'}한 뒤 squash merge 합니다.`);
1818
+ out.log(`[dry-run] 머리 고정 없는 일반 착지: ${existing.url ? '기존 PR을 갱신하고 ready 상태를 보장' : 'PR을 생성하고 ready 상태를 보장'}한 뒤 squash merge 합니다.`);
1757
1819
  }
1758
1820
  return 0;
1759
1821
  }
@@ -1927,7 +1989,7 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1927
1989
  ...(mergeable ? { mergeable } : {}),
1928
1990
  ...(mergeStateStatus ? { mergeStateStatus } : {}),
1929
1991
  });
1930
- out.error(`✗ merge: ${detail}`);
1992
+ refuse(`✗ merge: ${detail}`);
1931
1993
  if (mergeable === 'CONFLICTING') {
1932
1994
  out.error(' ↳ 충돌 — 이 브랜치가 기준 브랜치의 최근 착지와 같은 줄을 고쳤다. `bun bin/elanous.mjs git fetch origin` → `bun bin/elanous.mjs git rebase origin/<기준>` 로 풀고 다시 pr land.');
1933
1995
  }
@@ -0,0 +1,20 @@
1
+ import { readJourneyEdge, recordJourneyEdge } from '../self-dev/graph-journey-route.js';
2
+ import { debug } from '../debug/log.js';
3
+
4
+ /** The five outcomes of an observed `pr land` refusal. This function never retries a landing. */
5
+ export type PrLandRefusal = 'draft' | 'head-branch' | 'not-ancestor' | 'review-missing' | 'other';
6
+
7
+ export function classifyPrLandRefusal(message: string, context: { isDraft?: boolean } = {}): PrLandRefusal {
8
+ if (context.isDraft === true && message.startsWith('✗ expected-head: PR OPEN non-draft')) return 'draft';
9
+ if (message.startsWith('✗ branch: PR head branch와 현재 브랜치가 다릅니다.')) return 'head-branch';
10
+ if (message.startsWith('✗ ancestor-auto: ancestor-auto-not-ancestor:')) return 'not-ancestor';
11
+ if (/^✗ (?:ancestor-auto|overlap-evidence): (?:review-missing|review-not-reviewed|review-error|review-no-result|review-unreadable|review-pr-mismatch|review-head-mismatch|review-path-not-for-this-pr-head|review-verdict-null|review-must-fix-unknown)(?:\b|$)/.test(message)) return 'review-missing';
12
+ return 'other';
13
+ }
14
+
15
+ /** Read the declared recovery edge and observe the refusal. No recovery command runs here. */
16
+ export function observePrLandRefusal(message: string, context: { isDraft?: boolean } = {}): void {
17
+ const route = readJourneyEdge('merge', classifyPrLandRefusal(message, context));
18
+ if (route.to !== null) recordJourneyEdge(route, route.to, 'pr-land-refused; recovery-execution=none');
19
+ else debug.log('self-implement', 'graph-edge-unresolved', { from: 'merge', label: route.label, reason: 'pr-land-refused; recovery-execution=none' });
20
+ }
@@ -53,6 +53,7 @@ import { autoStartScheduledRelease, type AutoStartDeferral } from '../release-lo
53
53
  import { runRehearsalTick, type RehearsalDeps } from '../release-loop/rehearsal.js';
54
54
  import { landingFreezeMessage, LandingFrozenError, readLandingFreeze } from '../release-loop/landing-freeze.js';
55
55
  import { formatLightRc, runLightRc, type LightRcDeps } from '../release-loop/light-rc.js';
56
+ import { registerRfcCommands } from './rfc-cli.js';
56
57
 
57
58
  export const DEFAULT_PUBLIC_REPO = 'ElanvitalAI/elanous';
58
59
  const SEMVER = /^\d+\.\d+\.\d+(?:-(?:rc|alpha|beta)\.\d+)?$/;
@@ -623,6 +624,7 @@ function compareReleaseVersions(a: string, b: string): number {
623
624
  }
624
625
 
625
626
  export function registerReleaseCommands(program: Command, releaseRunDeps: UnattendedReleaseDeps = {}, landedDeps: LandedButYellowDeps = {}, hqDeps: HqDeps = {}, lightRcDeps: LightRcDeps = {}, rehearsalDeps: RehearsalDeps = {}): void {
627
+ registerRfcCommands(program);
626
628
  const release = program.command('release').description('공개 배포 한 판 — prepare(로컬) → publish(--yes) → verify (docs/manual/MANUAL-versioning-and-release-2026-09-25.md)');
627
629
  const schedule = release.command('schedule').description('판별 컷·착지 마감 조회·갱신');
628
630
  const scheduleLedgerRoot = () => releaseRunDeps.ledgerRoot ?? releaseLedgerRoot();
@@ -0,0 +1,24 @@
1
+ import type { Command } from 'commander';
2
+ import { CliUserError } from './cli-user-error.js';
3
+ import { listRfcs, showRfc } from '../rfc-registry/registry.js';
4
+
5
+ /** RFC-REGISTRY first slice: list/show initialize an empty registry if needed, then only read rows. */
6
+ export function registerRfcCommands(program: Command): void {
7
+ const rfc = program.command('rfc').description('RFC registry (list/show initialize the database when absent)');
8
+ rfc.command('list').description('registered RFCs').option('--json', 'JSON rows')
9
+ .action((opts: { json?: boolean }) => {
10
+ const rows = listRfcs();
11
+ if (opts.json) console.log(JSON.stringify(rows));
12
+ else for (const row of rows) console.log(`${row.id} · ${row.status} · ${row.title}`);
13
+ });
14
+ rfc.command('show <id>').description('RFC and its items').option('--json', 'JSON record')
15
+ .action((id: string, opts: { json?: boolean }) => {
16
+ const row = showRfc(id);
17
+ if (!row) throw new CliUserError(`없는 RFC: ${id}`);
18
+ if (opts.json) console.log(JSON.stringify(row));
19
+ else {
20
+ console.log(`${row.id} · ${row.status} · ${row.title}`);
21
+ for (const item of row.items) console.log(` ${item.id} · ${item.status} · ${item.title}${item.links.length ? ` → ${item.links.map((link) => link.target_item_id).join(', ')}` : ''}`);
22
+ }
23
+ });
24
+ }
@@ -1,17 +1,14 @@
1
1
  // Unified Tailscale Serve helper — single source of truth for the
2
2
  // two transport modes monad-agent uses on macOS:
3
3
  //
4
- // - `https-443` — share the daemon on the host's standard HTTPS:443
5
- // (one Serve per host · used by `pwa share enable`
6
- // and the legacy `bringShareUp` auto-share path in
7
- // `pwa-start`). HTTP/2 forwarder · NOT WebSocket-
8
- // friendly (Upgrade returns 502).
4
+ // - `https-443` — explicit legacy mode on the host's standard HTTPS:443.
5
+ // HTTP/2 forwarding does not preserve WebSocket Upgrade
6
+ // (the daily PWA sharing path no longer selects it).
9
7
  //
10
8
  // - `tls-tcp` — per-port TLS terminator forwarding plaintext TCP
11
9
  // (HTTP/1.1) to a backend on `localhost:<port>`.
12
- // Used by `pwa test --https` for project-local
13
- // isolated dogfood. WebSocket Upgrade returns 101
14
- // (the iPad-side multi-LLM dispatch needs this).
10
+ // Used by `pwa share enable`, `pwa-start` auto-share and
11
+ // `pwa test --https`. WebSocket Upgrade returns 101.
15
12
  //
16
13
  // Why unify? Before this lift, `defaultServe` (https-443) and
17
14
  // `mountTailscaleTestServe` (tls-tcp) duplicated: