elanous 0.2.21 → 0.2.22

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 (315) 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/1307-08b716476f1d50af.js +1 -0
  4. package/apps/pwa/out/_next/static/chunks/{2489-ff55a35b202c0f94.js → 2489-d238d3e2eb5b2bf5.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/app/approvals/page-88459e0903da2803.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/app/autopilot/{page-d781be3e3a9cfd74.js → page-d85c43f46f58716b.js} +1 -1
  12. package/apps/pwa/out/_next/static/chunks/app/board/{page-b0a80997903852d8.js → page-4e645600579ae952.js} +1 -1
  13. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-2b1263165630d9c8.js → page-87edbfd19117823b.js} +1 -1
  14. package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/app/chat/{page-e2d6bed48ac20120.js → page-cbaf66b1e1804adf.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/app/consult/{page-111cabe4d1fd69ae.js → page-80ed511e02c81412.js} +1 -1
  18. package/apps/pwa/out/_next/static/chunks/app/control/{page-544dd4bd4847eeb7.js → page-9f5610caaa06178c.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/app/decisions/{page-3ee191319bf97d87.js → page-ec8f3575e339de74.js} +1 -1
  20. package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/app/exec/{page-a449f1ed472b81c2.js → page-2a19c5cd3b562580.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/app/field/{page-9045094d6d3b5cd0.js → page-b6a09cde2e07521a.js} +1 -1
  24. package/apps/pwa/out/_next/static/chunks/app/inside/{page-c06673596849ef45.js → page-f7eae1518ca0c353.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/app/{layout-9f81233f29dcd409.js → layout-8462d6a543cbb2d9.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/app/loops/page-abd86cd832aaa011.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8c3f168fc3f91939.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/app/morning/{page-7a12f61be4a579d1.js → page-786fb4504d0f2fa9.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/app/{not-found-c85b0589591a99c9.js → not-found-75209f14597dcb8f.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/app/observatory/{page-725a4da02dd129eb.js → page-bf30affe3a85af7e.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/app/{page-21bec4afeb2f0917.js → page-76cf838050a8d681.js} +1 -1
  40. package/apps/pwa/out/_next/static/chunks/app/reflection/{page-dc39ee7a36d26385.js → page-7ec8e289b4c14df6.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/app/scheduler/{page-84ae759f76053672.js → page-8c8ac17d52be2a79.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/app/sessions/{page-3db58ddb61fe2be9.js → page-d359ab048d63a9d9.js} +1 -1
  43. package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-c5315e30f3528dc4.js → page-b8b345c880bf78d1.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/app/settings/{page-2fe368efb6de3b6a.js → page-f151cc10ad026940.js} +1 -1
  45. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/app/share/{page-c69762987b751174.js → page-bf495a1e284f4e00.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/app/term/page-9abcfac07e02a542.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/app/workflows/{page-7f8d7fcdf058a845.js → page-69cb93d1a2e57e0e.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/app/workspace/{page-22163556cd38bc88.js → page-72ec543928d67c3e.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +1 -0
  58. package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +1 -0
  59. package/apps/pwa/out/approvals/index.html +1 -1
  60. package/apps/pwa/out/approvals/index.txt +14 -14
  61. package/apps/pwa/out/autopilot/index.html +1 -1
  62. package/apps/pwa/out/autopilot/index.txt +14 -14
  63. package/apps/pwa/out/board/index.html +1 -1
  64. package/apps/pwa/out/board/index.txt +14 -14
  65. package/apps/pwa/out/botlab/index.html +1 -1
  66. package/apps/pwa/out/botlab/index.txt +14 -14
  67. package/apps/pwa/out/bots/index.html +1 -1
  68. package/apps/pwa/out/bots/index.txt +14 -14
  69. package/apps/pwa/out/ceo/index.html +1 -1
  70. package/apps/pwa/out/ceo/index.txt +14 -14
  71. package/apps/pwa/out/chat/index.html +1 -1
  72. package/apps/pwa/out/chat/index.txt +14 -14
  73. package/apps/pwa/out/consult/index.html +1 -1
  74. package/apps/pwa/out/consult/index.txt +14 -14
  75. package/apps/pwa/out/control/index.html +1 -1
  76. package/apps/pwa/out/control/index.txt +14 -14
  77. package/apps/pwa/out/decisions/index.html +1 -1
  78. package/apps/pwa/out/decisions/index.txt +14 -14
  79. package/apps/pwa/out/design-check/index.html +1 -1
  80. package/apps/pwa/out/design-check/index.txt +14 -14
  81. package/apps/pwa/out/editor/index.html +1 -1
  82. package/apps/pwa/out/editor/index.txt +14 -14
  83. package/apps/pwa/out/exec/index.html +1 -1
  84. package/apps/pwa/out/exec/index.txt +14 -14
  85. package/apps/pwa/out/field/index.html +1 -1
  86. package/apps/pwa/out/field/index.txt +14 -14
  87. package/apps/pwa/out/healthz +1 -1
  88. package/apps/pwa/out/index.html +1 -1
  89. package/apps/pwa/out/index.txt +14 -14
  90. package/apps/pwa/out/inside/index.html +1 -1
  91. package/apps/pwa/out/inside/index.txt +14 -14
  92. package/apps/pwa/out/intake/index.html +1 -1
  93. package/apps/pwa/out/intake/index.txt +14 -14
  94. package/apps/pwa/out/live/index.html +1 -1
  95. package/apps/pwa/out/live/index.txt +14 -14
  96. package/apps/pwa/out/live-run/index.html +1 -1
  97. package/apps/pwa/out/live-run/index.txt +14 -14
  98. package/apps/pwa/out/loops/index.html +1 -1
  99. package/apps/pwa/out/loops/index.txt +14 -14
  100. package/apps/pwa/out/market/index.html +1 -1
  101. package/apps/pwa/out/market/index.txt +14 -14
  102. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  103. package/apps/pwa/out/missions/placeholder/index.txt +14 -14
  104. package/apps/pwa/out/morning/index.html +1 -1
  105. package/apps/pwa/out/morning/index.txt +14 -14
  106. package/apps/pwa/out/observatory/index.html +1 -1
  107. package/apps/pwa/out/observatory/index.txt +14 -14
  108. package/apps/pwa/out/ops/checklist/index.html +1 -1
  109. package/apps/pwa/out/ops/checklist/index.txt +14 -14
  110. package/apps/pwa/out/ops/release/index.html +1 -1
  111. package/apps/pwa/out/ops/release/index.txt +14 -14
  112. package/apps/pwa/out/ops/seats/index.html +1 -1
  113. package/apps/pwa/out/ops/seats/index.txt +14 -14
  114. package/apps/pwa/out/outputs/index.html +1 -1
  115. package/apps/pwa/out/outputs/index.txt +14 -14
  116. package/apps/pwa/out/reflection/index.html +1 -1
  117. package/apps/pwa/out/reflection/index.txt +15 -15
  118. package/apps/pwa/out/scheduler/index.html +1 -1
  119. package/apps/pwa/out/scheduler/index.txt +14 -14
  120. package/apps/pwa/out/sessions/index.html +1 -1
  121. package/apps/pwa/out/sessions/index.txt +14 -14
  122. package/apps/pwa/out/settings/devices/index.html +1 -1
  123. package/apps/pwa/out/settings/devices/index.txt +14 -14
  124. package/apps/pwa/out/settings/index.html +1 -1
  125. package/apps/pwa/out/settings/index.txt +14 -14
  126. package/apps/pwa/out/setup/done/index.html +1 -1
  127. package/apps/pwa/out/setup/done/index.txt +14 -14
  128. package/apps/pwa/out/setup/index.html +1 -1
  129. package/apps/pwa/out/setup/index.txt +14 -14
  130. package/apps/pwa/out/share/index.html +1 -1
  131. package/apps/pwa/out/share/index.txt +14 -14
  132. package/apps/pwa/out/showroom/index.html +1 -1
  133. package/apps/pwa/out/showroom/index.txt +14 -14
  134. package/apps/pwa/out/tasks/index.html +1 -1
  135. package/apps/pwa/out/tasks/index.txt +14 -14
  136. package/apps/pwa/out/term/index.html +1 -1
  137. package/apps/pwa/out/term/index.txt +14 -14
  138. package/apps/pwa/out/today/index.html +1 -1
  139. package/apps/pwa/out/today/index.txt +14 -14
  140. package/apps/pwa/out/trace/index.html +1 -1
  141. package/apps/pwa/out/trace/index.txt +14 -14
  142. package/apps/pwa/out/vault/index.html +1 -1
  143. package/apps/pwa/out/vault/index.txt +14 -14
  144. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  145. package/apps/pwa/out/workflows/chat-ui/index.txt +14 -14
  146. package/apps/pwa/out/workflows/index.html +1 -1
  147. package/apps/pwa/out/workflows/index.txt +14 -14
  148. package/apps/pwa/out/workspace/index.html +1 -1
  149. package/apps/pwa/out/workspace/index.txt +14 -14
  150. package/apps/pwa/out/worktrees/index.html +1 -1
  151. package/apps/pwa/out/worktrees/index.txt +14 -14
  152. package/graphs/catalog/catalog.yaml +1 -1
  153. package/graphs/drafts/recipes.yaml +2 -2
  154. package/graphs/test-diet/recipes.yaml +3 -0
  155. package/graphs/test-diet/test-diet.yaml +3 -1
  156. package/package.json +1 -1
  157. package/scripts/f-session-monitor.ts +69 -0
  158. package/scripts/hq/standby-snapshot.ts +7 -3
  159. package/scripts/knowledge-compress.ts +11 -0
  160. package/scripts/nightly-docops.ts +90 -3
  161. package/scripts/research-coo-admin-dates.ts +39 -0
  162. package/scripts/skills/public-check.ts +7 -2
  163. package/scripts/smart-merge/resync-shadow.ts +5 -3
  164. package/scripts/test-diet/lib.ts +81 -1
  165. package/scripts/test-diet/node.ts +48 -2
  166. package/scripts/verify-coo-admin-evidence.ts +83 -0
  167. package/src/acp/client.ts +4 -2
  168. package/src/agent/run-context.ts +4 -0
  169. package/src/agent-env/profile.ts +25 -5
  170. package/src/agent-mission/driver.ts +26 -12
  171. package/src/agent-mission/supervisor-metrics.ts +17 -2
  172. package/src/agent-substrate/acp-reviewer.ts +12 -5
  173. package/src/agent-substrate/pr-reviewer.ts +11 -4
  174. package/src/agent-substrate/review-intent.ts +102 -3
  175. package/src/autopilot/build/llm-conflict-merge.ts +22 -8
  176. package/src/autopilot/pr-manager.ts +18 -8
  177. package/src/away/release-watch.ts +47 -8
  178. package/src/briefing/brief-items.ts +104 -11
  179. package/src/chat/index.ts +1 -0
  180. package/src/cli/brief-cli.ts +20 -2
  181. package/src/cli/config-classify.ts +83 -0
  182. package/src/cli/control-cli.ts +14 -0
  183. package/src/cli/decisions-cli.ts +26 -16
  184. package/src/cli/logs-model-input.ts +1 -1
  185. package/src/cli/pr-cli.ts +65 -8
  186. package/src/cli/release-cli.ts +21 -4
  187. package/src/cli/tasks-cli.ts +108 -1
  188. package/src/connectors/types.ts +6 -6
  189. package/src/context-bus/context-now-surfaces.ts +18 -0
  190. package/src/context-bus/coord-events.ts +32 -4
  191. package/src/context-bus/long-term-memory.ts +23 -6
  192. package/src/context-bus/nightly-condense.ts +169 -21
  193. package/src/control/control-status.ts +87 -0
  194. package/src/control-plane/light-member.ts +5 -3
  195. package/src/control-plane/member.ts +172 -7
  196. package/src/core-turn/run-goal-loop.ts +22 -1
  197. package/src/dashboard/slash-runtime/dashboard-handlers.ts +9 -0
  198. package/src/decisions/decision-cards.ts +20 -1
  199. package/src/decisions/decision-ledger.ts +11 -8
  200. package/src/decisions/web-push-decision-cards.ts +19 -3
  201. package/src/discord-self-message.ts +2 -2
  202. package/src/domains/coo-admin-dates.evidence.json +876 -0
  203. package/src/domains/coo-admin-tool.ts +48 -14
  204. package/src/domains/ops-status.ts +53 -0
  205. package/src/domains/outbound-alert.ts +24 -1
  206. package/src/exec-requests/planner.ts +6 -0
  207. package/src/graph-kinds/registry.ts +6 -6
  208. package/src/graph-runner/graph-cli.ts +34 -2
  209. package/src/graph-runner/graph-run-api.ts +7 -0
  210. package/src/graph-runner/graph-tick.ts +73 -12
  211. package/src/graph-runner/runner.ts +43 -11
  212. package/src/graph-unify/wf-to-graph.ts +79 -0
  213. package/src/graph-wizard/generate.ts +34 -2
  214. package/src/graph-wizard/steps.ts +13 -0
  215. package/src/harness/harness-cli-command.ts +121 -23
  216. package/src/harness/harness-queue.ts +58 -14
  217. package/src/harness/launch-advice.ts +23 -0
  218. package/src/index.ts +36 -7
  219. package/src/knowledge/conclusion-compress.ts +93 -0
  220. package/src/knowledge/know-find.ts +9 -2
  221. package/src/knowledge/query.ts +20 -0
  222. package/src/llm.ts +26 -16
  223. package/src/loops/neighbor-runtime.ts +88 -0
  224. package/src/loops/orchestrator/author-depth.ts +29 -11
  225. package/src/loops/orchestrator/overlap.ts +7 -1
  226. package/src/loops/orchestrator/resync-shadow.ts +1 -1
  227. package/src/loops/orchestrator/tick.ts +35 -2
  228. package/src/loops/orchestrator/traffic.ts +2 -0
  229. package/src/loops/registry.ts +5 -0
  230. package/src/market/publish.ts +17 -1
  231. package/src/maturity/feature-maturity.ts +2 -1
  232. package/src/mss/logging/redaction.ts +17 -0
  233. package/src/nexus/api/draft-metrics.ts +22 -8
  234. package/src/nexus/api/graph-peer-edit.ts +77 -0
  235. package/src/nexus/api/graph-wizard-api.ts +9 -1
  236. package/src/nexus/api/graphs-api.ts +145 -7
  237. package/src/nexus/api/http-server.ts +93 -8
  238. package/src/nexus/api/plugins-market.ts +24 -0
  239. package/src/nexus/index.ts +3 -2
  240. package/src/oauth/claude-pty-maturity.ts +24 -0
  241. package/src/oauth/fallback-chain.ts +27 -14
  242. package/src/plugins/maker/market-bundle.ts +9 -0
  243. package/src/plugins/maker/plugin-maker.ts +9 -3
  244. package/src/plugins/maker/wizard-generate.ts +73 -9
  245. package/src/policy/llm-policy.ts +11 -6
  246. package/src/release-loop/checklist-board.ts +27 -0
  247. package/src/release-loop/checklist.ts +38 -0
  248. package/src/seat-address/seat-address.ts +1 -0
  249. package/src/seat-loop/seat-loop.ts +174 -20
  250. package/src/seat-loop/seat-report.ts +29 -1
  251. package/src/self-dev/dev-cli.ts +90 -8
  252. package/src/self-dev/dev-pipeline.ts +20 -1
  253. package/src/self-dev/draft-sweep.ts +45 -8
  254. package/src/self-dev/orchestrate.ts +3 -0
  255. package/src/self-dev/review-provider-fallback.ts +83 -0
  256. package/src/self-dev/run-supervisor.ts +5 -1
  257. package/src/self-implement/harness-policy-gates.ts +7 -5
  258. package/src/self-implement/host-regate.ts +28 -14
  259. package/src/self-implement/l8-merge-queue.ts +80 -8
  260. package/src/self-implement/orchestrator.ts +68 -27
  261. package/src/self-implement/seams.ts +5 -3
  262. package/src/self-implement/self-implement-cli.ts +4 -0
  263. package/src/shell-env-bootstrap.ts +19 -4
  264. package/src/steward/triage.ts +25 -8
  265. package/src/storage/file-lock.ts +33 -4
  266. package/src/task-agent/completion-evidence.ts +31 -3
  267. package/src/task-agent/cover.ts +61 -0
  268. package/src/task-agent/live-moves.ts +126 -3
  269. package/src/task-agent/shadow.ts +19 -4
  270. package/src/task-agent/task-hand.ts +2 -0
  271. package/src/task-orchestrator/surfaces/pod-pool.ts +138 -15
  272. package/src/task-orchestrator/surfaces/self-implement.ts +7 -0
  273. package/src/telegram-commands.ts +8 -0
  274. package/src/telegram-project-command.ts +6 -0
  275. package/src/telegram.ts +2 -2
  276. package/src/typecheck-ratchet.ts +2 -1
  277. package/src/user-config.ts +35 -4
  278. package/src/version/packed-revision.json +1 -1
  279. package/src/workflow-runtime/executor.ts +24 -2
  280. package/src/workflow-runtime/triggers/registry.ts +27 -0
  281. package/src/workflow-runtime/triggers/schedule-source.ts +30 -3
  282. package/apps/pwa/out/_next/static/chunks/1307-c97eba9fb72a9a5e.js +0 -1
  283. package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +0 -1
  284. package/apps/pwa/out/_next/static/chunks/5977-59fedea50d13c762.js +0 -1
  285. package/apps/pwa/out/_next/static/chunks/8857-f1762140ef9a96b1.js +0 -1
  286. package/apps/pwa/out/_next/static/chunks/9247-7581825d511a64c0.js +0 -1
  287. package/apps/pwa/out/_next/static/chunks/9497-b0e758d1cd4ae8d7.js +0 -1
  288. package/apps/pwa/out/_next/static/chunks/app/approvals/page-937c92292a4ab4f0.js +0 -1
  289. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea998f7f5d156bea.js +0 -1
  290. package/apps/pwa/out/_next/static/chunks/app/ceo/page-33c328b64ca508f8.js +0 -1
  291. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e4bcb2c503dab04b.js +0 -1
  292. package/apps/pwa/out/_next/static/chunks/app/editor/page-300897dcbbd5ed76.js +0 -1
  293. package/apps/pwa/out/_next/static/chunks/app/intake/page-103fa3191c1b2e08.js +0 -1
  294. package/apps/pwa/out/_next/static/chunks/app/live/page-be8b4615c919e36c.js +0 -1
  295. package/apps/pwa/out/_next/static/chunks/app/live-run/page-c685b104e0dfa609.js +0 -1
  296. package/apps/pwa/out/_next/static/chunks/app/loops/page-8d693331cfbb6add.js +0 -1
  297. package/apps/pwa/out/_next/static/chunks/app/market/page-cef4f30a4c22fae1.js +0 -1
  298. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66ea1b54fc83fa15.js +0 -1
  299. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-8cc707bd09a497d9.js +0 -1
  300. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-90b55be1f15ce0e8.js +0 -1
  301. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cb16606e08be65db.js +0 -1
  302. package/apps/pwa/out/_next/static/chunks/app/outputs/page-16dc64b74ed6a40a.js +0 -1
  303. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8d04132dd0ac5e10.js +0 -1
  304. package/apps/pwa/out/_next/static/chunks/app/setup/page-f23484de467c9ea3.js +0 -1
  305. package/apps/pwa/out/_next/static/chunks/app/showroom/page-5456692bda39aafb.js +0 -1
  306. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d75f7cd65845ce98.js +0 -1
  307. package/apps/pwa/out/_next/static/chunks/app/term/page-5603f5e568b25ce3.js +0 -1
  308. package/apps/pwa/out/_next/static/chunks/app/today/page-d2cc0f4e89f42028.js +0 -1
  309. package/apps/pwa/out/_next/static/chunks/app/trace/page-a6eb73b8a4840f1c.js +0 -1
  310. package/apps/pwa/out/_next/static/chunks/app/vault/page-c0a3f4d10edb83fa.js +0 -1
  311. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6c0b88068c143f15.js +0 -1
  312. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-141436fd26dd56fc.js +0 -1
  313. package/apps/pwa/out/_next/static/css/e81df11490b4413b.css +0 -1
  314. /package/apps/pwa/out/_next/static/{MObU8ujkMciAKr6ljAV05 → aBi6EyMtLsrl7J8eH4kF7}/_buildManifest.js +0 -0
  315. /package/apps/pwa/out/_next/static/{MObU8ujkMciAKr6ljAV05 → aBi6EyMtLsrl7J8eH4kF7}/_ssgManifest.js +0 -0
@@ -180,6 +180,7 @@ export const GOAL_CONTINUATION_PROMPT = [
180
180
  '[continue]',
181
181
  '아직 목표가 완료로 증명되지 않았다. 완료를 미리 선언하지 말고, 현재 상태 대비 실제로 검증하라:',
182
182
  '남은 요구사항을 식별하고, 다음 최고가치 스텝을 지금 도구로 실행하라.',
183
+ '이미 사용자에게 한 답을 다시 쓰지 마라 — 새 사실이 없으면 텍스트 없이 update_goal 만 호출하라.',
183
184
  // evidence-audit(ref codex ext/goal continuation.md:41,51) — 스푸핑·조기완료 차단.
184
185
  '완료 증거로 의도/부분진전/이전 작업 기억/그럴듯한 답을 쓰지 마라. 현재 상태(파일·명령출력·테스트결과·PR·런타임 동작)를 실제로 확인한 증거만 인정한다.',
185
186
  '예산이 곧 소진된다거나 그만두고 싶다는 이유로 완료를 선언하지 마라.',
@@ -196,6 +197,7 @@ export const GOAL_READBACK_PROMPT = [
196
197
  '[finalize]',
197
198
  `완료를 텍스트로만 말했다. 텍스트 문장은 완료 신호가 아니다 — 완료가 사실이면 ${UPDATE_GOAL_TOOL_NAME} 도구를 status="complete" 로 호출하고 evidence 에 현재 상태에서 실제로 확인한 증거(파일·명령출력·테스트·PR)를 적어라.`,
198
199
  '아직 미충족 항목이 있으면 완료를 주장하지 말고 다음 스텝을 지금 실행하라.',
200
+ '이미 사용자에게 한 답을 다시 쓰지 마라 — 새 사실이 없으면 텍스트 없이 update_goal 만 호출하라.',
199
201
  ].join('\n');
200
202
 
201
203
  /** evidence 누락 complete 재주입 — update_goal(complete) 를 호출했으나 evidence 가 비었을 때. */
@@ -689,6 +691,7 @@ export async function runGoalLoop(
689
691
  },
690
692
  };
691
693
 
694
+ const previousFinalText = lastResult.finalText;
692
695
  try {
693
696
  lastResult = await runTurn(turnCtx);
694
697
  } finally {
@@ -786,8 +789,26 @@ export async function runGoalLoop(
786
789
  debug.log('goal.loop', 'complete', {
787
790
  sessionId: ctx.sessionId, ...runAttribution, iterations, via: 'update_goal', evidenceCheck,
788
791
  }, { level: 'info' });
792
+ const normalizeAnswer = (text: string) => text.trim().replace(/\s+/g, ' ');
793
+ const previousAnswer = normalizeAnswer(previousFinalText);
794
+ const completionAnswer = normalizeAnswer(lastResult.finalText);
795
+ const previousAt = previousAnswer ? completionAnswer.indexOf(previousAnswer) : -1;
796
+ const prefix = previousAt >= 0 ? completionAnswer.slice(0, previousAt).trim() : '';
797
+ const suffix = previousAt >= 0 ? completionAnswer.slice(previousAt + previousAnswer.length).trim() : '';
798
+ // Only a readback preface is non-factual; a new sentence before the old answer
799
+ // (including one joined by a colon) must survive just like a new suffix.
800
+ const readbackPreface = /^(?:확인 결과|(?:방금\s+)?다시\s+확인(?:했습니다|했지만|해보니|해 보니|해봤지만|해 봤지만|했으나|했는데))[\s::,.!?。!?-]*$/u;
801
+ const hasNewFact = (prefix.length > 0 && !readbackPreface.test(prefix)) || /\p{L}|\p{N}/u.test(suffix);
802
+ const duplicateAnswer = previousAnswer.length > 0 && (
803
+ completionAnswer.length === 0 || (previousAt >= 0 && !hasNewFact)
804
+ );
805
+ if (duplicateAnswer) {
806
+ debug.log('goal.loop', 'complete-duplicate-answer-suppressed', {
807
+ sessionId: ctx.sessionId, ...runAttribution, iterations, chars: lastResult.finalText.length,
808
+ });
809
+ }
789
810
  return finish(
790
- { finalText: lastResult.finalText, iterations, stopReason: 'goal_complete', goalComplete: true },
811
+ { finalText: duplicateAnswer ? previousFinalText : lastResult.finalText, iterations, stopReason: 'goal_complete', goalComplete: true },
791
812
  { summary: completionSummary, changedFiles: completionChangedFiles },
792
813
  );
793
814
  }
@@ -395,6 +395,8 @@ import { dispatchTerminalModalObserve } from '../../skills/tools/terminal-modal.
395
395
  import { SlashCommandRegistry } from './registry.js';
396
396
  import { cronSecondDueAt, filterLoopRows, formatLoopsTable, localLoopRows, type LoopsTableRow } from './loops-table.js';
397
397
  import { loopCronVerdict } from '../../loops/verdict.js';
398
+ import { checklistBoardSlash } from '../../release-loop/checklist-board.js';
399
+ import type { Checklist } from '../../release-loop/checklist.js';
398
400
  import { executeImmediateDashboardSlash } from '../input/slash-executor.js';
399
401
  import {
400
402
  buildContextSlashCommand,
@@ -1046,6 +1048,8 @@ export interface DashboardSlashContext {
1046
1048
 
1047
1049
  /** Test seam for the local read-only loop and cron registry. */
1048
1050
  loopsLocalRows?: (now: Date) => LoopsTableRow[];
1051
+ /** Test seam for the read-only release checklist. */
1052
+ checklistRead?: (version: string) => Checklist;
1049
1053
 
1050
1054
  sessionSlash: {
1051
1055
  /** opts.remote — when the dashboard is attached to a remote daemon. */
@@ -1467,6 +1471,11 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
1467
1471
  ctx.setChatScrollOffset(-1);
1468
1472
  });
1469
1473
 
1474
+ registry.register('board', (args, ctx) => {
1475
+ for (const line of checklistBoardSlash(args, ctx.checklistRead).split('\n')) ctx.pushChatLine(line);
1476
+ ctx.setChatScrollOffset(-1);
1477
+ });
1478
+
1470
1479
  registry.register('wish', (args, ctx) => {
1471
1480
  const text = args.join(' ').trim();
1472
1481
  if (!text) {
@@ -34,7 +34,9 @@ export function isIrreversible(entry: Pick<DecisionEntry, 'category'>): boolean
34
34
  return IRREVERSIBLE.has(entry.category);
35
35
  }
36
36
 
37
- const kst = (at: string) => new Intl.DateTimeFormat('ko-KR', { timeZone: 'Asia/Seoul', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(at));
37
+ const kst = (at: string) => Number.isFinite(Date.parse(at))
38
+ ? new Intl.DateTimeFormat('ko-KR', { timeZone: 'Asia/Seoul', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(at))
39
+ : '읽을 수 없음';
38
40
 
39
41
  /** The card opens with a short pitch; the full question and choice buttons remain below it. */
40
42
  export function renderCardText(e: DecisionEntry, extra: { note?: string; confirm?: string } = {}): string {
@@ -101,6 +103,7 @@ interface CardState {
101
103
  * deploy); they stay reachable through `/decisions`. */
102
104
  since?: string;
103
105
  cards: Record<string, { refs: CardRef[]; closed?: boolean; remindedAt?: string; note?: string; attempts?: number; noSubscribers?: boolean }>;
106
+ deferred?: Record<string, true>;
104
107
  testOriginQuestions?: Record<string, true>;
105
108
  }
106
109
 
@@ -113,6 +116,10 @@ export interface DecisionCardServiceOptions {
113
116
  /** Where this platform keeps which card it sent (one file per platform — the two bots may run in different processes). */
114
117
  statePath?: string;
115
118
  now?: () => Date;
119
+ /** Optional gate for new-card delivery. Omit to send every eligible open decision. */
120
+ sendFilter?: (entry: DecisionEntry, now: Date) => boolean;
121
+ /** Label recorded in the `push-deferred` observation when `sendFilter` holds a decision back. */
122
+ deferredReason?: (entry: DecisionEntry, now: Date) => string;
116
123
  /** Tell the seat that raised it. Default: none (observed only). */
117
124
  replyToRaiser?: (entry: DecisionEntry, via: CardPlatform) => Promise<void>;
118
125
  }
@@ -223,6 +230,18 @@ export class DecisionCardService {
223
230
  const card = state.cards[e.id];
224
231
  if (e.status === 'open' && (!card || (platform === 'webpush' && !card.refs.length && (card.attempts ?? 0) < WEBPUSH_MAX_SEND_ATTEMPTS))
225
232
  && e.options.length >= 2 && e.raisedAt !== undefined && e.raisedAt >= state.since) {
233
+ if (this.opts.sendFilter) {
234
+ const now = this.now();
235
+ if (!this.opts.sendFilter(e, now)) {
236
+ if (!state.deferred?.[e.id]) {
237
+ (state.deferred ??= {})[e.id] = true;
238
+ dirty = true;
239
+ debug.log(platform === 'webpush' ? 'decisions.webpush' : 'decisions.telegram', 'push-deferred',
240
+ { ...(platform === 'webpush' ? {} : { platform }), id: e.id, urgency: this.opts.deferredReason?.(e, now) ?? 'filtered' });
241
+ }
242
+ continue;
243
+ }
244
+ }
226
245
  if (platform === 'webpush' && !chats.length) {
227
246
  if (!card?.noSubscribers) {
228
247
  state.cards[e.id] = { ...(card ?? { refs: [] }), noSubscribers: true };
@@ -5,6 +5,8 @@ import { readPendingQuestionAnswer, readPendingQuestions, writePendingQuestionAn
5
5
  import { debug, redactSecretText } from '../debug/log.js';
6
6
  import { createVersionResolver, type VersionOptions, type Versions } from '../directives/version-at.js';
7
7
  import { getUserConfig } from '../user-config.js';
8
+ import { registeredSeats, resolveSeat } from '../seat-address/seat-address.js';
9
+ import { isSeatId } from '../seat-dispatch/seat-questions.js';
8
10
 
9
11
  export type DecisionCategory = 'secret' | 'publish' | 'money' | 'security' | 'scope' | 'irreversible' | 'other';
10
12
  /** Old track letters (S·T·F·O) stay readable; seat names (OP·MK·TC·UX) are the current identities. */
@@ -53,7 +55,8 @@ export class DecisionAnswerDeliveryError extends Error {
53
55
  }
54
56
  }
55
57
  const CATEGORIES: readonly string[] = ['secret', 'publish', 'money', 'security', 'scope', 'irreversible', 'other'];
56
- const TRACKS: readonly string[] = ['S', 'T', 'F', 'O', 'OP', 'MK', 'TC', 'UX'];
58
+ const isDecisionTrack = (value: string): boolean => registeredSeats().some(({ id, alias }) => value === id || value === alias);
59
+ const isRegisteredSeat = (value: string): boolean => isSeatId(value) && resolveSeat(value)?.id === value;
57
60
 
58
61
  function required(value: string, name: string): string {
59
62
  if (typeof value !== 'string' || !value.trim()) throw new Error(`${name} is required`);
@@ -88,7 +91,7 @@ function validate(input: RaiseInput, historical = false): RaiseInput {
88
91
  const title = safe(single(input.title, 'title'));
89
92
  if (!CATEGORIES.includes(input.category)) throw new Error('invalid category');
90
93
  if (!input.raisedBy?.agent) throw new Error('raisedBy.agent is required');
91
- if (input.raisedBy.track && !TRACKS.includes(input.raisedBy.track)) throw new Error('invalid track');
94
+ if (input.raisedBy.track && !isDecisionTrack(input.raisedBy.track)) throw new Error('invalid track');
92
95
  const s = scqaField(input.scqa.s, 's');
93
96
  const c = scqaField(input.scqa.c, 'c');
94
97
  const q = input.scqa.q?.trim() ? scqaField(input.scqa.q, 'q') : undefined;
@@ -117,7 +120,7 @@ function validate(input: RaiseInput, historical = false): RaiseInput {
117
120
  if (input.crossCheck !== undefined && !Array.isArray(input.crossCheck)) throw new Error('cross-check must be a list');
118
121
  const crossCheck = input.crossCheck?.map(check => {
119
122
  const seat = single(check.seat, 'cross-check seat');
120
- if (!['OP', 'MK', 'TC', 'UX'].includes(seat)) throw new Error('invalid cross-check seat');
123
+ if (!isRegisteredSeat(seat)) throw new Error('invalid cross-check seat');
121
124
  return { seat, at: utc(check.at), note: safe(single(check.note, 'cross-check note')) };
122
125
  });
123
126
  const crossCheckSkipped = input.crossCheckSkipped === undefined ? undefined : safe(single(input.crossCheckSkipped, 'cross-check skipped reason'));
@@ -242,7 +245,7 @@ export class DecisionLedger {
242
245
  /** Delegated decisions are already made: they share the append-only ledger, never the owner's open-card state machine. */
243
246
  recordSeatDecision(input: SeatDecisionInput): SeatDecisionRecord {
244
247
  const seat = input.seat;
245
- if (!['OP', 'MK', 'TC', 'UX'].includes(seat)) throw new Error('invalid seat');
248
+ if (!isRegisteredSeat(seat)) throw new Error('invalid seat');
246
249
  const title = safe(single(input.title, 'title'));
247
250
  const decision = safe(single(input.decision, 'decision'));
248
251
  const delegation = safe(single(input.delegation, 'delegation'));
@@ -263,7 +266,7 @@ export class DecisionLedger {
263
266
  }
264
267
  seatReport(filters: { since?: string; seat?: Seat } = {}): SeatDecisionRecord[] {
265
268
  const since = filters.since === undefined ? undefined : utc(filters.since);
266
- if (filters.seat && !['OP', 'MK', 'TC', 'UX'].includes(filters.seat)) throw new Error('invalid seat');
269
+ if (filters.seat && !isRegisteredSeat(filters.seat)) throw new Error('invalid seat');
267
270
  return this.events().filter((event): event is Extract<Event, { type: 'seat-recorded' }> => event.type === 'seat-recorded')
268
271
  .map(event => event.entry)
269
272
  .filter(entry => (!since || (entry.recordedAt ?? entry.decidedAt ?? '') >= since) && (!filters.seat || entry.seat === filters.seat))
@@ -307,7 +310,7 @@ export class DecisionLedger {
307
310
  if (!by || (by.kind !== 'human' && by.kind !== 'auto')) throw new Error('decidedBy is required');
308
311
  if (by.kind === 'auto') {
309
312
  single(by.delegation, 'delegation'); single(by.agent, 'agent');
310
- if (by.track && !TRACKS.includes(by.track)) throw new Error('invalid track');
313
+ if (by.track && !isDecisionTrack(by.track)) throw new Error('invalid track');
311
314
  by = { ...by, agent: safe(single(by.agent, 'agent')), delegation: safe(single(by.delegation, 'delegation')) };
312
315
  }
313
316
  return this.locked(() => {
@@ -424,7 +427,7 @@ export class DecisionLedger {
424
427
  if (choice ? !clean.options.some(o => o.key === choice) : clean.options.length !== 0) throw new Error(`option not found: ${choice}`);
425
428
  if (by.kind === 'auto') {
426
429
  single(by.agent, 'agent'); single(by.delegation, 'delegation');
427
- if (by.track && !TRACKS.includes(by.track)) throw new Error('invalid track');
430
+ if (by.track && !isDecisionTrack(by.track)) throw new Error('invalid track');
428
431
  by = { ...by, agent: safe(single(by.agent, 'agent')), delegation: safe(single(by.delegation, 'delegation')) };
429
432
  }
430
433
  const cleanNote = safe(single(note, 'note'));
@@ -449,7 +452,7 @@ export class DecisionLedger {
449
452
  completeRecorded(id: string, choice: string | undefined, by: DecisionActor, note: string, sourceOptions: DecisionOption[]): DecisionEntry {
450
453
  if (by.kind === 'auto') {
451
454
  single(by.agent, 'agent'); single(by.delegation, 'delegation');
452
- if (by.track && !TRACKS.includes(by.track)) throw new Error('invalid track');
455
+ if (by.track && !isDecisionTrack(by.track)) throw new Error('invalid track');
453
456
  by = { ...by, agent: safe(single(by.agent, 'agent')), delegation: safe(single(by.delegation, 'delegation')) };
454
457
  }
455
458
  const cleanNote = safe(single(note, 'note'));
@@ -1,8 +1,24 @@
1
1
  import { debug } from '../debug/log.js';
2
2
  import { listSubscriptions } from '../web-push/subscriptions.js';
3
3
  import { sendPushToAll } from '../web-push/sender.js';
4
- import { type CardTransport, type CardView } from './decision-cards.js';
5
- import { DecisionLedger } from './decision-ledger.js';
4
+ import { isIrreversible, type CardTransport, type CardView } from './decision-cards.js';
5
+ import { DecisionLedger, type DecisionEntry } from './decision-ledger.js';
6
+
7
+ /** How close a deadline must be for an otherwise reversible decision to ring the phone. */
8
+ export const WEB_PUSH_URGENT_WINDOW_MS = 24 * 3600_000;
9
+
10
+ export type WebPushUrgency = 'irreversible' | 'due-soon' | 'not-urgent' | 'due-unreadable';
11
+
12
+ /** Web push rings only for urgent decisions; an unreadable deadline is its own value (fail open, never folded into not-urgent). */
13
+ export function webPushUrgency(entry: DecisionEntry, now: Date): WebPushUrgency {
14
+ if (isIrreversible(entry)) return 'irreversible';
15
+ if (entry.dueAt !== undefined) {
16
+ const due = Date.parse(entry.dueAt);
17
+ if (!Number.isFinite(due)) return 'due-unreadable';
18
+ if (due - now.getTime() <= WEB_PUSH_URGENT_WINDOW_MS) return 'due-soon';
19
+ }
20
+ return 'not-urgent';
21
+ }
6
22
 
7
23
  const ID_IN_CARD = /^🗳 결정 요청 (D-\d{8}-\d+)(?: ·|\n)/;
8
24
  const ID_IN_REMINDER = /^⏰ 기한 2시간 전 — (D-\d{8}-\d+) /;
@@ -26,7 +42,7 @@ export function webPushDecisionTransport(
26
42
  const entry = ledger.show(id);
27
43
  if (entry.status !== 'open') return null;
28
44
  const recommendation = 'skipped' in entry.recommendation ? '추천안 없음' : `추천안: ${entry.recommendation.option.toUpperCase()}`;
29
- const body = `${recommendation}${entry.dueAt ? ` · 기한: ${new Intl.DateTimeFormat('ko-KR', { timeZone: 'Asia/Seoul', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(entry.dueAt))}` : ''}`;
45
+ const body = `${recommendation}${entry.dueAt ? ` · 기한: ${Number.isFinite(Date.parse(entry.dueAt)) ? new Intl.DateTimeFormat('ko-KR', { timeZone: 'Asia/Seoul', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(entry.dueAt)) : '읽을 수 없음'}` : ''}`;
30
46
  const result = await push({ title: title('대표 결정 · ', entry.title), body, url: url(id), tag: tag(id) });
31
47
  if (result.attempted) debug.log('decisions.webpush', 'card-sent', { id, delivered: result.delivered });
32
48
  return result.delivered ? { chat: 'webpush', message: id } : null;
@@ -64,7 +64,7 @@ import { getUserConfig } from './user-config.js';
64
64
  import { detectCard, runCardFollowup, NotACardError } from './card-followup/core.js';
65
65
  import { localOcrText } from './telegram-card-followup.js';
66
66
  import type { runGraph } from './graph-runner/runner.js';
67
- import { readSlashContextNow, renderTelegramNow } from './context-bus/context-now-surfaces.js';
67
+ import { readSlashContextNow, renderContextFirstNow, renderTelegramNow } from './context-bus/context-now-surfaces.js';
68
68
  import { contextNow, type ContextNowDeps } from './context-bus/context-now.js';
69
69
  import { createContextFirstGate, renderContextFirst } from './context-bus/context-first.js';
70
70
  import { telegramLoopsStatus, type LoopsSources } from './telegram-loops-command.js';
@@ -160,7 +160,7 @@ export function buildDiscordSelfOnMessage(deps: DiscordSelfMessageDeps): DcMessa
160
160
  const maybeSendContextFirst = async (channelId: string): Promise<void> => {
161
161
  if (!contextFirstGate.take(channelId) || cfg.discord?.contextFirst === false) return;
162
162
  try {
163
- await deps.getBot()?.sendMessage(channelId, renderContextFirst(contextNow, deps.nowDeps, renderTelegramNow));
163
+ await deps.getBot()?.sendMessage(channelId, renderContextFirst(contextNow, deps.nowDeps, renderContextFirstNow));
164
164
  } catch (err) {
165
165
  log(`discord context-first failed: ${err instanceof Error ? err.message : String(err)}`);
166
166
  }