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.
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/LZcstaO9_NXypPFmujolv/_buildManifest.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7334.a6679d9168f37aa8.js → 1268.0840ff91e083fcbd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1307-33ffcc49ab45123b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9656-c1540088f5859c80.js → 1844-9ec4b1d12f6e80eb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1866-e7a6999f25548b30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{390.c373e31b3b9d0c41.js → 1948.15f356b15a625597.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +1 -0
- package/apps/pwa/out/_next/static/chunks/224-798346143007ff65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2699-63b73fa4d3bcf6ff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2957-96ffab3d521fb08f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4144-a0041c8dc3be57ac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4554-3565eea1f1495ba7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4685-c3c1c625b71accd1.js → 4614-21403aac730d4586.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{8039-df92e08fede5de8f.js → 4795-f372490b178583fc.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5135-44008fe8b1f2aa41.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5233-bf28bd6bd7a32099.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5360-be1f1d8f9fcc9755.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5977-c952712c87a1f757.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5994-ae92c0de046ab9ba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1452.93700483b9d4fc61.js → 6110.1297d4093fdfbb0d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6158.9c0449a9a8d0064b.js +2 -0
- package/apps/pwa/out/_next/static/chunks/6877-7c6208705c284124.js +1 -0
- package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1829-b453a1b22d3999bb.js → 7327-2d69fb321ba73389.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7395-164e238f471b5d7b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7787-02a1c0b04e25e811.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8827-e2f5b09a8d37e83b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8868-10a3a4440fb0ccd8.js +25 -0
- package/apps/pwa/out/_next/static/chunks/{8421-1c4acfb1395a0edf.js → 8949-ecb4128a0858b911.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/899-46946fe8363e1262.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9070.067c106528ec1ae6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9103-7a3ae7f60af3b99f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3869-3cd46526879f454c.js → 9247-29d889b809288e65.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{79f8be9e-957d68913b590b08.js → a9f2b54d-7865aba0f4d2ee49.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-0e2c57fe6add4b2a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-e05a77df7e005b04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-f544338193a9a762.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-5491c115b1f9a923.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-b8c49f6b4fa2df91.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-96398e364fbd4548.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-976813c91d7394ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-28b9448091776c06.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-1d4901eb7c2d8822.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-72d3e7ff35a8c954.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-60c7a8e1a4fe62ce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-2a52b316cb143d9c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-c3ce483c8d5db370.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-13c7b53e0c2519a9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-96f074f6538e8a2c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-e97be5334d83a9f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-65e484302921a932.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-34d08facaf08f556.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-955ec2da3be4c560.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-9f88fbc15d9058d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-c1343f9499d86f3f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-8739a2e0ae793130.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-c9fc5706b8abaa11.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-d23b12bb92242558.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-8d47f45a0dc044ac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-c7fea475488201a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-e2ee2896811e98d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-83b19dae8619de05.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-5efbf81124c474ae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f1a1fc0a82738c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-da6c08aae0f92768.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-06ee266953d9c879.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-153c2b3bcc89e8de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-87a11e6a05f15199.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-7d4182964407c09c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-0d6d23b40263a7ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-7e8c39241f8eb6d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-008c1a96618a4887.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-63d14a4d8fe1e1c1.js → page-f5597e894c02cd33.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-0337fdf7fb5e37b6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-73735b64bfe1ae67.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-8fcec4c9ea2e7f70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-f7e631e9b4daf66e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-4881b8f9f63694b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-9817c7f9007466cc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-97f9f43172a3a90e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5cd7e3a9-404fd6b8d0ecd44c.js → f6231284-45726550aba08fca.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{f48170cc-d05d28bf87a43bf4.js → f6b7c9ba.64a895b8b2fedbdc.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-5c169757551134ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-539cde99554be20f.js +1 -0
- package/apps/pwa/out/_next/static/css/1f7c958c41ffa3b9.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -0
- package/apps/pwa/out/ceo/index.txt +33 -0
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/loops/index.html +1 -0
- package/apps/pwa/out/loops/index.txt +30 -0
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/graphs/heal/heal-loop.yaml +1 -1
- package/graphs/implement-loop.yaml +1 -1
- package/graphs/orchestrator/orchestrator.yaml +59 -0
- package/graphs/orchestrator/recipes.yaml +18 -0
- package/graphs/release/recipes.yaml +6 -0
- package/graphs/release/release-loop.yaml +6 -1
- package/graphs/rhythm/daily.yaml +38 -0
- package/graphs/rhythm/recipes.yaml +18 -0
- package/graphs/rhythm/weekly.yaml +39 -0
- package/graphs/video/recipes.yaml +3 -0
- package/graphs/video/youtube-summary.yaml +17 -0
- package/package.json +1 -1
- package/scripts/audit-test-state-writes.ts +72 -17
- package/scripts/brand/check.ts +188 -0
- package/scripts/ci-typecheck-changed.ts +50 -18
- package/scripts/coord-post.sh +11 -1
- package/scripts/docs/generate-graph-anatomy.ts +315 -0
- package/scripts/docs-cli-check.ts +23 -6
- package/scripts/expose-rubric-check.ts +118 -0
- package/scripts/expose-rubric-suggest.ts +169 -0
- package/scripts/heal/run-role.ts +14 -0
- package/scripts/hq/standby-verify.ts +11 -7
- package/scripts/lecture-note/node.ts +31 -11
- package/scripts/lessons/handbook-page.ts +112 -0
- package/scripts/marketing/generate-ax-brief.ts +140 -0
- package/scripts/marketing/generate-feature-map.ts +118 -0
- package/scripts/release-loop/checklist-gate-node.ts +53 -14
- package/scripts/release-loop/gate-node.ts +89 -14
- package/scripts/release-loop/publish-node.ts +14 -1
- package/scripts/release-loop/unattended-release.ts +23 -1
- package/scripts/release-loop/vault-note-node.ts +428 -0
- package/scripts/release-story/draft.ts +220 -0
- package/scripts/rhythm/daily.ts +570 -0
- package/scripts/rhythm/weekly.ts +315 -0
- package/scripts/skills/public-check.ts +169 -0
- package/scripts/smart-merge/resync-shadow.ts +147 -0
- package/scripts/test-deterministic.ts +4 -8
- package/scripts/test-diet/effectiveness.ts +195 -0
- package/scripts/test-diet/lib.ts +16 -8
- package/scripts/test-diet/node.ts +77 -9
- package/scripts/ux/demo-rehearsal.ts +2 -2
- package/scripts/ux/lib/rehearsal-verdict.ts +1 -0
- package/scripts/video/youtube-summary.ts +133 -0
- package/skills/diagram-master/SKILL.md +42 -49
- package/skills/diagram-master/references/pyproject.toml +4 -1
- package/skills/diagram-master/references/routing-guide.md +4 -2
- package/skills/grill-me/SKILL.md +1 -0
- package/skills/youtube-master/SKILL.md +13 -13
- package/skills/youtube-master/package-lock.json +0 -545
- package/skills/youtube-master/package.json +2 -5
- package/skills/youtube-master/scripts/main.ts +2 -2
- package/skills/youtube-master/scripts/transcribe-local.ts +1 -1
- package/skills/youtube-master/src/util.ts +30 -7
- package/src/agent-env/profile.ts +161 -0
- package/src/agent-mission/driver.ts +3 -3
- package/src/agent-substrate/pr-reviewer.ts +2 -0
- package/src/ask-user-question/pending-questions.ts +5 -0
- package/src/auth/github-app-token.ts +112 -13
- package/src/autopilot/build/llm-conflict-merge.ts +73 -10
- package/src/autopilot/build/merge-intent.ts +53 -0
- package/src/briefing/brief-items.ts +121 -0
- package/src/chat/index.ts +2 -0
- package/src/claims/claims-ledger.ts +232 -0
- package/src/claims/claims-render.ts +166 -0
- package/src/cli/agent-env-cli.ts +21 -0
- package/src/cli/claims-cli.ts +94 -0
- package/src/cli/decisions-cli.ts +44 -3
- package/src/cli/docs-cli.ts +2 -0
- package/src/cli/doctor-cli.ts +23 -1
- package/src/cli/doctor-node-modules.ts +147 -0
- package/src/cli/flow-cli.ts +11 -0
- package/src/cli/freeze-cli.ts +45 -0
- package/src/cli/intake-cli.ts +46 -17
- package/src/cli/lesson-cli.ts +108 -0
- package/src/cli/logs-cli.ts +104 -2
- package/src/cli/logs-model-input.ts +131 -0
- package/src/cli/pod-cli.ts +2 -0
- package/src/cli/pr-cli.ts +29 -1
- package/src/cli/private-ledger-commands.ts +54 -4
- package/src/cli/pty-drive-verdict.ts +11 -2
- package/src/cli/release-cli.ts +190 -33
- package/src/cli/rfc-status.ts +91 -0
- package/src/cli/seat-requests-cli.ts +52 -0
- package/src/connectors/linear.ts +5 -3
- package/src/context-bus/condense.ts +15 -20
- package/src/context-bus/context-now-public.ts +96 -0
- package/src/context-bus/context-now-surfaces.ts +55 -2
- package/src/context-bus/context-now.ts +6 -3
- package/src/context-bus/coord-events.ts +6 -4
- package/src/context-bus/long-term-memory.ts +92 -11
- package/src/dashboard/index.ts +75 -22
- package/src/dashboard/slash-runtime/chat-persona.ts +66 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +99 -0
- package/src/dashboard/slash-runtime/loops-table.ts +77 -0
- package/src/decisions/decision-cards.ts +33 -7
- package/src/decisions/decision-ledger.ts +40 -1
- package/src/decisions/proact-meter.ts +286 -0
- package/src/decisions/proact1-lite.ts +86 -0
- package/src/decisions/web-push-decision-cards.ts +1 -1
- package/src/discord/sprint21-runtime.ts +16 -0
- package/src/discord-self-message.ts +8 -0
- package/src/discord-slash-wire.ts +31 -2
- package/src/domains/alert-audit.ts +271 -0
- package/src/domains/core-tools.ts +4 -3
- package/src/domains/ops-facts-tool.ts +31 -1
- package/src/domains/outbound-alert.ts +1 -1
- package/src/elanous-config-dir.ts +29 -4
- package/src/execution-loop/launch-gate.ts +29 -14
- package/src/flow/cards.ts +239 -0
- package/src/graph-runner/graph-tick.ts +4 -0
- package/src/graph-runner/runner.ts +30 -5
- package/src/harness/harness-cli-command.ts +259 -38
- package/src/harness/harness-incidents.ts +45 -12
- package/src/harness/harness-pod-dispatch.ts +102 -11
- package/src/harness/harness-queue-child.ts +3 -3
- package/src/harness/harness-queue.ts +583 -65
- package/src/harness/helper-repair.ts +87 -0
- package/src/harness/helper-scan.ts +151 -0
- package/src/harness/launch-stamp.ts +236 -0
- package/src/harness/ledger-write-guard-child.fixture.ts +12 -0
- package/src/harness/ledger-write-guard.ts +35 -0
- package/src/harness/model-input-observation.ts +37 -0
- package/src/harness/pod-memory-policy.ts +15 -0
- package/src/harness/repository-name.ts +55 -0
- package/src/hq/fence-audit.ts +90 -0
- package/src/hq/hq.ts +63 -5
- package/src/hq/lease.ts +4 -4
- package/src/hq/move-plan.ts +126 -0
- package/src/hq/promote.ts +332 -0
- package/src/index.ts +159 -27
- package/src/intake-plane/check.ts +63 -0
- package/src/intake-plane/digest.ts +37 -15
- package/src/intake-plane/front-classifier.ts +6 -0
- package/src/intake-plane/items.ts +3 -2
- package/src/intake-plane/lens.ts +177 -0
- package/src/intake-plane/linear-wish.ts +39 -11
- package/src/intake-plane/route.ts +145 -1
- package/src/intake-plane/wish-benchmark-ledger.ts +129 -0
- package/src/intake-plane/wish-card.ts +53 -2
- package/src/intake-plane/wish-folder.ts +5 -2
- package/src/intake-plane/wish-reply.ts +72 -0
- package/src/launch-head/seat-goal-queue-lock.fixture.ts +15 -0
- package/src/launch-head/seat-goal-queue.ts +198 -0
- package/src/lessons/lesson-import.ts +106 -0
- package/src/lessons/lesson-ledger.ts +206 -0
- package/src/loops/activity.ts +203 -0
- package/src/loops/budget.ts +63 -0
- package/src/loops/checker.ts +5 -3
- package/src/loops/contract/examples/orchestrator.loop.yaml +1 -1
- package/src/loops/loop-cli.ts +36 -4
- package/src/loops/neighbors.ts +40 -0
- package/src/loops/observe.ts +10 -0
- package/src/loops/orchestrator/author-depth.ts +220 -0
- package/src/loops/orchestrator/author-input-check.ts +82 -0
- package/src/loops/orchestrator/author-ledger.ts +232 -0
- package/src/loops/orchestrator/finish-rate.ts +175 -0
- package/src/loops/orchestrator/overlap.ts +51 -12
- package/src/loops/orchestrator/resync-shadow.ts +227 -0
- package/src/loops/orchestrator/seat-share.ts +56 -0
- package/src/loops/orchestrator/tick.ts +309 -0
- package/src/loops/orchestrator/traffic.ts +134 -13
- package/src/loops/registry.ts +535 -9
- package/src/loops/status-rows.ts +118 -0
- package/src/loops/verdict.ts +17 -5
- package/src/maturity/bot-slash-catalog.ts +66 -0
- package/src/maturity/feature-maturity.ts +9 -5
- package/src/maturity/tui-slash-availability.ts +31 -0
- package/src/mss/logging/log-store.ts +35 -4
- package/src/nexus/api/dashboard.ts +6 -1
- package/src/nexus/api/http-server.ts +33 -3
- package/src/nexus/api/loop-edges.ts +173 -0
- package/src/nexus/api/merge-approvals-gate.ts +1 -1
- package/src/nexus/api/schedules-read.ts +18 -1
- package/src/nexus/api/seat-requests.ts +79 -56
- package/src/nexus/api/task-cards-api.ts +44 -5
- package/src/nexus/api/workflows.ts +2 -1
- package/src/prompt-enhance/enhance.ts +6 -1
- package/src/release-loop/auto-start.ts +51 -0
- package/src/release-loop/checklist.ts +22 -4
- package/src/release-loop/feature-store.ts +71 -32
- package/src/release-loop/landing-freeze.ts +121 -0
- package/src/release-loop/merged-pr-checklist.ts +125 -0
- package/src/release-loop/placement.ts +302 -0
- package/src/release-loop/release-schedule.ts +3 -1
- package/src/seat-dispatch/ceo-commands.ts +2 -2
- package/src/seat-dispatch/seat-ask.ts +16 -3
- package/src/seat-dispatch/seat-questions.ts +58 -0
- package/src/seat-dispatch/seat-request-eligibility.ts +19 -0
- package/src/seat-dispatch/seat-request-ledger.ts +133 -0
- package/src/seat-loop/seat-loop.ts +531 -40
- package/src/self-dev/dev-pipeline.ts +14 -6
- package/src/self-dev/draft-sweep.ts +162 -6
- package/src/self-dev/draft-triage-rules.ts +25 -8
- package/src/self-dev/orchestrate.ts +15 -1
- package/src/self-dev/review-provider-fallback.ts +6 -1
- package/src/self-dev/run-store.ts +73 -1
- package/src/self-dev/run-supervisor.ts +57 -2
- package/src/self-dev/self-orchestrate-runtime.ts +5 -1
- package/src/self-implement/budget-gate.ts +29 -0
- package/src/self-implement/expose-gate.ts +47 -0
- package/src/self-implement/frozen-merges.ts +295 -0
- package/src/self-implement/gate-cli.ts +10 -4
- package/src/self-implement/gate-scope.ts +46 -9
- package/src/self-implement/goal-archive.ts +222 -0
- package/src/self-implement/goal-author.ts +43 -5
- package/src/self-implement/goal-clarification-escalation.ts +5 -0
- package/src/self-implement/goal-lookup.ts +147 -0
- package/src/self-implement/heal-intake.ts +197 -0
- package/src/self-implement/host-regate.ts +32 -2
- package/src/self-implement/l8-merge-queue.ts +132 -0
- package/src/self-implement/orchestrator.ts +299 -48
- package/src/self-implement/pipeline-shape.ts +1 -1
- package/src/self-implement/revert-guard.ts +97 -0
- package/src/self-implement/run-ledger.ts +3 -1
- package/src/self-implement/run-status-mapping.ts +2 -0
- package/src/self-implement/seams.ts +29 -9
- package/src/self-implement/self-implement-cli.ts +1 -0
- package/src/self-implement/speed-claims.ts +338 -0
- package/src/session/index.ts +2 -0
- package/src/steward/triage.ts +74 -3
- package/src/steward/working-backwards.ts +4 -1
- package/src/task-cards/card-cli.ts +10 -2
- package/src/task-cards/card-store.ts +10 -6
- package/src/task-orchestrator/surfaces/pod-artifact-return.ts +63 -48
- package/src/task-orchestrator/surfaces/pod-command-job.ts +84 -9
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +48 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +5 -2
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +46 -6
- package/src/task-orchestrator/surfaces/pod-pool.ts +60 -8
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +224 -49
- package/src/task-orchestrator/surfaces/self-implement.ts +5 -1
- package/src/telegram-commands.ts +27 -3
- package/src/telegram-loops-command.ts +44 -0
- package/src/telegram.ts +25 -4
- package/src/user-config.ts +146 -18
- package/src/version/packed-revision.json +1 -1
- package/src/workflow-runtime/nodes/bash.ts +9 -1
- package/src/workflow-runtime/storage.ts +31 -13
- package/apps/pwa/out/_next/static/D51l8jUBplJrIpWvENsDK/_buildManifest.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1159-0c5ef8bc21cb6afb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1394-931c9827067b2276.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2176-c379e3ebce874151.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2426.8c6ee0c668d53def.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3170-7ec60a56fa0e4728.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3278-ae6ef084769f6195.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3454-988a53dac60a1763.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3638-aa80b4641ea439db.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3735-fe3402553ac1c9c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3992-fe5c06d6b31f8b25.js +0 -25
- package/apps/pwa/out/_next/static/chunks/4215-c9d91dd644ec1719.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4508-5d0161d1e724d735.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4733-623a79345b171e1c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4883.3bd969ea1d3aaaff.js +0 -2
- package/apps/pwa/out/_next/static/chunks/5250-c78ca295585bbf95.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5532.6899a12958a89b72.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5845-e6c003ce8d5fd36a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5978-b27004c677119115.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6048-4c5c33579bc4ef78.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6303-422dbf0f67c72aac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6511-ff8360be3d65aaa4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6588-ba380869b67c4fa7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6751-bb3595948b2e311b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7274-19b7279f18b47ab3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7551-a0e0707b79164ddd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7758-85c2b53f731da024.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7777-79f845045aa1ed86.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8025-cc24ee5d8f2fb6f8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8206-c6684dcde12be721.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8605-9da4678f8a310d18.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8725.bf46bb1395dd0fa2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8734-252d511cd276c0dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8834-ca1cb09c1cb1a6bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9269.d2a4795bc6812717.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9538-2816b90923606459.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9906-e7b8b5310a169dfe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d16993889b125c42.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-e5b4e1b256f41076.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-e49b9b76c565a0b1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-b4f032c893b21cc9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-f14987d5850a31e0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-b433308aad13ceb6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-4c1dbb21861beab2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-c85b816e3b269dbb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-f6bc66b919b2ea7d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-60603c1e056c9b25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-a0ea8f5a2341ee6b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-45c5bf04b4a605e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-36c6c4183353ac9e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-d16993889b125c42.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-cb2eb0fd809980da.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-31012264da8a341f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-50309aeb0bdd554a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-bc00e964e855f4df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-0696ee3fac9fe56c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66c27608f651b866.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-6ddd2109b7fc3a80.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-4e50b7298c1f69a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-7a2bf830038a2264.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1f327f18694fabca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-e5cef2fe6e4028df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cf596128d2b420ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-f672536f14f0969f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-b52365662232db89.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-e7a6c80f288b1948.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-29a709616df9b050.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-fee842d7c2151129.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-78b40a344ed22f24.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-75d199f448171014.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-a011dd5b0bff29c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-d16993889b125c42.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-d92e32d51ab5157e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-5f21aed6932ef375.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-1e1a53946804debf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-a1833cd43d832601.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-2a511d320f762e06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-1c3e03f88dac1e21.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-c4d5289c2ea97a89.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b91f8952deaeaf27.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-71b43a2588489987.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-2b256feed331546f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-505bb96d69a8622c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-172630e6aa5e2d7f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-f0fe2d7477845181.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-fc98ac70b44eccb0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-5bd7f10271f72413.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-97d0d85ea05fef9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-9e4d02d567b98240.js +0 -1
- package/apps/pwa/out/_next/static/css/128fb7fb670b2fbf.css +0 -1
- /package/apps/pwa/out/_next/static/{D51l8jUBplJrIpWvENsDK → LZcstaO9_NXypPFmujolv}/_ssgManifest.js +0 -0
package/src/index.ts
CHANGED
|
@@ -31,6 +31,7 @@ import { collectCommandEntrances, renderCommandEntrances } from './self-dev/entr
|
|
|
31
31
|
import { isGoalAuthorFileName } from './self-implement/goal-document.js';
|
|
32
32
|
import { DEV_PIPELINE_SINK_SURFACE } from './self-implement/self-cli-sink-surface.js';
|
|
33
33
|
import { registerPrivateLedgerCommands } from './cli/private-ledger-commands.js';
|
|
34
|
+
import { registerSeatRequestsCommands } from './cli/seat-requests-cli.js';
|
|
34
35
|
import { applyTestStateDirFlagFromArgv } from './cli/test-state-dir-flag.js';
|
|
35
36
|
import { applyTestFlagFromArgv, observeTestFlagOwnership, uncoveredTestFlagPaths, staleTestFlagPaths } from './cli/test-flag.js';
|
|
36
37
|
import { registerPtyTakeoverCommands } from './cli/pty-takeover-cli.js';
|
|
@@ -46,6 +47,7 @@ import { registerPublishCommands } from './cli/publish-cli.js';
|
|
|
46
47
|
import { registerAutopilotCommands } from './cli/autopilot-cli.js';
|
|
47
48
|
import { registerRoleCommands } from './cli/role-cli.js';
|
|
48
49
|
import { registerMachineCommands } from './cli/machine-cli.js';
|
|
50
|
+
import { registerAgentEnvCommands } from './cli/agent-env-cli.js';
|
|
49
51
|
import { registerScheduleCommands } from './cli/schedule-cli.js';
|
|
50
52
|
export { runSchedule, scheduleCreatePlan } from './cli/schedule-cli.js';
|
|
51
53
|
export type { ScheduleDispatch } from './cli/schedule-cli.js';
|
|
@@ -63,6 +65,8 @@ import { registerUsageCommand } from './cli/usage-cli.js';
|
|
|
63
65
|
import { registerLiveCommands } from './cli/live-cli.js';
|
|
64
66
|
import { registerResearchCommand } from './cli/research-cli.js';
|
|
65
67
|
import { registerReleaseCommands } from './cli/release-cli.js';
|
|
68
|
+
import { registerFreezeCommands } from './cli/freeze-cli.js';
|
|
69
|
+
import { registerFlowCommands } from './cli/flow-cli.js';
|
|
66
70
|
import { registerModelWatchCommand } from './cli/model-watch-cli.js';
|
|
67
71
|
import { registerIntakeCommands } from './cli/intake-cli.js';
|
|
68
72
|
import { registerTasksCommands } from './cli/tasks-cli.js';
|
|
@@ -78,6 +82,7 @@ import { registerStartCommand } from './cli/start-cli.js';
|
|
|
78
82
|
import { registerGroundingSourcesCli } from './grounding/sources-cli.js';
|
|
79
83
|
import { registerGraphCommands } from './graph-runner/graph-cli.js';
|
|
80
84
|
import { registerLoopCommands } from './loops/loop-cli.js';
|
|
85
|
+
import { registerHqMovePlanCommand } from './hq/hq.js';
|
|
81
86
|
import { registerCardCommand } from './task-cards/card-cli.js';
|
|
82
87
|
import { registerLaunchHeadCommands } from './launch-head/launch-head-cli.js';
|
|
83
88
|
import { acpServerHelpText } from './boot/acp-server-help.js';
|
|
@@ -854,6 +859,7 @@ registerPrCommands(program);
|
|
|
854
859
|
registerRepoCommands(program);
|
|
855
860
|
registerRoleCommands(program);
|
|
856
861
|
registerMachineCommands(program);
|
|
862
|
+
registerAgentEnvCommands(program);
|
|
857
863
|
// CLI entry: where action → resolveCurrentInstance → resolveInstance (instance universe).
|
|
858
864
|
registerWhereCommand(program);
|
|
859
865
|
registerShadowCommand(program);
|
|
@@ -869,6 +875,8 @@ registerUsageCommand(program);
|
|
|
869
875
|
registerLiveCommands(program);
|
|
870
876
|
registerResearchCommand(program);
|
|
871
877
|
registerReleaseCommands(program);
|
|
878
|
+
registerFreezeCommands(program);
|
|
879
|
+
registerFlowCommands(program);
|
|
872
880
|
// HQ-HB · HQ-FENCE (10-04): one writer across mbp · node-b · cloud-vm — lease on the arbiter, 2-of-3 quorum, generation fencing.
|
|
873
881
|
const hqCmd = program.command('hq').description('본부 임대 — 하트비트·중재·단일 작성자 래퍼');
|
|
874
882
|
async function hqSink(): Promise<void> {
|
|
@@ -897,6 +905,19 @@ hqCmd.command('lease').argument('<action>', 'acquire|renew|status|release')
|
|
|
897
905
|
if (!result.ok) process.exitCode = 2;
|
|
898
906
|
} catch (error) { if (error instanceof CliUserError) throw error; console.error(`hq lease: ${error instanceof Error ? error.message : String(error)}`); process.exitCode = 1; }
|
|
899
907
|
});
|
|
908
|
+
hqCmd.command('promote').description('HQ 승격 런북 (기본 dry-run · --apply 일 때만 변경)')
|
|
909
|
+
.requiredOption('--to <host>', '승격 대상 호스트')
|
|
910
|
+
.option('--apply', '대기 사본을 승격 우주에 반영하고 넥서스·rescue 실행')
|
|
911
|
+
.option('--json', 'JSON 출력')
|
|
912
|
+
.action(async (opts: { to: string; apply?: boolean; json?: boolean }) => {
|
|
913
|
+
try {
|
|
914
|
+
const { promoteHq, formatPromote } = await import('./hq/promote.js');
|
|
915
|
+
const result = promoteHq(opts.to, opts.apply === true);
|
|
916
|
+
if (opts.json) await writeStdoutJson(`${JSON.stringify(result)}\n`);
|
|
917
|
+
else console.log(formatPromote(result));
|
|
918
|
+
if (!result.ok) process.exitCode = 1;
|
|
919
|
+
} catch (error) { console.error(`hq promote: ${error instanceof Error ? error.message : String(error)}`); process.exitCode = 1; }
|
|
920
|
+
});
|
|
900
921
|
hqCmd.command('heartbeat').description('보유자는 갱신 · 아니면 대기(보유자에 닿는지 중재자에 보고)').option('--json', 'JSON 출력')
|
|
901
922
|
.action(async (opts: { json?: boolean }) => {
|
|
902
923
|
try {
|
|
@@ -920,6 +941,18 @@ hqCmd.command('seen').description('이 호스트가 본 가장 높은 임대 세
|
|
|
920
941
|
else console.log(result.seen ? `hq seen: generation ${result.generation}` : 'hq seen: never');
|
|
921
942
|
process.exitCode = result.seen ? 0 : 3;
|
|
922
943
|
});
|
|
944
|
+
registerHqMovePlanCommand(hqCmd);
|
|
945
|
+
hqCmd.command('fence-audit').description('운영 crontab 의 HQ 울타리 밖 쓰기 잡 목록과 감싼 줄 제안(읽기 전용)')
|
|
946
|
+
.option('--json', 'JSON 출력')
|
|
947
|
+
.action(async (opts: { json?: boolean }) => {
|
|
948
|
+
try {
|
|
949
|
+
await hqSink();
|
|
950
|
+
const rows = (await import('./hq/fence-audit.js')).hqFenceAudit();
|
|
951
|
+
if (opts.json) await writeStdoutJson(`${JSON.stringify(rows)}\n`);
|
|
952
|
+
else if (!rows.length) console.log('hq fence-audit: unfenced 0');
|
|
953
|
+
else for (const row of rows) console.log(`${row.raw}\n role: ${row.recommendedRole}\n suggested: ${row.suggestedLine}`);
|
|
954
|
+
} catch (error) { console.error(`hq fence-audit: ${error instanceof Error ? error.message : String(error)}`); process.exitCode = 1; }
|
|
955
|
+
});
|
|
923
956
|
hqCmd.command('fence').description('이 호스트가 임대를 쥐었을 때만 명령 실행(아니면 건너뜀 · exit 0)')
|
|
924
957
|
.requiredOption('--role <role>', 'telegram-poller|cron|seat-loop|release-run|conatus|git-push')
|
|
925
958
|
.argument('<command...>', '-- 뒤의 명령')
|
|
@@ -930,6 +963,7 @@ hqCmd.command('fence').description('이 호스트가 임대를 쥐었을 때만
|
|
|
930
963
|
process.exitCode = hqFenceRun(opts.role as 'cron', command);
|
|
931
964
|
});
|
|
932
965
|
const seatCmd = program.command('seat').description('분배된 자리의 하루 루프와 보고');
|
|
966
|
+
registerSeatRequestsCommands(seatCmd);
|
|
933
967
|
seatCmd.command('answer <askId> <answer>').description('자리 질문에 답을 남기고 원래 표면으로 회신 예약')
|
|
934
968
|
.action(async (askId: string, answer: string) => {
|
|
935
969
|
try {
|
|
@@ -945,10 +979,10 @@ seatCmd.command('loop').requiredOption('--seat <SEAT>', 'MK|OP|TC|UX')
|
|
|
945
979
|
try {
|
|
946
980
|
// V3 F5: without the sink, the seat loop's judgment lines (seat.loop) never reach the log store when cron runs it.
|
|
947
981
|
await (await import('./domains/standalone-log-sink.js')).registerStandaloneLogSink('seat-loop');
|
|
948
|
-
const { runSeatLoopTurn } = await import('./seat-loop/seat-loop.js');
|
|
982
|
+
const { runSeatLoopTurn, seatLoopTickLine } = await import('./seat-loop/seat-loop.js');
|
|
949
983
|
const result = await runSeatLoopTurn(opts.seat);
|
|
950
984
|
if (opts.json) await writeStdoutJson(`${JSON.stringify(result)}\n`);
|
|
951
|
-
else console.log(
|
|
985
|
+
else console.log(seatLoopTickLine(result));
|
|
952
986
|
} catch (error) { console.error(`seat loop: ${error instanceof Error ? error.message : String(error)}`); process.exitCode = 1; }
|
|
953
987
|
});
|
|
954
988
|
seatCmd.command('report').requiredOption('--seat <SEAT>', 'MK|OP|TC|UX')
|
|
@@ -3034,6 +3068,8 @@ export async function runHarnessOrchestrateExecution(
|
|
|
3034
3068
|
prior,
|
|
3035
3069
|
goals,
|
|
3036
3070
|
pid,
|
|
3071
|
+
...(['OP', 'TC', 'MK', 'UX'].includes(process.env.ELANOUS_HARNESS_SEAT ?? '')
|
|
3072
|
+
? { seat: process.env.ELANOUS_HARNESS_SEAT as SelfDevRunState['seat'] } : {}),
|
|
3037
3073
|
runIdSource,
|
|
3038
3074
|
now,
|
|
3039
3075
|
onPersistenceFailure: reportPersistenceFailure,
|
|
@@ -3151,7 +3187,7 @@ contextCmd.command('condense')
|
|
|
3151
3187
|
if (!/^[1-9]\d*h$/.test(opts.since)) throw new Error('--since requires positive hours, e.g. 24h');
|
|
3152
3188
|
const { runContextCondense } = await import('./context-bus/condense.js');
|
|
3153
3189
|
const report = await runContextCondense({ hours: Number(opts.since.slice(0, -1)), apply: opts.apply === true });
|
|
3154
|
-
await writeStdoutJson(JSON.stringify({ since: report.since, until: report.until, cards: report.cards, conflicts: report.conflicts, skipped: report.skipped, folded: report.folded, ...(report.applied ? { applied: report.applied } : {}) }) + '\n');
|
|
3190
|
+
await writeStdoutJson(JSON.stringify({ since: report.since, until: report.until, cards: report.cards, conflicts: report.conflicts, skipped: report.skipped, folded: report.folded, droppedHarnessChild: report.droppedHarnessChild, funnel: report.funnel, ...(report.applied ? { applied: report.applied } : {}) }) + '\n');
|
|
3155
3191
|
if (!opts.json) await writeStdoutFully(report.markdown);
|
|
3156
3192
|
} catch (error) {
|
|
3157
3193
|
console.error(`context condense: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -3438,6 +3474,22 @@ selfCmd
|
|
|
3438
3474
|
}
|
|
3439
3475
|
});
|
|
3440
3476
|
|
|
3477
|
+
selfCmd
|
|
3478
|
+
.command('speed-claims')
|
|
3479
|
+
.description('런 원장 발사→종결 시간의 자리별·결과별 분포를 읽기 전용으로 출력한다')
|
|
3480
|
+
.option('--json', '구조화된 JSON으로 출력한다')
|
|
3481
|
+
.action(async (opts: { json?: boolean }) => {
|
|
3482
|
+
try {
|
|
3483
|
+
const { measureSpeedClaims, renderSpeedClaims } = await import('./self-implement/speed-claims.js');
|
|
3484
|
+
const result = measureSpeedClaims();
|
|
3485
|
+
if (opts.json) await writeStdoutJson(JSON.stringify(result) + '\n');
|
|
3486
|
+
else console.log(renderSpeedClaims(result));
|
|
3487
|
+
} catch (error) {
|
|
3488
|
+
console.error(`speed-claims measurement failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
3489
|
+
process.exitCode = 1;
|
|
3490
|
+
}
|
|
3491
|
+
});
|
|
3492
|
+
|
|
3441
3493
|
selfCmd
|
|
3442
3494
|
.command('goal-source-distribution')
|
|
3443
3495
|
.description('self-implement 런 원장의 start goalSource 분포를 읽기 전용으로 출력한다')
|
|
@@ -4300,6 +4352,35 @@ selfCmd
|
|
|
4300
4352
|
} catch (e) { console.error(`⛔ ${(e as Error).message}`); process.exitCode = 1; }
|
|
4301
4353
|
});
|
|
4302
4354
|
|
|
4355
|
+
export async function announceLaunchQuotaPolicy(input: {
|
|
4356
|
+
runId: string;
|
|
4357
|
+
current: import('./oauth/codex-quota-policy.js').ResolvedCodexQuotaPolicy;
|
|
4358
|
+
universe: { kind: 'prod' | 'test'; root: string };
|
|
4359
|
+
production?: import('./oauth/codex-quota-policy.js').ResolvedCodexQuotaPolicy;
|
|
4360
|
+
}): Promise<{ line: string; warning?: string; quotaPolicy: {
|
|
4361
|
+
policy: import('./oauth/codex-quota-policy.js').CodexQuotaPolicy;
|
|
4362
|
+
source: import('./oauth/codex-quota-policy.js').ResolvedCodexQuotaPolicy['source'];
|
|
4363
|
+
universeKind: 'prod' | 'test';
|
|
4364
|
+
} }> {
|
|
4365
|
+
const { describeLaunchQuotaPolicy } = await import('./oauth/codex-quota-policy.js');
|
|
4366
|
+
const { appendRunLedgerEntry } = await import('./self-implement/run-ledger.js');
|
|
4367
|
+
const described = describeLaunchQuotaPolicy(input);
|
|
4368
|
+
const data = { policy: input.current.policy, source: input.current.source, universe: input.universe,
|
|
4369
|
+
...(described.warning ? { warning: described.warning } : {}) };
|
|
4370
|
+
try {
|
|
4371
|
+
appendRunLedgerEntry({ runId: input.runId, timestamp: new Date().toISOString(), event: 'launch-quota-policy', data });
|
|
4372
|
+
} catch (error) {
|
|
4373
|
+
debug.log('pod.quota-policy', 'ledger-unavailable', { runId: input.runId, error: String(error) }, { level: 'warn' });
|
|
4374
|
+
throw new Error(`pod launch quota policy ledger write failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
4375
|
+
}
|
|
4376
|
+
debug.log('pod.quota-policy', 'announced', data);
|
|
4377
|
+
return { ...described, quotaPolicy: { policy: input.current.policy, source: input.current.source, universeKind: input.universe.kind } };
|
|
4378
|
+
}
|
|
4379
|
+
|
|
4380
|
+
export function withLaunchQuotaPolicy<T extends object>(results: readonly T[], quotaPolicy: Awaited<ReturnType<typeof announceLaunchQuotaPolicy>>['quotaPolicy'] | undefined): (T & { quotaPolicy?: Awaited<ReturnType<typeof announceLaunchQuotaPolicy>>['quotaPolicy'] })[] {
|
|
4381
|
+
return quotaPolicy ? results.map((result) => ({ ...result, quotaPolicy })) : [...results];
|
|
4382
|
+
}
|
|
4383
|
+
|
|
4303
4384
|
// self orchestrate — 병렬 self-dev(S1·2026-07-21) — N개 독립 goal 을 각자 `elanous self implement` 서브프로세스로
|
|
4304
4385
|
// TOX 디스패처 위에서 동시성캡 병렬 실행. 각 잡=자기 프로세스=자기 harness-space(병렬안전). 엔진(그래프/
|
|
4305
4386
|
// 디스패처)은 기존 재사용·새 조각=self-implement surface 어댑터. [[PLAN-parallel-self-dev-orchestrator-2026-07-21]].
|
|
@@ -4331,6 +4412,9 @@ const selfOrchestrateCmd = selfCmd
|
|
|
4331
4412
|
.option('--no-pod-rebuild', 'pod: 이미지 판(elanous.commit)이 HEAD 와 달라도 다시 굽지 않는다 — 측정은 «이미지 판»을 잰다')
|
|
4332
4413
|
.option('--pod-pass-env <keys>', 'pod: 호스트 env 에서 Pod 로 넘길 키(쉼표) — 예 OPENROUTER_API_KEY,ANTHROPIC_API_KEY(벤치마크 과금 경로)')
|
|
4333
4414
|
.option('--bench-arms <spec>', 'pod 벤치마크: 골 1개를 팔마다 «라벨 한 줄만 다르게» 복제해 동시에 — "id=provider[:model][@KEY+KEY];…" (예 codex=openai-codex;or-kimi=openrouter:openrouter/moonshotai/kimi-k3@OPENROUTER_API_KEY) · --auto-merge 거부 · RFC fleet 슈퍼바이저 §A3')
|
|
4415
|
+
.addOption(new Option('--child-llm-provider <id>', 'pod: 구현 자식 LLM provider(openai-codex|grok) — 하니스 --child-llm-provider 가 이 자리로 온다(10-05)').hideHelp())
|
|
4416
|
+
.addOption(new Option('--child-llm-model <id>', 'pod: 구현 자식 LLM model(--child-llm-provider 와 함께)').hideHelp())
|
|
4417
|
+
.addOption(new Option('--child-llm-effort <level>', 'pod: 구현 자식 추론 노력(--child-llm-provider 와 함께)').hideHelp())
|
|
4334
4418
|
.option('--help-all', '모든 orchestrate 옵션 표시')
|
|
4335
4419
|
.action(function (this: Command, parts: string[], opts: { goalFile?: string[]; concurrency?: string; autoMerge?: boolean; autoReview?: boolean; openPr?: boolean; base?: string; teardown?: boolean; resume?: string; board?: boolean; decompose?: boolean; fabricDecompose?: boolean; maxTasks?: string; supervise?: boolean; superviseRounds?: string; json?: boolean }) {
|
|
4336
4420
|
return (async () => {
|
|
@@ -4458,6 +4542,8 @@ const selfOrchestrateCmd = selfCmd
|
|
|
4458
4542
|
prior,
|
|
4459
4543
|
goals,
|
|
4460
4544
|
pid: process.pid,
|
|
4545
|
+
...(['OP', 'TC', 'MK', 'UX'].includes(process.env.ELANOUS_HARNESS_SEAT ?? '')
|
|
4546
|
+
? { seat: process.env.ELANOUS_HARNESS_SEAT as SelfDevRunState['seat'] } : {}),
|
|
4461
4547
|
runIdSource,
|
|
4462
4548
|
now: () => Date.now(),
|
|
4463
4549
|
});
|
|
@@ -4492,6 +4578,7 @@ const selfOrchestrateCmd = selfCmd
|
|
|
4492
4578
|
// coordinator 해석(decompose·run-identity·checkpoint·board)은 액션에 유지·감독 콜백은 runtime 으로 주입.
|
|
4493
4579
|
// ☸️ 실행 칸 — pod 면 self-implement 자식을 k8s Job 으로(계약 동일 · 슈퍼바이저 무수정).
|
|
4494
4580
|
const substrate = (opts as { substrate?: string }).substrate ?? 'local';
|
|
4581
|
+
let launchQuotaPolicy: Awaited<ReturnType<typeof announceLaunchQuotaPolicy>>['quotaPolicy'] | undefined;
|
|
4495
4582
|
let podSpawn: import('./task-orchestrator/surfaces/self-implement.js').SelfImplementJobSpawn | undefined;
|
|
4496
4583
|
let podTargets: { context: string; namespace: string }[] | undefined;
|
|
4497
4584
|
if (substrate === 'pod') {
|
|
@@ -4562,6 +4649,19 @@ const selfOrchestrateCmd = selfCmd
|
|
|
4562
4649
|
let rotationAccounts: readonly string[] | undefined;
|
|
4563
4650
|
let podProvider: 'openai-codex' | 'grok' = 'openai-codex';
|
|
4564
4651
|
let grokApiKeyOptIn = false;
|
|
4652
|
+
{
|
|
4653
|
+
// 10-05 PODPROVIDER: refuse child choices this Pod launch cannot honour instead of dropping them.
|
|
4654
|
+
const child = opts as { childLlmProvider?: string; childLlmModel?: string; childLlmEffort?: string };
|
|
4655
|
+
const named = child.childLlmProvider?.trim();
|
|
4656
|
+
const refuse = !named && (child.childLlmModel?.trim() || child.childLlmEffort?.trim())
|
|
4657
|
+
? 'pod: --child-llm-model/--child-llm-effort 는 --child-llm-provider 와 함께'
|
|
4658
|
+
: named && benchArms
|
|
4659
|
+
? 'pod: --child-llm-provider 는 --bench-arms 와 함께 못 쓴다(팔마다 모델이 하나다)'
|
|
4660
|
+
: named === 'grok' && explicitPodAccount
|
|
4661
|
+
? 'pod: --child-llm-provider grok 은 --pod-account 와 함께 못 쓴다(그것은 codex 계정을 고정한다)'
|
|
4662
|
+
: undefined;
|
|
4663
|
+
if (refuse) { ui.error(refuse); debug.log('self-implement.pod', 'child-provider-refused', { provider: named ?? null, reason: refuse }); process.exit(2); }
|
|
4664
|
+
}
|
|
4565
4665
|
if (!explicitPodAccount && !benchArms) {
|
|
4566
4666
|
const { inspectCodexRotation } = await import('./oauth/codex-account-store.js');
|
|
4567
4667
|
const { planPodProvider, makePodAccountBroker } = await import('./task-orchestrator/surfaces/pod-account-broker.js');
|
|
@@ -4574,34 +4674,57 @@ const selfOrchestrateCmd = selfCmd
|
|
|
4574
4674
|
const resolvedQuota = resolveCodexQuotaPolicy(getUserConfig().llm);
|
|
4575
4675
|
const quotaPolicy = resolvedQuota.policy;
|
|
4576
4676
|
// POL1 — say which policy this launch uses and where it came from; warn when a test universe disagrees with production.
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4677
|
+
const { effectiveInstanceRoot, prodInstanceRoot } = await import('./instance/resolve.js');
|
|
4678
|
+
const root = effectiveInstanceRoot();
|
|
4679
|
+
const kind = root === prodInstanceRoot() ? 'prod' as const : 'test' as const;
|
|
4680
|
+
let production: ReturnType<typeof resolveCodexQuotaPolicy> | undefined;
|
|
4681
|
+
if (kind === 'test') {
|
|
4682
|
+
try {
|
|
4683
|
+
const { readFileSync } = await import('node:fs');
|
|
4684
|
+
const prodLlm = (JSON.parse(readFileSync(`${prodInstanceRoot()}/config.json`, 'utf8')) as { llm?: Record<string, unknown> }).llm;
|
|
4685
|
+
production = resolveCodexQuotaPolicy(prodLlm);
|
|
4686
|
+
} catch { /* no production config on this machine */ }
|
|
4687
|
+
}
|
|
4688
|
+
const described = await announceLaunchQuotaPolicy({ runId, current: resolvedQuota, universe: { kind, root }, ...(production ? { production } : {}) });
|
|
4689
|
+
launchQuotaPolicy = described.quotaPolicy;
|
|
4690
|
+
debug.log('self-implement.pod', 'quota-policy', { policy: resolvedQuota.policy, source: resolvedQuota.source, universe: kind, productionPolicy: production?.policy ?? null });
|
|
4691
|
+
if (!opts.json) { ui.info(described.line); if (described.warning) ui.warn(described.warning); }
|
|
4692
|
+
// GROK-OPTIONAL (10-05): an expiring grok subscription the host cannot refresh is dropped from the chain here,
|
|
4693
|
+
// so the launch goes on with codex instead of dying later in hostGrokCredentials.
|
|
4694
|
+
let grokSubscriptionUsable = credential?.kind === 'subscription';
|
|
4695
|
+
if (grokSubscriptionUsable && codexPolicyAllowsFallback(quotaPolicy)) {
|
|
4696
|
+
const { podGrokSubscriptionUsable, podGrokSkippedLine } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
|
|
4697
|
+
const grokCheck = podGrokSubscriptionUsable();
|
|
4698
|
+
if (!grokCheck.usable) {
|
|
4699
|
+
grokSubscriptionUsable = false;
|
|
4700
|
+
if (!opts.json) ui.warn(podGrokSkippedLine(grokCheck));
|
|
4589
4701
|
}
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
const
|
|
4702
|
+
}
|
|
4703
|
+
// 10-05 PODPROVIDER: a launch that named the child provider gets it, or is refused — never a silent codex.
|
|
4704
|
+
const namedChild = (opts as { childLlmProvider?: string }).childLlmProvider?.trim();
|
|
4705
|
+
const { podNamedChildProvider, podFallbackCredentials, podGrokSubscriptionUsable: namedGrokUsable } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
|
|
4706
|
+
const namedChildDecision = podNamedChildProvider(namedChild, {
|
|
4707
|
+
grokSubscription: namedChild === 'grok' && credential?.kind === 'subscription' && (grokSubscriptionUsable || namedGrokUsable().usable),
|
|
4708
|
+
grokApiKey: credential?.kind === 'api_key' && grokApiKeyOptIn,
|
|
4709
|
+
});
|
|
4710
|
+
if (namedChildDecision.refuse) { ui.error(namedChildDecision.refuse); debug.log('self-implement.pod', 'child-provider-refused', { provider: namedChild, reason: namedChildDecision.refuse }); process.exit(2); }
|
|
4711
|
+
// A named codex child must stay codex — the plan may not fall back to grok (post-review must-fix).
|
|
4712
|
+
const namedCodex = namedChildDecision.provider === 'openai-codex';
|
|
4713
|
+
const plan: import('./task-orchestrator/surfaces/pod-account-broker.js').PodProviderPlan = namedChildDecision.provider === 'grok'
|
|
4714
|
+
? { provider: 'grok', excluded: [], grokSubscriptionEligible: credential?.kind === 'subscription' }
|
|
4715
|
+
: planPodProvider({
|
|
4595
4716
|
codexCandidates: inspectCodexRotation().candidates,
|
|
4596
4717
|
// Per-account caps (대표 default:97) override the Pod default cap — without them default was dropped at 60%.
|
|
4597
4718
|
thresholdPercentByAccount: getUserConfig().llm?.codexAccountRotationThresholdPercentByAccount,
|
|
4598
4719
|
// 대표 한도 정책 한 값(`llm.codexQuotaPolicy`) — 크레딧·폴백을 같이 정한다.
|
|
4599
4720
|
creditsAllowed: codexPolicyAllowsCredits(quotaPolicy),
|
|
4600
|
-
|
|
4601
|
-
|
|
4721
|
+
...podFallbackCredentials(namedChildDecision.provider, {
|
|
4722
|
+
grokSubscription: codexPolicyAllowsFallback(quotaPolicy) && grokSubscriptionUsable,
|
|
4723
|
+
grokApiKey: codexPolicyAllowsFallback(quotaPolicy) && credential?.kind === 'api_key',
|
|
4724
|
+
}),
|
|
4602
4725
|
grokApiKeyOptIn,
|
|
4603
4726
|
});
|
|
4604
|
-
if (plan.provider === null) { ui.error(`pod: 쓸 codex 계정이 없다 — ${plan.reasons.join(' · ')} · 계정을 명시하려면 --pod-account <이름>`); process.exit(2); }
|
|
4727
|
+
if (plan.provider === null) { ui.error(`pod: 쓸 codex 계정이 없다 — ${plan.reasons.join(' · ')}${namedCodex ? ' · child provider 를 openai-codex 로 지정해 grok 으로 넘기지 않는다' : ''} · 계정을 명시하려면 --pod-account <이름>`); process.exit(2); }
|
|
4605
4728
|
podProvider = plan.provider;
|
|
4606
4729
|
if (plan.provider === 'openai-codex') {
|
|
4607
4730
|
accountBroker = makePodAccountBroker({ usable: plan.accounts, excluded: plan.excluded });
|
|
@@ -4610,6 +4733,10 @@ const selfOrchestrateCmd = selfCmd
|
|
|
4610
4733
|
{ const { emitDecision } = await import('./live/detail-switch.js');
|
|
4611
4734
|
emitDecision({ kind: 'ROUTE', what: `Pod 계정 배분 ${plan.accounts.join(' → ')}`, reason: plan.excluded.length ? `뺌 ${plan.excluded.map((x) => `${x.name}(${x.why})`).join(', ')}` : '모든 계정 여유', purpose: plan.creditAccounts ? '구독 잔량 0 — 정책상 크레딧으로 병렬 조각을 돌린다' : '병렬 조각이 한 계정에 몰리지 않게 잔량 순으로 돌려 준다', phase: 'dispatch', target: `Pod ${plan.accounts.length}계정`, paths: plan.accounts.length + plan.excluded.length }); }
|
|
4612
4735
|
if (!opts.json) ui.info(`[pod] 계정 배분(잔량 순 · 돌려 가며): ${plan.accounts.join(' → ')}${plan.creditAccounts ? ' · 💳 크레딧(구독 잔량 0 · 허가됨)' : ''}${plan.excluded.length ? ` · 뺌 ${plan.excluded.map((x) => `${x.name}(${x.why})`).join(', ')}` : ''}`);
|
|
4736
|
+
} else if (namedChildDecision.provider === 'grok') {
|
|
4737
|
+
const model = (opts as { childLlmModel?: string }).childLlmModel?.trim() || defaultGrokModel().id;
|
|
4738
|
+
debug.log('self-implement.pod', 'provider-named', { provider: 'grok', model, credential: credential?.kind ?? null });
|
|
4739
|
+
if (!opts.json) ui.info(`[pod] child provider = grok(모델 ${model}) — 발사 인자로 지정됨`);
|
|
4613
4740
|
} else {
|
|
4614
4741
|
const model = defaultGrokModel().id;
|
|
4615
4742
|
debug.log('self-implement.pod', 'provider-fallback', { from: 'openai-codex', to: 'grok', excluded: plan.excluded, model });
|
|
@@ -4637,7 +4764,10 @@ const selfOrchestrateCmd = selfCmd
|
|
|
4637
4764
|
...(podSource.kind === 'bundle' ? { headCommit: podSource.headCommit, sizeBytes: podSource.sizeBytes } : {}),
|
|
4638
4765
|
});
|
|
4639
4766
|
}
|
|
4640
|
-
const
|
|
4767
|
+
const childFlags = opts as { childLlmProvider?: string; childLlmModel?: string; childLlmEffort?: string };
|
|
4768
|
+
const podChildLlm = childFlags.childLlmProvider?.trim() ? { childProviderExplicit: true, ...(childFlags.childLlmModel?.trim() ? { childModel: childFlags.childLlmModel.trim() } : {}), ...(childFlags.childLlmEffort?.trim() ? { childEffort: childFlags.childLlmEffort.trim() } : {}) } : {};
|
|
4769
|
+
if (childFlags.childLlmProvider?.trim()) debug.log('self-implement.pod', 'child-provider-named', { provider: childFlags.childLlmProvider.trim(), model: childFlags.childLlmModel ?? null, podProvider });
|
|
4770
|
+
const podBase = { hostSupervised: opts.supervise === true, ...podChildLlm, ...(remoteOnlyPool ? { imageCommit: image.imageCommit } : {}), account: podProvider === 'grok' ? 'grok' : explicitPodAccount ?? 'team', ...(accountBroker ? { accountBroker, rotationAccounts } : {}), ...(podProvider === 'grok' ? { provider: 'grok' as const, grokApiKeyOptIn } : {}), passEnv, ...(pool ? { pool } : {}), ...((opts as { podSkillEnv?: boolean }).podSkillEnv ? { skillEnv: true } : {}), ...(podSource ? { source: podSource } : {}) };
|
|
4641
4771
|
if (benchArms) {
|
|
4642
4772
|
const { benchPodSpawn } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
|
|
4643
4773
|
podSpawn = benchPodSpawn(benchArms, podBase);
|
|
@@ -4714,7 +4844,7 @@ const selfOrchestrateCmd = selfCmd
|
|
|
4714
4844
|
debug.log('self-dev.reduce', 'orchestrate-reduce', { runId, shards: shards.length, kind: r.kind });
|
|
4715
4845
|
}
|
|
4716
4846
|
}
|
|
4717
|
-
if (opts.json) { await writeStdoutJson(JSON.stringify(results) + '\n'); await reportRun(results); return; }
|
|
4847
|
+
if (opts.json) { await writeStdoutJson(JSON.stringify(withLaunchQuotaPolicy(results, launchQuotaPolicy)) + '\n'); await reportRun(results); return; }
|
|
4718
4848
|
const done = results.filter((r) => r.status === 'done').length;
|
|
4719
4849
|
const promoted = results.filter((r) => r.prUrl).length;
|
|
4720
4850
|
const incomplete = results.length - done;
|
|
@@ -6811,7 +6941,8 @@ const selfDevCmd = program
|
|
|
6811
6941
|
const { dispatchHarnessOnPod } = await import('./harness/harness-pod-dispatch.js');
|
|
6812
6942
|
const { devAskPodDispatchInput } = await import('./harness/harness-substrate-default.js');
|
|
6813
6943
|
const { classifyHarnessPodExit, harnessPodRunId, recordClassifiedHarnessPodExit, warnRecentIncidentBurst } = await import('./harness/harness-cli-command.js');
|
|
6814
|
-
warnRecentIncidentBurst(
|
|
6944
|
+
warnRecentIncidentBurst(undefined, undefined, undefined,
|
|
6945
|
+
{ entrance: 'cli-dev-ask', seat: opts.seat });
|
|
6815
6946
|
let podOutput = '';
|
|
6816
6947
|
let podRunId: string | undefined;
|
|
6817
6948
|
const previousLeaseId = process.env.ELANOUS_POD_RESERVED_LEASE;
|
|
@@ -6831,7 +6962,8 @@ const selfDevCmd = program
|
|
|
6831
6962
|
}
|
|
6832
6963
|
if (status !== 0) {
|
|
6833
6964
|
const classified = classifyHarnessPodExit({ status }, podOutput, { ...(podRunId ? { runId: podRunId } : {}) });
|
|
6834
|
-
recordClassifiedHarnessPodExit(podRunId ?? harnessPodRunId(podOutput), classified.reason, status
|
|
6965
|
+
recordClassifiedHarnessPodExit(podRunId ?? harnessPodRunId(podOutput), classified.reason, status,
|
|
6966
|
+
{ entrance: 'cli-dev-ask', seat: opts.seat, output: podOutput });
|
|
6835
6967
|
for (const line of classified.lines) console.error(line);
|
|
6836
6968
|
}
|
|
6837
6969
|
completionGuard.conclude();
|
|
@@ -61,8 +61,22 @@ export interface IntakeCheckEvidence {
|
|
|
61
61
|
readonly contrary?: boolean;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
export interface IntakeReplacementCandidate {
|
|
65
|
+
readonly tool: string;
|
|
66
|
+
readonly paidDependency: string;
|
|
67
|
+
readonly status: '현장 시험 필요';
|
|
68
|
+
/** A comparison claim is not evidence that any of these checks have passed. */
|
|
69
|
+
readonly trial: {
|
|
70
|
+
readonly installation: '미검증';
|
|
71
|
+
readonly sampleRun: '미검증';
|
|
72
|
+
readonly license: '미검증';
|
|
73
|
+
readonly maintenanceStatus: '미검증';
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
64
77
|
export interface IntakeCheckItem {
|
|
65
78
|
readonly fact: string;
|
|
79
|
+
readonly replacementCandidate?: IntakeReplacementCandidate;
|
|
66
80
|
/** Source identity preserved from the supplied fact for card-backed goal evidence. */
|
|
67
81
|
readonly sourceRef?: string;
|
|
68
82
|
readonly originalClaims?: readonly string[];
|
|
@@ -1053,6 +1067,40 @@ function factKey(text: string): string {
|
|
|
1053
1067
|
return text.replace(/\s+/g, ' ').trim().toLowerCase();
|
|
1054
1068
|
}
|
|
1055
1069
|
|
|
1070
|
+
/** A stated possibility is a trial candidate, not proof of a working replacement. */
|
|
1071
|
+
function replacementCandidate(fact: string): IntakeReplacementCandidate | undefined {
|
|
1072
|
+
if (!/(?:대체(?:하|한|할| 가능| 후보|재)|replace|replacement|alternative to)/i.test(fact)
|
|
1073
|
+
|| /(?:대체하지\s*(?:는|도|조차|를)?\s*(?:않|못)|대체\s*못|대체할\s*수\s*(?:는|도|가)?\s*없|대체(?:가|는| 후보가)?\s*(?:아니|불가)|cannot replace|can't replace|does not replace|not a replacement)/i.test(fact)) return undefined;
|
|
1074
|
+
const paid = fact.match(/(?:유료|paid)\s*(?:(?:서비스|의존성|도구|툴|API|dependency|service|tool)\s*)?`?([a-z][\w.-]+)`?/i);
|
|
1075
|
+
// firecrawl is a named paid-dependency example even when the claim omits the word "paid".
|
|
1076
|
+
const paidDependency = paid?.[1] ?? fact.match(/(?:^|[^\w])`?(firecrawl)`?(?=$|[^\w])/i)?.[1];
|
|
1077
|
+
if (!paidDependency) return undefined;
|
|
1078
|
+
const names = [...fact.matchAll(/`([a-z][\w.-]+)`/gi)].map((match) => match[1]!);
|
|
1079
|
+
const explicit = names.filter((name) => name.toLowerCase() !== paidDependency.toLowerCase());
|
|
1080
|
+
const plain = fact.match(/^\s*([a-z][\w.-]+)\s*(?:가|이|는|은|으로|로|can\b|could\b|may\b)/i)?.[1];
|
|
1081
|
+
const tool = explicit.length === 1 ? explicit[0] : explicit.length === 0 ? plain : undefined;
|
|
1082
|
+
if (!tool || tool.toLowerCase() === paidDependency.toLowerCase() || tool.toLowerCase() === 'elanous') return undefined;
|
|
1083
|
+
// Names appearing together do not establish the direction of replacement.
|
|
1084
|
+
const clause = fact.replace(/`/g, '').replace(/(?:유료|paid)\s*(?:(?:서비스|의존성|도구|툴|API|dependency|service|tool)\s*)?/gi, '');
|
|
1085
|
+
const escape = (name: string): string => name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1086
|
+
const name = (value: string): string => `(?<![\\w.-])${escape(value)}(?![\\w.-])`;
|
|
1087
|
+
const toolName = name(tool);
|
|
1088
|
+
const dependencyName = name(paidDependency);
|
|
1089
|
+
const replaces = (subject: string, object: string): boolean => [
|
|
1090
|
+
new RegExp(`${subject}\\s*(?:이|가|은|는)?\\s+${object}\\s*(?:을|를)\\s*대체(?:하|한|할| 가능| 후보|재)`, 'i'),
|
|
1091
|
+
new RegExp(`${object}\\s*(?:을|를)\\s+${subject}\\s*(?:이|가|은|는)\\s*대체(?:하|한|할| 가능| 후보|재)`, 'i'),
|
|
1092
|
+
new RegExp(`${subject}\\s+(?:can |could |may )?replace(?:s|d)?\\s+${object}`, 'i'),
|
|
1093
|
+
new RegExp(`${subject}\\s+(?:is |could be |may be )?(?:an? )?(?:replacement|alternative)\\s+to\\s+${object}`, 'i'),
|
|
1094
|
+
].some((pattern) => pattern.test(clause));
|
|
1095
|
+
if (!replaces(toolName, dependencyName) || replaces(dependencyName, toolName)) return undefined;
|
|
1096
|
+
return {
|
|
1097
|
+
tool,
|
|
1098
|
+
paidDependency,
|
|
1099
|
+
status: '현장 시험 필요',
|
|
1100
|
+
trial: { installation: '미검증', sampleRun: '미검증', license: '미검증', maintenanceStatus: '미검증' },
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1056
1104
|
function isLens(value: string): value is PreprocessLens {
|
|
1057
1105
|
return (PREPROCESS_LENSES as readonly string[]).includes(value);
|
|
1058
1106
|
}
|
|
@@ -1414,8 +1462,17 @@ export function runIntakeCheck(
|
|
|
1414
1462
|
}
|
|
1415
1463
|
// src/index.ts intake check .action → runIntakeCheck / runIntakeCheckDocument → runIntakeCheck → judgeFact.
|
|
1416
1464
|
const judged = judgeFact(fact, ruler, deps);
|
|
1465
|
+
const candidate = replacementCandidate(fact.text);
|
|
1466
|
+
const verdict = candidate && judged.verdict !== '못 쟀다' ? '판단 필요' : judged.verdict;
|
|
1467
|
+
const current = candidate && judged.verdict !== '못 쟀다'
|
|
1468
|
+
? `${judged.current} · 대체 후보 ${candidate.tool} → ${candidate.paidDependency}: 설치·샘플 실행·라이선스·유지보수 상태 현장 시험 필요`
|
|
1469
|
+
: judged.current;
|
|
1417
1470
|
const item: IntakeCheckItem = {
|
|
1418
1471
|
...judged,
|
|
1472
|
+
verdict,
|
|
1473
|
+
current,
|
|
1474
|
+
line: `${fact.text} → ${current} → ${verdict}`,
|
|
1475
|
+
...(candidate ? { replacementCandidate: candidate } : {}),
|
|
1419
1476
|
quotes: [quote],
|
|
1420
1477
|
...(fact.sourceRef ? { sourceRef: fact.sourceRef } : {}),
|
|
1421
1478
|
...(fact.originalClaim ? { originalClaims: [fact.originalClaim] } : {}),
|
|
@@ -1711,6 +1768,11 @@ export function renderIntakeCheckReport(report: IntakeCheckReport): string {
|
|
|
1711
1768
|
for (const item of report.items) {
|
|
1712
1769
|
lines.push(item.line);
|
|
1713
1770
|
lines.push(` 판정: ${item.verdict}`);
|
|
1771
|
+
if (item.replacementCandidate) {
|
|
1772
|
+
const candidate = item.replacementCandidate;
|
|
1773
|
+
lines.push(` 대체 후보: ${candidate.tool} → 유료 의존성 ${candidate.paidDependency} (${candidate.status})`);
|
|
1774
|
+
lines.push(' 현장 시험: 설치 미검증 · 샘플 실행 미검증 · 라이선스 미검증 · 유지보수 상태 미검증');
|
|
1775
|
+
}
|
|
1714
1776
|
if (item.goalDraftPath) lines.push(` 골 초안: ${item.goalDraftPath}`);
|
|
1715
1777
|
for (const quote of item.quotes) lines.push(` 인용: ${quote}`);
|
|
1716
1778
|
for (const original of item.originalClaims ?? []) lines.push(` 원 주장: ${original}`);
|
|
@@ -1746,6 +1808,7 @@ export function intakeCheckReportJson(report: IntakeCheckReport): Record<string,
|
|
|
1746
1808
|
current: item.current,
|
|
1747
1809
|
verdict: item.verdict,
|
|
1748
1810
|
line: item.line,
|
|
1811
|
+
...(item.replacementCandidate ? { replacementCandidate: item.replacementCandidate } : {}),
|
|
1749
1812
|
quotes: item.quotes,
|
|
1750
1813
|
evidence: item.evidence,
|
|
1751
1814
|
patterns: item.patterns,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// 흡수 하루 다이제스트 — 그날 흡수한 것을 사람이 «발견»하는 자리. 노트 절(마크다운) ⊕ 텔레그램 짧은 판.
|
|
2
2
|
// 결정론만: 요약 한 줄은 각 노트가 이미 쓴 「한 줄 결론」을 뽑는다(LLM 을 다시 부르지 않는다).
|
|
3
3
|
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
-
import { basename, join
|
|
4
|
+
import { basename, join } from 'node:path';
|
|
5
5
|
import { loadIntakeLedger, type IntakeItem } from './items.js';
|
|
6
6
|
import { readSavedCursorAt } from './collect-telegram-saved.js';
|
|
7
7
|
import { intakeOutboxDir, kstDay } from './route.js';
|
|
8
8
|
|
|
9
|
-
export interface DigestEntry { id: string; sources: string[]; url?: string; note?: string; noteName?: string; oneLiner?: string; axis: string }
|
|
9
|
+
export interface DigestEntry { id: string; sources: string[]; url?: string; note?: string; noteName?: string; oneLiner?: string; axis: string; impact?: { fact: string; current: string; action: string } }
|
|
10
10
|
export interface IntakeDigest { day: string; absorbed: DigestEntry[]; goals: { fact: string; url?: string }[]; review?: { fact: string; note?: string }[]; grounding: number; release: number; manual: number; savedSilence?: { days: number; lastNewAt: string } }
|
|
11
11
|
|
|
12
12
|
const AXIS_LABEL: Record<string, string> = {
|
|
@@ -43,17 +43,38 @@ const SAVED_SILENCE_MS = 48 * 3600_000;
|
|
|
43
43
|
export function buildIntakeDigest(root: string, day: string, readFile: (p: string) => string | undefined = (p) => (existsSync(p) ? readFileSync(p, 'utf8') : undefined), now: Date = new Date()): IntakeDigest {
|
|
44
44
|
const items = [...loadIntakeLedger(root).items.values()]
|
|
45
45
|
.filter((i) => (i.status === 'absorbed' || i.status === 'routed') && kstDay(i.lastSeenAt) === day && i.outputs.some((o) => o.kind === 'note'));
|
|
46
|
+
const out = intakeOutboxDir(root);
|
|
47
|
+
const relevant = new Map<string, NonNullable<DigestEntry['impact']>>();
|
|
48
|
+
for (const [folder, action] of [
|
|
49
|
+
['goals', '없는 기능의 골 후보를 세운다'],
|
|
50
|
+
['manual', '문서·약속을 현재 동작에 맞게 보강한다'],
|
|
51
|
+
['review', '대조 근거를 추가로 확인한다'],
|
|
52
|
+
['release', '이미 착지한 기능의 바깥 맥락을 릴리스 노트에 반영한다'],
|
|
53
|
+
] as const) {
|
|
54
|
+
for (const row of readJsonl(join(out, folder, `${day}.jsonl`))) {
|
|
55
|
+
if (typeof row.id !== 'string' || relevant.has(row.id)) continue;
|
|
56
|
+
const fact = folder === 'release' ? row.title : row.fact;
|
|
57
|
+
if (typeof fact !== 'string' || !fact.trim()) continue;
|
|
58
|
+
relevant.set(row.id, {
|
|
59
|
+
fact,
|
|
60
|
+
current: typeof (folder === 'release' ? row.summary : row.current) === 'string'
|
|
61
|
+
? String(folder === 'release' ? row.summary : row.current) : '대조 근거 없음',
|
|
62
|
+
action,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
46
66
|
const absorbed = items.map((i: IntakeItem): DigestEntry => {
|
|
47
67
|
const note = [...i.outputs].reverse().find((o) => o.kind === 'note')?.ref;
|
|
48
68
|
const md = note ? readFile(note) : undefined;
|
|
69
|
+
const impact = relevant.get(i.id);
|
|
49
70
|
return {
|
|
50
71
|
id: i.id, sources: i.sources, ...(i.url ? { url: i.url } : {}),
|
|
51
72
|
...(note ? { note, noteName: basename(note, '.md') } : {}),
|
|
52
73
|
...(md ? { oneLiner: noteOneLiner(md) } : {}),
|
|
53
74
|
axis: AXIS_LABEL[i.judgement?.axis ?? i.axis ?? ''] ?? (i.sources.includes('telegram-saved') ? '내가 저장한 것' : '그 밖'),
|
|
75
|
+
...(impact ? { impact } : {}),
|
|
54
76
|
};
|
|
55
77
|
});
|
|
56
|
-
const out = intakeOutboxDir(root);
|
|
57
78
|
const goals = readJsonl(join(out, 'goals', `${day}.jsonl`)).map((g) => ({ fact: String(g.fact ?? ''), ...(g.url ? { url: String(g.url) } : {}) }));
|
|
58
79
|
const review = readJsonl(join(out, 'review', `${day}.jsonl`)).map((r) => ({ fact: String(r.fact ?? ''), ...(r.note ? { note: String(r.note) } : {}) }));
|
|
59
80
|
const grounding = readJsonl(join(out, 'grounding.jsonl')).filter((g) => typeof g.at === 'string' && kstDay(g.at) === day).length;
|
|
@@ -94,18 +115,19 @@ export function renderDigestMarkdown(d: IntakeDigest): string {
|
|
|
94
115
|
return L.join('\n');
|
|
95
116
|
}
|
|
96
117
|
|
|
97
|
-
/** 텔레그램
|
|
98
|
-
export function renderDigestTelegram(d: IntakeDigest,
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
118
|
+
/** 텔레그램 — 흡수 렌즈가 대조한 항목만 SCQA 짧은 판으로 낸다. */
|
|
119
|
+
export function renderDigestTelegram(d: IntakeDigest, _opts: { vaultRoot?: string; notePath?: string } = {}): string {
|
|
120
|
+
const touching = d.absorbed.filter((e) => e.impact);
|
|
121
|
+
const L = [`흡수 ${d.absorbed.length} → 우리에게 닿는 것 ${touching.length}`];
|
|
122
|
+
if (!touching.length) return L[0];
|
|
123
|
+
for (const e of touching.slice(0, 3)) {
|
|
124
|
+
L.push('',
|
|
125
|
+
`S 무엇: ${e.impact!.fact}`,
|
|
126
|
+
`C 우리에게 왜: ${e.impact!.current}`,
|
|
127
|
+
`A 그래서 무엇을 하나: ${e.impact!.action}`,
|
|
128
|
+
`🔗 원문 링크: ${e.url?.trim() || '링크 없음'}`,
|
|
129
|
+
);
|
|
109
130
|
}
|
|
131
|
+
if (d.absorbed.length > touching.length) L.push('', `그 밖 ${d.absorbed.length - touching.length}건 · 닿지 않음`);
|
|
110
132
|
return L.join('\n');
|
|
111
133
|
}
|
|
@@ -18,6 +18,12 @@ export interface FrontClassifierDecision extends IntakeFrontRouteDecision {
|
|
|
18
18
|
urlRoute: UrlRouteDecision | null;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
/** Only Telegram links explicitly routed to saved/absorbed work enter the event lane. */
|
|
22
|
+
export function telegramAbsorbUrls(input: FrontClassifierInput, decision: FrontClassifierDecision): string[] {
|
|
23
|
+
if (input.surface !== 'telegram' || decision.track !== 'absorb' || !decision.urlRoute) return [];
|
|
24
|
+
return decision.urlRoute.urls;
|
|
25
|
+
}
|
|
26
|
+
|
|
21
27
|
const QUESTION_WORD_RE = new RegExp(
|
|
22
28
|
`(?:${INTAKE_FRONT_QUESTION_WORDS.map((word) => /^[a-z]+$/i.test(word) ? `(?<![\\p{L}\\p{N}_])${word}(?![\\p{L}\\p{N}_])` : word).join('|')})[.!?。?!]*$`,
|
|
23
29
|
'iu',
|
|
@@ -5,6 +5,7 @@ import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { debug } from '../debug/log.js';
|
|
7
7
|
import { findTrack } from '../autopilot/mission-phase-track.js';
|
|
8
|
+
import { wasIntakeEventScheduled } from './route.js';
|
|
8
9
|
|
|
9
10
|
export const INTAKE_SOURCES = ['x', 'youtube', 'github', 'telegram-saved', 'telegram-bot', 'memo', 'pwa'] as const;
|
|
10
11
|
export type RegisteredIntakeSourceKind = 'rss' | 'command';
|
|
@@ -243,13 +244,13 @@ export function parseRawIntakeJsonl(text: string): { raws: RawIntakeItem[]; bad:
|
|
|
243
244
|
*/
|
|
244
245
|
const STALE_QUEUED_MS = 24 * 3600_000;
|
|
245
246
|
|
|
246
|
-
export function pickAbsorbQueue(instanceRoot: string, opts: { max: number; laneMax?: number; kind?: IntakeKind; dryRun?: boolean }, now = new Date().toISOString()): IntakeItem[] {
|
|
247
|
+
export function pickAbsorbQueue(instanceRoot: string, opts: { max: number; laneMax?: number; kind?: IntakeKind; dryRun?: boolean }, now = new Date().toISOString(), taskStatus?: Parameters<typeof wasIntakeEventScheduled>[3]): IntakeItem[] {
|
|
247
248
|
const userLeft = (i: IntakeItem) => i.sources.some((s) => s === 'telegram-saved' || s === 'memo');
|
|
248
249
|
const score = (i: IntakeItem) => Math.max(0, ...Object.entries(i.signals).filter(([k]) => k.endsWith('.score')).map(([, v]) => v));
|
|
249
250
|
const eligible = [...loadIntakeLedger(instanceRoot).items.values()]
|
|
250
251
|
// queued 로 옮긴 뒤 흡수·표시가 없이 하루가 지난 것(흡수 도중 죽은 판)은 다시 고른다.
|
|
251
252
|
.filter((i) => (i.status === 'new' || (i.status === 'queued' && Date.parse(now) - Date.parse(i.lastSeenAt) > STALE_QUEUED_MS))
|
|
252
|
-
&& !!i.url && (!opts.kind || i.kind === opts.kind))
|
|
253
|
+
&& !!i.url && !wasIntakeEventScheduled(instanceRoot, i.url, now, taskStatus) && (!opts.kind || i.kind === opts.kind))
|
|
253
254
|
.sort((a, b) => Number(userLeft(b)) - Number(userLeft(a)) || b.sources.length - a.sources.length || score(b) - score(a) || b.lastSeenAt.localeCompare(a.lastSeenAt));
|
|
254
255
|
const laneMax = opts.laneMax ?? 30;
|
|
255
256
|
const lane = eligible.filter((i) => i.sources.includes('telegram-saved')).slice(0, Math.max(0, laneMax));
|