elanous 0.2.19 → 0.2.20
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/{J5H7BvqgSI8DUjtRRcA_S → Bam1YziK2iH9bN4K0utGk}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{4323.c5dfb6f503304775.js → 1268.0840ff91e083fcbd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1307-77fad80cf54477c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1612-f60c0c93ec773f81.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1844-9ec4b1d12f6e80eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1866-e7a6999f25548b30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1948.15f356b15a625597.js +5 -0
- package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2977-e38442e86289f1d3.js → 211-9c9090c59e2c5907.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2116-6429c188eb846ab8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +1 -0
- package/apps/pwa/out/_next/static/chunks/224-e7be8f762fe74986.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2489-ff55a35b202c0f94.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2549-89c518a4c8ed4d00.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.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/3857-995ea9f5ef33d71e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5360-be1f1d8f9fcc9755.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5755-ea7ed88eb956f47b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5977-94ed6f78e9814b2b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4847.56f5bc454fbcc827.js → 6110.1297d4093fdfbb0d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6158.af2e93b7adff709b.js +2 -0
- package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1470.98a6ab61ccb4131c.js → 726.83532d69452ee24b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6062-73e68343a9814f6a.js → 7327-2d69fb321ba73389.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{8870-9614a213b990b10b.js → 7748-6e51bfe927019f5c.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.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/8401-35e94e9091f5eb8d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9070.067c106528ec1ae6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9247-c1753a059e7bac08.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7647.2fcd30d894d5ee30.js → 935.4ddaa99fc1d1126c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{ae787e4c-e5b1ef00b2dbceca.js → a9f2b54d-33c0689b70ed8cf3.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-c855c24de7db74fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-85b316bb4235980b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-9b2b26a33cb2cd42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-c9955fde67b1bcb5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-7a852956c74015a3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c5a5c621be0e04ae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-4ba4abe096b6c2a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-575d4a8b4f7becb2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-f5d56ff5f45ad164.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-2260e9eef0357421.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-7c058069c5e7fa63.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-dc5da0b8a2edb8a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-466bf0ee16ad1432.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-a23bc71713bcc08f.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-5b29d9b06ceadade.js → page-ed4a6f799f005d09.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-9cd565005b93aca6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-55f0f40c6db95f15.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-474cb5888ea0e8f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-35bfec2e631d3eae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-9ca21f9ad3208a61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-f9ccb1b1adbea14d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-ec102c9b8b691e37.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-a9c2cfa8dda922a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-6da35144878feb6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-f6055495e9ed7ea8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-25204694fa9984a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-a60e035f151d84d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-189c587f36874538.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-c56634bde705a65d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-db03ae3589a81c9e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-4a6463b97f0ad94f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-75bffecc9aa1004e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a8d2fe0c669e0de4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-31d5b875760bb62d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c26fa10aac6c21c4.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-68793c6e10331d66.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-46d5201d2207a511.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-d81c07a7b4f618ae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-be1c4e8697f22360.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-cf0a4b4abead71ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-a4717e2c4bf7a28f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-0fd895fab9b62c1b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-8b6c1454a8e8f306.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c6e4364d9de8f717.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0acc8e198f7b0dfb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-34882c84f84021c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-0506a1e0e4bdb2f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8046cadf-211ca3c0e00f2b72.js → f6231284-45726550aba08fca.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2ea96958.e8c7e112de50b067.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-c260571513bf43c2.js +1 -0
- package/apps/pwa/out/_next/static/css/c23d959d3ee15e57.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 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- 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/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- 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 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- 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/demo/editor-recipes.yaml +22 -0
- package/graphs/retro/daily.yaml +25 -0
- package/graphs/retro/recipes.yaml +24 -0
- package/package.json +1 -1
- package/scripts/ask-marker-check.ts +3 -1
- package/scripts/land-global-checks.ts +89 -0
- package/scripts/lib/pch-regress-map.ts +2 -1
- package/scripts/release-loop/gate-node.ts +296 -25
- package/scripts/release-loop/gate-timing.ts +116 -7
- package/scripts/release-loop/preflight.ts +6 -4
- package/scripts/release-loop/publish-window.ts +141 -0
- package/scripts/release-loop/release-docs.ts +1 -4
- package/scripts/release-loop/release-universe.ts +38 -0
- package/scripts/release-loop/resume-release.ts +4 -1
- package/scripts/release-loop/unattended-release.ts +10 -2
- package/scripts/release-story/draft.ts +5 -1
- package/scripts/retro/shadow-compare.ts +71 -0
- package/scripts/rhythm/daily.ts +6 -1
- package/src/agent-mission/driver.ts +34 -6
- package/src/autopilot/build/llm-conflict-merge.ts +132 -7
- package/src/autopilot/build/merge-intent.ts +135 -7
- package/src/away/release-watch.ts +20 -3
- package/src/cli/config-drift.ts +513 -0
- package/src/cli/log-event-names.ts +4 -0
- package/src/cli/pr-cli.ts +20 -0
- package/src/cli/release-cli.ts +20 -5
- package/src/cli/retro-cli.ts +78 -0
- package/src/cli/tasks-cli.ts +94 -8
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -4
- package/src/dashboard/slash-runtime/help-from-registry.ts +57 -31
- package/src/domains/outbound-log-probe.ts +6 -1
- package/src/graph-runner/graph-run-api.ts +205 -0
- package/src/graph-runner/runner.ts +11 -1
- package/src/harness/harness-cli-command.ts +419 -52
- package/src/harness/harness-queue.ts +315 -25
- package/src/harness/harness-salvage-cli.ts +62 -0
- package/src/hq/fence-outcomes.ts +63 -0
- package/src/hq/fence-wrapper.ts +33 -0
- package/src/hq/hq.ts +11 -1
- package/src/index.ts +69 -6
- package/src/maturity/feature-maturity.ts +2 -2
- package/src/nexus/api/graph-kinds.ts +10 -4
- package/src/nexus/api/graphs-api.ts +178 -6
- package/src/nexus/api/http-server.ts +38 -3
- package/src/nexus/api/loop-edges.ts +4 -2
- package/src/nexus/api/ops-api.ts +22 -7
- package/src/nexus/api/ops-board-route.ts +48 -0
- package/src/onboarding/entry-hints.ts +5 -0
- package/src/onboarding.ts +24 -6
- package/src/release-loop/feature-store.ts +14 -11
- package/src/release-loop/gate-shards.ts +158 -0
- package/src/release-loop/release-schedule.ts +6 -2
- package/src/retro/daily.ts +372 -0
- package/src/seat-loop/op-decide.ts +173 -0
- package/src/seat-loop/seat-loop.ts +60 -3
- package/src/seat-loop/seat-report.ts +58 -3
- package/src/self-dev/ask-launch-flow.ts +5 -4
- package/src/self-dev/ask-launch-io.ts +49 -1
- package/src/self-dev/ask-path-candidates.ts +40 -2
- package/src/self-dev/draft-sweep.ts +371 -16
- package/src/self-dev/draft-triage-rules.ts +19 -4
- package/src/self-dev/pr-preview.ts +84 -16
- package/src/self-implement/blocked-draft-policy.ts +101 -0
- package/src/self-implement/execution-clarification.ts +11 -0
- package/src/self-implement/gate-env-retry.ts +83 -0
- package/src/self-implement/orchestrator.ts +218 -5
- package/src/self-implement/run-stop.ts +123 -0
- package/src/self-implement/run-ttl.ts +258 -0
- package/src/self-implement/salvage-retention.ts +123 -0
- package/src/self-implement/seams.ts +4 -0
- package/src/self-implement/self-implement-cli.ts +2 -0
- package/src/self-implement/sibling-resync.ts +223 -0
- package/src/self-implement/stop-autoheal.ts +204 -0
- package/src/task-agent/board.ts +1 -1
- package/src/task-agent/card-evidence.ts +99 -10
- package/src/task-agent/judge.ts +7 -0
- package/src/task-agent/live-moves.ts +120 -20
- package/src/task-agent/mission.ts +1 -1
- package/src/task-agent/shadow.ts +10 -1
- package/src/task-agent/task-hand.ts +7 -2
- package/src/task-orchestrator/surfaces/pod-command-job.ts +19 -5
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +4 -0
- package/src/task-orchestrator/surfaces/pod-install-slots.ts +89 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +93 -10
- package/src/task-orchestrator/surfaces/pod-pool.ts +147 -34
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +19 -3
- package/src/telegram-commands.ts +41 -0
- package/src/testing/real-cli-spawn.ts +106 -0
- package/src/user-config.ts +56 -3
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1157-cba0e8553d35a980.js +0 -1
- package/apps/pwa/out/_next/static/chunks/171-23a877ed11720de9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2336-e830c777eb6bce04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2375-e061bb24cd2b5cde.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2415.ed6428ff334c7ce2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3094.67339318c7f72a3a.js +0 -2
- package/apps/pwa/out/_next/static/chunks/338-ceb956612dcfaa86.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3395-835e4ceaa6335ba4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +0 -5
- package/apps/pwa/out/_next/static/chunks/3441-be82e3595aef3a20.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3689-89905039bf3e7257.js +0 -1
- package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3822-6f268bc26c6a84ac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4457-d7df81c90f9d0268.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4551-77dadae76f6cbace.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4978.6fd93b974441e87f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5012-f746f6549b869f91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +0 -1
- package/apps/pwa/out/_next/static/chunks/62-5bfed1e23790b745.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6320-9bc8561fde416e07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/649-ca96d1c5d09e02b8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6726-85a7db59b288c53f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6735-33267c4630d0d963.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7633-141682015873beb6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8067-143791231c99bd02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8430-a10cfba8ef282d4e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9454-12c2f30dea62291c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/976-4a9b4ebdca7c739a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9989-15cdf568bafa9fc8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-deef5ee191830f14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-b193da485f9a14b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-b6e1a79df0e214f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-e84df4d907f703c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-a5fb9a5db89ae4ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-1499f481d7fc52d6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-c7cf753aeb648790.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-4118469e514e10fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-e968f7630654332a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-505915052f947022.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-c2f962fb4a3b06c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-7b5ed0bd8a589ec4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-cf8193250dd42dd4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-cf3f5dfa35dea8e9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a15e7fcc283e9ca7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-d2915e7b70ff3d0e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-b70cd005d9169e25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-2595f0eba29f57e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-c776322454156e36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-77bbd17f4435aa10.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-049689e611ecc936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-85954a4fb09c44eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-e773e552e1068ee6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5633c4bfa7684b4a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d829b92bd01b4994.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-061c317fc771becf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3a45ece8865ed4b6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-0be990618c0d56bd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-bfea4865dc244b73.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-0d6ba8e337741484.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-76a88b55d816482e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-bba1542df59f61ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-4185c95689bb372e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-b699e1a8d5d34b8b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-c225e338c31bf274.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-449353f70507ca1f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-90b889714102476d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f1ee7fbeb7f96ddc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-d59a95e1434dfaa0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-71491a23414d1a47.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-de7112bdb65fa4fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-feb4d0d88079660d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-f17d887b40dd6b1d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-8da77be2192bcd5d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-72c3b9a5e9582b29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c3afe4c8d0c48c39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-b9308f2d8a931531.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-6f35f9d892fa630b.js +0 -1
- package/apps/pwa/out/_next/static/css/85f53c6f35d11382.css +0 -1
- /package/apps/pwa/out/_next/static/{J5H7BvqgSI8DUjtRRcA_S → Bam1YziK2iH9bN4K0utGk}/_ssgManifest.js +0 -0
|
@@ -26,6 +26,7 @@ import { answerCrossCheck, answerSeat, askCrossCheck, askSeat, crossCheckAnswer,
|
|
|
26
26
|
import { queryRunningRuns } from '../self-implement/running-runs.js';
|
|
27
27
|
import { checklistHistory, listChecklist, type Checklist } from '../release-loop/checklist.js';
|
|
28
28
|
import { readSchedules, releasedVersion } from '../release-loop/feature-store.js';
|
|
29
|
+
import { runOpDecide, type OpDecideCandidate } from './op-decide.js';
|
|
29
30
|
|
|
30
31
|
// `kind`/`createdAt` are the V3 shadow-compare keys (내부 문서 `METHOD-v3-shadow-compare-2026-10-02` · MK 10-02 18:54).
|
|
31
32
|
export type SeatItem = { source: 'request' | 'checklist' | 'hook' | 'seat-question'; kind?: 'request' | 'cell' | 'hook-task' | 'seat-question'; id: string; title: string; text: string; evidence?: string; status?: string; version?: string; seat?: string; evidenceHash?: string; asOf?: string; queuedAt?: string; createdAt?: string; from?: SeatId };
|
|
@@ -43,7 +44,7 @@ export type TcCandidate =
|
|
|
43
44
|
| { kind: 'publication-pr-approval-wait'; pr: number; title: string; readyAt: string; approvalWaitAt: string; paths: string[] }
|
|
44
45
|
| { kind: 'other-seat-cell-defect'; version: string; id: string; title: string; to: SeatId };
|
|
45
46
|
export type TcPullRequest = { number: number; title: string; body?: string; state: 'OPEN' | 'MERGED' | 'CLOSED'; isDraft: boolean; createdAt: string; updatedAt?: string; mergedAt?: string | null; readyAt?: string; approvalWaitAt?: string; paths?: string[]; reviewDecision?: string };
|
|
46
|
-
export type SeatEntry = { seat: string; ts?: string; at: string; modeDowngradeReason?: string; status: 'shadow' | 'attempting' | 'outcome-unknown' | 'queued' | 'refused' | 'held' | 'launched' | 'hitl' | 'wait' | 'asked' | 'answered' | 'awaiting-answer' | 'awaiting-xcheck' | 'awaiting-resolution' | 'resolved-by-neighbor' | 'resolved' | 'rejected-no-evidence' | 'skipped-budget' | 'skipped-empty'; item?: SeatItem; candidate?: OpCandidate | TcCandidate; action?: SeatAction; reason?: string; runId?: string; queueId?: string; inquiry?: SeatInquiry; answer?: string; escalated?: boolean; xcheckRequestedAt?: string; xcheckQuestionId?: number; xcheckNeighbor?: SeatId; xcheckNote?: string; xcheckJudgmentEvidence?: string; xcheckWaitMinutes?: number };
|
|
47
|
+
export type SeatEntry = { seat: string; ts?: string; at: string; modeDowngradeReason?: string; status: 'shadow' | 'attempting' | 'outcome-unknown' | 'queued' | 'refused' | 'held' | 'launched' | 'hitl' | 'wait' | 'asked' | 'answered' | 'awaiting-answer' | 'awaiting-xcheck' | 'awaiting-resolution' | 'resolved-by-neighbor' | 'resolved' | 'rejected-no-evidence' | 'skipped-budget' | 'skipped-empty'; item?: SeatItem; candidate?: OpCandidate | TcCandidate | OpDecideCandidate; action?: SeatAction; reason?: string; runId?: string; queueId?: string; inquiry?: SeatInquiry; answer?: string; escalated?: boolean; xcheckRequestedAt?: string; xcheckQuestionId?: number; xcheckNeighbor?: SeatId; xcheckNote?: string; xcheckJudgmentEvidence?: string; xcheckWaitMinutes?: number };
|
|
47
48
|
export type SeatLoopResult = SeatEntry | { seat: string; status: 'skipped-off'; modeDowngradeReason?: string };
|
|
48
49
|
|
|
49
50
|
export function seatLoopTickLine(result: SeatLoopResult): string {
|
|
@@ -99,6 +100,8 @@ export type SeatDeps = {
|
|
|
99
100
|
/** Judge a decision draft against the receiving seat's evidence; null leaves the request pending. */
|
|
100
101
|
crossCheck?: (seat: SeatId, draft: string, from: SeatId) => Promise<CrossCheckJudgment | null> | CrossCheckJudgment | null;
|
|
101
102
|
decisionsConfig?: UserConfig['decisions'];
|
|
103
|
+
/** OP-LOOP-DECIDE: who owns a run (for run-blocking cards). Default = today's seat ledgers' launched rows. */
|
|
104
|
+
runOwner?: (runId: string) => SeatId | undefined;
|
|
102
105
|
};
|
|
103
106
|
|
|
104
107
|
const repoRoot = resolve(import.meta.dir, '../..');
|
|
@@ -291,6 +294,8 @@ function personReopened(ledger: readonly SeatEntry[], seat: string, item: SeatIt
|
|
|
291
294
|
const ref = decisionRef(seat, item);
|
|
292
295
|
return new DecisionLedger({ stateDir: root }).list({ status: 'all' }).some((card) => {
|
|
293
296
|
if (!card.refs?.includes(ref) || card.status !== 'decided' || !card.decidedAt) return false;
|
|
297
|
+
// «멈춘다» on a repeat-stop card keeps the cell held — only a reopen (or any other card's decision) frees it (OP-LOOP-DECIDE).
|
|
298
|
+
if (/ 반복 착지 0$/.test(card.title) && card.options.find((option) => option.key === card.choice)?.label === '멈춘다') return false;
|
|
294
299
|
const decidedAt = Date.parse(card.decidedAt);
|
|
295
300
|
return Number.isFinite(decidedAt) && decidedAt > heldAt;
|
|
296
301
|
});
|
|
@@ -551,6 +556,40 @@ export async function gatherSeatInputs(seat: string, deps: SeatDeps = {}, ledger
|
|
|
551
556
|
return { requests: pending, checklist, role: read(join(deps.repo ?? repoRoot, 'docs', 'roles', `${seat}.md`)).slice(0, 4_000) };
|
|
552
557
|
}
|
|
553
558
|
|
|
559
|
+
/** OP-LOOP-DECIDE: filter open decision cards each OP turn. Shadow records; live decides/routes. A failure never blocks the turn. */
|
|
560
|
+
function opDecidePass(config: SeatLoopConfig, deps: SeatDeps, now: Date, path: string, stateRoot: string, ledger: readonly SeatEntry[]): void {
|
|
561
|
+
const mode = config.opDecide?.mode === 'live' ? 'live' : 'shadow';
|
|
562
|
+
let owners: Map<string, SeatId> | undefined;
|
|
563
|
+
try {
|
|
564
|
+
const append = deps.append ?? defaultAppend;
|
|
565
|
+
const recorded = new Map<string, OpDecideCandidate[]>();
|
|
566
|
+
for (const row of ledger) {
|
|
567
|
+
if (row.candidate?.kind === 'decision-filter') recorded.set(row.candidate.id, [...(recorded.get(row.candidate.id) ?? []), row.candidate]);
|
|
568
|
+
}
|
|
569
|
+
runOpDecide({
|
|
570
|
+
mode,
|
|
571
|
+
ledger: cardLedger(stateRoot, deps, now),
|
|
572
|
+
runOwner: deps.runOwner ?? ((runId) => {
|
|
573
|
+
owners ??= new Map((['OP', 'UX', 'MK', 'TC'] as const).flatMap((owner) =>
|
|
574
|
+
readSeatLedger(owner, deps, now).filter((row) => row.runId).map((row) => [row.runId!, owner] as const)));
|
|
575
|
+
return owners.get(runId);
|
|
576
|
+
}),
|
|
577
|
+
routeToSeat: (to, card, reason) => {
|
|
578
|
+
askSeat(stateRoot, 'OP', to, `결정 카드 ${card.id} «${card.title}» — ${reason}. 런 주인이 판단해 elanous decisions decide ${card.id} 로 닫아 주세요.`,
|
|
579
|
+
`op-decide:${card.id}:${to}`);
|
|
580
|
+
return true;
|
|
581
|
+
},
|
|
582
|
+
recorded: (id) => recorded.get(id) ?? [],
|
|
583
|
+
record: (candidate) => {
|
|
584
|
+
append(path, { seat: 'OP', ts: now.toISOString(), at: now.toISOString(),
|
|
585
|
+
status: mode === 'shadow' ? 'shadow' : candidate.verdict === 'auto' ? 'resolved' : 'hitl',
|
|
586
|
+
...(candidate.verdict === 'route' && candidate.to === 'CEO' ? { escalated: true } : {}),
|
|
587
|
+
candidate, reason: candidate.reason });
|
|
588
|
+
},
|
|
589
|
+
});
|
|
590
|
+
} catch (error) { observe('op-decide', { event: 'pass-failed', mode, error: String(error).slice(0, 200) }); }
|
|
591
|
+
}
|
|
592
|
+
|
|
554
593
|
const OP_CUTOFF_WINDOW_MS = 2 * 60 * 60_000;
|
|
555
594
|
const RUN_REFERENCE = /\brun-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi;
|
|
556
595
|
|
|
@@ -870,10 +909,25 @@ const SEAT_ACTION_RULES: ReadonlyArray<{ kind: 'wait' | 'harness' | 'decision';
|
|
|
870
909
|
{ kind: 'wait', signal: /실측\s*대기|(?:사람|실제)\s*기기(?!\s*(?:(?:실측|측정|확인)\s*)?완료)(?:\s*(?:실측|측정|확인|대기))?|실물\s*측정(?!\s*완료)/iu, source: 'content', resolvedBy: /(?:실측|측정|(?:사람|실제)\s*기기|실물\s*측정)\s*완료/iu },
|
|
871
910
|
{ kind: 'wait', signal: /\u{1F451}\s*확인\s*대기/iu, source: 'content', resolvedBy: /\u{1F451}\s*확인\s*완료/iu },
|
|
872
911
|
{ kind: 'decision', signal: TRACK_AGENT_FORBIDDEN_ACTION_REGEX, source: 'task' },
|
|
912
|
+
{ kind: 'decision', signal: /토큰\s*(?:을|를)?\s*(?:출력|노출|공개|첨부|붙여)/iu, source: 'task' },
|
|
873
913
|
{ kind: 'decision', signal: /(?:마켓|레지스트리)(?:에|로)?\s*(?:게시|등록|발행)|사이트\s*운영\s*반영|SNS(?:에|로)?\s*(?:게시|발행|업로드)|공개\s*발행/iu, source: 'task' },
|
|
874
914
|
{ kind: 'harness', signal: /(?:마켓|레지스트리|사이트|SNS|공개)?(?:에|로)?\s*(?:게시|발행|배포|등록|운영\s*반영)(?:를?\s*위한)?\s*(?:준비|초안|원고|자료|구현|점검|테스트)|(?:마켓|레지스트리|사이트|SNS|공개)?(?:에|로)?\s*(?:게시|발행|배포|등록)(?:용|를?\s*위한)\s*(?:초안|원고|자료|코드|기능)/iu, source: 'task' },
|
|
875
915
|
];
|
|
876
916
|
|
|
917
|
+
// SEAT-FORBID-NEGATION: «비밀 0» · «비밀 제외» · «no secret» name the word to exclude it, not to act on it.
|
|
918
|
+
// Only a negation right next to the hit (optionally after a short noun such as 키 · 증명 and a particle) clears it;
|
|
919
|
+
// «비밀 키를 붙여라» keeps its imperative and stays a decision.
|
|
920
|
+
const FORBID_NEGATION = '(?:0(?![\\dx.,])|제외|없이|빼고|금지|없음|none\\b|no\\b|without\\b|excluding\\b)';
|
|
921
|
+
const FORBID_NEGATION_AFTER = new RegExp(`^(?:\\s*(?:증명|정보|키|값|토큰|keys?|tokens?)(?![A-Za-z]))?\\s*(?:은|는|이|가|을|를|:)?\\s*${FORBID_NEGATION}`, 'iu');
|
|
922
|
+
const FORBID_NEGATION_BEFORE = /(?:^|[\s(\[«"'·,:])(?:no|without|excluding|none|제외|금지)\s*[:·-]?\s*$/iu;
|
|
923
|
+
|
|
924
|
+
export const FORBID_JUDGMENT_LINE = (word: string | undefined): string =>
|
|
925
|
+
`판정 근거: «${word ?? '?'}» 바로 앞뒤에 부정 문면(0·제외·없이·빼고·금지·없음·no·without·excluding)이 없어 실행 요청으로 봤다`;
|
|
926
|
+
|
|
927
|
+
export function forbiddenHitNegated(text: string, index: number, length: number): boolean {
|
|
928
|
+
return FORBID_NEGATION_AFTER.test(text.slice(index + length)) || FORBID_NEGATION_BEFORE.test(text.slice(0, index));
|
|
929
|
+
}
|
|
930
|
+
|
|
877
931
|
export function planAction(item: SeatItem, seat?: string): { kind: 'decision' | 'harness' | 'wait'; text: string; reason?: string } {
|
|
878
932
|
const task = `${item.id}\n${item.title}\n${item.text}`;
|
|
879
933
|
const content = `${task}\n${item.evidence ?? ''}`;
|
|
@@ -884,7 +938,9 @@ export function planAction(item: SeatItem, seat?: string): { kind: 'decision' |
|
|
|
884
938
|
if (resolvedBy?.test(item.evidence ?? '')) return null;
|
|
885
939
|
const hits = [...text.matchAll(new RegExp(signal.source, `${signal.flags.replace('g', '')}g`))];
|
|
886
940
|
const hit = kind === 'decision' ? hits.find((match) => !prepared.some((prep) =>
|
|
887
|
-
match.index! >= prep.index! && match.index! + match[0].length <= prep.index! + prep[0].length)
|
|
941
|
+
match.index! >= prep.index! && match.index! + match[0].length <= prep.index! + prep[0].length)
|
|
942
|
+
&& !(forbiddenHitNegated(text, match.index!, match[0].length)
|
|
943
|
+
&& (observe('forbid-negated', { item: item.id, word: match[0] }), true))) : hits[0];
|
|
888
944
|
return hit ? { kind, reason: hit[0] } : null;
|
|
889
945
|
}).find((hit) => hit !== null);
|
|
890
946
|
const kind = rule?.kind ?? 'harness';
|
|
@@ -1004,6 +1060,7 @@ export async function runSeatLoopOnce(seat: string, deps: SeatDeps = {}): Promis
|
|
|
1004
1060
|
} catch (error) { observe('heartbeat-write-failed', { seat, error: String(error).slice(0, 200) }); }
|
|
1005
1061
|
const recorded = readSeatLedger(seat, deps, now);
|
|
1006
1062
|
const ledger = config.mode === 'live-safe' ? reconciledQueueLedger(recorded, stateRoot, deps) : recorded;
|
|
1063
|
+
if (seat === 'OP') opDecidePass(config, deps, now, path, stateRoot, ledger);
|
|
1007
1064
|
let turnError: unknown;
|
|
1008
1065
|
try {
|
|
1009
1066
|
if (config.mode === 'on' && config.questions === 'on') {
|
|
@@ -1494,7 +1551,7 @@ export async function runSeatLoopOnce(seat: string, deps: SeatDeps = {}): Promis
|
|
|
1494
1551
|
: undefined;
|
|
1495
1552
|
} catch (error) { observe('decision-source-unreadable', { seat, item: item.id, error: String(error).slice(0, 200) }); }
|
|
1496
1553
|
const material = decisionCardMaterial({ what: `${seat} 배정 항목: ${item.title} 역할: ${inputs.role || '역할 근거 없음'}`, soFar: `요청 내용: ${item.text}`,
|
|
1497
|
-
current: `밑바탕 재측: ${currentStatus ?? '상태 미확인'}; 요청에서 금지 문면 «${action.reason}» 발견 — 실행 전 사람 승인
|
|
1554
|
+
current: `밑바탕 재측: ${currentStatus ?? '상태 미확인'}; 요청에서 금지 문면 «${action.reason}» 발견 — 실행 전 사람 승인 필요; ${FORBID_JUDGMENT_LINE(action.reason)}`,
|
|
1498
1555
|
question: `금지 문면 «${action.reason}»이 걸린 요청을 승인할까?`, answer: '승인 전에는 집행하지 않고 보류한다',
|
|
1499
1556
|
options, recommendation, confidence: '높음 — 요청에 금지 문면 직접 일치',
|
|
1500
1557
|
ifUntouched: '자동 집행되지 않고 해당 칸은 보류 상태로 남는다',
|
|
@@ -6,6 +6,7 @@ import { promisify } from 'node:util';
|
|
|
6
6
|
import { debug } from '../debug/log.js';
|
|
7
7
|
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
8
8
|
import { getUserConfig, type SeatLoopConfig } from '../user-config.js';
|
|
9
|
+
import { collectDraftMetrics, collectOverlapMetrics, countSalvagedToday, type DraftMetrics, type OverlapMetrics } from '../self-dev/draft-sweep.js';
|
|
9
10
|
import { seatDay, seatLedgerPath, type OpCandidate, type SeatEntry } from './seat-loop.js';
|
|
10
11
|
|
|
11
12
|
export type SeatReportDeps = {
|
|
@@ -16,6 +17,10 @@ export type SeatReportDeps = {
|
|
|
16
17
|
config?: SeatLoopConfig;
|
|
17
18
|
post?: boolean;
|
|
18
19
|
send?: (body: string, seat: string, pr: number) => Promise<void> | void;
|
|
20
|
+
draftMetrics?: (now: Date) => Promise<DraftMetrics>;
|
|
21
|
+
overlapMetrics?: (now: Date) => Promise<OverlapMetrics>;
|
|
22
|
+
/** DRAFT-NOT-ARCHIVE salvage branches since the KST day start; null = unreadable. */
|
|
23
|
+
salvagedToday?: (dayStart: Date, now: Date) => Promise<number | null>;
|
|
19
24
|
};
|
|
20
25
|
export type SeatReportResult = { seat: string; date: string; body: string; posted: boolean };
|
|
21
26
|
const repoRoot = resolve(import.meta.dir, '../..');
|
|
@@ -36,6 +41,21 @@ function opJudgment(candidate: OpCandidate): { kind: 'card' | 'todo'; text: stri
|
|
|
36
41
|
text: `${text} (${candidate.category ?? '범주 없음'})` };
|
|
37
42
|
}
|
|
38
43
|
|
|
44
|
+
/** OVERLAP-METRIC line; ⛔ an unmeasured value says so instead of printing 0. */
|
|
45
|
+
function overlapLine(metrics: OverlapMetrics): string {
|
|
46
|
+
if (metrics.sourceIncomplete || metrics.launches24h === null) return ' · 겹침 발사 24h 못 잼(원천 불완전)';
|
|
47
|
+
const launched = metrics.launched === null ? '' : metrics.unmeasured
|
|
48
|
+
? ` 이상 (발사 ${metrics.launched} 중 ${metrics.unmeasured} 못 잼)` : ` (발사 ${metrics.launched})`;
|
|
49
|
+
const rate = metrics.autoRate === null || metrics.linked === null || metrics.autoLanded === null
|
|
50
|
+
? (metrics.linked === 0 ? '표본 없음' : '못 잼')
|
|
51
|
+
: `${(metrics.autoRate * 100).toFixed(1)}% (${metrics.autoLanded}/${metrics.linked})`;
|
|
52
|
+
const median = metrics.secondSiblingMedianHours === null ? (metrics.linked === null ? '못 잼' : '표본 없음')
|
|
53
|
+
: `${metrics.secondSiblingMedianHours.toFixed(1)}h`;
|
|
54
|
+
const salvage = (metrics.salvaged ? ` · 수확 가지 형제 ${metrics.salvaged}(미착지)` : '')
|
|
55
|
+
+ (metrics.salvageUnmeasured ? ` · 수확 가지 ${metrics.salvageUnmeasured} 못 잼` : '');
|
|
56
|
+
return ` · 겹침 발사 24h ${metrics.launches24h}${launched} · 겹침 자동 착지 ${rate} · 둘째 형제 착지 중앙값 ${median}${salvage}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
39
59
|
async function defaultSend(body: string, seat: string, pr: number, repo: string): Promise<void> {
|
|
40
60
|
const dir = mkdtempSync(join(tmpdir(), 'seat-report-'));
|
|
41
61
|
try {
|
|
@@ -58,8 +78,13 @@ export async function seatReport(seat: string, deps: SeatReportDeps = {}): Promi
|
|
|
58
78
|
// One line per item, its last state wins: an `attempting` row followed by `launched` is not «unconfirmed».
|
|
59
79
|
const latest = new Map<string, SeatEntry>();
|
|
60
80
|
const judgments = new Map<string, OpCandidate>();
|
|
81
|
+
const filtered = { auto: 0, route: 0 };
|
|
61
82
|
for (const entry of entries) {
|
|
62
|
-
if (
|
|
83
|
+
if (entry.candidate?.kind === 'decision-filter') {
|
|
84
|
+
filtered[entry.candidate.verdict] += 1;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (seat === 'OP' && entry.candidate && 'verdict' in entry.candidate) {
|
|
63
88
|
if (entry.candidate.verdict === 'none') {
|
|
64
89
|
if (entry.candidate.id) {
|
|
65
90
|
const key = entry.candidate.kind === 'unassigned-cell'
|
|
@@ -89,8 +114,38 @@ export async function seatReport(seat: string, deps: SeatReportDeps = {}): Promi
|
|
|
89
114
|
return `건너뜀 ${entry.status} ${label}`;
|
|
90
115
|
});
|
|
91
116
|
const classified = [...judgments.values()].map(opJudgment).filter((row): row is NonNullable<typeof row> => row !== null);
|
|
92
|
-
const opDetail = classified.length ? ` · 결정 카드 후보: ${classified.filter((row) => row.kind === 'card').map((row) => row.text).join(' / ') || '없음'} · OP 가 할 일: ${classified.filter((row) => row.kind === 'todo').map((row) => row.text).join(' / ') || '없음'}` : ''
|
|
93
|
-
|
|
117
|
+
const opDetail = (classified.length ? ` · 결정 카드 후보: ${classified.filter((row) => row.kind === 'card').map((row) => row.text).join(' / ') || '없음'} · OP 가 할 일: ${classified.filter((row) => row.kind === 'todo').map((row) => row.text).join(' / ') || '없음'}` : '')
|
|
118
|
+
+ (filtered.auto + filtered.route ? ` · 카드 거르기: 자동 ${filtered.auto} · 넘김 ${filtered.route}` : '');
|
|
119
|
+
let draftDetail = '';
|
|
120
|
+
if (seat === 'OP') {
|
|
121
|
+
try {
|
|
122
|
+
const metrics = await (deps.draftMetrics ?? (async (clock: Date) => {
|
|
123
|
+
const [{ resolveRepositoryName }, { githubDraftSweepAdapters }] = await Promise.all([
|
|
124
|
+
import('../harness/repository-name.js'), import('../harness/harness-cli-command.js'),
|
|
125
|
+
]);
|
|
126
|
+
return collectDraftMetrics(resolveRepositoryName({}), githubDraftSweepAdapters(), clock);
|
|
127
|
+
}))(now);
|
|
128
|
+
draftDetail = ` · draft 재고 ${metrics.inventory} · 최장 나이 ${metrics.oldestAgeHours === null ? '해당 없음' : `${metrics.oldestAgeHours.toFixed(1)}h`} · needs-owner ${metrics.needsOwner} · 48h 전환율 ${metrics.conversion48h === null ? '표본 없음' : `${(metrics.conversion48h * 100).toFixed(1)}% (${metrics.converted48h}/${metrics.cohort48h})`}`;
|
|
129
|
+
} catch { draftDetail = ' · draft 지표 못 읽음'; }
|
|
130
|
+
try {
|
|
131
|
+
const overlap = await (deps.overlapMetrics ?? (async (clock: Date) => {
|
|
132
|
+
const [{ resolveRepositoryName }, { githubDraftSweepAdapters }, { readAskPreflightRowsSince, readSalvagedRowsSince }] = await Promise.all([
|
|
133
|
+
import('../harness/repository-name.js'), import('../harness/harness-cli-command.js'), import('../self-dev/ask-launch-io.js'),
|
|
134
|
+
]);
|
|
135
|
+
return collectOverlapMetrics(resolveRepositoryName({}), { ...githubDraftSweepAdapters(), listPreflightRows: readAskPreflightRowsSince, listSalvagedRows: readSalvagedRowsSince }, clock);
|
|
136
|
+
}))(now);
|
|
137
|
+
draftDetail += overlapLine(overlap);
|
|
138
|
+
} catch { draftDetail += ' · 겹침 지표 못 읽음'; }
|
|
139
|
+
let salvagedToday: number | null = null;
|
|
140
|
+
try {
|
|
141
|
+
salvagedToday = await (deps.salvagedToday ?? (async (dayStart: Date, clock: Date) => {
|
|
142
|
+
const { readSalvagedRowsSince } = await import('../self-dev/ask-launch-io.js');
|
|
143
|
+
return countSalvagedToday(await readSalvagedRowsSince(dayStart), dayStart, clock);
|
|
144
|
+
}))(new Date(`${date}T00:00:00+09:00`), now);
|
|
145
|
+
} catch { salvagedToday = null; }
|
|
146
|
+
draftDetail += ` · 수확 가지 오늘 ${salvagedToday === null ? '못 잼' : salvagedToday}`;
|
|
147
|
+
}
|
|
148
|
+
const body = `**[${seat}]** {{TS}} → 보고 ${date}: ${detail.join(' · ') || (classified.length ? 'OP 그림자 판단' : '원장 기록 없음')}${opDetail}${draftDetail}`;
|
|
94
149
|
const pr = (deps.config ?? getUserConfig().loops?.seat)?.reportPr;
|
|
95
150
|
const posted = deps.post === true && pr !== undefined;
|
|
96
151
|
if (posted) await (deps.send ?? ((text, id, number) => defaultSend(text, id, number, deps.repo ?? repoRoot)))(body, seat, pr);
|
|
@@ -1026,11 +1026,12 @@ export async function runAskLaunchFlow(
|
|
|
1026
1026
|
...(candidates.error === undefined ? {} : { error: candidates.error }),
|
|
1027
1027
|
}, candidates.error === undefined ? 'info' : 'warn');
|
|
1028
1028
|
}
|
|
1029
|
-
|
|
1030
|
-
|
|
1029
|
+
const selectedPaths = candidates.paths.slice(0, 1);
|
|
1030
|
+
if (selectedPaths.length > 0) {
|
|
1031
|
+
deps.print(`[ask] ⑴ 코드에서 후보 경로 ${selectedPaths.length}개를 찾아 넣고 다시 저작한다: ${selectedPaths.join(' · ')}`);
|
|
1031
1032
|
}
|
|
1032
|
-
authored = await authorAndPreflight(
|
|
1033
|
-
? `대상 경로: ${
|
|
1033
|
+
authored = await authorAndPreflight(selectedPaths.length > 0
|
|
1034
|
+
? `대상 경로: ${selectedPaths.join(' · ')}\n${input.askText}`
|
|
1034
1035
|
: input.askText);
|
|
1035
1036
|
deps.log('ask-auto-reauthor', {
|
|
1036
1037
|
candidatePathCount: candidates.paths.length,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// 72차 판이 복제를 금지했으므로 여기로 옮긴다. CLI 와 TUI 가 «같은 조회»를 쓴다.
|
|
6
6
|
// ⛔ 판정은 여기 없다 — 여기는 「무엇을 조회하는가」뿐이고, 「그래서 막나」는 launch-preflight 가 정한다.
|
|
7
7
|
import { execFileSync } from 'node:child_process';
|
|
8
|
-
import { readFileSync } from 'node:fs';
|
|
8
|
+
import { readFileSync, realpathSync } from 'node:fs';
|
|
9
9
|
import {
|
|
10
10
|
parseAskTargetPathHints,
|
|
11
11
|
parseAskTargetPathHintsResult,
|
|
@@ -300,6 +300,54 @@ export async function readAskPreflightLogRows(): Promise<AskLogRow[] | null> {
|
|
|
300
300
|
} catch { return null; }
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
+
/** Every `ask-preflight` row since `since`, all universes, paged past the 1000-row cap (OVERLAP-METRIC).
|
|
304
|
+
* ⛔ Unreadable ⇒ `null` — never an empty list that reads as «no overlap launches». */
|
|
305
|
+
export async function readAskPreflightRowsSince(since: Date): Promise<AskLogRow[] | null> {
|
|
306
|
+
return readLogRowsSince(since, 'dev-pipeline', 'ask-preflight');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/** Every DRAFT-NOT-ARCHIVE `salvaged` row since `since`, all universes (OVERLAP-METRIC salvage siblings).
|
|
310
|
+
* ⛔ Unreadable ⇒ `null` — a salvage branch we could not see is «unmeasured», not «none». */
|
|
311
|
+
export async function readSalvagedRowsSince(since: Date): Promise<AskLogRow[] | null> {
|
|
312
|
+
return readLogRowsSince(since, 'self-implement.draft-not-archive', 'salvaged');
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async function readLogRowsSince(since: Date, category: string, event: string): Promise<AskLogRow[] | null> {
|
|
316
|
+
try {
|
|
317
|
+
const [{ resolveLogTargets }, { LogStore }] = await Promise.all([
|
|
318
|
+
import('../cli/logs-cli.js'),
|
|
319
|
+
import('../mss/logging/log-store.js'),
|
|
320
|
+
]);
|
|
321
|
+
const { targets } = resolveLogTargets({ all: true, includeTest: true });
|
|
322
|
+
const rows: AskLogRow[] = [];
|
|
323
|
+
// ⛔ One store can be registered under two names (`~/.monad` → `~/.elanous` symlink) — read each real file once,
|
|
324
|
+
// or every prod row is counted twice (OVERLAP-METRIC 실측: 169 행 중 69 가 같은 prod 파일의 겹침).
|
|
325
|
+
const seen = new Set<string>();
|
|
326
|
+
for (const target of targets) {
|
|
327
|
+
let real = target.dbPath;
|
|
328
|
+
try { real = realpathSync(target.dbPath); } catch { /* missing store: LogStore below decides */ }
|
|
329
|
+
if (seen.has(real)) continue;
|
|
330
|
+
seen.add(real);
|
|
331
|
+
const store = new LogStore(target.dbPath, { readonly: true });
|
|
332
|
+
try {
|
|
333
|
+
let beforeId: number | undefined;
|
|
334
|
+
for (let page = 0; page < 100; page++) {
|
|
335
|
+
const batch = store.query({ exactCategories: [category], events: [event], sinceMs: since.getTime(),
|
|
336
|
+
limit: 1_000, ...(beforeId === undefined ? {} : { beforeId }) });
|
|
337
|
+
for (const row of batch) {
|
|
338
|
+
const parsed = typeof row.data === 'string' ? JSON.parse(row.data) : row.data;
|
|
339
|
+
rows.push({ ts: row.ts, data: (parsed ?? null) as Record<string, unknown> | null });
|
|
340
|
+
}
|
|
341
|
+
if (batch.length < 1_000) break;
|
|
342
|
+
if (page === 99) return null;
|
|
343
|
+
beforeId = batch.at(-1)!.id;
|
|
344
|
+
}
|
|
345
|
+
} finally { store.close?.(); }
|
|
346
|
+
}
|
|
347
|
+
return rows;
|
|
348
|
+
} catch { return null; }
|
|
349
|
+
}
|
|
350
|
+
|
|
303
351
|
const stringList = (value: unknown): string[] =>
|
|
304
352
|
Array.isArray(value) ? value.filter((entry): entry is string => typeof entry === 'string') : [];
|
|
305
353
|
|
|
@@ -14,6 +14,43 @@ export type AskPathCandidates =
|
|
|
14
14
|
const STOP_WORDS = new Set(['the', 'and', 'test', 'src', 'scripts', 'file', 'path', 'paths', 'code', 'with', 'from', 'this', 'that', 'into', 'for', 'then', 'when', 'have', 'does', 'should', 'will', 'please', 'target', 'change']);
|
|
15
15
|
const WORD = /[-/]?[A-Za-z][A-Za-z0-9_.-]*(?:\/[A-Za-z0-9_.-]+)*/g;
|
|
16
16
|
|
|
17
|
+
// ⛔ AUTO-TARGET (10-08 실측 · `ask-auto-target-candidates` Pod 로그): 한글 ask 에서 영문 낱말은 거의
|
|
18
|
+
// «포장»뿐이었다 — 디스패처 머리 `[UX · 0.2.20 칸 <ID> · TASK-AGENT(OP 디스패처)]` ⊕ Pod 샤드 꼬리
|
|
19
|
+
// `## Shard identity {"shardId","totalShards","position","summary","siblings"}` ⊕ `## Working-memory handoff`.
|
|
20
|
+
// 그 낱말들이 하니스 파일(orchestrate.ts · orchestrator.ts · self-implement-pod.ts · index.ts)을 끌어와
|
|
21
|
+
// 네 칸이 엉뚱한 골로 저작됐다. ⇒ 포장을 «증거»에서 걷고, 남는 것이 없으면 «후보 없음»(=근거 없음)을 낸다.
|
|
22
|
+
/** Machine-appended sections whose words describe the transport, not the request. */
|
|
23
|
+
const WRAPPER_SECTION_HEADINGS = new Set(['shard identity', 'working-memory handoff']);
|
|
24
|
+
/** Dispatcher wrapper lines that are identical for every card. */
|
|
25
|
+
const WRAPPER_LINE = /^\s*(?:보존 계약|판정)\s*:/;
|
|
26
|
+
/** Dispatcher header `[OWNER · <ver> 칸 <ID> · …]` — the title after it is kept. */
|
|
27
|
+
const WRAPPER_HEADER = /^\s*\[[^\]\n]*칸[^\]\n]*\]\s*/;
|
|
28
|
+
/** Dispatcher evidence label — the evidence itself is kept. */
|
|
29
|
+
const WRAPPER_LABEL = /^\s*칸 근거 끝\(남은 것\)\s*:\s*/;
|
|
30
|
+
/** Seat/role/surface words and similar labels that name the process, not the code. */
|
|
31
|
+
const GENERIC_TOKENS = new Set(['task-agent', 'op', 'mk', 'tc', 'ux', 'ceo', 'coo', 'cmo', 'cto', 'cxo', 'pr', 'prs', 'pod', 'tui', 'pwa', 'cli', 'hitl', 'p0', 'p1', 'p2']);
|
|
32
|
+
|
|
33
|
+
function isGenericToken(token: string): boolean {
|
|
34
|
+
const lower = token.toLowerCase().replace(/[.]+$/, '');
|
|
35
|
+
if (GENERIC_TOKENS.has(lower)) return true;
|
|
36
|
+
if (/^v?\d+(?:\.\d+)+(?:-[a-z0-9.]+)?$/i.test(lower)) return true; // version strings
|
|
37
|
+
if (/^[0-9a-f]{7,40}$/.test(lower) && /\d/.test(lower)) return true; // commit shas
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Remove dispatcher/Pod wrapper text so only the request body counts as lexical evidence. */
|
|
42
|
+
export function stripAskWrapper(askText: string): string {
|
|
43
|
+
const kept: string[] = [];
|
|
44
|
+
let skipping = false;
|
|
45
|
+
for (const line of askText.split(/\r?\n/)) {
|
|
46
|
+
const heading = /^##\s+(.+?)\s*$/.exec(line);
|
|
47
|
+
if (heading) skipping = WRAPPER_SECTION_HEADINGS.has(heading[1]!.toLowerCase());
|
|
48
|
+
if (skipping || WRAPPER_LINE.test(line)) continue;
|
|
49
|
+
kept.push(line.replace(WRAPPER_HEADER, '').replace(WRAPPER_LABEL, ''));
|
|
50
|
+
}
|
|
51
|
+
return kept.join('\n');
|
|
52
|
+
}
|
|
53
|
+
|
|
17
54
|
function existingFile(fragment: string, cwd: string): string | null {
|
|
18
55
|
const path = fragment.replace(/^\.\//, '');
|
|
19
56
|
if (!path.includes('/') && !/\.[A-Za-z][A-Za-z0-9]*$/.test(path)) return null;
|
|
@@ -29,7 +66,8 @@ export function findAskPathCandidates(askText: string, { cwd, run = execFileSync
|
|
|
29
66
|
const scores = new Map<string, Set<string>>();
|
|
30
67
|
const tokens: string[] = [];
|
|
31
68
|
const seen = new Set<string>();
|
|
32
|
-
const
|
|
69
|
+
const body = stripAskWrapper(askText);
|
|
70
|
+
const chunks = [...body.matchAll(/`([^`]+)`/g)].map((match) => match[1]!).concat([body]);
|
|
33
71
|
for (const chunk of chunks) {
|
|
34
72
|
for (const match of chunk.matchAll(WORD)) {
|
|
35
73
|
const raw = match[0];
|
|
@@ -40,7 +78,7 @@ export function findAskPathCandidates(askText: string, { cwd, run = execFileSync
|
|
|
40
78
|
hits.add(token);
|
|
41
79
|
scores.set(file, hits);
|
|
42
80
|
}
|
|
43
|
-
if (STOP_WORDS.has(token.toLowerCase()) || seen.has(token)) continue;
|
|
81
|
+
if (STOP_WORDS.has(token.toLowerCase()) || isGenericToken(token) || seen.has(token)) continue;
|
|
44
82
|
if (!file && !token.includes('/') && !token.includes('.') && !token.includes('-') && !token.includes('_')
|
|
45
83
|
&& !/[a-z][A-Z]/.test(token) && token.length < 4) continue;
|
|
46
84
|
seen.add(token);
|