elanous 0.2.13 → 0.2.14
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/chunks/{7334.a6679d9168f37aa8.js → 1268.0840ff91e083fcbd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1307-6e7e0377c1db0bdc.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/4562-071d8bac44a01069.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-2df489622a52a33a.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/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-74383f890f075511.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-7b2b4f378354869a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-c496bb16da85385f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-f14987d5850a31e0.js → page-1abfe3aec3be6bdc.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-1512d91c7491ed62.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-a627db94ec6904a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-fb260b9283dbf646.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-e6b84ab07d3567d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-61ec1d2e92bdd50a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-fed69f9759d248d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-15374909d8f1aebd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-012a742f81218b01.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-fd7e200d4d83fbd7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-99effd9d893a43dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-938de57ae0315e46.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-d47266766766d227.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-160089123a40dd91.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-629e1ede482ec6eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/{page-66c27608f651b866.js → page-2ce5471926761fdd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-27e99b4e54a849d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-e995d30f6800b6bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-39f89c53038a51d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-32cde713be47cddb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-e7e10cd3386222e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-5a753bb4ec0cc511.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-04250f0e2c0d03df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-341480ed8e3c1ea8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-e64caff084f7ce21.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-db07eaffba0df7e3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-8ac8d71c2adf9c8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-78b40a344ed22f24.js → page-e1e47d8d940aba3d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-86f91034bd5cabe5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-94dc383d3d54db1a.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-b3759cc14da80908.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-ce4d8a1215ce53a3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-58043db78ba519ae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-357750dfb91bf960.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-63d14a4d8fe1e1c1.js → page-274703bc41b71333.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-194dce4a83143fce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-35bdeae2e2c17147.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-3b7e821dc492bdfd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-16bef3da05a900c3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-f8da5dc6f3752276.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-2f810b18d89ecba6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-134c1bc762aee62c.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/2e33713c444d5b39.css +1 -0
- package/apps/pwa/out/_next/static/x6mjI6vqOkVVu0jFuDkz1/_buildManifest.js +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/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/orchestrator/orchestrator.yaml +59 -0
- package/graphs/orchestrator/recipes.yaml +18 -0
- package/graphs/release/recipes.yaml +3 -0
- package/graphs/release/release-loop.yaml +4 -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 +186 -0
- package/scripts/coord-post.sh +11 -1
- package/scripts/docs-cli-check.ts +23 -6
- package/scripts/expose-rubric-check.ts +118 -0
- package/scripts/expose-rubric-suggest.ts +163 -0
- package/scripts/heal/run-role.ts +14 -0
- package/scripts/hq/standby-verify.ts +11 -7
- package/scripts/lessons/handbook-page.ts +85 -0
- package/scripts/release-loop/gate-node.ts +9 -0
- 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 +196 -0
- package/scripts/release-story/draft.ts +172 -0
- package/scripts/rhythm/daily.ts +383 -0
- package/scripts/rhythm/weekly.ts +294 -0
- package/scripts/skills/public-check.ts +169 -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-mission/driver.ts +3 -3
- package/src/autopilot/build/llm-conflict-merge.ts +45 -8
- package/src/autopilot/build/merge-intent.ts +53 -0
- package/src/chat/index.ts +2 -0
- package/src/claims/claims-ledger.ts +232 -0
- package/src/claims/claims-render.ts +157 -0
- package/src/cli/claims-cli.ts +94 -0
- package/src/cli/decisions-cli.ts +35 -3
- package/src/cli/docs-cli.ts +2 -0
- package/src/cli/flow-cli.ts +11 -0
- package/src/cli/freeze-cli.ts +45 -0
- 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/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 +144 -21
- package/src/cli/rfc-status.ts +91 -0
- package/src/connectors/linear.ts +5 -3
- package/src/context-bus/condense.ts +15 -20
- package/src/context-bus/context-now-public.ts +86 -0
- package/src/context-bus/context-now-surfaces.ts +55 -2
- package/src/context-bus/context-now.ts +4 -3
- 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-ledger.ts +40 -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/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 +152 -27
- package/src/harness/harness-incidents.ts +43 -12
- package/src/harness/harness-pod-dispatch.ts +2 -0
- package/src/harness/harness-queue-child.ts +3 -3
- package/src/harness/harness-queue.ts +216 -28
- package/src/harness/helper-scan.ts +139 -0
- package/src/harness/model-input-observation.ts +37 -0
- package/src/hq/hq.ts +1 -1
- package/src/hq/promote.ts +301 -0
- package/src/index.ts +83 -21
- package/src/intake-plane/linear-wish.ts +39 -11
- 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/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 +32 -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 +164 -0
- package/src/loops/orchestrator/author-input-check.ts +77 -0
- package/src/loops/orchestrator/author-ledger.ts +230 -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/tick.ts +302 -0
- package/src/loops/orchestrator/traffic.ts +18 -3
- package/src/loops/registry.ts +454 -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 +7 -4
- package/src/nexus/api/dashboard.ts +6 -1
- package/src/nexus/api/http-server.ts +18 -2
- package/src/nexus/api/merge-approvals-gate.ts +1 -1
- package/src/nexus/api/schedules-read.ts +5 -1
- package/src/nexus/api/task-cards-api.ts +44 -5
- package/src/nexus/api/workflows.ts +2 -1
- package/src/release-loop/auto-start.ts +48 -0
- package/src/release-loop/checklist.ts +13 -4
- package/src/release-loop/feature-store.ts +28 -16
- package/src/release-loop/landing-freeze.ts +121 -0
- package/src/release-loop/placement.ts +242 -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-loop/seat-loop.ts +406 -31
- package/src/self-dev/dev-pipeline.ts +6 -2
- package/src/self-dev/draft-sweep.ts +76 -0
- package/src/self-dev/run-store.ts +73 -1
- package/src/self-dev/run-supervisor.ts +8 -0
- 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 +294 -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-lookup.ts +147 -0
- package/src/self-implement/heal-intake.ts +79 -0
- package/src/self-implement/host-regate.ts +25 -2
- package/src/self-implement/orchestrator.ts +114 -10
- package/src/self-implement/revert-guard.ts +62 -0
- package/src/self-implement/run-ledger.ts +1 -1
- package/src/self-implement/seams.ts +28 -8
- package/src/session/index.ts +2 -0
- package/src/task-cards/card-cli.ts +10 -2
- package/src/task-cards/card-store.ts +10 -6
- 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/self-implement-pod.ts +80 -16
- package/src/telegram-commands.ts +27 -3
- package/src/telegram-loops-command.ts +44 -0
- package/src/user-config.ts +120 -16
- package/src/version/packed-revision.json +1 -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/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/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/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 → x6mjI6vqOkVVu0jFuDkz1}/_ssgManifest.js +0 -0
|
@@ -38,7 +38,7 @@ import { lookupEntrance, type EntranceId } from './entrance-registry.js';
|
|
|
38
38
|
import type { IngestionEntry } from '../agent-substrate/execution/ingestion-policy.js';
|
|
39
39
|
import type { ReviewerContextItem } from '../agent-substrate/pr-reviewer.js';
|
|
40
40
|
import { resolveRunIdentity, type RunIdSource } from '../harness/harness-space.js';
|
|
41
|
-
import { addSelfDevRunParticipant, saveSelfDevRun } from './run-store.js';
|
|
41
|
+
import { addSelfDevRunParticipant, processBirthId, saveSelfDevRun } from './run-store.js';
|
|
42
42
|
import { getUserConfig, resolveRoleLlm } from '../user-config.js';
|
|
43
43
|
import { reviewReasoningEffort } from '../model-tier/review-effort.js';
|
|
44
44
|
import { getProvider, inferProviderFromModel } from '../llm.js';
|
|
@@ -1718,7 +1718,11 @@ export async function runDevPipeline(spec: DevPipelineSpec, deps: DevPipelineDep
|
|
|
1718
1718
|
if (spec.runId) {
|
|
1719
1719
|
const runIdSource = spec.runIdSource ?? resolveRunIdentity({ explicit: spec.runId }).source;
|
|
1720
1720
|
const now = Date.now();
|
|
1721
|
-
|
|
1721
|
+
const seat = process.env.ELANOUS_HARNESS_SEAT;
|
|
1722
|
+
const pidStart = processBirthId(process.pid);
|
|
1723
|
+
saveSelfDevRun({ runId: spec.runId, createdAt: now, updatedAt: now, results: [], pid: process.pid,
|
|
1724
|
+
...(pidStart ? { pidStart } : {}),
|
|
1725
|
+
...(seat === 'OP' || seat === 'TC' || seat === 'MK' || seat === 'UX' ? { seat } : {}) });
|
|
1722
1726
|
addSelfDevRunParticipant(spec.runId, {
|
|
1723
1727
|
id: `process:${process.pid}`,
|
|
1724
1728
|
kind: 'process',
|
|
@@ -31,6 +31,8 @@ export interface DraftSweepAdapters {
|
|
|
31
31
|
hasFinalRunResult?(draft: SweepDraft, repository: string): Promise<boolean | undefined>;
|
|
32
32
|
/** Per-file last change on the draft branch; undefined means file coverage is unverified. */
|
|
33
33
|
getLatestFileChanges?(draft: SweepDraft, repository: string): Promise<Readonly<Record<string, string>> | undefined>;
|
|
34
|
+
/** Optional merge-time file inventory for the existing all-files-landed decision. */
|
|
35
|
+
getPrFiles?(repository: string, number: number): Promise<readonly string[] | undefined>;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
export interface DraftSweepOptions {
|
|
@@ -84,6 +86,80 @@ const PAGE_SIZE = 100;
|
|
|
84
86
|
/** At most this many closes per tick, so a wrong rule cannot close everything at once. */
|
|
85
87
|
export const DRAFT_SWEEP_CLOSE_CAP = 10;
|
|
86
88
|
|
|
89
|
+
/** Post-merge shortcut: only the existing superseded-by decision can authorize a close. */
|
|
90
|
+
export async function supersedeDraftsOnMerge(input: {
|
|
91
|
+
repository: string;
|
|
92
|
+
merged: SweepMergedPr & { createdAt: string; mergedAt: string };
|
|
93
|
+
adapters: Pick<DraftSweepAdapters, 'listDrafts' | 'listLiveBranches' | 'getRunStatus' | 'setLabels' | 'closeDraft'>
|
|
94
|
+
& Pick<Partial<DraftSweepAdapters>, 'getLatestFileChanges' | 'getPrFiles'>;
|
|
95
|
+
}): Promise<{ closed: number[]; kept: number[] }> {
|
|
96
|
+
const { repository, merged, adapters } = input;
|
|
97
|
+
const closed: number[] = [];
|
|
98
|
+
const kept: number[] = [];
|
|
99
|
+
let drafts: SweepDraft[] = [];
|
|
100
|
+
let error: string | undefined;
|
|
101
|
+
const failed: number[] = [];
|
|
102
|
+
let closeAttempts = 0;
|
|
103
|
+
try {
|
|
104
|
+
const [listedDrafts, liveBranches] = await Promise.all([
|
|
105
|
+
collectPages((page, size) => adapters.listDrafts(page, size, repository)),
|
|
106
|
+
adapters.listLiveBranches(repository),
|
|
107
|
+
]);
|
|
108
|
+
drafts = listedDrafts;
|
|
109
|
+
if (!liveBranches || !Number.isInteger(merged.number) || !merged.branch || !merged.title
|
|
110
|
+
|| !Number.isFinite(Date.parse(merged.createdAt)) || !Number.isFinite(Date.parse(merged.mergedAt))
|
|
111
|
+
|| drafts.some((pr) => !Number.isInteger(pr.number) || !pr.branch || !Array.isArray(pr.labels)
|
|
112
|
+
|| !Number.isFinite(Date.parse(pr.createdAt)))) throw new Error('Incomplete merge draft inventory');
|
|
113
|
+
const statuses = new Map<number, string | undefined>();
|
|
114
|
+
const latestChanges = new Map<number, Readonly<Record<string, string>> | undefined>();
|
|
115
|
+
const mergedFiles = await adapters.getPrFiles?.(repository, merged.number);
|
|
116
|
+
const landed = { ...merged, changedFiles: mergedFiles };
|
|
117
|
+
for (const draft of drafts) {
|
|
118
|
+
if (draft.number !== merged.number && !liveBranches.has(draft.branch)
|
|
119
|
+
&& Date.parse(draft.createdAt) < Date.parse(merged.mergedAt)) {
|
|
120
|
+
statuses.set(draft.number, await adapters.getRunStatus(draft, repository));
|
|
121
|
+
if (draft.changedFiles?.length && adapters.getLatestFileChanges) {
|
|
122
|
+
latestChanges.set(draft.number, await adapters.getLatestFileChanges(draft, repository));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
for (const listedDraft of drafts) {
|
|
127
|
+
const draft = { ...listedDraft, latestFileChanges: latestChanges.get(listedDraft.number) };
|
|
128
|
+
if (draft.number === merged.number || liveBranches.has(draft.branch)
|
|
129
|
+
|| Date.parse(draft.createdAt) >= Date.parse(merged.mergedAt)) {
|
|
130
|
+
kept.push(draft.number);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const decision = decideDraft({ draft, runStatus: statuses.get(draft.number),
|
|
134
|
+
mergedTwins: [landed], liveBranches, ageHours: NaN });
|
|
135
|
+
if (decision.action !== 'close' || !decision.reason.startsWith(`superseded-by #${merged.number}`)
|
|
136
|
+
|| PR_LABELS.filter((entry) => entry.axis === 'state' && draft.labels.includes(entry.name)).length > 1
|
|
137
|
+
|| (draft.labels.length === 0 && !draft.branch.startsWith('self-impl/'))
|
|
138
|
+
|| closeAttempts >= DRAFT_SWEEP_CLOSE_CAP) {
|
|
139
|
+
kept.push(draft.number);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
closeAttempts += 1;
|
|
143
|
+
const remove = stateLabels.filter((entry) => draft.labels.includes(entry.name) && entry.name !== supersededLabel).map((entry) => entry.name);
|
|
144
|
+
try {
|
|
145
|
+
// Label first: a failed label write must never strand a closed, unlabelled PR outside open-draft sweeps.
|
|
146
|
+
if (!draft.labels.includes(supersededLabel)) await adapters.setLabels(repository, draft.number, { add: supersededLabel, remove });
|
|
147
|
+
await adapters.closeDraft(repository, draft.number, `Draft sweep: superseded-by #${merged.number}. Branch preserved.`);
|
|
148
|
+
closed.push(draft.number);
|
|
149
|
+
} catch (failure) {
|
|
150
|
+
kept.push(draft.number);
|
|
151
|
+
failed.push(draft.number);
|
|
152
|
+
error = String(failure);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
} catch (failure) {
|
|
156
|
+
error = String(failure);
|
|
157
|
+
kept.push(...drafts.map((draft) => draft.number).filter((number) => !closed.includes(number) && !kept.includes(number)));
|
|
158
|
+
}
|
|
159
|
+
debug.log('drafts.cleanup', 'superseded-on-merge', { merged: merged.number, closed, kept, ...(failed.length ? { failed } : {}), ...(error ? { error } : {}) });
|
|
160
|
+
return { closed, kept };
|
|
161
|
+
}
|
|
162
|
+
|
|
87
163
|
async function collectPages<T>(fetch: (page: number, perPage: number) => Promise<readonly T[]>): Promise<T[]> {
|
|
88
164
|
const rows: T[] = [];
|
|
89
165
|
for (let page = 1; page <= 100; page++) {
|
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
* Cf. PLAN-parallel-self-dev-orchestrator-2026-07-21 §5 (S3).
|
|
17
17
|
*/
|
|
18
18
|
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
19
|
+
import { dlopen, FFIType } from 'bun:ffi';
|
|
19
20
|
import { randomUUID } from 'node:crypto';
|
|
20
|
-
import { debug } from '../debug/log.js';
|
|
21
|
+
import { debug, redactSecretText } from '../debug/log.js';
|
|
21
22
|
import { elanousStateRoot } from '../autopilot/state-paths.js';
|
|
22
23
|
import { loadRunLedger, queryInterruptedRunLedgers, runLedgerDir, type RunLedgerEntry } from '../self-implement/run-ledger.js';
|
|
23
24
|
import { join, resolve, sep } from 'node:path';
|
|
@@ -68,6 +69,8 @@ export interface SelfDevRunState {
|
|
|
68
69
|
createdAt: number;
|
|
69
70
|
updatedAt: number;
|
|
70
71
|
results: SelfDevJobResult[];
|
|
72
|
+
/** Redacted, bounded one-line projection for loop readers; legacy checkpoints omit it. */
|
|
73
|
+
summaryLine?: string;
|
|
71
74
|
/** Undefined means a legacy checkpoint has no dependency information; each key is a shard ID and its array lists predecessor shard IDs. */
|
|
72
75
|
dependencies?: Record<string, string[]>;
|
|
73
76
|
/**
|
|
@@ -93,6 +96,10 @@ export interface SelfDevRunState {
|
|
|
93
96
|
* non-terminal goal 은 **실행중(running)** 이지 막힌(interrupted) 게 아니다. 죽었으면(오케스트레이터
|
|
94
97
|
* killed) 진짜 interrupted. isPidAlive 로 구분해 라이브 잡을 parked/repair-signals 에서 제외. */
|
|
95
98
|
pid?: number;
|
|
99
|
+
/** OS process birth identity, paired with pid to reject a recycled pid. */
|
|
100
|
+
pidStart?: string;
|
|
101
|
+
/** Seat fixed at launch; survives removal of the launch worktree. */
|
|
102
|
+
seat?: 'OP' | 'TC' | 'MK' | 'UX';
|
|
96
103
|
}
|
|
97
104
|
|
|
98
105
|
/** `<ELANOUS_STATE_DIR or ~/.elanous>/self-dev-runs`. */
|
|
@@ -103,6 +110,34 @@ export function selfDevRunsDir(stateDir?: string): string {
|
|
|
103
110
|
|
|
104
111
|
const RUN_ID = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
|
|
105
112
|
|
|
113
|
+
/** Kernel process birth identity: Linux boot ID + start ticks or Darwin microseconds since epoch. */
|
|
114
|
+
export function processBirthId(pid: number, platform: NodeJS.Platform = process.platform): string | undefined {
|
|
115
|
+
if (!Number.isSafeInteger(pid) || pid < 1) return undefined;
|
|
116
|
+
try {
|
|
117
|
+
if (platform === 'linux') {
|
|
118
|
+
const stat = readFileSync(`/proc/${pid}/stat`, 'utf8');
|
|
119
|
+
const tail = stat.slice(stat.lastIndexOf(')') + 2).trim().split(/\s+/);
|
|
120
|
+
const ticks = tail[19]; // field 22 (starttime), after pid and parenthesized comm
|
|
121
|
+
const bootId = readFileSync('/proc/sys/kernel/random/boot_id', 'utf8').trim();
|
|
122
|
+
return ticks && /^\d+$/.test(ticks) && /^[0-9a-f-]{36}$/i.test(bootId)
|
|
123
|
+
? `linux:${bootId}:${ticks}` : undefined;
|
|
124
|
+
}
|
|
125
|
+
if (platform === 'darwin') {
|
|
126
|
+
const libproc = dlopen('/usr/lib/libproc.dylib', {
|
|
127
|
+
proc_pidinfo: { args: [FFIType.i32, FFIType.i32, FFIType.u64, FFIType.ptr, FFIType.i32], returns: FFIType.i32 },
|
|
128
|
+
});
|
|
129
|
+
try {
|
|
130
|
+
const buf = new Uint8Array(136);
|
|
131
|
+
if (libproc.symbols.proc_pidinfo(pid, 3, 0n, buf, buf.length) !== buf.length) return undefined;
|
|
132
|
+
const view = new DataView(buf.buffer);
|
|
133
|
+
if (view.getUint32(12, true) !== pid) return undefined;
|
|
134
|
+
return `darwin:${view.getBigUint64(120, true) * 1_000_000n + view.getBigUint64(128, true)}`;
|
|
135
|
+
} finally { libproc.close(); }
|
|
136
|
+
}
|
|
137
|
+
} catch { /* Unreadable birth identity is not evidence of a match. */ }
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
|
|
106
141
|
function runPath(runId: string, dir: string): string {
|
|
107
142
|
if (!RUN_ID.test(runId)) throw new Error(`invalid self-dev run ID: ${runId}`);
|
|
108
143
|
const root = resolve(dir);
|
|
@@ -154,6 +189,40 @@ function mergeParticipants(
|
|
|
154
189
|
return [...byId.values()];
|
|
155
190
|
}
|
|
156
191
|
|
|
192
|
+
const SUMMARY_LINE_LIMIT = 120;
|
|
193
|
+
const FINISHED_RESULT_STATUSES = new Set(['done', 'failed', 'cancelled', 'superseded']);
|
|
194
|
+
|
|
195
|
+
function boundedSummaryLine(text: string): string {
|
|
196
|
+
const redacted = redactSecretText(text.replace(/\s+/g, ' ').trim());
|
|
197
|
+
if (redacted.length <= SUMMARY_LINE_LIMIT) return redacted;
|
|
198
|
+
const head = redacted.slice(0, SUMMARY_LINE_LIMIT - 1).replace(/[\uD800-\uDBFF]$/, '');
|
|
199
|
+
return `${head}…`;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Read-only projection for loop readers; missing legacy fields are derived in memory. */
|
|
203
|
+
export function runSummaryLine(state: SelfDevRunState): string {
|
|
204
|
+
if (state.summaryLine !== undefined) return boundedSummaryLine(state.summaryLine);
|
|
205
|
+
const feature = state.goals?.[0]?.feature ?? state.results[0]?.feature ?? '';
|
|
206
|
+
const head = feature.split(/\r?\n/, 1)[0]?.trim() ?? '';
|
|
207
|
+
const header = /^「하니스로 구현」\s+(\S+?)\s+—\s*(.*)$/.exec(head);
|
|
208
|
+
const id = state.goals?.[0]?.goalId ?? header?.[1] ?? state.goals?.[0]?.id ?? state.runId;
|
|
209
|
+
const phrase = (header?.[2] ?? head).split(/[.!?。;;]/, 1)[0]?.trim() ?? '';
|
|
210
|
+
const finished = state.results.length > 0
|
|
211
|
+
&& state.results.every((result) => FINISHED_RESULT_STATUSES.has(result.status));
|
|
212
|
+
if (finished) {
|
|
213
|
+
// A completed shard cannot hide a failed one merely by settling later.
|
|
214
|
+
const result = state.results.find(({ status }) => status === 'failed')
|
|
215
|
+
?? state.results.find(({ status }) => status === 'cancelled')
|
|
216
|
+
?? state.results.find(({ status }) => status === 'superseded')
|
|
217
|
+
?? state.results.at(-1)!;
|
|
218
|
+
const stage = result.stage ?? result.status;
|
|
219
|
+
const prNumber = result.prNumber ?? Number(/\/pull\/(\d+)(?:[/?#]|$)/.exec(result.prUrl ?? '')?.[1]);
|
|
220
|
+
const pr = Number.isSafeInteger(prNumber) && prNumber > 0 ? ` · PR #${prNumber}` : '';
|
|
221
|
+
return boundedSummaryLine(`${id} · ${stage}${pr}`);
|
|
222
|
+
}
|
|
223
|
+
return boundedSummaryLine(`「하니스로 구현」 ${id}${phrase ? ` — ${phrase}` : ''}`);
|
|
224
|
+
}
|
|
225
|
+
|
|
157
226
|
/** Persist a run checkpoint (fail-soft — never throws into the caller). */
|
|
158
227
|
export function saveSelfDevRun(state: SelfDevRunState, dir = selfDevRunsDir()): void {
|
|
159
228
|
try {
|
|
@@ -163,7 +232,10 @@ export function saveSelfDevRun(state: SelfDevRunState, dir = selfDevRunsDir()):
|
|
|
163
232
|
const participants = mergeParticipants(current?.participants, state.participants);
|
|
164
233
|
const saved = {
|
|
165
234
|
...state,
|
|
235
|
+
summaryLine: runSummaryLine({ ...state, goals: state.goals ?? current?.goals, summaryLine: undefined }),
|
|
166
236
|
...(participants === undefined ? {} : { participants }),
|
|
237
|
+
...(current?.seat && !state.seat ? { seat: current.seat } : {}),
|
|
238
|
+
...(current?.pidStart && current.pid === state.pid && !state.pidStart ? { pidStart: current.pidStart } : {}),
|
|
167
239
|
...(current?.parkedResolution && !state.parkedResolution ? { parkedResolution: current.parkedResolution } : {}),
|
|
168
240
|
};
|
|
169
241
|
writeSelfDevRun(saved, dir);
|
|
@@ -5,6 +5,7 @@ import type { DeployVerifyFinding } from '../harness/browser-verify.js';
|
|
|
5
5
|
import type { SelfDevJobResult } from './orchestrate.js';
|
|
6
6
|
import { recordSelfDevRunSupervisorStop, selfDevRunsDir } from './run-store.js';
|
|
7
7
|
import { debug } from '../debug/log.js';
|
|
8
|
+
import { sweepFrozenMerges } from '../self-implement/frozen-merges.js';
|
|
8
9
|
|
|
9
10
|
export interface SupervisorRound {
|
|
10
11
|
round: number;
|
|
@@ -410,6 +411,7 @@ export interface SuperviseRunOptions {
|
|
|
410
411
|
onRound?: (results: readonly SupervisorJobResult[]) => void;
|
|
411
412
|
runStore?: { runId?: string; operatorDir?: string; dir?: string; isolatedDir?: string };
|
|
412
413
|
observe?: (event: string, data: Record<string, unknown>) => void;
|
|
414
|
+
sweepPendingMerges?: typeof sweepFrozenMerges;
|
|
413
415
|
observeDeliverables?: () => Promise<{
|
|
414
416
|
readonly deployFindings: ReadonlyMap<string, { target: string; findings?: readonly DeployVerifyFinding[] | readonly unknown[] }>;
|
|
415
417
|
readonly unmeasured: readonly unknown[];
|
|
@@ -432,6 +434,12 @@ export async function superviseRun(opts: SuperviseRunOptions): Promise<Superviso
|
|
|
432
434
|
let history: SupervisorRound[] = [];
|
|
433
435
|
|
|
434
436
|
for (;;) {
|
|
437
|
+
try {
|
|
438
|
+
const resumed = await (opts.sweepPendingMerges ?? sweepFrozenMerges)();
|
|
439
|
+
if (resumed.pending || resumed.merged) opts.observe?.('frozen-merges', resumed);
|
|
440
|
+
} catch (error) {
|
|
441
|
+
try { debug.log('harness.merge', 'resume-failed', { error: String(error) }); } catch { /* observation must not interrupt supervision */ }
|
|
442
|
+
}
|
|
435
443
|
if (opts.enrich) results = [...opts.enrich(results)];
|
|
436
444
|
|
|
437
445
|
let observed: {
|
|
@@ -13,7 +13,7 @@ import { posix as posixPath } from 'node:path';
|
|
|
13
13
|
import type { LLMToolSpec } from '../llm.js';
|
|
14
14
|
import type { ToolRuntime, ToolRuntimeContext } from '../tool-runtime/types.js';
|
|
15
15
|
import { orchestrateSelfDev, type SelfDevJobResult, type OrchestrateSelfDevOptions, type SelfDevGoal } from './orchestrate.js';
|
|
16
|
-
import type
|
|
16
|
+
import { processBirthId, type SelfDevRunParticipant, type SelfDevRunState } from './run-store.js';
|
|
17
17
|
import { HARNESS_RUN_ID_ENV, resolveRunIdentity as defaultResolveRunIdentity } from '../harness/harness-space.js';
|
|
18
18
|
import { decomposeSelfDevGoal, type SelfDevDecomposition, type SelfDevDecomposeOptions } from './decompose.js';
|
|
19
19
|
import { decomposeFabricRequest, type FabricDecomposeRequestOptions, type FabricDecomposeRequestResult } from './fabric-decompose-adapter.js';
|
|
@@ -302,6 +302,7 @@ interface OrchestrateRunLedgerInput {
|
|
|
302
302
|
readonly prior: Pick<SelfDevRunState, 'dependencies' | 'results'> | null;
|
|
303
303
|
readonly goals: readonly SelfDevGoal[];
|
|
304
304
|
readonly pid: number;
|
|
305
|
+
readonly seat?: SelfDevRunState['seat'];
|
|
305
306
|
readonly runIdSource: SelfDevRunParticipant['runIdSource'];
|
|
306
307
|
readonly now: () => number;
|
|
307
308
|
readonly onPersistenceFailure?: (stage: 'checkpoint' | 'participant', error: unknown) => void;
|
|
@@ -421,6 +422,7 @@ export function bindOrchestrateRunLedger(
|
|
|
421
422
|
input: OrchestrateRunLedgerInput,
|
|
422
423
|
): OrchestrateRunLedgerBinding {
|
|
423
424
|
const dependencies = deps.checkpointDependencies(input.prior, input.goals);
|
|
425
|
+
const pidStart = processBirthId(input.pid);
|
|
424
426
|
const checkpoint = (results: SelfDevRunState['results']): void => {
|
|
425
427
|
try {
|
|
426
428
|
deps.saveRun({
|
|
@@ -431,6 +433,8 @@ export function bindOrchestrateRunLedger(
|
|
|
431
433
|
dependencies,
|
|
432
434
|
goals: [...input.goals],
|
|
433
435
|
pid: input.pid,
|
|
436
|
+
...(pidStart ? { pidStart } : {}),
|
|
437
|
+
...(input.seat ? { seat: input.seat } : {}),
|
|
434
438
|
});
|
|
435
439
|
} catch (error) {
|
|
436
440
|
if (input.onPersistenceFailure) input.onPersistenceFailure('checkpoint', error);
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
import type { RotationCandidate } from '../oauth/codex-account-rotation.js';
|
|
5
5
|
import { inspectCodexRotation } from '../oauth/codex-account-store.js';
|
|
6
|
+
import { codexPolicyAllowsCredits } from '../oauth/codex-quota-policy.js';
|
|
6
7
|
import { getUsageStore } from '../budget/usage-store.js';
|
|
7
8
|
import type { UsageSnapshot } from '../budget/types.js';
|
|
9
|
+
import { debug } from '../debug/log.js';
|
|
8
10
|
import {
|
|
9
11
|
DEFAULT_BUDGET_GATE_MAX_USED_PERCENT,
|
|
10
12
|
type BudgetGateMaxUsedPercent,
|
|
@@ -25,6 +27,9 @@ export interface BudgetCodexCandidate {
|
|
|
25
27
|
readonly name: string;
|
|
26
28
|
readonly reached?: boolean;
|
|
27
29
|
readonly usedPercent?: number;
|
|
30
|
+
/** 선불 크레딧 잔액(계정에 귀속된 신호만). 모르면 비운다. */
|
|
31
|
+
readonly creditBalance?: number;
|
|
32
|
+
readonly hasCredits?: boolean;
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
export interface DecideBudgetInput {
|
|
@@ -36,6 +41,8 @@ export interface DecideBudgetInput {
|
|
|
36
41
|
/** 주간 사용률. `undefined` 는 «모름» — 쓸 수 있다고 보지 않는다. */
|
|
37
42
|
readonly grokUsedPercent: number | undefined;
|
|
38
43
|
readonly maxUsedPercent: BudgetGateMaxUsedPercent;
|
|
44
|
+
/** codex 한도 정책이 credits 인가(`codexPolicyAllowsCredits` · 회전·Pod 배분과 같은 해석). 없으면 false. */
|
|
45
|
+
readonly codexCreditsAllowed?: boolean;
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
export interface BudgetDecision {
|
|
@@ -50,6 +57,7 @@ export interface BudgetInputs {
|
|
|
50
57
|
readonly codexCandidates: readonly BudgetCodexCandidate[];
|
|
51
58
|
readonly grokUsedPercent: number | undefined;
|
|
52
59
|
readonly maxUsedPercent: BudgetGateMaxUsedPercent;
|
|
60
|
+
readonly codexCreditsAllowed?: boolean;
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
const WEEKLY_WINDOW_MINUTES = 7 * 24 * 60;
|
|
@@ -98,6 +106,16 @@ function codexCandidateUsable(candidate: BudgetCodexCandidate, cap: number | und
|
|
|
98
106
|
return candidate.usedPercent < cap;
|
|
99
107
|
}
|
|
100
108
|
|
|
109
|
+
/** BUDGET-GATE(10-05) — 정책이 credits 면 구독 % 가 차도 크레딧 잔액이 «확인된» 계정으로 계속 간다(Pod 배분과 같은 결론).
|
|
110
|
+
* 잔액을 모르면 쓰지 않는다 — 크레딧은 돈이라 fail-closed. 잔액이 가장 큰 계정 하나를 돌려준다. */
|
|
111
|
+
function codexCreditCandidate(input: DecideBudgetInput): BudgetCodexCandidate | undefined {
|
|
112
|
+
if (input.codexCreditsAllowed !== true) return undefined;
|
|
113
|
+
return input.codexCandidates
|
|
114
|
+
.filter((candidate) => candidate.hasCredits !== false
|
|
115
|
+
&& typeof candidate.creditBalance === 'number' && Number.isFinite(candidate.creditBalance) && candidate.creditBalance > 0)
|
|
116
|
+
.sort((a, b) => (b.creditBalance! - a.creditBalance!) || (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))[0];
|
|
117
|
+
}
|
|
118
|
+
|
|
101
119
|
function slotUsable(
|
|
102
120
|
provider: string,
|
|
103
121
|
input: DecideBudgetInput,
|
|
@@ -106,6 +124,13 @@ function slotUsable(
|
|
|
106
124
|
if (provider === CODEX_PROVIDER) {
|
|
107
125
|
const cap = capFor(input.maxUsedPercent, CODEX_PROVIDER);
|
|
108
126
|
const measuredUsable = input.codexCandidates.some((candidate) => codexCandidateUsable(candidate, cap));
|
|
127
|
+
const credit = measuredUsable ? undefined : codexCreditCandidate(input);
|
|
128
|
+
if (credit) {
|
|
129
|
+
try {
|
|
130
|
+
debug.log('budget.gate', 'credits-allowed', { used: credit.usedPercent ?? null, balance: credit.creditBalance, policy: 'credits' });
|
|
131
|
+
} catch { /* observation is fail-soft */ }
|
|
132
|
+
return { usable: true, reason: `${formatCodexReason(input.codexCandidates, cap)} · credits allowed (balance ${credit.creditBalance})` };
|
|
133
|
+
}
|
|
109
134
|
const unmeasured = allowUnmeasured && !measuredUsable && (input.codexCandidates.length === 0
|
|
110
135
|
|| input.codexCandidates.some((candidate) => candidate.reached !== true
|
|
111
136
|
&& (typeof candidate.usedPercent !== 'number' || !Number.isFinite(candidate.usedPercent))));
|
|
@@ -188,6 +213,8 @@ export function codexCandidatesFromRotation(
|
|
|
188
213
|
name: candidate.name,
|
|
189
214
|
...(candidate.reached !== undefined ? { reached: candidate.reached } : {}),
|
|
190
215
|
...(candidate.usedPercent !== undefined ? { usedPercent: candidate.usedPercent } : {}),
|
|
216
|
+
...(candidate.creditBalance !== undefined ? { creditBalance: candidate.creditBalance } : {}),
|
|
217
|
+
...(candidate.hasCredits !== undefined ? { hasCredits: candidate.hasCredits } : {}),
|
|
191
218
|
}));
|
|
192
219
|
}
|
|
193
220
|
|
|
@@ -212,6 +239,8 @@ export function readBudgetInputs(deps: ReadBudgetInputsDeps = {}): BudgetInputs
|
|
|
212
239
|
codexCandidates: codexCandidatesFromRotation(rotation.candidates),
|
|
213
240
|
grokUsedPercent: grokWeeklyUsedPercent(snapshot),
|
|
214
241
|
maxUsedPercent,
|
|
242
|
+
// 회전·Pod 배분과 같은 해석(`resolveCodexQuotaPolicy` → `codexPolicyAllowsCredits`)을 읽는다 — 다시 짓지 않는다.
|
|
243
|
+
...(rotation.policy && codexPolicyAllowsCredits(rotation.policy.policy) ? { codexCreditsAllowed: true } : {}),
|
|
215
244
|
};
|
|
216
245
|
}
|
|
217
246
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { debug } from '../debug/log.js';
|
|
3
|
+
|
|
4
|
+
type ExposeMode = 'warn' | 'strict';
|
|
5
|
+
type ProcessResult = { status: number | null; stdout?: string; stderr?: string; error?: Error };
|
|
6
|
+
type ExposeResult = { passed: boolean; log: string };
|
|
7
|
+
|
|
8
|
+
/** The rubric only accepts root-level public Markdown documents. */
|
|
9
|
+
export function publicExposureFiles(changed: readonly string[]): string[] {
|
|
10
|
+
return [...new Set(changed.filter((file) => /^release\/public\/docs\/[^/]+\.md$/.test(file)))];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function runExposeGate(
|
|
14
|
+
cwd: string,
|
|
15
|
+
changed: readonly string[],
|
|
16
|
+
mode: ExposeMode,
|
|
17
|
+
run: (command: string, args: string[], cwd: string) => ProcessResult = (command, args, dir) => {
|
|
18
|
+
const result = spawnSync(command, args, { cwd: dir, encoding: 'utf8', timeout: 300_000 });
|
|
19
|
+
return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '', error: result.error };
|
|
20
|
+
},
|
|
21
|
+
): ExposeResult {
|
|
22
|
+
const files = publicExposureFiles(changed);
|
|
23
|
+
if (files.length === 0) return { passed: true, log: '' };
|
|
24
|
+
let unreviewed: number | null = null;
|
|
25
|
+
let failed: number | null = null;
|
|
26
|
+
let docs: number | null = null;
|
|
27
|
+
let error = '';
|
|
28
|
+
try {
|
|
29
|
+
const result = run('bun', ['scripts/expose-rubric-check.ts', '--json', '--files', ...files], cwd);
|
|
30
|
+
if (result.status !== 0 || result.error) throw new Error(result.stderr?.trim() || result.error?.message || `exit ${result.status}`);
|
|
31
|
+
const parsed = JSON.parse(result.stdout ?? '') as Record<string, unknown>;
|
|
32
|
+
const lists = ['missing', 'orphan', 'failing', 'internal', 'unreviewed', 'unjudged'] as const;
|
|
33
|
+
if (!Number.isSafeInteger(parsed.docs) || (parsed.docs as number) < 0 || !lists.every((key) => Array.isArray(parsed[key]))) {
|
|
34
|
+
throw new Error('invalid exposure rubric JSON');
|
|
35
|
+
}
|
|
36
|
+
docs = parsed.docs as number;
|
|
37
|
+
unreviewed = new Set([...(parsed.missing as string[]), ...(parsed.unjudged as string[])]).size;
|
|
38
|
+
failed = new Set([...(parsed.orphan as string[]), ...(parsed.failing as Array<{ path: string }>).map((item) => item.path), ...(parsed.internal as string[])]).size;
|
|
39
|
+
} catch (cause) {
|
|
40
|
+
error = cause instanceof Error ? cause.message : String(cause);
|
|
41
|
+
}
|
|
42
|
+
try { debug.log('self-implement.gate', 'expose', { files, unreviewed, failed, mode }); } catch { /* observation must not change judgment */ }
|
|
43
|
+
const log = docs === null
|
|
44
|
+
? `[expose] 못 쟀다 — ${error}`
|
|
45
|
+
: `[expose] ${files.length}개 · 미판정 ${unreviewed} · fail ${failed}`;
|
|
46
|
+
return { passed: mode === 'warn' || (docs !== null && unreviewed === 0 && failed === 0), log };
|
|
47
|
+
}
|