elanous 0.2.0 → 0.2.4
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/.env.example +6 -0
- package/README.md +16 -14
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1191-7b13a24117a689fa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1201-09613bce624467c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1377-1efeffbbac0963ff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1470.98a6ab61ccb4131c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2375-3fcae5186c64fe6b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2415.ed6428ff334c7ce2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2929-617f1e66a55be184.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2977-e38442e86289f1d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2982-2a2df543be3d2e5a.js +25 -0
- package/apps/pwa/out/_next/static/chunks/{2a79f15a-2013e4d421d6df88.js → 2ea96958-e8c7e112de50b067.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/319-d37df1b6e0cbeff4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +5 -0
- package/apps/pwa/out/_next/static/chunks/3441-a1dd4acfeda14488.js +1 -0
- package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6804.8ed6ab492bc5fc0a.js → 4323.c5dfb6f503304775.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4836-3c93795ab834381e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{320-d7013ec072863e5e.js → 5080-1613752891fcadb4.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6062-73e68343a9814f6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6090-1bd6077591603947.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6416-505ba707cacafbba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7457-f5cb1cc8db9f7453.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7647.2fcd30d894d5ee30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8046cadf-211ca3c0e00f2b72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8067-f74bf14d67ad98f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8142-011e1f474efb8b33.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8519-0059d82bdb4812bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9740-52467f244755917f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9804-64c02c3c127d5014.js +1 -0
- package/apps/pwa/out/_next/static/chunks/ae787e4c-f2998de7f1ba72a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-21c3261af6ab377c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-1991445b8ea86274.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-4ebfaee2369fe248.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-9fa879ebf5959096.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ca7c3cc305c3285a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-9951930add3d2051.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-4472ddf1e2458e69.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-4de08d4b766f134b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-7a975e2b9db1dfb7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-49270714ef35bb96.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-33fbdf353e2a5982.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-259f122e2dd64317.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-65b82726753658e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-4b8df3748dc06285.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-112f7e477bda77fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-542a5c0006da637c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-63ffb347831262ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-98e4e359d97263b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-97e24ac675ce576e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ac6391f26391d89d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f45c9d45ffc43bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-36995b9cb5d98218.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-0c795b577988d63f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-b4311e2f71c6735a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-eb2381074df20dba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-b01336e64eba01ae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-7af7f21c1f2858ef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-a98ecd364586c89b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-57f0502dfbfa089b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-3467d2e1abd8a14a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-7842ca23d53ba682.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-ae9ac882912b0198.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-3a0d72e3f783bcef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-f3b39fe8358c2a97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-5a22af3181ac2afb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-1457627bb302a22c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-e5bea36f183b25e6.js +1 -0
- package/apps/pwa/out/_next/static/css/e66b7f5efc8df3f3.css +1 -0
- package/apps/pwa/out/_next/static/zoQX5iTvXOsIvCjxCe1Ji/_buildManifest.js +1 -0
- package/apps/pwa/out/approvals/index.html +1 -0
- package/apps/pwa/out/approvals/index.txt +30 -0
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +27 -26
- package/apps/pwa/out/board/index.html +1 -0
- package/apps/pwa/out/board/index.txt +30 -0
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +24 -23
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +24 -23
- package/apps/pwa/out/chat/index.html +1 -2
- package/apps/pwa/out/chat/index.txt +24 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +27 -26
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +27 -26
- package/apps/pwa/out/editor/index.html +1 -0
- package/apps/pwa/out/editor/index.txt +31 -0
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +24 -23
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +27 -26
- package/apps/pwa/out/live/index.html +1 -0
- package/apps/pwa/out/live/index.txt +30 -0
- package/apps/pwa/out/market/index.html +1 -0
- package/apps/pwa/out/market/index.txt +27 -0
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +24 -23
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +27 -26
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +27 -26
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +25 -24
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +27 -26
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +24 -23
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +27 -26
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +27 -26
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +27 -26
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +27 -26
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +27 -26
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +24 -23
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +27 -26
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +27 -26
- package/apps/pwa/out/trace/index.html +1 -0
- package/apps/pwa/out/trace/index.txt +30 -0
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +27 -26
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +27 -26
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +27 -27
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +27 -26
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +27 -26
- package/catalog/resources.yaml +8 -11
- package/docs/design/systems/LICENSE +201 -0
- package/docs/design/systems/NOTICE.md +29 -0
- package/docs/design/systems/SOURCE.json +291 -0
- package/docs/design/systems/application/DESIGN.md +71 -0
- package/docs/design/systems/application/manifest.json +54 -0
- package/docs/design/systems/application/tokens.css +63 -0
- package/docs/design/systems/artistic/DESIGN.md +71 -0
- package/docs/design/systems/artistic/manifest.json +54 -0
- package/docs/design/systems/artistic/tokens.css +63 -0
- package/docs/design/systems/bento/DESIGN.md +71 -0
- package/docs/design/systems/bento/manifest.json +54 -0
- package/docs/design/systems/bento/tokens.css +63 -0
- package/docs/design/systems/bold/DESIGN.md +71 -0
- package/docs/design/systems/bold/manifest.json +54 -0
- package/docs/design/systems/bold/tokens.css +63 -0
- package/docs/design/systems/brutalism/DESIGN.md +71 -0
- package/docs/design/systems/brutalism/manifest.json +54 -0
- package/docs/design/systems/brutalism/tokens.css +63 -0
- package/docs/design/systems/cafe/DESIGN.md +71 -0
- package/docs/design/systems/cafe/manifest.json +54 -0
- package/docs/design/systems/cafe/tokens.css +63 -0
- package/docs/design/systems/claymorphism/DESIGN.md +71 -0
- package/docs/design/systems/claymorphism/manifest.json +54 -0
- package/docs/design/systems/claymorphism/tokens.css +63 -0
- package/docs/design/systems/clean/DESIGN.md +71 -0
- package/docs/design/systems/clean/manifest.json +54 -0
- package/docs/design/systems/clean/tokens.css +63 -0
- package/docs/design/systems/colorful/DESIGN.md +71 -0
- package/docs/design/systems/colorful/manifest.json +54 -0
- package/docs/design/systems/colorful/tokens.css +63 -0
- package/docs/design/systems/contemporary/DESIGN.md +71 -0
- package/docs/design/systems/contemporary/manifest.json +54 -0
- package/docs/design/systems/contemporary/tokens.css +63 -0
- package/docs/design/systems/corporate/DESIGN.md +71 -0
- package/docs/design/systems/corporate/manifest.json +54 -0
- package/docs/design/systems/corporate/tokens.css +63 -0
- package/docs/design/systems/cosmic/DESIGN.md +71 -0
- package/docs/design/systems/cosmic/manifest.json +54 -0
- package/docs/design/systems/cosmic/tokens.css +63 -0
- package/docs/design/systems/creative/DESIGN.md +71 -0
- package/docs/design/systems/creative/manifest.json +54 -0
- package/docs/design/systems/creative/tokens.css +63 -0
- package/docs/design/systems/dashboard/DESIGN.md +71 -0
- package/docs/design/systems/dashboard/manifest.json +54 -0
- package/docs/design/systems/dashboard/tokens.css +63 -0
- package/docs/design/systems/default/DESIGN.md +62 -0
- package/docs/design/systems/default/manifest.json +69 -0
- package/docs/design/systems/default/tokens.css +200 -0
- package/docs/design/systems/dithered/DESIGN.md +71 -0
- package/docs/design/systems/dithered/manifest.json +54 -0
- package/docs/design/systems/dithered/tokens.css +63 -0
- package/docs/design/systems/doodle/DESIGN.md +71 -0
- package/docs/design/systems/doodle/manifest.json +54 -0
- package/docs/design/systems/doodle/tokens.css +63 -0
- package/docs/design/systems/dramatic/DESIGN.md +71 -0
- package/docs/design/systems/dramatic/manifest.json +54 -0
- package/docs/design/systems/dramatic/tokens.css +63 -0
- package/docs/design/systems/editorial/DESIGN.md +71 -0
- package/docs/design/systems/editorial/manifest.json +54 -0
- package/docs/design/systems/editorial/tokens.css +63 -0
- package/docs/design/systems/elegant/DESIGN.md +71 -0
- package/docs/design/systems/elegant/manifest.json +54 -0
- package/docs/design/systems/elegant/tokens.css +63 -0
- package/docs/design/systems/energetic/DESIGN.md +72 -0
- package/docs/design/systems/energetic/manifest.json +54 -0
- package/docs/design/systems/energetic/tokens.css +63 -0
- package/docs/design/systems/enterprise/DESIGN.md +71 -0
- package/docs/design/systems/enterprise/manifest.json +54 -0
- package/docs/design/systems/enterprise/tokens.css +63 -0
- package/docs/design/systems/expressive/DESIGN.md +71 -0
- package/docs/design/systems/expressive/manifest.json +54 -0
- package/docs/design/systems/expressive/tokens.css +63 -0
- package/docs/design/systems/fantasy/DESIGN.md +71 -0
- package/docs/design/systems/fantasy/manifest.json +54 -0
- package/docs/design/systems/fantasy/tokens.css +63 -0
- package/docs/design/systems/flat/DESIGN.md +71 -0
- package/docs/design/systems/flat/manifest.json +54 -0
- package/docs/design/systems/flat/tokens.css +63 -0
- package/docs/design/systems/friendly/DESIGN.md +71 -0
- package/docs/design/systems/friendly/manifest.json +54 -0
- package/docs/design/systems/friendly/tokens.css +63 -0
- package/docs/design/systems/glassmorphism/DESIGN.md +71 -0
- package/docs/design/systems/glassmorphism/manifest.json +54 -0
- package/docs/design/systems/glassmorphism/tokens.css +63 -0
- package/docs/design/systems/gradient/DESIGN.md +71 -0
- package/docs/design/systems/gradient/manifest.json +54 -0
- package/docs/design/systems/gradient/tokens.css +63 -0
- package/docs/design/systems/luxury/DESIGN.md +71 -0
- package/docs/design/systems/luxury/manifest.json +54 -0
- package/docs/design/systems/luxury/tokens.css +63 -0
- package/docs/design/systems/minimal/DESIGN.md +71 -0
- package/docs/design/systems/minimal/manifest.json +54 -0
- package/docs/design/systems/minimal/tokens.css +63 -0
- package/docs/design/systems/modern/DESIGN.md +71 -0
- package/docs/design/systems/modern/manifest.json +54 -0
- package/docs/design/systems/modern/tokens.css +63 -0
- package/docs/design/systems/mono/DESIGN.md +71 -0
- package/docs/design/systems/mono/manifest.json +54 -0
- package/docs/design/systems/mono/tokens.css +63 -0
- package/docs/design/systems/neobrutalism/DESIGN.md +71 -0
- package/docs/design/systems/neobrutalism/manifest.json +54 -0
- package/docs/design/systems/neobrutalism/tokens.css +63 -0
- package/docs/design/systems/neon/DESIGN.md +71 -0
- package/docs/design/systems/neon/manifest.json +54 -0
- package/docs/design/systems/neon/tokens.css +63 -0
- package/docs/design/systems/neumorphism/DESIGN.md +71 -0
- package/docs/design/systems/neumorphism/manifest.json +54 -0
- package/docs/design/systems/neumorphism/tokens.css +63 -0
- package/docs/design/systems/paper/DESIGN.md +71 -0
- package/docs/design/systems/paper/manifest.json +54 -0
- package/docs/design/systems/paper/tokens.css +63 -0
- package/docs/design/systems/perspective/DESIGN.md +71 -0
- package/docs/design/systems/perspective/manifest.json +54 -0
- package/docs/design/systems/perspective/tokens.css +63 -0
- package/docs/design/systems/premium/DESIGN.md +71 -0
- package/docs/design/systems/premium/manifest.json +54 -0
- package/docs/design/systems/premium/tokens.css +63 -0
- package/docs/design/systems/professional/DESIGN.md +71 -0
- package/docs/design/systems/professional/manifest.json +54 -0
- package/docs/design/systems/professional/tokens.css +63 -0
- package/docs/design/systems/publication/DESIGN.md +71 -0
- package/docs/design/systems/publication/manifest.json +54 -0
- package/docs/design/systems/publication/tokens.css +63 -0
- package/docs/design/systems/refined/DESIGN.md +71 -0
- package/docs/design/systems/refined/manifest.json +54 -0
- package/docs/design/systems/refined/tokens.css +63 -0
- package/docs/design/systems/retro/DESIGN.md +71 -0
- package/docs/design/systems/retro/manifest.json +54 -0
- package/docs/design/systems/retro/tokens.css +63 -0
- package/docs/design/systems/shadcn/DESIGN.md +71 -0
- package/docs/design/systems/shadcn/manifest.json +54 -0
- package/docs/design/systems/shadcn/tokens.css +255 -0
- package/docs/design/systems/simple/DESIGN.md +71 -0
- package/docs/design/systems/simple/manifest.json +54 -0
- package/docs/design/systems/simple/tokens.css +63 -0
- package/docs/design/systems/skeumorphism/DESIGN.md +71 -0
- package/docs/design/systems/skeumorphism/manifest.json +54 -0
- package/docs/design/systems/skeumorphism/tokens.css +63 -0
- package/docs/design/systems/sleek/DESIGN.md +71 -0
- package/docs/design/systems/sleek/manifest.json +54 -0
- package/docs/design/systems/sleek/tokens.css +63 -0
- package/docs/design/systems/spacious/DESIGN.md +71 -0
- package/docs/design/systems/spacious/manifest.json +54 -0
- package/docs/design/systems/spacious/tokens.css +63 -0
- package/docs/design/systems/storytelling/DESIGN.md +71 -0
- package/docs/design/systems/storytelling/manifest.json +54 -0
- package/docs/design/systems/storytelling/tokens.css +63 -0
- package/docs/design/systems/tom-modern/DESIGN.md +361 -0
- package/docs/design/systems/tom-modern/manifest.json +16 -0
- package/docs/design/systems/tom-modern/tokens.css +99 -0
- package/docs/design/systems/vibrant/DESIGN.md +71 -0
- package/docs/design/systems/vibrant/manifest.json +54 -0
- package/docs/design/systems/vibrant/tokens.css +63 -0
- package/docs/design/systems/vintage/DESIGN.md +71 -0
- package/docs/design/systems/vintage/manifest.json +54 -0
- package/docs/design/systems/vintage/tokens.css +63 -0
- package/docs/design/systems/warm-editorial/DESIGN.md +65 -0
- package/docs/design/systems/warm-editorial/manifest.json +54 -0
- package/docs/design/systems/warm-editorial/tokens.css +63 -0
- package/docs/goal-context/01-goal-authoring-checks.md +18 -0
- package/docs/goal-context/steward-directives-2026-09-28.md +44 -0
- package/graphs/catalog/catalog.yaml +615 -0
- package/graphs/default-loop.yaml +1 -1
- package/graphs/document-loop.yaml +1 -1
- package/graphs/examples/stale-draft-digest/digest.ts +26 -0
- package/graphs/examples/stale-draft-digest/recipes.yaml +8 -0
- package/graphs/examples/stale-draft-digest/stale-draft-digest.yaml +22 -0
- package/graphs/heal/heal-loop.yaml +155 -0
- package/graphs/heal/recipes.yaml +19 -0
- package/graphs/implement-loop.yaml +2 -2
- package/graphs/intake/intake-daily.yaml +55 -0
- package/graphs/intake/recipes.yaml +16 -0
- package/graphs/landing/landing-heal.yaml +22 -0
- package/graphs/landing/recipes.yaml +8 -0
- package/graphs/launch/launch-head.yaml +66 -0
- package/graphs/launch/recipes.yaml +8 -0
- package/graphs/operate-loop.yaml +1 -1
- package/graphs/ops/docs-publish.yaml +31 -0
- package/graphs/ops/recipes.yaml +8 -0
- package/graphs/release/recipes.yaml +38 -0
- package/graphs/release/release-loop.yaml +40 -0
- package/graphs/research-loop.yaml +1 -1
- package/graphs/steward/recipes.yaml +12 -0
- package/graphs/steward/steward.yaml +45 -0
- package/graphs/video/broll-line.yaml +54 -0
- package/package.json +7 -5
- package/plugins/job-coach/.agents/plugins/marketplace.json +12 -0
- package/plugins/job-coach/.codex-plugin/plugin.json +6 -0
- package/plugins/job-coach/.mcp.json +9 -0
- package/plugins/job-coach/README.md +20 -0
- package/plugins/job-coach/connectors/ncs/server.ts +89 -0
- package/plugins/job-coach/examples/interview-sample.md +11 -0
- package/plugins/job-coach/graphs/course-links.ts +46 -0
- package/plugins/job-coach/graphs/recipes.yaml +18 -0
- package/plugins/job-coach/graphs/report.yaml +20 -0
- package/plugins/job-coach/graphs/run-step.ts +108 -0
- package/plugins/job-coach/plugin.json +13 -0
- package/plugins/job-coach/plugin.ts +6 -0
- package/plugins/job-coach/skills/career-report/SKILL.md +6 -0
- package/plugins/job-coach/skills/interview-to-profile/SKILL.md +6 -0
- package/plugins/job-coach/skills/run-report/SKILL.md +15 -0
- package/scripts/backup/elanous-backup.sh +139 -13
- package/scripts/backup/elanous-restore.sh +122 -0
- package/scripts/ci-daemon-port-gate.ts +164 -0
- package/scripts/ci-typecheck-changed.ts +15 -1
- package/scripts/cli-json-exit-scan.ts +126 -0
- package/scripts/codex-quota-alert-format.ts +52 -0
- package/scripts/codex-quota-alert.ts +63 -13
- package/scripts/continuation-dogfood.ts +2 -1
- package/scripts/coord-channel-watch.sh +5 -5
- package/scripts/coord-tracks.json +5 -4
- package/scripts/cron-run.ts +37 -16
- package/scripts/daemon-port-baseline.txt +9 -0
- package/scripts/design/extract-corpus-bench.ts +469 -0
- package/scripts/design/extract-corpus-score.ts +510 -0
- package/scripts/design/vendor-open-design-systems.ts +100 -0
- package/scripts/docs-lint.ts +1 -1
- package/scripts/fleet/node-setup.sh +38 -4
- package/scripts/heal/run-role.ts +328 -0
- package/scripts/install-role-watch.sh +95 -0
- package/scripts/install.ps1 +11 -1
- package/scripts/install.sh +81 -9
- package/scripts/isolation-hardcode-baseline.txt +1 -1
- package/scripts/landing-heal/must-fix-match.ts +37 -0
- package/scripts/landing-heal/run-mission.ts +101 -0
- package/scripts/lib/pwa-scenarios/acp-replay.ts +79 -0
- package/scripts/lib/pwa-scenarios/cdp-driver.ts +67 -0
- package/scripts/lib/pwa-scenarios/runner.ts +200 -0
- package/scripts/lib/pwa-scenarios/scenarios.ts +202 -0
- package/scripts/market/db-check.ts +212 -0
- package/scripts/market-posture-cycle.ts +63 -4
- package/scripts/nightly-docops.ts +1 -1
- package/scripts/ops/channel-bot-token-migrate.ts +146 -0
- package/scripts/ops-health-check.ts +15 -3
- package/scripts/pty-scenarios/run.ts +272 -0
- package/scripts/public-leak-baseline.txt +0 -7
- package/scripts/publish-internal-dist.ts +119 -0
- package/scripts/pwa-scenarios.ts +106 -0
- package/scripts/rebrand-elanous.ts +1 -1
- package/scripts/release-loop/cutoff.ts +139 -0
- package/scripts/release-loop/docs-land-node.ts +65 -0
- package/scripts/release-loop/docs-node.ts +172 -0
- package/scripts/release-loop/gate-diff.ts +29 -0
- package/scripts/release-loop/gate-node.ts +353 -0
- package/scripts/release-loop/node-verdict.ts +85 -0
- package/scripts/release-loop/prepare-node.ts +31 -0
- package/scripts/release-loop/publish-node.ts +57 -0
- package/scripts/release-loop/pwa-node-verdict.ts +45 -0
- package/scripts/release-loop/pwa-scenarios-node.ts +140 -0
- package/scripts/release-loop/release-docs.ts +102 -0
- package/scripts/release-loop/tui-node-checks.ts +29 -0
- package/scripts/release-loop/tui-sim-node.ts +113 -0
- package/scripts/release-loop/upgrade-node.ts +25 -0
- package/scripts/release-loop/verify-node.ts +21 -0
- package/scripts/release-loop/version-node.ts +147 -0
- package/scripts/release-upgrade-check.sh +53 -0
- package/scripts/se-mission-prepare.ts +9 -15
- package/scripts/test-deterministic.ts +2 -1
- package/scripts/uninstall.sh +10 -3
- package/scripts/video-broll-line.ts +89 -0
- package/scripts/waitlist-daily-digest.ts +108 -0
- package/scripts/window-landings.sh +1 -1
- package/skills/motion-broll/LICENSE +25 -0
- package/skills/motion-broll/SKILL.md +150 -0
- package/skills/motion-broll/SOURCE.md +6 -0
- package/skills/motion-broll/engine/base.css +19 -0
- package/skills/motion-broll/engine/beats.js +11 -0
- package/skills/motion-broll/engine/build.py +21 -0
- package/skills/motion-broll/engine/fonts/Geist-Variable.woff2 +0 -0
- package/skills/motion-broll/engine/fonts/GeistMono-Medium.woff2 +0 -0
- package/skills/motion-broll/engine/fonts/OFL-Geist.txt +92 -0
- package/skills/motion-broll/engine/motion.js +146 -0
- package/skills/motion-broll/engine/render.js +22 -0
- package/skills/motion-broll/examples/opus-aoe2/01-opus-drop.html +41 -0
- package/skills/motion-broll/examples/opus-aoe2/02-pip-builds.html +110 -0
- package/skills/motion-broll/examples/opus-aoe2/03-effort-slider.html +38 -0
- package/skills/motion-broll/examples/opus-aoe2/04-master-prompt.html +56 -0
- package/skills/motion-broll/examples/opus-aoe2/05-low-vs-max.html +49 -0
- package/skills/motion-broll/examples/opus-aoe2/06-chapter.html +18 -0
- package/skills/motion-broll/examples/opus-aoe2/plan.json +14 -0
- package/skills/motion-broll/reference/engine-api.md +106 -0
- package/skills/motion-broll/scripts/composite.py +14 -0
- package/skills/motion-broll/scripts/inspect_video.py +34 -0
- package/skills/motion-broll/scripts/make_pages.py +34 -0
- package/skills/motion-broll/scripts/setup.sh +16 -0
- package/skills/motion-broll/scripts/words.py +13 -0
- package/skills/motion-broll/templates/compare.html +135 -0
- package/skills/motion-broll/templates/viewer.html +97 -0
- package/skills/omni-digest/SKILL.md +260 -0
- package/skills/omni-digest/digest.md +197 -0
- package/skills/omni-digest/docs/diagrams/noncode-terminal-promotion-path-2026-08-13.mmd +32 -0
- package/skills/omni-digest/package-lock.json +558 -0
- package/skills/omni-digest/package.json +13 -0
- package/skills/omni-digest/scripts/main.ts +404 -0
- package/skills/omni-digest/src/delegate.ts +34 -0
- package/skills/omni-digest/src/detect.ts +46 -0
- package/skills/omni-digest/src/diagram.ts +72 -0
- package/skills/omni-digest/src/domain-staging.ts +50 -0
- package/skills/omni-digest/src/env.ts +38 -0
- package/skills/omni-digest/src/fetch.ts +237 -0
- package/skills/omni-digest/src/media.ts +180 -0
- package/skills/omni-digest/src/obsidian.ts +69 -0
- package/skills/omni-digest/src/ocr.ts +149 -0
- package/skills/omni-digest/src/router.ts +60 -0
- package/skills/omni-digest/src/summarize.ts +87 -0
- package/skills/omni-digest/src/types.ts +124 -0
- package/skills/omni-digest/src/util.ts +34 -0
- package/skills/omni-digest/src/visual.ts +129 -0
- package/skills/omni-digest/src/x-api.ts +151 -0
- package/skills/omni-digest/tsconfig.json +13 -0
- package/src/a2a/agent-card.ts +29 -0
- package/src/a2a/server.ts +173 -0
- package/src/acp/auto-persist.ts +3 -6
- package/src/acp/backend-registry.ts +6 -10
- package/src/acp/channel-browser-shell.ts +1 -535
- package/src/acp/client.ts +106 -36
- package/src/acp/fs-roots.ts +20 -4
- package/src/acp/obsidian-tags.ts +6 -3
- package/src/acp/server.ts +189 -32
- package/src/agent/pty-binding.ts +1 -1
- package/src/agent/spawn-embodied-agent-in-vw.ts +5 -336
- package/src/agent/subagent-callable.ts +39 -1
- package/src/agent-mission/browser-login.ts +241 -0
- package/src/agent-mission/capabilities-cli.ts +33 -0
- package/src/agent-mission/capability-matrix.ts +31 -0
- package/src/agent-mission/capability-readers.ts +79 -0
- package/src/agent-mission/capability-types.ts +15 -0
- package/src/agent-mission/claude-headless.ts +131 -0
- package/src/agent-mission/claude-subscription.ts +57 -0
- package/src/agent-mission/doc-guided-install.ts +185 -0
- package/src/agent-mission/driver.ts +821 -69
- package/src/agent-mission/env-profile.ts +68 -0
- package/src/agent-mission/handoff.ts +128 -0
- package/src/agent-mission/in-agent-plugin.ts +311 -0
- package/src/agent-mission/mission-cli.ts +19 -1
- package/src/agent-mission/parse.ts +9 -4
- package/src/agent-mission/pr-review-watch.ts +62 -13
- package/src/agent-mission/resource-ladder.ts +187 -0
- package/src/agent-mission/tool-install.ts +249 -0
- package/src/agent-mission/tool-ladder.ts +37 -0
- package/src/agent-room/room-builder.ts +6 -600
- package/src/agent-substrate/review-intent.ts +43 -1
- package/src/auth/scope.ts +8 -4
- package/src/auth/temp-tokens.ts +131 -0
- package/src/auto-research/obsidian-bridge.ts +2 -0
- package/src/autopilot/build/integrity-gate.ts +27 -4
- package/src/autopilot/build/isolated-instance.ts +2 -1
- package/src/autopilot/build/llm-conflict-merge.ts +27 -0
- package/src/autopilot/llm-control-brain.ts +54 -12
- package/src/autopilot/mission-engine.ts +15 -1
- package/src/autopilot/mission-notify.ts +4 -2
- package/src/autopilot/mission-origin.ts +5 -5
- package/src/autopilot/mission-phase-track.ts +52 -0
- package/src/autopilot/mission-tool.ts +1 -1
- package/src/autopilot/pty-control-loop.ts +94 -2
- package/src/autopilot/track-agent.ts +138 -0
- package/src/autopilot/track-courier.ts +153 -0
- package/src/boot/acp-server.ts +16 -2
- package/src/boot/check-same-origin.ts +19 -5
- package/src/boot/daemon-multi-llm-runtime.ts +14 -8
- package/src/boot/daemon-prompt-turn.ts +2 -0
- package/src/boot/daemon-runtime.ts +36 -14
- package/src/boot/daemon-tools/index.ts +16 -0
- package/src/boot/daemon-tools/self-implement.ts +4 -0
- package/src/boot/daemon-tools/types.ts +3 -0
- package/src/browser-cdp/chrome-flags.ts +7 -0
- package/src/browser-cdp/client.ts +2 -0
- package/src/browser-pane/mount.ts +1 -246
- package/src/budget/codex-reset-credit-state.ts +15 -0
- package/src/budget/fetchers/codex.ts +2 -1
- package/src/budget/run-usage-rollup.ts +11 -4
- package/src/budget/unified-usage.ts +2 -1
- package/src/capture/tui-self-report.ts +10 -0
- package/src/channel-bot-token.ts +126 -0
- package/src/chat/index.ts +21 -45
- package/src/chat/input-text-key.ts +2 -2
- package/src/chat/mode/manual.ts +2 -4
- package/src/chat/pickers/state.ts +10 -27
- package/src/chat/search/modal.ts +14 -2
- package/src/chat/tool-render/types.ts +1 -1
- package/src/chat/turn-typeahead.ts +2 -1
- package/src/chat/wrap.ts +6 -8
- package/src/cli/__fixtures__/agent-help-before/agent.txt +18 -0
- package/src/cli/__fixtures__/agent-help-before/registry.txt +13 -0
- package/src/cli/__fixtures__/agent-help-before/root.txt +100 -0
- package/src/cli/__fixtures__/agent-help-before/tier.txt +15 -0
- package/src/cli/a2a-cli.ts +52 -0
- package/src/cli/agent-cli.ts +721 -0
- package/src/cli/autopilot-cli.ts +739 -0
- package/src/cli/bg-launch.ts +20 -4
- package/src/cli/claude-plugin-setup.ts +199 -0
- package/src/cli/config-test-sync.ts +94 -10
- package/src/cli/connector-cli.ts +204 -0
- package/src/cli/control-cli.ts +220 -0
- package/src/cli/control-join-cli.ts +142 -0
- package/src/cli/docs-cli.ts +38 -0
- package/src/cli/doctor-cli.ts +225 -26
- package/src/cli/doctor-distro.ts +17 -1
- package/src/cli/doctor-fix.ts +145 -17
- package/src/cli/doctor-llm-assist.ts +71 -0
- package/src/cli/doctor-private-files.ts +66 -0
- package/src/cli/doctor-readiness.ts +8 -5
- package/src/cli/fleet-cli.ts +63 -0
- package/src/cli/g6a-registration-probe.ts +16 -0
- package/src/cli/git-install-plan.ts +51 -0
- package/src/cli/hooks-cli.ts +44 -0
- package/src/cli/ingest-token-cli.ts +21 -0
- package/src/cli/intake-cli.ts +416 -0
- package/src/cli/labels-cli.ts +74 -0
- package/src/cli/leader-cli.ts +10 -159
- package/src/cli/live-cli.ts +48 -0
- package/src/cli/llm-detect-cli.ts +130 -0
- package/src/cli/logs-cli.ts +231 -7
- package/src/cli/machine-cli.ts +38 -0
- package/src/cli/mcp-call.ts +43 -13
- package/src/cli/mcp-gateway-cli.ts +90 -0
- package/src/cli/mcp-login.ts +116 -8
- package/src/cli/mcp-reload.ts +20 -3
- package/src/cli/nexus-dist.ts +18 -13
- package/src/cli/nexus-ios-bind.ts +20 -7
- package/src/cli/ops-cli.ts +225 -0
- package/src/cli/plugin-cli.ts +103 -0
- package/src/cli/pod-cli.ts +83 -0
- package/src/cli/port-lease-local.ts +124 -0
- package/src/cli/pr-cli.ts +12 -1
- package/src/cli/provider-cli.ts +720 -0
- package/src/cli/pty-record-cli.ts +63 -0
- package/src/cli/pty-takeover-cli.ts +57 -40
- package/src/cli/pty-web-address.ts +52 -0
- package/src/cli/publish-cli.ts +44 -0
- package/src/cli/pwa-build.ts +18 -12
- package/src/cli/pwa-dev.ts +13 -8
- package/src/cli/pwa-registry.ts +6 -0
- package/src/cli/pwa-share.ts +65 -22
- package/src/cli/pwa-show.ts +20 -4
- package/src/cli/pwa-start.ts +99 -27
- package/src/cli/pwa-test.ts +201 -96
- package/src/cli/release-cli.ts +90 -7
- package/src/cli/remotes-cli.ts +20 -1
- package/src/cli/remotes.ts +2 -1
- package/src/cli/repo-cli.ts +315 -36
- package/src/cli/research-cli.ts +66 -0
- package/src/cli/role-cli.ts +320 -0
- package/src/cli/schedule-cli.ts +246 -0
- package/src/cli/self-update.ts +98 -10
- package/src/cli/setup-cli.ts +64 -2
- package/src/cli/shadow-cli.ts +188 -0
- package/src/cli/share-auto-mount.ts +12 -8
- package/src/cli/start-cli.ts +221 -0
- package/src/cli/stdout-flush.ts +8 -0
- package/src/cli/storage-cli.ts +334 -0
- package/src/cli/tailscale-serve.ts +34 -19
- package/src/cli/tasks-cli.ts +176 -0
- package/src/cli/test-state-dir-flag.ts +1 -1
- package/src/cli/usage-cli.ts +15 -4
- package/src/cli/where-cli.ts +22 -55
- package/src/code-edit/diff-render.ts +6 -32
- package/src/code-edit/source-delta-browser.ts +0 -1
- package/src/codex/models.ts +1 -1
- package/src/config.ts +8 -13
- package/src/connectors/event-ledger.ts +41 -0
- package/src/connectors/linear-projector.ts +88 -0
- package/src/connectors/linear.ts +143 -0
- package/src/connectors/types.ts +19 -0
- package/src/control-plane/lease-holder.ts +41 -0
- package/src/control-plane/ledger.ts +146 -0
- package/src/control-plane/light-member.ts +164 -0
- package/src/control-plane/member-tokens.ts +88 -0
- package/src/control-plane/member.ts +159 -0
- package/src/control-plane/port-lease-heartbeat.ts +101 -0
- package/src/control-plane/ports.ts +40 -0
- package/src/control-plane/primary.ts +169 -0
- package/src/control-plane/server.ts +216 -0
- package/src/dashboard/acp-boot.ts +11 -38
- package/src/dashboard/assistant-render-state-runtime.ts +2 -2
- package/src/dashboard/assistant-sample-runtime.ts +2 -2
- package/src/dashboard/auto-compact-runtime.ts +11 -16
- package/src/dashboard/browser-help-runtime.ts +2 -3
- package/src/dashboard/chat/acp-chat.ts +2 -5
- package/src/dashboard/code-edit-post-turn-runtime.ts +1 -2
- package/src/dashboard/compact-surface-assembly.ts +0 -14
- package/src/dashboard/compact-surface-dispatch.ts +1 -38
- package/src/dashboard/compact-surface-inventory.ts +0 -8
- package/src/dashboard/compact-surface-runtime.ts +0 -14
- package/src/dashboard/context-menu-provider-boot.ts +0 -9
- package/src/dashboard/context-window-runtime-boot.ts +0 -37
- package/src/dashboard/index.ts +278 -2558
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +0 -6
- package/src/dashboard/input/chat-main-slash-command.ts +2 -2
- package/src/dashboard/input/dashboard-priority-key-route.ts +1 -43
- package/src/dashboard/input/mouse-modal-surface-runtime.ts +1 -5
- package/src/dashboard/input/mouse-wiring.ts +2 -3
- package/src/dashboard/layout-display-runtime-registration.ts +0 -10
- package/src/dashboard/modals/pane-multi.ts +1 -1
- package/src/dashboard/replay-preview.ts +1 -1
- package/src/dashboard/runtime/approvers.ts +0 -1
- package/src/dashboard/runtime/state-snapshot.ts +0 -90
- package/src/dashboard/scenario-runtime-boot.ts +16 -16
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +134 -1456
- package/src/dashboard/slash-runtime/design-pick.ts +96 -0
- package/src/dashboard/slash-runtime/help-from-registry.ts +77 -0
- package/src/dashboard/surface-registry-wiring.ts +2 -15
- package/src/dashboard/turn-message-runtime.ts +0 -4
- package/src/dashboard/turn-preamble.ts +1 -1
- package/src/dashboard/turn-stream-formatter.ts +2 -2
- package/src/dashboard/turn-stream-runtime.ts +2 -2
- package/src/dashboard-pane-context-menu.ts +0 -14
- package/src/debug/log.ts +7 -0
- package/src/decide/boundary-shadow.ts +131 -0
- package/src/design/apply-direction.ts +209 -0
- package/src/design/css-root-tokens.ts +89 -0
- package/src/design/custom-system-create.ts +230 -0
- package/src/design/design-directions.ts +61 -41
- package/src/design/design-gate.ts +241 -0
- package/src/design/design-library.ts +57 -0
- package/src/design/design-previews.ts +138 -0
- package/src/design/design-systems.ts +61 -0
- package/src/design/lint-artifact-run.ts +46 -6
- package/src/design/lint-artifact.ts +5 -1
- package/src/design/open-design-client.ts +247 -0
- package/src/design/system-from-extract.ts +767 -0
- package/src/design/system-schema.ts +123 -0
- package/src/discord-slash-wire.ts +2 -1
- package/src/discord-test-runner.ts +2 -1
- package/src/discord-voice-wire.ts +2 -1
- package/src/discord.ts +1 -1
- package/src/dispatch/opportunistic-launcher.ts +24 -1
- package/src/domains/ops-status.ts +35 -2
- package/src/domains/outbound-alert.ts +16 -4
- package/src/domains/repeated-failure.ts +89 -0
- package/src/domains/schedule-manage-tool.ts +28 -8
- package/src/domains/schedule-migrate.ts +22 -4
- package/src/domains/schedule-registry.ts +88 -33
- package/src/domains/schedule-runs.ts +132 -0
- package/src/domains/schedule-state.ts +152 -0
- package/src/element-registry/address.ts +1 -3
- package/src/git-fs/gh-cli.ts +47 -17
- package/src/git-fs/retry.ts +1 -0
- package/src/git-fs/runner.ts +1 -0
- package/src/git-fs/worktree.ts +6 -5
- package/src/github/pr-labels.ts +68 -0
- package/src/graph-kinds/plugin-nodes.ts +60 -0
- package/src/graph-kinds/registry.ts +118 -0
- package/src/graph-runner/graph-cli.ts +103 -0
- package/src/graph-runner/graph-notify.ts +220 -0
- package/src/graph-runner/graph-tick.ts +119 -0
- package/src/graph-runner/release-manifest.ts +93 -0
- package/src/graph-runner/runner.ts +457 -0
- package/src/grok/credential.ts +158 -5
- package/src/grounding/ensure-grounding.ts +131 -0
- package/src/grounding/mirror-export.ts +89 -0
- package/src/grounding/mirror-manifest.ts +252 -0
- package/src/grounding/sources-cli.ts +209 -0
- package/src/grounding/sources.ts +333 -0
- package/src/grounding/token.ts +115 -0
- package/src/harness/harness-cli-command.ts +352 -19
- package/src/harness/harness-pod-dispatch.ts +110 -0
- package/src/harness/harness-stop.ts +131 -0
- package/src/harness/harness-substrate-default.ts +40 -0
- package/src/harness/harness-worktrees.ts +1 -1
- package/src/harness/harness-write-boundary.ts +2 -0
- package/src/harness/llm-decompose.ts +2 -1
- package/src/harness/self-send-decide.ts +224 -0
- package/src/harness/shell-relay.ts +5 -0
- package/src/hooks/providers.ts +77 -0
- package/src/hooks/queue.ts +73 -0
- package/src/hooks/receiver.ts +133 -0
- package/src/index.ts +666 -3406
- package/src/input-core/dispatcher.ts +1 -1
- package/src/input-core/drag-esc-interceptor.ts +1 -1
- package/src/instance/current.ts +5 -5
- package/src/instance/leader.ts +10 -326
- package/src/instance/nexus-run-refusal.ts +27 -92
- package/src/instance/project-local-exclude.ts +27 -0
- package/src/instance/resolve.ts +40 -175
- package/src/intake-plane/capture.ts +14 -1
- package/src/intake-plane/check.ts +34 -14
- package/src/intake-plane/collect-github.ts +258 -0
- package/src/intake-plane/collect-pod.ts +100 -0
- package/src/intake-plane/collect-telegram-saved.ts +86 -0
- package/src/intake-plane/digest.ts +102 -0
- package/src/intake-plane/enrich-plugins.ts +1 -1
- package/src/intake-plane/front-classifier.ts +56 -0
- package/src/intake-plane/front-route-classifier.ts +80 -0
- package/src/intake-plane/front-route-rules.ts +152 -0
- package/src/intake-plane/grounding-docs.ts +185 -0
- package/src/intake-plane/harness-target.ts +20 -0
- package/src/intake-plane/intake-to-tasks.ts +303 -0
- package/src/intake-plane/items.ts +247 -0
- package/src/intake-plane/link-ledger.ts +27 -0
- package/src/intake-plane/route.ts +104 -0
- package/src/intake-plane/runtime-callables.ts +3 -1
- package/src/intake-plane/sketch-ledger.ts +34 -0
- package/src/intake-plane/slash.ts +30 -2
- package/src/intake-plane/submit-intake-work.ts +160 -0
- package/src/intake-plane/telegram-work.ts +56 -0
- package/src/iul/sidebar-shell.ts +0 -165
- package/src/launch-head/capability-check.ts +162 -0
- package/src/launch-head/launch-head-cli.ts +242 -0
- package/src/launch-head/load-balance.ts +81 -0
- package/src/live/detail-switch.ts +175 -0
- package/src/llm/provider-detect.ts +247 -0
- package/src/llm/provider-probe.ts +57 -0
- package/src/llm.ts +55 -23
- package/src/log-entry.ts +1 -1
- package/src/log-pane/attachment-popup.ts +1 -2
- package/src/loops/loop-cli.ts +37 -0
- package/src/loops/registry.ts +174 -0
- package/src/market/official-keys.ts +5 -0
- package/src/market/publish.ts +273 -0
- package/src/market/signed-index.ts +156 -0
- package/src/market/tgz.ts +121 -0
- package/src/mcp/client.ts +1 -1
- package/src/mcp/mcp-oauth.ts +40 -5
- package/src/mcp/server.ts +75 -7
- package/src/mcp-gateway/gateway.ts +128 -0
- package/src/mcp-gateway/pat-store.ts +124 -0
- package/src/mss/logging/log-store.ts +91 -2
- package/src/mss/logging/scoped-level.ts +5 -9
- package/src/native-tool-catalog.ts +64 -343
- package/src/nexus/api/connect-info.ts +23 -25
- package/src/nexus/api/context-url.ts +1 -1
- package/src/nexus/api/design-check.ts +90 -59
- package/src/nexus/api/design-previews-route.ts +182 -0
- package/src/nexus/api/design-system-create-route.ts +123 -0
- package/src/nexus/api/graph-kinds.ts +69 -0
- package/src/nexus/api/graphs-api.ts +221 -0
- package/src/nexus/api/harness-api.ts +31 -2
- package/src/nexus/api/health.ts +15 -0
- package/src/nexus/api/http-server.ts +274 -43
- package/src/nexus/api/image-generate.ts +3 -0
- package/src/nexus/api/ingest-token.ts +175 -0
- package/src/nexus/api/intake-ledger-api.ts +54 -0
- package/src/nexus/api/intake-route.ts +111 -0
- package/src/nexus/api/json-response.ts +33 -0
- package/src/nexus/api/live-detail.ts +47 -0
- package/src/nexus/api/live-shipped.ts +78 -0
- package/src/nexus/api/log-fabric.ts +33 -2
- package/src/nexus/api/markdown-publish.ts +3 -2
- package/src/nexus/api/mcp-http.ts +14 -9
- package/src/nexus/api/mcp-oauth-hint.ts +30 -0
- package/src/nexus/api/mcp-public-allowlist.ts +33 -0
- package/src/nexus/api/merge-approvals-gate.ts +79 -0
- package/src/nexus/api/merge-approvals.ts +306 -0
- package/src/nexus/api/meta-api.ts +4 -0
- package/src/nexus/api/next-fluent-wiring.ts +7 -9
- package/src/nexus/api/plugins-market.ts +125 -0
- package/src/nexus/api/pod-credential-api.ts +133 -0
- package/src/nexus/api/public-routes.ts +80 -0
- package/src/nexus/api/rest-route-paths.ts +15 -0
- package/src/nexus/api/schedules-action.ts +12 -3
- package/src/nexus/api/schedules-read.ts +228 -0
- package/src/nexus/api/sessions-store.ts +8 -2
- package/src/nexus/api/setup-answer-priority.ts +130 -0
- package/src/nexus/api/setup-channel-bot.ts +56 -0
- package/src/nexus/api/setup-child-llm.ts +228 -0
- package/src/nexus/api/setup-obsidian-skills.ts +93 -0
- package/src/nexus/api/task-cards-api.ts +34 -0
- package/src/nexus/api/tasks-create.ts +136 -0
- package/src/nexus/api/telegram-trigger-bot.ts +3 -3
- package/src/nexus/api/terminals.ts +204 -18
- package/src/nexus/api/trace.ts +354 -0
- package/src/nexus/api/vault-api.ts +140 -7
- package/src/nexus/api/worktrees.ts +18 -2
- package/src/nexus/boot/register-mcp-clients.ts +38 -4
- package/src/nexus/daemon-endpoint.ts +85 -0
- package/src/nexus/default-port.ts +1 -0
- package/src/nexus/index.ts +329 -111
- package/src/nexus/onboarding/pwa-share-prompt.ts +31 -8
- package/src/nexus/onboarding/tailscale-probe.ts +9 -1
- package/src/nexus/setup-status.ts +58 -0
- package/src/nexus/supervisor/lock.ts +8 -0
- package/src/nexus/webterm/pty.ts +15 -0
- package/src/oauth/codex-account-rotation.ts +122 -16
- package/src/oauth/codex-account-store.ts +88 -19
- package/src/oauth/codex-quota-policy.ts +55 -0
- package/src/oauth/store.ts +28 -25
- package/src/obsidian/default-vault.ts +17 -0
- package/src/obsidian/vault-write-guard.ts +46 -0
- package/src/onboarding/help/llm.md +2 -2
- package/src/onboarding.ts +2 -2
- package/src/panes/alt-skip-predicate.ts +4 -3
- package/src/panes/external-terminal-pane.ts +3 -4
- package/src/panes/factory.ts +1 -18
- package/src/panes/index.ts +1 -5
- package/src/panes/pane-cycle.ts +1 -1
- package/src/panes/types.ts +1 -1
- package/src/platform/env-literal.ts +4 -0
- package/src/plugin-hooks/dispatcher.ts +10 -4
- package/src/plugins/core/host.ts +94 -4
- package/src/plugins/core/manifest.ts +104 -7
- package/src/plugins/install/market-fetch.ts +249 -0
- package/src/plugins/install/plugin-install.ts +387 -0
- package/src/policy/claude-subscription-guard.ts +25 -0
- package/src/preview/terminal.ts +24 -1
- package/src/preview-pane/mount.ts +1 -142
- package/src/prompt/references.ts +4 -51
- package/src/pty-shell/pty-control-ipc.ts +57 -3
- package/src/pty-shell/pty-mouse.ts +75 -0
- package/src/pty-shell/pty-recording.ts +108 -0
- package/src/pty-shell/registry.ts +53 -3
- package/src/python/resolve-python.ts +1 -1
- package/src/release-loop/manifest.ts +65 -0
- package/src/release-loop/release-note.ts +174 -0
- package/src/roles/lease-cas.ts +52 -0
- package/src/roles/machine-name.ts +48 -0
- package/src/roles/machine-profile.ts +65 -0
- package/src/roles/role-lease-read.ts +81 -0
- package/src/roles/role-lease.ts +63 -0
- package/src/roles/role-watch.ts +69 -0
- package/src/self-dev/ask-launch-flow.ts +39 -22
- package/src/self-dev/ask-launch-io.ts +1 -1
- package/src/self-dev/dev-cli.ts +250 -139
- package/src/self-dev/dev-pipeline.ts +80 -8
- package/src/self-dev/draft-sweep.ts +231 -0
- package/src/self-dev/draft-triage-rules.ts +42 -0
- package/src/self-dev/entrance-baseline.ts +156 -4
- package/src/self-dev/fabric-decompose-adapter.ts +10 -0
- package/src/self-dev/launch-preflight.ts +1 -1
- package/src/self-dev/orchestrate.ts +297 -20
- package/src/self-dev/repair-signals.ts +6 -0
- package/src/self-dev/run-store.ts +20 -5
- package/src/self-dev/run-supervisor.ts +43 -3
- package/src/self-implement/abandoned-classification.ts +15 -1
- package/src/self-implement/blocked-draft-policy.ts +6 -0
- package/src/self-implement/budget-gate.ts +236 -0
- package/src/self-implement/child-llm-preference.ts +84 -0
- package/src/self-implement/decision-events.ts +57 -0
- package/src/self-implement/decision-signal-press.ts +5 -2
- package/src/self-implement/dependency-change-gate.ts +90 -0
- package/src/self-implement/gate-baseline.ts +32 -1
- package/src/self-implement/gate-cli.ts +29 -7
- package/src/self-implement/gate-scope.ts +7 -1
- package/src/self-implement/goal-author-decompose.ts +22 -4
- package/src/self-implement/goal-author.ts +23 -2
- package/src/self-implement/goal-boundary.ts +65 -0
- package/src/self-implement/goal-clarification-escalation.ts +1 -0
- package/src/self-implement/goal-documents-dir.ts +6 -1
- package/src/self-implement/goal-execution-records.ts +58 -0
- package/src/self-implement/goal-run-store.ts +42 -24
- package/src/self-implement/graph-authority.ts +13 -28
- package/src/self-implement/graph-catalog.ts +48 -0
- package/src/self-implement/graph-run-contract.ts +127 -0
- package/src/self-implement/graph-templates.ts +14 -7
- package/src/self-implement/graph-yaml.ts +35 -6
- package/src/self-implement/harness-policy-gates.ts +42 -0
- package/src/self-implement/headless-elanous-driver.ts +30 -6
- package/src/self-implement/heal-triage.ts +229 -0
- package/src/self-implement/host-regate.ts +240 -0
- package/src/self-implement/non-git-consent.ts +23 -0
- package/src/self-implement/orchestrator.ts +481 -132
- package/src/self-implement/pipeline-shape.ts +1 -1
- package/src/self-implement/pr-evidence-artifact.ts +6 -19
- package/src/self-implement/prior-draft-findings.ts +128 -0
- package/src/self-implement/pwa-import-graph.ts +65 -0
- package/src/self-implement/repo-provision.ts +18 -21
- package/src/self-implement/report-origin.ts +39 -0
- package/src/self-implement/rework-policy.ts +21 -0
- package/src/self-implement/run-ledger-compact.ts +438 -0
- package/src/self-implement/run-ledger.ts +212 -29
- package/src/self-implement/run-report.ts +24 -0
- package/src/self-implement/run-status-mapping.ts +2 -0
- package/src/self-implement/running-runs.ts +112 -14
- package/src/self-implement/scoped-typecheck-config.ts +49 -0
- package/src/self-implement/seams.ts +203 -38
- package/src/self-implement/self-implement-cli.ts +17 -2
- package/src/self-implement/shadow-repo.ts +350 -0
- package/src/self-implement/supervision-vocabulary.ts +7 -0
- package/src/shell-runner/dispatch.ts +3 -0
- package/src/shell-runner/index.ts +0 -7
- package/src/skills/runner.ts +0 -69
- package/src/skills/tools/agent-room-slash.ts +2 -1
- package/src/skills/tools/agent-room.ts +8 -140
- package/src/skills/tools/agent.ts +5 -3
- package/src/skills/tools/context.ts +5 -140
- package/src/skills/tools/control.ts +4 -188
- package/src/skills/tools/dashboard-slash.ts +3 -11
- package/src/skills/tools/dashboard-state.ts +3 -5
- package/src/skills/tools/dev-harness.ts +3 -2
- package/src/skills/tools/omni-search.ts +29 -1
- package/src/skills/tools/shell.ts +11 -29
- package/src/skills/tools/spawn-coding-agent-headless.ts +6 -9
- package/src/ssh/ssh-picker-modal.ts +1 -1
- package/src/steward/directive.ts +99 -0
- package/src/steward/triage.ts +203 -0
- package/src/storage/cli-bin.ts +67 -0
- package/src/storage/object-store-visibility.ts +169 -0
- package/src/storage/object-store.ts +452 -0
- package/src/storage/s3.ts +53 -10
- package/src/storage/storage-detect.ts +337 -0
- package/src/surface/address.ts +3 -5
- package/src/surface/index.ts +0 -6
- package/src/surface/llm-tools.ts +1 -2
- package/src/surface/shell-runner-boot.ts +4 -89
- package/src/task-cards/card-cli.ts +64 -0
- package/src/task-cards/card-store.ts +241 -0
- package/src/task-orchestrator/boot.ts +27 -1
- package/src/task-orchestrator/dispatcher.ts +49 -7
- package/src/task-orchestrator/external-fingerprint.ts +10 -0
- package/src/task-orchestrator/external-policy.ts +86 -0
- package/src/task-orchestrator/feedback-loop.ts +4 -2
- package/src/task-orchestrator/graph.ts +18 -1
- package/src/task-orchestrator/runtimes/create.ts +128 -0
- package/src/task-orchestrator/store.ts +78 -18
- package/src/task-orchestrator/surface-registry.ts +5 -2
- package/src/task-orchestrator/surfaces/external-exec.ts +180 -0
- package/src/task-orchestrator/surfaces/idea-approval-pr.ts +118 -0
- package/src/task-orchestrator/surfaces/index.ts +4 -3
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +60 -5
- package/src/task-orchestrator/surfaces/pod-artifact-return.ts +136 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +348 -0
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +177 -0
- package/src/task-orchestrator/surfaces/pod-pool.ts +128 -12
- package/src/task-orchestrator/surfaces/pod-skills.ts +11 -3
- package/src/task-orchestrator/surfaces/pod-source-bundle.ts +132 -0
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +91 -0
- package/src/task-orchestrator/surfaces/pod-source-spec.ts +77 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +782 -41
- package/src/task-orchestrator/surfaces/self-implement.ts +8 -1
- package/src/task-orchestrator/tox-loop.ts +204 -0
- package/src/task-orchestrator/types.ts +21 -1
- package/src/telegram-commands.ts +8 -0
- package/src/telegram-report.ts +2 -1
- package/src/telegram-run.ts +18 -5
- package/src/telegram.ts +92 -22
- package/src/tool-runtime/acp-session-runtime.ts +28 -7
- package/src/tool-runtime/agent-runtime.ts +1 -0
- package/src/tool-runtime/context-runtime.ts +18 -35
- package/src/tool-runtime/control-runtime.ts +8 -21
- package/src/tool-runtime/dashboard-state-runtime.ts +1 -5
- package/src/tool-runtime/elanous-asana-runtimes.ts +205 -0
- package/src/tool-runtime/elanous-control-runtimes.ts +16 -2
- package/src/tool-runtime/elanous-task-submit-runtime.ts +124 -0
- package/src/tool-runtime/index.ts +4 -1
- package/src/tool-runtime/scenario-runtimes.ts +22 -21
- package/src/tool-runtime/scenario-target-mount.ts +6 -32
- package/src/tool-runtime/types.ts +8 -0
- package/src/tui/chat/attachment-summary.ts +4 -4
- package/src/tui-client/headless-core-guard.ts +0 -1
- package/src/tui.ts +8 -5
- package/src/typecheck-ratchet.ts +15 -0
- package/src/ui/hover-presenter.ts +3 -7
- package/src/user-config.ts +427 -190
- package/src/version/code-revision.ts +33 -8
- package/src/version/packed-revision.json +1 -1
- package/src/video-pipeline/broll-agent.ts +102 -0
- package/src/video-pipeline/recipes/broll.ts +263 -0
- package/src/video-pipeline/walk-line.ts +2 -1
- package/src/views/scratch-image-size.ts +10 -0
- package/src/voice/channel-adapters/pwa-voice-adapter.ts +2 -18
- package/src/voice/channel-adapters/telegram-voice-adapter.ts +1 -6
- package/src/voice/voice-tts-singleton.ts +46 -8
- package/src/web-push/vapid-keys.ts +1 -1
- package/src/web-search/index.ts +5 -5
- package/src/web-terminal/preview-tap-registry.ts +152 -43
- package/src/workflow-runtime/executor.ts +18 -22
- package/src/workflow-runtime/node-catalog.ts +20 -1
- package/src/workflow-runtime/nodes/bash.ts +1 -0
- package/src/workflow-runtime/nodes/task.ts +74 -0
- package/src/workflow-runtime/nodes/triggers.ts +24 -1
- package/src/workflow-runtime/plugin-kind-node.ts +138 -0
- package/src/workflow-runtime/schema.ts +98 -2
- package/src/workflow-runtime/triggers/webhook-router.ts +43 -3
- package/src/workflow-runtime/triggers/webhook-source.ts +19 -1
- package/src/workflow-runtime/types.ts +74 -4
- package/apps/pwa/out/_next/static/Ksn99fVf2HUWhSyV1-FC8/_buildManifest.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1176-4943bd83b00e53a2.js +0 -25
- package/apps/pwa/out/_next/static/chunks/1380-9c652e1002032c86.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1863-2ea170dfec26b88b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2091-2d6b7f4f16300f83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2347-366617ec73babe3b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2598.814f64e3268634e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3089-e60cc8f5d35ee239.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3158-c77ed9ea34f9cc9f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3607-f0b5c5ee18fcf56a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3659-05b2d5d971b42dbc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3736-b6a7bfdcb8f56ec6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3839-eebf298e89a7bb77.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4012.832a2824b978e7ee.js +0 -5
- package/apps/pwa/out/_next/static/chunks/4706-d85d7f3345f3ff91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/526-17a6a2e0e6dc4498.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5508-676ac75f2757ad40.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5583-8a0317f4b8e68db9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5927.8378481a12cc8044.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6258-b58f722b10e8d31d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6820-32fd097e6186fdc9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6852-983db7ca958634b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7235-e583e4a015e159b9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7482-7b417330b24a996a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7701-99b7d4dedb955bf8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/77f1928d-bd3777589042d3ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8366-36956cafc5e33614.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8370-23d0de995be666f8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8617-307421f3b0e8b2a2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8837-e45de46a9fedf1f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9058-0e8055a5ea3ebdd6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-84b84eca12acada4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-1f23568c29e88f7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-bf6fc9aafd6135a7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-3f8539ae4b719d2e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-d2900febb74ecf32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-e82dec647dd79c36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/dashboard/page-096ec743a8ee955a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-255c2ceded4b3493.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-84b84eca12acada4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-2db61b2f9efba61f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-e11ee17f221aaa9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e075974e029ce4c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-ec5b68a9af3366a0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-986c177afb4adae6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-a72781461af2f2a3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-92781cbaafc487ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2c14d2a1f2930f33.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-22ee4bf8070b2b4d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-9c06e4a8297942a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d0cd32f6d373798f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-0c1642018d87ebb8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-93e5e97d614df487.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-84b84eca12acada4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-b1ce871940d7393e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-ae154addf345febe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-90af3aa813d2053c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f3f962fda428a738.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-1c1f7cc1d5def06d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-09d4cbdaaacf06c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e877b8e8ca90b27f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-71d902f463dea526.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-40ea576cefa25fe6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a56a3f178c3831f6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/bcc499d1-804a270d878e0842.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-b25b7c5501c59b6d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-a9ec9da43387afff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-aa2c05954aaa6754.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-bb3768fb4b84aebb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-2820ba75b87b2f5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-58c73b145f189b1c.js +0 -1
- package/apps/pwa/out/_next/static/css/effec8adf767aa75.css +0 -1
- package/apps/pwa/out/dashboard/index.html +0 -1
- package/apps/pwa/out/dashboard/index.txt +0 -26
- package/src/acp/resident-shell.ts +0 -244
- package/src/agent/spawn-local-llm-in-vw.ts +0 -240
- package/src/dashboard/agent-spawn-tools-boot.ts +0 -14
- package/src/dashboard/dock-picker-inventory.ts +0 -41
- package/src/dashboard/goal-plan-hud-bridge.ts +0 -112
- package/src/dashboard/hud-mirror.ts +0 -207
- package/src/dashboard/input/mouse-dock-runtime.ts +0 -156
- package/src/dashboard/input/mouse-hover-runtime.ts +0 -46
- package/src/dashboard/input/mouse-pill-context-runtime.ts +0 -74
- package/src/dashboard/input/mouse-workspace-restore-runtime.ts +0 -64
- package/src/dashboard/input/scratch-actions.ts +0 -36
- package/src/dashboard/input/virtual-window-key-router.ts +0 -24
- package/src/dashboard/rich-scratch-viewers.ts +0 -77
- package/src/dashboard/scratch-slash-runtime.ts +0 -36
- package/src/dashboard/scratch-state-runtime.ts +0 -42
- package/src/dashboard/scratch-widget-runtime.ts +0 -37
- package/src/dashboard/sim-shell.ts +0 -313
- package/src/dashboard/virtual-window-control-runtime.ts +0 -57
- package/src/dashboard/virtual-window-help-runtime.ts +0 -113
- package/src/dashboard/virtual-window-input-runtime.ts +0 -99
- package/src/dashboard/virtual-window-mutation-runtime.ts +0 -102
- package/src/dashboard/virtual-window-split-runtime.ts +0 -70
- package/src/dashboard/vw-popup-openers.ts +0 -126
- package/src/dashboard/window-picker-popup.ts +0 -74
- package/src/dashboard/window-slash-runtime.ts +0 -108
- package/src/dashboard/windowing/companion-slash.ts +0 -78
- package/src/dashboard/windowing/fast-switch.ts +0 -138
- package/src/dashboard/windowing/lifecycle.ts +0 -185
- package/src/dashboard/windowing/virtual-windows.ts +0 -259
- package/src/dashboard/windowing/visibility-chord.ts +0 -77
- package/src/iul/resident-vw.ts +0 -55
- package/src/panes/content-adapter.ts +0 -162
- package/src/prompt/vw-reference.ts +0 -153
- package/src/shell-runner/external-terminal-pane.ts +0 -157
- package/src/sim/resident-vw.ts +0 -48
- package/src/skills/tools/spawn-coding-agent-vw.ts +0 -181
- package/src/skills/tools/virtual-windows.ts +0 -632
- package/src/surface/adapters/window-surface-adapter.ts +0 -141
- package/src/tool-runtime/layout-runtimes.ts +0 -81
- package/src/tool-runtime/scenario-window-mount.ts +0 -207
- package/src/views/ui-mode.ts +0 -100
- package/src/virtual-window-context-menu.ts +0 -97
- package/src/virtual-windows/addressing.ts +0 -195
- package/src/virtual-windows/benchmark-preset.ts +0 -119
- package/src/virtual-windows/event-bus.ts +0 -202
- package/src/virtual-windows/layout/apply-planner.ts +0 -189
- package/src/virtual-windows/layout/index.ts +0 -68
- package/src/virtual-windows/layout/layout-commands.ts +0 -186
- package/src/virtual-windows/layout/layout-tools.ts +0 -262
- package/src/virtual-windows/layout/persistence.ts +0 -219
- package/src/virtual-windows/layout/presets.ts +0 -114
- package/src/virtual-windows/layout/restore-planner.ts +0 -223
- package/src/virtual-windows/layout/serializer.ts +0 -197
- package/src/virtual-windows/layout/tree.ts +0 -147
- package/src/virtual-windows/layout/types.ts +0 -63
- package/src/virtual-windows/layout-tree.ts +0 -389
- package/src/virtual-windows/navigation.ts +0 -251
- package/src/virtual-windows/pane-capture.ts +0 -142
- package/src/virtual-windows/pane-content.ts +0 -611
- package/src/virtual-windows/pane-spawner.ts +0 -278
- package/src/virtual-windows/pty-tail-content.ts +0 -291
- package/src/virtual-windows/resident-window.ts +0 -59
- package/src/virtual-windows/secondary-action.ts +0 -25
- package/src/virtual-windows/terminal-slot-content.ts +0 -165
- package/src/virtual-windows/virtual-window.ts +0 -1301
- package/src/virtual-windows/vw-local-input-target-popup.ts +0 -110
- package/src/virtual-windows/vw-rename-modal.ts +0 -77
- package/src/virtual-windows/vw-selector-popup.ts +0 -177
- package/src/virtual-windows/window-registry.ts +0 -519
- package/src/voice/channel-adapters/discord-voice-adapter.ts +0 -202
- package/src/voice/voice-pwa-dispatch.ts +0 -245
- package/src/window-picker-modal.ts +0 -135
- /package/apps/pwa/out/_next/static/{Ksn99fVf2HUWhSyV1-FC8 → zoQX5iTvXOsIvCjxCe1Ji}/_ssgManifest.js +0 -0
- /package/src/dashboard/{companion-slash-runtime.ts → companion-messages-runtime.ts} +0 -0
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
type PrEvidenceInput,
|
|
20
20
|
} from './pr-evidence-artifact.js';
|
|
21
21
|
import { assessImplementationArtifactCompleteness } from './implementation-artifact-completeness.js';
|
|
22
|
+
import { runContractAtNode, type RunContract } from './graph-run-contract.js';
|
|
22
23
|
export {
|
|
23
24
|
PR_EVIDENCE_AXES,
|
|
24
25
|
composePrEvidenceArtifact,
|
|
@@ -59,11 +60,15 @@ export function formatAutoMergeSuccessMessage(input: {
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
import { GoalRunStore, insertGoalRunRecord, type GoalPriorRuns } from './goal-run-store.js';
|
|
63
|
+
import { writeGoalRunRecordFragment } from './goal-execution-records.js';
|
|
64
|
+
import { getUserConfig } from '../user-config.js';
|
|
62
65
|
import { appendRunLedgerEntry, loadRunLedger, parseRunShardIdentity, queryRunChain, type RunChainShardSibling, type RunLedgerEntry, type RunLedgerWriter, type RunOriginData, type RunShardIdentity } from './run-ledger.js';
|
|
63
66
|
import { decideLineageSupersede, lineageSupersedeCloseComment, type LineageSupersedeOpenDraft } from './lineage-supersede.js';
|
|
64
67
|
import { basename, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
65
68
|
import { enqueueControlMemo, readSoftStopRequestStatus, type SoftStopRequestRead } from '../harness/control-inbox.js';
|
|
66
69
|
import { debug } from '../debug/log.js';
|
|
70
|
+
import { emitDecision } from '../live/detail-switch.js';
|
|
71
|
+
import { reworkDecision } from './decision-events.js';
|
|
67
72
|
import type { LogSink } from '../mss/logging/sink.js';
|
|
68
73
|
import type { LogQuery, LogStoreRow } from '../mss/logging/log-store.js';
|
|
69
74
|
import { refreshCodexQuotaSignals } from '../budget/codex-quota-refresh.js';
|
|
@@ -73,6 +78,7 @@ import { parseAskProseTitle } from '../self-dev/launch-preflight.js';
|
|
|
73
78
|
import { classifyReviewProviderFailure } from '../self-dev/review-provider-fallback.js';
|
|
74
79
|
import { classifyError } from '../session-runtime/retry-policy.js';
|
|
75
80
|
import { decomposeSelfDevGoal, inferHotPaths, type SelfDevDecomposeOptions } from '../self-dev/decompose.js';
|
|
81
|
+
import { boundaryGlobs, boundaryViolations } from './goal-boundary.js';
|
|
76
82
|
import { targetScopedGoalText } from './goal-text-path-scope.js';
|
|
77
83
|
import type { SelfDevGoalType } from '../self-dev/orchestrate.js';
|
|
78
84
|
import { DEFAULT_BRANCH_WORKTREE_BASE, gateGitResidue, observeGitResidue } from '../git-fs/worktree.js';
|
|
@@ -86,11 +92,12 @@ import { originObservationFields } from '../agent/origin-observation.js';
|
|
|
86
92
|
import { getHarnessSpace, normalizeSpaceId, resolveRunIdentity } from '../harness/harness-space.js';
|
|
87
93
|
import { getElanousConfigDir } from '../elanous-config-dir.js';
|
|
88
94
|
import { elanousStateRoot } from '../autopilot/state-paths.js';
|
|
95
|
+
import { harnessReleaseNote, releaseNotesDir, renderReleaseNoteSection, writeReleaseNote, type ReleaseNoteFragment } from '../release-loop/release-note.js';
|
|
89
96
|
import { plannedSelfImplBranch } from '../harness/worktree-branch-prefix.js';
|
|
90
97
|
export { slugifyFeature } from '../harness/worktree-branch-prefix.js';
|
|
91
98
|
import { resolveAutoReviewLabels } from './context-capsule.js';
|
|
92
99
|
import { GOAL_TYPES, extractVerbatimOriginalAsk, leadingGoalMetadata, parseAskFile, parseGoalType, type GoalType } from './goal-author.js';
|
|
93
|
-
import { resolveAdaptiveMaxReworkDecision, resolveEscalateTier, resolveEscalateTarget, buildReworkFeature, failIndicator, appendReworkHistory, truncateReworkHistoryByItem, applyReworkBudgetDecision, parseContractConflictRelaxation, parseReworkBudgetDecision, resolveReworkBudgetCarry, stripReworkBudgetHeaders, countConsecutiveMustFixIds, mergeReworkNotes, resolveReworkKind, type ReworkPlanRevision, type ReworkNotePart } from './rework-policy.js';
|
|
100
|
+
import { resolveAdaptiveMaxReworkDecision, resolveEscalateTier, resolveEscalateTarget, buildReworkFeature, failIndicator, isRepeatedUnverifiedOnlyGateFailure, unverifiedRepeatKey, appendReworkHistory, truncateReworkHistoryByItem, applyReworkBudgetDecision, parseContractConflictRelaxation, parseReworkBudgetDecision, resolveReworkBudgetCarry, stripReworkBudgetHeaders, countConsecutiveMustFixIds, mergeReworkNotes, resolveReworkKind, type ReworkPlanRevision, type ReworkNotePart } from './rework-policy.js';
|
|
94
101
|
import type { SupervisionReworkSource } from './supervision-vocabulary.js';
|
|
95
102
|
import { classifyReworkBudgetShadow } from './classify-shadow.js';
|
|
96
103
|
import { createReworkBudgetJudgment, REWORK_BUDGET_JUDGMENT, reworkBudgetEvidenceForObservation, reworkBudgetWorkflow } from './rework-budget-judgment.js';
|
|
@@ -169,12 +176,15 @@ import type { RunOutcome, ReworkBudgetVerdict } from './run-outcome.js';
|
|
|
169
176
|
import type { EscalateTier } from './rework-policy.js';
|
|
170
177
|
import type { ClassifyShadowCallLLM } from './classify-shadow.js';
|
|
171
178
|
import { hasModuleLoadFailure, type GateTestFailure } from './gate-baseline.js';
|
|
172
|
-
import { defaultBranchRef } from './seams.js';
|
|
179
|
+
import { commitWorktree, defaultBranchRef } from './seams.js';
|
|
180
|
+
import { blockedDraftDisposition } from './blocked-draft-policy.js';
|
|
173
181
|
import { formatLlmMergeOutcome } from '../autopilot/build/llm-conflict-merge.js';
|
|
174
182
|
import { FOUND_CITED_PATH_REFUTATION_QUOTE, MISSING_CITED_PATH_REFUTATION_QUOTE, MUST_FIX_REFUTATION_ACKNOWLEDGEMENT_WITH_REASON, REFUTATION_QUOTE_GRAMMAR, observeMustFixCitedPaths, parseMustFixRefutationAcknowledgement, parseMustFixRefutations, renderMustFixCitedPathFacts, snapshotMustFixFindings, stableMustFixId, type ReflectEvidenceFacts, type ReflectGateFacts, type MustFixCitedPathFact, type MustFixFinding, type MustFixRecurrenceHistory, type MustFixRefutation, type MustFixRefutationKind } from './reflect-mustfix.js';
|
|
175
183
|
import type { IngestionEntry } from '../agent-substrate/execution/ingestion-policy.js';
|
|
176
184
|
import { buildReviewIntent } from '../agent-substrate/review-intent.js';
|
|
185
|
+
import { collectPriorDraftFindings, goalTitleFromTargetGoalFile } from './prior-draft-findings.js';
|
|
177
186
|
import { resolveDesignCheck, type DesignCheckOutcome } from '../design/design-check.js';
|
|
187
|
+
import { runDesignGate, type DesignGateResult } from '../design/design-gate.js';
|
|
178
188
|
import type { ReviewerContextBudget } from '../agent-substrate/pr-reviewer.js';
|
|
179
189
|
import { persistReviewArtifact, type ReviewArtifactWriter } from '../agent-substrate/review-artifact.js';
|
|
180
190
|
import { createArtifactStore } from '../artifact/index.js';
|
|
@@ -429,21 +439,30 @@ export function decideGateFailureDisposition(facts: {
|
|
|
429
439
|
return 'rework';
|
|
430
440
|
}
|
|
431
441
|
|
|
442
|
+
function postSyncTimeoutOnly(facts: { introduced?: number; unknown?: number; timedOut?: number; flakyRerun?: number; childResponsibility?: string } | undefined): boolean {
|
|
443
|
+
// Post-sync attribution may omit childResponsibility; zero introduced/unknown with only
|
|
444
|
+
// timeout evidence is sufficient here, without weakening the main-loop predicate.
|
|
445
|
+
return (facts?.childResponsibility === undefined || facts.childResponsibility === 'none')
|
|
446
|
+
&& isTimeoutOnlyUnmeasuredGate(facts && { ...facts, childResponsibility: 'none' });
|
|
447
|
+
}
|
|
448
|
+
|
|
432
449
|
function postSyncGatePolicy(
|
|
433
450
|
passed: boolean,
|
|
434
|
-
|
|
451
|
+
facts: { introduced?: number; unknown?: number; timedOut?: number; flakyRerun?: number; childResponsibility?: string } | undefined,
|
|
435
452
|
syncStatus: PostSyncStatus,
|
|
436
453
|
): PostSyncGatePolicy {
|
|
437
|
-
const
|
|
438
|
-
|
|
454
|
+
const timeoutOnly = !passed && postSyncTimeoutOnly(facts);
|
|
455
|
+
const introduced = (facts?.introduced ?? 0) > 0;
|
|
456
|
+
const childResponsibility = facts?.childResponsibility;
|
|
457
|
+
const exemptionWithheld = !timeoutOnly && !passed
|
|
458
|
+
&& !introduced && childResponsibility === 'none'
|
|
439
459
|
&& syncStatus === 'llm-resolved';
|
|
440
460
|
const exempted = !passed
|
|
441
|
-
&& childResponsibility === 'none'
|
|
442
|
-
&& syncStatus === 'merged';
|
|
461
|
+
&& (timeoutOnly || (!introduced && childResponsibility === 'none' && syncStatus === 'merged'));
|
|
443
462
|
return {
|
|
444
463
|
exempted,
|
|
445
464
|
exemptionWithheld,
|
|
446
|
-
mustStop: !passed && (childResponsibility !== 'none' || exemptionWithheld),
|
|
465
|
+
mustStop: !passed && !timeoutOnly && (introduced || childResponsibility !== 'none' || exemptionWithheld),
|
|
447
466
|
};
|
|
448
467
|
}
|
|
449
468
|
|
|
@@ -455,7 +474,7 @@ export function postSyncGateObservation(
|
|
|
455
474
|
testStepExecuted?: boolean;
|
|
456
475
|
measuredFileCount?: number;
|
|
457
476
|
comparisonBase?: string | null;
|
|
458
|
-
reflectGateFacts?: { introduced: number; preexisting: number; unknown: number; timedOut?: number; childResponsibility?: string };
|
|
477
|
+
reflectGateFacts?: { introduced: number; preexisting: number; unknown: number; timedOut?: number; flakyRerun?: number; childResponsibility?: string };
|
|
459
478
|
},
|
|
460
479
|
branch: string,
|
|
461
480
|
detectModuleLoadFailure: (output: string) => boolean,
|
|
@@ -464,7 +483,7 @@ export function postSyncGateObservation(
|
|
|
464
483
|
const facts = regate.reflectGateFacts;
|
|
465
484
|
const { exempted, exemptionWithheld } = postSyncGatePolicy(
|
|
466
485
|
regate.passed,
|
|
467
|
-
facts
|
|
486
|
+
facts,
|
|
468
487
|
syncStatus,
|
|
469
488
|
);
|
|
470
489
|
return {
|
|
@@ -590,6 +609,7 @@ export interface ReviewDiffContext {
|
|
|
590
609
|
goalDocumentPath?: string;
|
|
591
610
|
round?: number;
|
|
592
611
|
appliedLastRound?: readonly string[];
|
|
612
|
+
priorRunFindings?: import('./prior-draft-findings.js').PriorDraftFinding[];
|
|
593
613
|
/** Existing run-chain projection of sibling shards; absent means no sibling runs were observed. */
|
|
594
614
|
shardSiblings?: {
|
|
595
615
|
items: readonly RunChainShardSibling[];
|
|
@@ -622,6 +642,8 @@ export interface ReviewDiffContext {
|
|
|
622
642
|
};
|
|
623
643
|
/** Read-only comparison of the worktree DESIGN.md declaration and installed craft rulebooks. */
|
|
624
644
|
designCheck?: DesignCheckOutcome;
|
|
645
|
+
/** Deterministic design-token result supplied to review, never the implementation gate. */
|
|
646
|
+
designGate?: DesignGateResult | { unmeasured: string };
|
|
625
647
|
}
|
|
626
648
|
|
|
627
649
|
/** 런 사실(커밋 제목·변경 파일)을 fail-soft 로 걷어 온다. seam(git) 이 실패하면 그 종류를 생략하고,
|
|
@@ -789,6 +811,13 @@ function observeDeclaredScopeDiff(
|
|
|
789
811
|
// ⭐ 관측은 «언제나» 남기고, ***사람 줄은 「하나도 안 만들었을 때만»*** 낸다.
|
|
790
812
|
const line = declaredScopeUnmadeLine(diff);
|
|
791
813
|
if (line !== null) input.progress?.('declared-targets-unmade', line);
|
|
814
|
+
// ⭐ 그 옆 — `경계:` 글로브에 닿은 변경. 못 읽었거나 변경 목록이 없으면 조용하다.
|
|
815
|
+
if (goalDocument !== null && input.changedFiles !== undefined) {
|
|
816
|
+
const violations = boundaryViolations(boundaryGlobs(goalDocument), input.changedFiles);
|
|
817
|
+
if (violations.length > 0) {
|
|
818
|
+
input.progress?.('boundary-violated', `⚠️ 경계로 선언한 경로를 고쳤다 — ${violations.join(' · ')}`);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
792
821
|
}
|
|
793
822
|
|
|
794
823
|
/**
|
|
@@ -946,10 +975,14 @@ export interface SelfImplementSeams {
|
|
|
946
975
|
* `buildReviewIntent` 가 `goal` 하나로 직접 추출한다(`extractIntentBlocks` · 결정론 · LLM 0).
|
|
947
976
|
* ⇒ 같은 값을 두 경로로 나르면 갈라진다. 골을 SSOT 로 둔다. */
|
|
948
977
|
reviewDiff?: (cwd: string, ctx?: ReviewDiffContext) => Promise<SelfImplementReview>;
|
|
978
|
+
/** Read-only prior-draft reviewer findings; tests inject the lookup to avoid network access. */
|
|
979
|
+
collectPriorDraftFindings?: typeof collectPriorDraftFindings;
|
|
949
980
|
/** Existing run-chain query projection. The orchestrator only selects the current entry's producer-computed siblings. */
|
|
950
981
|
queryRunChain?: () => { entries: readonly { runId: string; prNumber?: number | null; merged?: boolean; shardSiblings: readonly RunChainShardSibling[] }[] };
|
|
951
982
|
/** Computes the worktree's design declaration verdict for review context; informational only. */
|
|
952
983
|
resolveDesignCheck?: (worktreePath: string) => DesignCheckOutcome;
|
|
984
|
+
/** Read-only design-token check for HTML/CSS changes; exceptions remain review-visible. */
|
|
985
|
+
runDesignGate?: typeof runDesignGate;
|
|
953
986
|
/** 실행 원장 우선, 기존 base 브랜치 PR 코멘트 폴백으로 자동 반영 항목을 읽는다. 실패·부재는 빈 목록으로 수렴한다. */
|
|
954
987
|
findAppliedReviewItems?: (branch: string, goalId?: string) => Promise<{ basePrLocated: boolean; items: readonly string[]; headlineComments?: number; source?: 'ledger' | 'pr-comment' | 'unavailable' }>;
|
|
955
988
|
/** ★ 반사-기각 seam(RFC-selfdev-judgment-context-substrate Facet C) — must-fix 재주입 前 각 항목을
|
|
@@ -962,6 +995,8 @@ export interface SelfImplementSeams {
|
|
|
962
995
|
/** PR을 열기 전에 보존할 산출물이 있는지 판별한다. `base` 대비 branch 고유 변경과 미커밋 변경을 함께 본다.
|
|
963
996
|
* 생략 시 기존 주입 seam 호환을 위해 산출물이 있다고 본다. */
|
|
964
997
|
preservationHasChanges?: (ctx: { cwd: string; base?: string }) => boolean | Promise<boolean>;
|
|
998
|
+
/** Test seam for blocked environment branch persistence; return whether the branch was pushed. */
|
|
999
|
+
preserveBlockedBranch?: (ctx: { cwd: string; branch: string; title: string }) => boolean | Promise<boolean>;
|
|
965
1000
|
/** Hard-cap salvage evidence: a clean worktree and commits ahead of origin/main. */
|
|
966
1001
|
readReworkSalvageEvidence?: (cwd: string) => Promise<ReworkSalvageEvidence>;
|
|
967
1002
|
/** Starts exactly one detached `elanous dev --file <goal> --base <branch>` follow-up. */
|
|
@@ -978,7 +1013,7 @@ export interface SelfImplementSeams {
|
|
|
978
1013
|
readPrDiff?: (opts: { number: number; cwd: string; baseCommit: string; headCommit: string }) => Promise<string>;
|
|
979
1014
|
/** ★ ⑦ 병합 seam(2026-07-21·auto-merge) — 열린 PR 을 실제 병합(gh pr merge --squash). `matchHeadCommit`이 있으면
|
|
980
1015
|
* 검사한 고정 head 뒤 변경을 gh가 거부한다. autoMerge + 리뷰 clean 일 때만 호출(outward-facing·main 자율병합). */
|
|
981
|
-
mergePr?: (opts: { number: number; cwd: string; matchHeadCommit?: string }) => Promise<{ merged: boolean; baseRefName?: string; detail?: string }>;
|
|
1016
|
+
mergePr?: (opts: { number: number; cwd: string; matchHeadCommit?: string }) => Promise<{ merged: boolean; baseRefName?: string; mergeCommit?: string; detail?: string }>;
|
|
982
1017
|
/** Post-merge cleanup is opt-in and injectable so tests never touch the filesystem. */
|
|
983
1018
|
postMergeCleanup?: {
|
|
984
1019
|
enabled: boolean;
|
|
@@ -1052,6 +1087,8 @@ export const SELF_IMPLEMENT_PROGRESS_STAGES = [
|
|
|
1052
1087
|
// ⛔ 기존 단계 이름을 «빌려 쓰지 않는다» — `progress()` 는 단계 이름으로 원장 행을 만들므로
|
|
1053
1088
|
// 빌려 쓰면 그 단계 집계가 오염된다([T] 2026-09-12 · `#17767` 이후 계약).
|
|
1054
1089
|
'declared-targets-unmade',
|
|
1090
|
+
// ⭐ `경계:` 글로브에 실제로 닿은 변경. 막지 않고 이름만 낸다.
|
|
1091
|
+
'boundary-violated',
|
|
1055
1092
|
] as const;
|
|
1056
1093
|
|
|
1057
1094
|
export type SelfImplementProgressStage = typeof SELF_IMPLEMENT_PROGRESS_STAGES[number];
|
|
@@ -1821,7 +1858,6 @@ export type GoalRunRecordWriter = (goalFile: string, record: GoalExecutionRecord
|
|
|
1821
1858
|
|
|
1822
1859
|
export function appendGoalExecutionRecord(goalFile: string, record: GoalExecutionRecord): void {
|
|
1823
1860
|
const existing = readFileSync(goalFile, 'utf8');
|
|
1824
|
-
if (existing.includes(`- runId: ${record.runId}\n`)) return;
|
|
1825
1861
|
const entry = [
|
|
1826
1862
|
'## 실행 기록',
|
|
1827
1863
|
`- runId: ${record.runId}`,
|
|
@@ -1890,6 +1926,14 @@ export function appendGoalExecutionRecord(goalFile: string, record: GoalExecutio
|
|
|
1890
1926
|
: []),
|
|
1891
1927
|
'',
|
|
1892
1928
|
].join('\n');
|
|
1929
|
+
const goalId = existing.match(/^- GoalId: ([0-9a-f]{16})$/m)?.[1];
|
|
1930
|
+
if (goalId) {
|
|
1931
|
+
const path = writeGoalRunRecordFragment(goalId, record.runId, entry);
|
|
1932
|
+
logRunAwareFailSoft(record.runId, 'goal-record-fragment-written', { goalId, path });
|
|
1933
|
+
}
|
|
1934
|
+
// Legacy documents without GoalId have no fragment key; retain the append so the run is not lost.
|
|
1935
|
+
if (goalId && getUserConfig().tools.selfImplement.goalRecordInDoc === false) return;
|
|
1936
|
+
if (existing.includes(`- runId: ${record.runId}\n`)) return;
|
|
1893
1937
|
appendFileSync(goalFile, `${existing.endsWith('\n') ? '' : '\n'}${entry}`);
|
|
1894
1938
|
}
|
|
1895
1939
|
|
|
@@ -1899,13 +1943,6 @@ export interface SelfImplementOptions {
|
|
|
1899
1943
|
* ⇒ 런 슈퍼바이저는 「시도의 요약 판정」만 보고 「어떻게 걸었나」를 «못 봤다».
|
|
1900
1944
|
* ⛔ 관측용이다 — 흐름을 바꾸지 않는다. ⛔ 던져도 런이 안 죽는다(호출부가 감싼다). */
|
|
1901
1945
|
onNodeEntry?: (node: PipelineNodeId, round: number) => void;
|
|
1902
|
-
/** ⛔⭐ 실험 — 그래프 선언을 «실행 권위»로 올린다(RFC §5 1단계). config 를 «이긴다».
|
|
1903
|
-
*
|
|
1904
|
-
* 📌 이 칸이 있는 이유가 둘이다:
|
|
1905
|
-
* ⓐ 「건너뛰는 쪽」을 시험에서 «누를 수» 있어야 한다 — 없으면 그 갈래는 실물로만 확인된다.
|
|
1906
|
-
* ⓑ `resolveGraphAuthority` 의 `source: 'flag'` 가 «아무도 안 쓰는» 퇴화 축이었다
|
|
1907
|
-
* (같은 날 `goalTypeSource` 가 같은 병을 앓았다 — 값이 언제나 하나면 그 축은 아무것도 안 가른다). */
|
|
1908
|
-
graphAuthoritative?: boolean;
|
|
1909
1946
|
/** 시험이 런치 오버레이를 빼 «지금 YAML 예산»을 읽게 할 때 쓴다. 생략하면 디스크 오버레이다. */
|
|
1910
1947
|
graphOverlays?: readonly GraphOverlaySpec[];
|
|
1911
1948
|
/** ★ K run-identity — 이 self-implement 호출의 per-run join anchor. 미지정 시 상속(env)→canonical mint.
|
|
@@ -1985,6 +2022,8 @@ export interface SelfImplementOptions {
|
|
|
1985
2022
|
* outward-facing(main 병합)이라 명시 opt-in 만. mergePr seam 이 있어야 실제 병합(없으면 non-draft PR 까지).
|
|
1986
2023
|
* completion이 없던 기존 호출자의 호환 입력으로 유지한다. */
|
|
1987
2024
|
autoMerge?: boolean;
|
|
2025
|
+
/** Pod-only: stop after passing the same merge guards, leaving the ready PR for host regate. */
|
|
2026
|
+
mergeByHost?: boolean;
|
|
1988
2027
|
/** ★ G8 자기판단(2026-07-23·[[ROADMAP-elanous-is-all-pty-unified-autonomy-2026-07-21]] §2b) — PR 을 열 때
|
|
1989
2028
|
* `auto-review` opt-in 라벨을 붙일지. **2단 게이트**: 이 플래그(사람 옵트인) AND assessAutonomyEligibility
|
|
1990
2029
|
* (작업 위험도 자기판단·fail-safe) 통과여야 부착. 부적합(외부배포·실주문·설계분기·파괴·보안·리뷰 must-fix)이면
|
|
@@ -2096,6 +2135,8 @@ export interface SelfImplementResult {
|
|
|
2096
2135
|
supervisorWantedContinue?: true;
|
|
2097
2136
|
/** Additive hard-cap disposition; outcome remains the stable public terminal contract. */
|
|
2098
2137
|
salvage?: 'launched' | 'parked';
|
|
2138
|
+
/** Rework stopped on exclusively baseline/flaky/precondition failures; do not retry this goal against the same base. */
|
|
2139
|
+
terminationReason?: 'blocked-by-baseline';
|
|
2099
2140
|
sessionId?: string;
|
|
2100
2141
|
worktreePath?: string;
|
|
2101
2142
|
branch?: string;
|
|
@@ -2134,6 +2175,7 @@ export interface SelfImplementResult {
|
|
|
2134
2175
|
mergeReason?: string;
|
|
2135
2176
|
prUrl?: string;
|
|
2136
2177
|
prNumber?: number;
|
|
2178
|
+
checkedHeadCommit?: string;
|
|
2137
2179
|
detail?: string;
|
|
2138
2180
|
}
|
|
2139
2181
|
|
|
@@ -2443,7 +2485,30 @@ function formatGoalFileForPrBody(goalFile: string, cwd = process.cwd()): string
|
|
|
2443
2485
|
return relative(canonicalRoot, canonicalGoal).split(sep).join('/');
|
|
2444
2486
|
}
|
|
2445
2487
|
|
|
2446
|
-
|
|
2488
|
+
export class MergedReleaseNoteWriteError extends Error {
|
|
2489
|
+
readonly prNumber: number;
|
|
2490
|
+
readonly prUrl: string;
|
|
2491
|
+
readonly directory: string;
|
|
2492
|
+
readonly fragment: ReleaseNoteFragment;
|
|
2493
|
+
|
|
2494
|
+
constructor(prUrl: string, directory: string, fragment: ReleaseNoteFragment, cause: unknown) {
|
|
2495
|
+
super(`PR #${fragment.pr} was merged, but its release note could not be written to ${directory}: ${safeErrorDescription(cause)}`, { cause });
|
|
2496
|
+
this.name = 'MergedReleaseNoteWriteError';
|
|
2497
|
+
this.prNumber = fragment.pr;
|
|
2498
|
+
this.prUrl = prUrl;
|
|
2499
|
+
this.directory = directory;
|
|
2500
|
+
this.fragment = fragment;
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
|
|
2504
|
+
function goalDocumentForReleaseNote(goalFile?: string): string {
|
|
2505
|
+
if (!goalFile) return '';
|
|
2506
|
+
try { return readFileSync(goalFile, 'utf8'); }
|
|
2507
|
+
catch { return ''; }
|
|
2508
|
+
}
|
|
2509
|
+
|
|
2510
|
+
function prBody(feature: string, implSummary: string, gateLog?: string, review?: SelfImplementReview, reviewIntent?: string, autoReviewDeclineReasons?: readonly string[], evidence?: string, goalFile?: string, planRevision?: ReworkPlanRevision, releaseNote?: ReturnType<typeof harnessReleaseNote>): string {
|
|
2511
|
+
const note = releaseNote ?? harnessReleaseNote(goalDocumentForReleaseNote(goalFile), prTitle(feature));
|
|
2447
2512
|
const relaxation = planRevision?.relaxation
|
|
2448
2513
|
? ['', '## 감독 수용 기준 완화', `- 대상: ${planRevision.relaxation.target}`, `- 이전: ${planRevision.relaxation.expected}`, `- 완화: ${planRevision.relaxation.replacement}`, `- 이유: ${planRevision.reason}`, `- 적용: ${planRevision.application?.status ?? 'failed'}${planRevision.application?.detail ? ` (${planRevision.application.detail})` : ''}`, ...(planRevision.disposition ? [`- 충돌 처분: ${planRevision.disposition}`] : [])]
|
|
2449
2514
|
: [];
|
|
@@ -2454,6 +2519,8 @@ function prBody(feature: string, implSummary: string, gateLog?: string, review?:
|
|
|
2454
2519
|
'',
|
|
2455
2520
|
'## 구현 요약',
|
|
2456
2521
|
implSummary.trim() || '(요약 없음)',
|
|
2522
|
+
'',
|
|
2523
|
+
renderReleaseNoteSection(note).trimEnd(),
|
|
2457
2524
|
// ★ I-9 — 성공 경로도 수확본을 싣는다. blocked 쪽만 실으면 **통과한 PR 에서 증거가 사라진다**.
|
|
2458
2525
|
...(evidence ? ['', '## 자식이 남긴 증거 (EVIDENCE/RESULT · 화면 전체에서 수확)', '```', evidence, '```'] : []),
|
|
2459
2526
|
...(reviewIntent ? ['', '## 리뷰 intent', reviewIntent] : []),
|
|
@@ -2972,11 +3039,11 @@ export function federationObservation(shardIdentity: RunShardIdentity): Record<s
|
|
|
2972
3039
|
* 🚨 그것을 `pr-only` 라 부르면 ***「PR 을 연다」로 읽히는데 worktree-only 도 여기 들어온다*** — 이름이 거짓이 된다.
|
|
2973
3040
|
* ⇒ 📌 세 번째 값이 필요하면 `completion` 자체를 seam 으로 내려보내야 한다(계약 변경).
|
|
2974
3041
|
*/
|
|
2975
|
-
export function completionIntentOf(opts: Pick<SelfImplementOptions, 'completion' | 'autoMerge'>): SelfImplementOptions['completion'] | 'not-auto-merge' {
|
|
2976
|
-
return opts.completion ?? (opts.autoMerge === true ? 'auto-merge' : 'not-auto-merge');
|
|
3042
|
+
export function completionIntentOf(opts: Pick<SelfImplementOptions, 'completion' | 'autoMerge' | 'mergeByHost'>): SelfImplementOptions['completion'] | 'not-auto-merge' {
|
|
3043
|
+
return opts.completion ?? (opts.autoMerge === true || opts.mergeByHost === true ? 'auto-merge' : 'not-auto-merge');
|
|
2977
3044
|
}
|
|
2978
3045
|
|
|
2979
|
-
function autoMergeEnabled(opts: Pick<SelfImplementOptions, 'completion' | 'autoMerge'>): boolean {
|
|
3046
|
+
function autoMergeEnabled(opts: Pick<SelfImplementOptions, 'completion' | 'autoMerge' | 'mergeByHost'>): boolean {
|
|
2980
3047
|
return completionIntentOf(opts) === 'auto-merge';
|
|
2981
3048
|
}
|
|
2982
3049
|
|
|
@@ -3314,13 +3381,30 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3314
3381
|
};
|
|
3315
3382
|
let loopRegistered = false;
|
|
3316
3383
|
let mergeApprovalReceived = false;
|
|
3384
|
+
let autoMergeAuthorizedBeforeSync = false;
|
|
3317
3385
|
let lastParsedSupervisorVerdict: ReworkBudgetVerdict | undefined;
|
|
3318
3386
|
let lastParsedSupervisorReason: string | undefined;
|
|
3319
3387
|
let providerErrorCount = 0;
|
|
3320
3388
|
let credentialFailureCount = 0;
|
|
3389
|
+
let failureSequence = 0;
|
|
3390
|
+
let lastProviderErrorSeq = 0;
|
|
3391
|
+
let lastCredentialFailureSeq = 0;
|
|
3392
|
+
let lastFailedGateSeq = 0;
|
|
3393
|
+
let lastMustFixReviewSeq = 0;
|
|
3394
|
+
const recordFailureVerdict = async (kind: 'gate' | 'review'): Promise<void> => {
|
|
3395
|
+
// Capture child errors at the verdict boundary, not when terminal reporting eventually reads them.
|
|
3396
|
+
await mergeChildProviderErrors();
|
|
3397
|
+
if (kind === 'gate') lastFailedGateSeq = ++failureSequence;
|
|
3398
|
+
else lastMustFixReviewSeq = ++failureSequence;
|
|
3399
|
+
};
|
|
3400
|
+
const latestVerdictSeq = (): number => Math.max(lastFailedGateSeq, lastMustFixReviewSeq);
|
|
3401
|
+
const hasCurrentProviderError = (): boolean => providerErrorCount > 0 && lastProviderErrorSeq > latestVerdictSeq();
|
|
3402
|
+
const hasCurrentCredentialFailure = (): boolean => credentialFailureCount > 0 && lastCredentialFailureSeq > latestVerdictSeq();
|
|
3321
3403
|
let lastProviderError: { provider?: string; message?: string } | undefined;
|
|
3322
3404
|
let lastCredentialFailure: { provider?: string; message?: string } | undefined;
|
|
3323
3405
|
let childProviderErrorQueryStatus: 'found' | 'none' | 'unavailable' | 'not-configured' = 'not-configured';
|
|
3406
|
+
let queriedProviderErrorCount = 0;
|
|
3407
|
+
let queriedCredentialFailureCount = 0;
|
|
3324
3408
|
const providerErrorsForResult = (): Pick<SelfImplementResult, 'providerErrors'> => {
|
|
3325
3409
|
if (providerErrorCount === 0) return {};
|
|
3326
3410
|
const message = lastProviderError?.message ?? '';
|
|
@@ -3340,8 +3424,14 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3340
3424
|
const result = await query({ runId, sinceMs: startedAtMs, untilMs: Date.now() });
|
|
3341
3425
|
childProviderErrorQueryStatus = result.status;
|
|
3342
3426
|
if (result.status !== 'found') return;
|
|
3343
|
-
|
|
3344
|
-
|
|
3427
|
+
const newProviderErrors = Math.max(0, result.providerErrorCount - queriedProviderErrorCount);
|
|
3428
|
+
const newCredentialFailures = Math.max(0, result.credentialFailureCount - queriedCredentialFailureCount);
|
|
3429
|
+
providerErrorCount += newProviderErrors;
|
|
3430
|
+
credentialFailureCount += newCredentialFailures;
|
|
3431
|
+
if (newProviderErrors > 0) lastProviderErrorSeq = ++failureSequence;
|
|
3432
|
+
if (newCredentialFailures > 0) lastCredentialFailureSeq = newProviderErrors > 0 ? lastProviderErrorSeq : ++failureSequence;
|
|
3433
|
+
queriedProviderErrorCount = Math.max(queriedProviderErrorCount, result.providerErrorCount);
|
|
3434
|
+
queriedCredentialFailureCount = Math.max(queriedCredentialFailureCount, result.credentialFailureCount);
|
|
3345
3435
|
lastProviderError = result.lastProviderError ?? lastProviderError;
|
|
3346
3436
|
lastCredentialFailure = result.lastCredentialFailure ?? lastCredentialFailure;
|
|
3347
3437
|
} catch {
|
|
@@ -3356,6 +3446,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3356
3446
|
if (!data || typeof data !== 'object') return;
|
|
3357
3447
|
const { provider, message } = data as Record<string, unknown>;
|
|
3358
3448
|
providerErrorCount++;
|
|
3449
|
+
lastProviderErrorSeq = ++failureSequence;
|
|
3359
3450
|
lastProviderError = {
|
|
3360
3451
|
...(typeof provider === 'string' ? { provider } : {}),
|
|
3361
3452
|
...(typeof message === 'string' ? { message } : {}),
|
|
@@ -3371,6 +3462,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3371
3462
|
// 여기서 문면 정규식으로 다시 재면 소비자마다 다른 답이 나온다.
|
|
3372
3463
|
if ((data as Record<string, unknown>).authRejected === true) {
|
|
3373
3464
|
credentialFailureCount++;
|
|
3465
|
+
lastCredentialFailureSeq = lastProviderErrorSeq;
|
|
3374
3466
|
lastCredentialFailure = { ...lastProviderError };
|
|
3375
3467
|
}
|
|
3376
3468
|
},
|
|
@@ -3379,6 +3471,15 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3379
3471
|
const progressDelivery = { delivered: 0, unwired: 0, callbackFailed: 0 };
|
|
3380
3472
|
let capturedPrNumber: number | undefined;
|
|
3381
3473
|
let openPrInvoked = false;
|
|
3474
|
+
const defaultProviderName = opts.seams.currentProviderName?.() ?? currentProviderName();
|
|
3475
|
+
const runProviderName = opts.childLlm?.provider ?? defaultProviderName;
|
|
3476
|
+
const logQuotaProvider = (assessment: QuotaExhaustionAssessment | undefined): void => {
|
|
3477
|
+
try {
|
|
3478
|
+
debug.log('self-implement.abandoned', 'quota-provider', {
|
|
3479
|
+
runProvider: runProviderName, defaultProvider: defaultProviderName, used: assessment?.exhausted !== undefined,
|
|
3480
|
+
});
|
|
3481
|
+
} catch { /* observation must not change the terminal result */ }
|
|
3482
|
+
};
|
|
3382
3483
|
const instrumentedOpts: SelfImplementOptions = {
|
|
3383
3484
|
...opts,
|
|
3384
3485
|
seams: {
|
|
@@ -3418,6 +3519,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3418
3519
|
/** ⭐ 방문 예산을 읽으려면 «지금 도는 선언»이 필요하다 — 신원과 «같은 패턴»으로 한 번 심는다.
|
|
3419
3520
|
* ⛔ 걸음(`traversedNodes`)은 이 스코프에 있고 선언은 안쪽에서 정해지므로, 둘을 잇는 자리가 여기다. */
|
|
3420
3521
|
let runGraphTemplate: GraphTemplate | undefined;
|
|
3522
|
+
let runContract: RunContract | undefined;
|
|
3421
3523
|
let runGraphIdentity: { graphId: string; graphVersion: string } | undefined;
|
|
3422
3524
|
const setRunGraphIdentity = (identity: { graphId: string; graphVersion: string }): void => {
|
|
3423
3525
|
runGraphIdentity = identity;
|
|
@@ -3469,6 +3571,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3469
3571
|
traversedNodes.push(node);
|
|
3470
3572
|
if (node === 'implement') roundCount++;
|
|
3471
3573
|
const fallbackGraphIdentity = observedGraphIdentity();
|
|
3574
|
+
const contractAtNode = runContract === undefined ? undefined : runContractAtNode(runContract);
|
|
3472
3575
|
observePipeline('pipeline-node-entry', {
|
|
3473
3576
|
...pipelineNodeEntryPayload(
|
|
3474
3577
|
runGraphTemplate ?? { graphId: fallbackGraphIdentity.graphId, version: fallbackGraphIdentity.graphVersion, nodes: [] },
|
|
@@ -3476,7 +3579,15 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3476
3579
|
),
|
|
3477
3580
|
node,
|
|
3478
3581
|
round,
|
|
3582
|
+
...contractAtNode,
|
|
3479
3583
|
});
|
|
3584
|
+
if (contractAtNode?.contractHonored === false) {
|
|
3585
|
+
observeOuter('graph-contract-violation', {
|
|
3586
|
+
node, round,
|
|
3587
|
+
contractSubstrate: contractAtNode.contractSubstrate,
|
|
3588
|
+
actualSubstrate: contractAtNode.actualSubstrate,
|
|
3589
|
+
}, { level: 'warn' });
|
|
3590
|
+
}
|
|
3480
3591
|
};
|
|
3481
3592
|
const observeRoundClassification = (classification: LifecycleScreenComparison): void => {
|
|
3482
3593
|
roundClassifications.push(classification);
|
|
@@ -3731,29 +3842,37 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3731
3842
|
}),
|
|
3732
3843
|
instrumentedOpts.seams.reworkBudgetReviewFindingRecurrence ?? (() => null),
|
|
3733
3844
|
() => { mergeApprovalReceived = true; },
|
|
3845
|
+
() => { autoMergeAuthorizedBeforeSync = true; },
|
|
3734
3846
|
(verdict) => { lastParsedSupervisorVerdict = verdict; },
|
|
3735
3847
|
(reason) => { lastParsedSupervisorReason = reason; },
|
|
3736
3848
|
(base) => { resolvedBase = base ?? undefined; },
|
|
3737
3849
|
(basis) => { observationMeasurementBasis = basis; },
|
|
3738
3850
|
(timeout) => { clarificationTimeout = timeout; },
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
() => providerErrorsForResult().providerErrors?.category,
|
|
3851
|
+
hasCurrentProviderError,
|
|
3852
|
+
hasCurrentCredentialFailure,
|
|
3853
|
+
() => hasCurrentProviderError() ? providerErrorsForResult().providerErrors?.category : undefined,
|
|
3742
3854
|
(rejectedCount) => { reviewReflectRejectedCount = (reviewReflectRejectedCount ?? 0) + rejectedCount; },
|
|
3743
3855
|
observeOuter,
|
|
3744
3856
|
(active) => { runActiveProvider = active; },
|
|
3745
3857
|
(sessionId) => { terminalSessionId = sessionId; },
|
|
3858
|
+
(contract) => { runContract = contract; },
|
|
3859
|
+
recordFailureVerdict,
|
|
3860
|
+
() => providerErrorCount > 0,
|
|
3861
|
+
() => credentialFailureCount > 0,
|
|
3862
|
+
hasCurrentProviderError,
|
|
3863
|
+
hasCurrentCredentialFailure,
|
|
3746
3864
|
);
|
|
3747
3865
|
terminalNode = result.node;
|
|
3748
3866
|
await mergeChildProviderErrors();
|
|
3749
3867
|
const addressedResult = attachAbandonedClassification(
|
|
3750
3868
|
attachReviewReflectionOutcome({ ...result, ...providerErrorsForResult(), runId, ...(lastParsedSupervisorReason ? { supervisorReason: lastParsedSupervisorReason } : {}), ...(mergeApprovalReceived ? { mergeApprovalReceived: true } : {}) }),
|
|
3751
3869
|
opts.goalFile,
|
|
3752
|
-
|
|
3753
|
-
|
|
3870
|
+
hasCurrentProviderError(),
|
|
3871
|
+
hasCurrentCredentialFailure(),
|
|
3754
3872
|
opts.seams.inspectCodexRotation,
|
|
3755
|
-
|
|
3873
|
+
runProviderName,
|
|
3756
3874
|
);
|
|
3875
|
+
if (isAbandonedClassificationOutcome(addressedResult.outcome)) logQuotaProvider(addressedResult.quotaExhaustionAssessment);
|
|
3757
3876
|
observeOuter('child-provider-error-query', { status: childProviderErrorQueryStatus });
|
|
3758
3877
|
if (lastProviderError) {
|
|
3759
3878
|
observeOuter('provider-error-observed', { count: providerErrorCount, ...lastProviderError });
|
|
@@ -3823,14 +3942,15 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3823
3942
|
branch,
|
|
3824
3943
|
...(worktreePath ? { worktreePath } : {}),
|
|
3825
3944
|
...(lastParsedSupervisorReason ? { supervisorReason: lastParsedSupervisorReason } : {}),
|
|
3826
|
-
...(mergeApprovalReceived ? { mergeApprovalReceived: true } : {}),
|
|
3945
|
+
...(mergeApprovalReceived || (e.step === 'merge' && autoMergeAuthorizedBeforeSync) ? { mergeApprovalReceived: true } : {}),
|
|
3827
3946
|
detail: worktreePath
|
|
3828
3947
|
? `자율 단계 '${e.step}' wall-clock ${e.ms}ms 초과 — hang 방지 종결(worktree 회수 경로: ${worktreePath})`
|
|
3829
3948
|
: `자율 단계 '${e.step}' wall-clock ${e.ms}ms 초과 — hang 방지 종결(worktree 생성 전)`,
|
|
3830
3949
|
};
|
|
3831
3950
|
terminalNode = result.node;
|
|
3832
3951
|
await mergeChildProviderErrors();
|
|
3833
|
-
const addressedResult = attachAbandonedClassification(attachReviewReflectionOutcome({ ...result, ...providerErrorsForResult() }), opts.goalFile,
|
|
3952
|
+
const addressedResult = attachAbandonedClassification(attachReviewReflectionOutcome({ ...result, ...providerErrorsForResult() }), opts.goalFile, hasCurrentProviderError(), hasCurrentCredentialFailure(), opts.seams.inspectCodexRotation, runProviderName);
|
|
3953
|
+
logQuotaProvider(addressedResult.quotaExhaustionAssessment);
|
|
3834
3954
|
observeOuter('child-provider-error-query', { status: childProviderErrorQueryStatus });
|
|
3835
3955
|
if (lastProviderError) {
|
|
3836
3956
|
observeOuter('provider-error-observed', { count: providerErrorCount, ...lastProviderError });
|
|
@@ -4012,12 +4132,24 @@ export function readQuotaExhausted(
|
|
|
4012
4132
|
// ⛔⭐⭐⭐ 그리고 이 신호는 **codex 전용**이다(2R must-fix) — provider 를 «안 보면»
|
|
4013
4133
|
// Claude·Grok 으로 돈 런까지 codex 쿼터로 «오분류»한다. 그건 이 PR 이 고치려던
|
|
4014
4134
|
// 「잡통」의 «반대 방향» 오류다.
|
|
4015
|
-
//
|
|
4016
|
-
//
|
|
4135
|
+
// 호출자는 구현 자식 provider 를 우선 넘긴다. 자식 선택이 없으면 프로세스 기본 provider 로 귀속한다.
|
|
4136
|
+
// 부모(리뷰·감독)의 별도 폴백이나 자식 내부 전환은 이 평가의 범위 밖이다.
|
|
4017
4137
|
const snapshot = rotationInspector();
|
|
4018
4138
|
// ⭐ 좁히지 않는다 — 스냅샷이 «이미 아는» 것을 증거로 그대로 옮긴다(`quotaAvailabilityEvidence`).
|
|
4019
4139
|
// ⛔⭐ 「언제 읽었나」를 «값으로» 박는다 — 이 읽기는 런이 «끝난 뒤»다(타입 머리말 참조).
|
|
4020
|
-
|
|
4140
|
+
const evidence = { ...quotaAvailabilityEvidence(snapshot), readPoint: 'postmortem' as const };
|
|
4141
|
+
// ⛔⭐ 정본 스토어가 아는 계정이 «0개»면 회전이 구성되지 않은 것이다 — 「쓸 계정 없음」을 소진으로 읽지 않는다.
|
|
4142
|
+
// 🩸 P6(2026-09-26 Pod 실물): Pod 는 계정 사본 하나만 받고 회전 목록이 없어 no-candidate → 「할당량 소진」으로
|
|
4143
|
+
// 분류됐다. 진짜 원인(게이트의 tsc 127 · P5)이 그 오분류에 가려졌다. 호스트의 진짜 소진(계정은 있는데 전부 찼다)은 그대로다.
|
|
4144
|
+
if (snapshot.knownAccountCount === 0) return { exhausted: undefined, accountAvailability: evidence };
|
|
4145
|
+
// ⛔⭐ 아는 계정이 «하나»뿐이면 no-candidate 는 «돌릴 곳이 원래 없다»는 뜻이지 «찼다»가 아니다.
|
|
4146
|
+
// 🩸 P2 #20869(2026-09-27 Pod 실물): Pod 는 배분받은 계정 사본 «하나»(third · 잔량 넉넉)만 갖고 그 계정의 사용률 신호가
|
|
4147
|
+
// 없었다 → 회전은 no-candidate → 「할당량 소진」으로 분류돼 진짜 원인(리뷰 UNCONVERGEABLE)을 가렸다.
|
|
4148
|
+
// ⇒ 그 한 계정의 사용률도 도달 신호도 없으면 «모름». 사용률을 알면 종전 판정(임계 미만=false · 이상=true)에 맡긴다.
|
|
4149
|
+
if (snapshot.knownAccountCount === 1 && evidence.reason === 'no-candidate' && snapshot.currentUsedPercent === undefined && snapshot.currentReached !== true) {
|
|
4150
|
+
return { exhausted: undefined, accountAvailability: evidence };
|
|
4151
|
+
}
|
|
4152
|
+
return assessQuotaExhaustion(providerName, evidence);
|
|
4021
4153
|
} catch {
|
|
4022
4154
|
return { exhausted: undefined, accountAvailability: undefined }; // fail-soft — 관측은 결론을 막지 않는다
|
|
4023
4155
|
}
|
|
@@ -4085,7 +4217,7 @@ export function attachAbandonedClassification(
|
|
|
4085
4217
|
...(quotaExhaustionAssessment.accountAvailability ? { quotaAccountAvailability: quotaExhaustionAssessment.accountAvailability } : {}),
|
|
4086
4218
|
...(credentialFailure ? { credentialFailure: true } : {}),
|
|
4087
4219
|
...(providerError ? { providerError: true } : {}),
|
|
4088
|
-
...(result.providerErrors?.category ? { providerErrorCategory: result.providerErrors.category } : {}),
|
|
4220
|
+
...(providerError && result.providerErrors?.category ? { providerErrorCategory: result.providerErrors.category } : {}),
|
|
4089
4221
|
worktreePorcelain: worktree.worktreePorcelain,
|
|
4090
4222
|
...(worktree.gitResidue ? { gitResidue: worktree.gitResidue } : {}),
|
|
4091
4223
|
...(result.completionDisposition ? { completionDisposition: result.completionDisposition } : {}),
|
|
@@ -4268,6 +4400,7 @@ async function runSelfImplementInner(
|
|
|
4268
4400
|
* 이제 null 이면 measureReviewFindingRecurrence 가 «실제로» 잰다. */
|
|
4269
4401
|
reworkBudgetReviewFindingRecurrence: () => ReviewFindingRecurrence | null = () => null,
|
|
4270
4402
|
onMergeApprovalReceived: () => void = () => {},
|
|
4403
|
+
onAutoMergeAuthorizedBeforeSync: () => void = () => {},
|
|
4271
4404
|
onSupervisorVerdictParsed: (verdict: ReworkBudgetVerdict) => void = () => {},
|
|
4272
4405
|
onSupervisorReasonParsed: (reason: string | undefined) => void = () => {},
|
|
4273
4406
|
onResolvedBase: (base: string | null) => void = () => {},
|
|
@@ -4282,16 +4415,20 @@ async function runSelfImplementInner(
|
|
|
4282
4415
|
* (그러면 「런이 끝날 무렵의 provider」가 되어 `F45` 를 그대로 밟는다). 시작 시점 값을 넘긴다. */
|
|
4283
4416
|
onActiveProvider: (active: { provider?: string; model?: string; auth?: string }) => void = () => {},
|
|
4284
4417
|
onSessionCreated: (sessionId: string) => void = () => {},
|
|
4418
|
+
onRunContractResolved: (contract: RunContract) => void = () => {},
|
|
4419
|
+
onFailureVerdict: (kind: 'gate' | 'review') => Promise<void> = async () => {},
|
|
4420
|
+
hasObservedProviderError: () => boolean = hasProviderError,
|
|
4421
|
+
hasObservedCredentialFailure: () => boolean = hasCredentialFailure,
|
|
4422
|
+
hasCurrentProviderError: () => boolean = hasProviderError,
|
|
4423
|
+
hasCurrentCredentialFailure: () => boolean = hasCredentialFailure,
|
|
4285
4424
|
): Promise<Omit<SelfImplementResult, 'runId'>> {
|
|
4286
4425
|
const s = opts.seams;
|
|
4287
4426
|
const pipelineStartedAtMs = Date.now();
|
|
4288
|
-
// Graph authority
|
|
4427
|
+
// Graph authority is always ON; retain the resolved event with default provenance.
|
|
4289
4428
|
// For research documents, its declared docs-only routing intentionally skips the gate.
|
|
4290
|
-
const
|
|
4291
|
-
const graphAuthority = resolveGraphAuthorityForUserConfig(userConfig, opts.graphAuthoritative);
|
|
4429
|
+
const graphAuthority = resolveGraphAuthorityForUserConfig();
|
|
4292
4430
|
// ⛔ 골 파일이 «없을 수» 있다 — 그때는 골 종류를 모르므로 implement-loop 으로 간다(없는 길로 안 보낸다).
|
|
4293
4431
|
// ⭐ 대표 지시 ② «변형» — 「최초 결정 시 해당 템플릿 변형을 한다」.
|
|
4294
|
-
// ⛔ 승격이 꺼져 있으면 `decideTemplate` 은 `activeTemplate` 과 «같은 값»을 낸다(고르지도 않는다).
|
|
4295
4432
|
const graphGoalType = opts.goalFile === undefined ? undefined : (goalTypeFields(opts.goalFile).goalType as GoalType | undefined);
|
|
4296
4433
|
// ⛔ 오버레이는 «한 번» 읽는다 — 라운드마다 디스크를 읽으면 도는 중에 파일이 바뀌어 걸음이 갈린다.
|
|
4297
4434
|
// ⛔ 이름이 `graph`인 이유: launch(②)·runtime(③) «둘 다» 이 목록에서 고른다. 단계는 인자로 갈린다.
|
|
@@ -4308,24 +4445,28 @@ async function runSelfImplementInner(
|
|
|
4308
4445
|
// ⛔⭐ `let` 인 이유는 ③ «다이나믹»이다 — 라운드마다 runtime 오버레이가 «앞을 보는 것»만 바꾼다.
|
|
4309
4446
|
// ⛔ 지난 노드를 재정의하지 않는다(RFC §6: 그러면 원장을 사후에 해석할 수 없다).
|
|
4310
4447
|
let graphTemplate = graphDecision.template;
|
|
4311
|
-
/** 단계 이름 → 그 템플릿의 노드 이름.
|
|
4448
|
+
/** 단계 이름 → 그 템플릿의 노드 이름. */
|
|
4312
4449
|
const node = (stage: PipelineNodeId): PipelineNodeId => nodeNameForStage(stage, graphTemplate) as PipelineNodeId;
|
|
4313
4450
|
// ⛔⭐ 맥락이 정해진 «직후» 관측기에 심는다 — 이 줄이 없으면 걸음은 YAML 을 따르고 «신원은 안 따른다».
|
|
4314
4451
|
onGraphResolved(graphIdentityOf(graphTemplate));
|
|
4315
|
-
//
|
|
4316
|
-
// 🩸 2026-09-08: 이 값은 `gate-skipped-by-graph` «한 자리»에서만 났고, 그 사건은
|
|
4317
|
-
// research-loop 이 문서만 바꿨을 때만 난다 ⇒ ***대부분의 런에서 「무엇이 켰나」가 원장에 없었다***.
|
|
4318
|
-
// ⛔ 그래서 A/B 의 관문(「두 팔이 갈렸나」)이 «원리상» 답을 못 얻었다.
|
|
4319
|
-
// ⛔ 「켜짐」만 남기지 않는다 — `source` 가 「안 켰다」와 「켰는데 안 먹었다」를 가른다.
|
|
4452
|
+
// 권위는 항상 켜지지만 이벤트의 필드 모양은 유지하고 출처를 default로 기록한다.
|
|
4320
4453
|
observe('graph-authority-resolved', graphAuthorityFields(graphAuthority, graphTemplate));
|
|
4454
|
+
// ⭐ 런 계약 — 런 시작 «한 번» 해석한다(대표 2026-09-26 «초반 계약을 노드가 준수»). 해석 출처(source)와
|
|
4455
|
+
// 실제 칸(actualSubstrate)을 같이 남겨 「계약이 Pod 인데 로컬에서 돌았나」를 원장이 답하게 한다.
|
|
4456
|
+
// 노드 진입 대조는 관측만 하며 실행을 막지 않는다.
|
|
4457
|
+
{
|
|
4458
|
+
const { resolveRunContract } = await import('./graph-run-contract.js');
|
|
4459
|
+
const runContract = resolveRunContract({ ...(graphTemplate.runContract ? { graph: graphTemplate.runContract } : {}), env: process.env });
|
|
4460
|
+
onRunContractResolved(runContract);
|
|
4461
|
+
observe('graph-run-contract-resolved', { ...graphIdentityOf(graphTemplate), ...runContract, ...runContractAtNode(runContract) });
|
|
4462
|
+
}
|
|
4321
4463
|
// ⛔ 승격이 꺼져 있으면 «심지 않는다» — 그러면 예산 관측도 안 난다(운영 원장이 오늘과 같다).
|
|
4322
4464
|
if (graphAuthority.enabled) onGraphTemplateResolved(graphTemplate);
|
|
4323
4465
|
// ⛔ 선택을 «전부» 싣는다 — 얹힌 것만 실으면 「왜 안 얹혔나」를 사후에 못 묻는다.
|
|
4324
|
-
// ⛔ 「없음」과 「안 봤음」을 가른다: 승격이 꺼졌으면 selections 가 «빈 배열»이고 그것이 값이다.
|
|
4325
4466
|
/** ⭐ ③ «다이나믹» — 라운드마다 runtime 오버레이를 다시 고른다.
|
|
4326
4467
|
* ⛔ **매번 «기준 선언»에서 다시 얹는다** — 이전 라운드 결과 위에 겹쳐 얹으면
|
|
4327
4468
|
* 「이 걸음을 무엇이 만들었나」가 «누적»이 되어 사후에 못 푼다.
|
|
4328
|
-
*
|
|
4469
|
+
* 오버레이 적용은 기존 실행 경로를 그대로 따른다. */
|
|
4329
4470
|
const applyRuntimeOverlays = (round: number): void => {
|
|
4330
4471
|
if (!graphAuthority.enabled) return;
|
|
4331
4472
|
// ⛔ 「지금 아는 것」만 준다 — 없는 값을 0 으로 지어내지 않는다(key-absent 가 그것을 말한다).
|
|
@@ -4406,11 +4547,13 @@ async function runSelfImplementInner(
|
|
|
4406
4547
|
// ⭐ 관측 이벤트와 «같은 값»을 원장으로도 보낸다 — 로그에만 있으면 원장 질의가 못 센다(`F12`).
|
|
4407
4548
|
try { onActiveProvider(activeProvider); } catch { /* 보조 기록이 런을 죽이지 않는다 */ }
|
|
4408
4549
|
const boundedFeature = boundReadableText(opts.feature, RUN_START_FEATURE_MAX_CHARS);
|
|
4550
|
+
const launchCwd = resolve(process.cwd());
|
|
4409
4551
|
observe('start', {
|
|
4410
4552
|
feature: boundedFeature.text, featureTruncated: boundedFeature.truncated, featureOriginalChars: boundedFeature.originalChars,
|
|
4411
4553
|
branch, base: opts.base ?? null, draft: opts.draft ?? true,
|
|
4412
4554
|
willFork: !!(opts.parentSessionId && s.forkSession), parentSessionId: opts.parentSessionId ?? null,
|
|
4413
|
-
nestDepth: nestInfo().depth, goalSource, goalFile: opts.goalFile
|
|
4555
|
+
nestDepth: nestInfo().depth, goalSource, goalFile: opts.goalFile === undefined ? null : resolve(launchCwd, opts.goalFile),
|
|
4556
|
+
targetRoot: gitRootOf(launchCwd) ?? launchCwd, ...originObservationFields(),
|
|
4414
4557
|
provider: activeProvider.provider ?? null, model: activeProvider.model ?? null, auth: activeProvider.auth ?? null,
|
|
4415
4558
|
...(opts.correlationId !== undefined ? { correlationId: opts.correlationId } : {}),
|
|
4416
4559
|
});
|
|
@@ -4777,12 +4920,15 @@ async function runSelfImplementInner(
|
|
|
4777
4920
|
return occurrencePattern.test(reason) && roundsPattern.test(reason);
|
|
4778
4921
|
};
|
|
4779
4922
|
const failCounts: number[] = [];
|
|
4923
|
+
// 직전 gate 실패 라운드의 미검증 집합(정렬 키). 통과하면 비운다 — «연속» 반복만 센다.
|
|
4924
|
+
let lastGateUnverifiedKey: string | undefined;
|
|
4780
4925
|
const reworkHistory: string[] = [];
|
|
4781
4926
|
const supervisorDecisionHistory: Array<{ round: number; verdict: ReworkBudgetVerdict; reason: string }> = [];
|
|
4782
4927
|
let judgedEffectiveMax: number | undefined;
|
|
4783
4928
|
let lastReworkVerdict: ReworkBudgetVerdict | undefined;
|
|
4784
4929
|
let lastSupervisorVerdict: ReworkBudgetVerdict | undefined;
|
|
4785
4930
|
let lastSupervisorReason: string | undefined;
|
|
4931
|
+
let consecutiveUnresolvedBudget = 0;
|
|
4786
4932
|
let pendingPlanRevision: ReworkPlanRevision | undefined;
|
|
4787
4933
|
let lastPlanRevision: ReworkPlanRevision | undefined;
|
|
4788
4934
|
const isReviewRework = (source: SupervisionReworkSource): boolean => {
|
|
@@ -4818,8 +4964,23 @@ async function runSelfImplementInner(
|
|
|
4818
4964
|
observe('review-context-carried', { base: opts.base, basePrLocated: false, carriedItems: 0, headlineComments: 0, source: 'unavailable', error: true, reason: 'lookup-failed' }, { level: 'warn' });
|
|
4819
4965
|
}
|
|
4820
4966
|
}
|
|
4967
|
+
const goalTitle = opts.goalFile ? goalTitleFromTargetGoalFile(opts.goalFile, wt.path) : undefined;
|
|
4968
|
+
let priorRunFindings: Awaited<ReturnType<typeof collectPriorDraftFindings>> = [];
|
|
4969
|
+
if (goalTitle) {
|
|
4970
|
+
try {
|
|
4971
|
+
priorRunFindings = await (s.collectPriorDraftFindings ?? collectPriorDraftFindings)({ goalTitle, currentRunId: runId, repoPath: wt.path });
|
|
4972
|
+
} catch (error) {
|
|
4973
|
+
observe('prior-findings.unreadable', { error: error instanceof Error ? error.message : String(error) });
|
|
4974
|
+
}
|
|
4975
|
+
}
|
|
4976
|
+
if (priorRunFindings.length) {
|
|
4977
|
+
observe('prior-findings.loaded', {
|
|
4978
|
+
prs: priorRunFindings.length,
|
|
4979
|
+
items: priorRunFindings.reduce((sum, finding) => sum + finding.items.length, 0),
|
|
4980
|
+
});
|
|
4981
|
+
}
|
|
4821
4982
|
let appliedLastRound: string[] | undefined;
|
|
4822
|
-
let reviewIntent = buildReviewIntent({ goal: opts.feature, goalFile: opts.goalFile });
|
|
4983
|
+
let reviewIntent = buildReviewIntent({ goal: opts.feature, goalFile: opts.goalFile, ...(priorRunFindings.length ? { priorRunFindings } : {}) });
|
|
4823
4984
|
// ⛔⭐ 리뷰 루프가 만든 마지막 컨텍스트를 잡아 둔다 — PR 본문 조립 직전에 **최종 커밋**의
|
|
4824
4985
|
// 런 사실로 갱신하기 위해서다(3R must-fix). 루프 안 수집은 `openPr` 단계가 만드는 커밋을
|
|
4825
4986
|
// 못 본다: 자식은 파일만 남기고 실제 커밋은 `commitWork` 가 루프 뒤에서 만든다.
|
|
@@ -4996,9 +5157,10 @@ async function runSelfImplementInner(
|
|
|
4996
5157
|
}
|
|
4997
5158
|
};
|
|
4998
5159
|
let preservationBase = wt.resolvedBase;
|
|
5160
|
+
const runProviderName = opts.childLlm?.provider ?? (s.currentProviderName?.() ?? currentProviderName());
|
|
4999
5161
|
let cachedQuotaExhaustionAssessment: QuotaExhaustionAssessment | undefined;
|
|
5000
5162
|
const quotaExhaustionAssessmentForRun = (): QuotaExhaustionAssessment => {
|
|
5001
|
-
cachedQuotaExhaustionAssessment ??= readQuotaExhausted(s.inspectCodexRotation,
|
|
5163
|
+
cachedQuotaExhaustionAssessment ??= readQuotaExhausted(s.inspectCodexRotation, runProviderName);
|
|
5002
5164
|
return cachedQuotaExhaustionAssessment;
|
|
5003
5165
|
};
|
|
5004
5166
|
const classifyUnfinishedRun = (stage: SelfImplementStage, verdict?: ReworkBudgetVerdict, decomposition?: TerminalDecomposition): AbandonedClassificationResult => {
|
|
@@ -5008,9 +5170,9 @@ async function runSelfImplementInner(
|
|
|
5008
5170
|
...(opts.goalFile ? { goalType: goalTypeFields(opts.goalFile).goalType } : {}),
|
|
5009
5171
|
...(quotaExhaustionAssessment.exhausted ? { quotaExhausted: true } : {}),
|
|
5010
5172
|
...(quotaExhaustionAssessment.accountAvailability ? { quotaAccountAvailability: quotaExhaustionAssessment.accountAvailability } : {}),
|
|
5011
|
-
...(
|
|
5012
|
-
...(
|
|
5013
|
-
...(providerErrorCategory() ? { providerErrorCategory: providerErrorCategory() } : {}),
|
|
5173
|
+
...(hasCurrentCredentialFailure() ? { credentialFailure: true } : {}),
|
|
5174
|
+
...(hasCurrentProviderError() ? { providerError: true } : {}),
|
|
5175
|
+
...(hasCurrentProviderError() && providerErrorCategory() ? { providerErrorCategory: providerErrorCategory() } : {}),
|
|
5014
5176
|
worktreePorcelain: worktree.worktreePorcelain,
|
|
5015
5177
|
...(worktree.gitResidue ? { gitResidue: worktree.gitResidue } : {}),
|
|
5016
5178
|
...(impl.completionDisposition ? { completionDisposition: impl.completionDisposition } : {}),
|
|
@@ -5145,30 +5307,76 @@ async function runSelfImplementInner(
|
|
|
5145
5307
|
opts.goalFile,
|
|
5146
5308
|
s.persistPrBodyArtifact,
|
|
5147
5309
|
);
|
|
5148
|
-
// worktree-only
|
|
5149
|
-
|
|
5150
|
-
|
|
5310
|
+
// no-changes wins; worktree-only remains local even for environment stops.
|
|
5311
|
+
const environmentStop = blockedDraftDisposition(classificationRecord.classification) === 'preserve-branch';
|
|
5312
|
+
const worktreeOnly = opts.completion === 'worktree-only';
|
|
5313
|
+
if (worktreeOnly || environmentStop) {
|
|
5151
5314
|
let artifactPath: string | undefined;
|
|
5152
5315
|
let artifactError: string | undefined;
|
|
5153
5316
|
try {
|
|
5154
5317
|
artifactPath = persistFullPrBody(s.persistPrBodyArtifact, {
|
|
5155
|
-
origin: 'self-implement-blocked-draft-pr-worktree-only',
|
|
5318
|
+
origin: worktreeOnly ? 'self-implement-blocked-draft-pr-worktree-only' : 'self-implement-blocked-draft-pr-environment-stop',
|
|
5156
5319
|
body: assembled.body,
|
|
5157
5320
|
originalChars: assembled.originalChars,
|
|
5158
5321
|
});
|
|
5159
5322
|
} catch (persistenceError) {
|
|
5160
5323
|
artifactError = persistenceError instanceof Error ? persistenceError.message : String(persistenceError);
|
|
5161
5324
|
}
|
|
5325
|
+
let pushed = false;
|
|
5326
|
+
let committed = false;
|
|
5327
|
+
let pushError: Error | undefined;
|
|
5328
|
+
let preservationErrorStep: 'worktree' | 'commit' | 'push' | undefined;
|
|
5329
|
+
if (environmentStop && !worktreeOnly) {
|
|
5330
|
+
try {
|
|
5331
|
+
if (!s.preserveBlockedBranch && !existsSync(wt.path)) {
|
|
5332
|
+
preservationErrorStep = 'worktree';
|
|
5333
|
+
throw new Error(`worktree not found: ${wt.path}`);
|
|
5334
|
+
}
|
|
5335
|
+
if (s.preserveBlockedBranch) {
|
|
5336
|
+
pushed = await s.preserveBlockedBranch({ cwd: wt.path, branch: wt.branch, title: prTitle(opts.feature) });
|
|
5337
|
+
if (!pushed) throw new Error('브랜치 push가 성공하지 않았음');
|
|
5338
|
+
} else {
|
|
5339
|
+
preservationErrorStep = 'commit';
|
|
5340
|
+
const commit = commitWorktree(wt.path, prTitle(opts.feature));
|
|
5341
|
+
if (!commit.ok && !/nothing to commit/.test(commit.out)) throw new Error(commit.out);
|
|
5342
|
+
committed = commit.ok;
|
|
5343
|
+
if (runGitCommand(wt.path, ['remote', 'get-url', 'origin']).status === 0) {
|
|
5344
|
+
preservationErrorStep = 'push';
|
|
5345
|
+
const push = runGitCommand(wt.path, ['push', '-u', 'origin', `HEAD:refs/heads/${wt.branch}`]);
|
|
5346
|
+
if (push.status !== 0) throw new Error(push.stderr || push.stdout);
|
|
5347
|
+
pushed = true;
|
|
5348
|
+
}
|
|
5349
|
+
}
|
|
5350
|
+
} catch (error) {
|
|
5351
|
+
pushError = error instanceof Error ? error : new Error(String(error));
|
|
5352
|
+
}
|
|
5353
|
+
}
|
|
5162
5354
|
observe('rework-blocked-draft-pr', {
|
|
5163
5355
|
...observation,
|
|
5164
|
-
skipped: 'worktree-only',
|
|
5356
|
+
skipped: worktreeOnly ? 'worktree-only' : 'environment-stop',
|
|
5357
|
+
...(!worktreeOnly && environmentStop ? { pushed, committed } : {}),
|
|
5165
5358
|
worktreePath: wt.path,
|
|
5359
|
+
...(pushError ? { pushError: pushError.message, preservationErrorStep: preservationErrorStep ?? 'push' } : {}),
|
|
5166
5360
|
...(artifactPath ? { prBodyArtifactPath: artifactPath } : {}),
|
|
5167
5361
|
...(artifactError ? { prBodyArtifactError: artifactError } : {}),
|
|
5168
|
-
});
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5362
|
+
}, pushError ? { level: 'warn' } : undefined);
|
|
5363
|
+
if (pushError) {
|
|
5364
|
+
const failure = preservationErrorStep === 'worktree' ? '워크트리 부재로 보존 실패' : preservationErrorStep === 'commit' ? '로컬 브랜치 커밋 실패' : '원격 브랜치 보존 실패';
|
|
5365
|
+
progress('aborted', `환경 탓 중단 — ${failure}: ${wt.branch} (${pushError.message}; worktree: ${wt.path})`);
|
|
5366
|
+
if (preservationErrorStep === 'worktree') return undefined;
|
|
5367
|
+
throw new Error(`환경 탓 중단 — ${failure}: ${wt.branch} (worktree: ${wt.path})`, { cause: pushError });
|
|
5368
|
+
}
|
|
5369
|
+
if (worktreeOnly) {
|
|
5370
|
+
progress(stage, artifactPath
|
|
5371
|
+
? `worktree-only 완료: draft PR을 열지 않음(worktree·branch 보존 · 중단 사유 보존: ${artifactPath} · worktree: ${wt.path} · branch: ${wt.branch})`
|
|
5372
|
+
: `worktree-only 완료: draft PR을 열지 않음(worktree·branch 보존 · 중단 사유 보존 실패: ${artifactError ?? 'unknown error'} · worktree: ${wt.path} · branch: ${wt.branch})`);
|
|
5373
|
+
} else {
|
|
5374
|
+
// No draft PR on this path, so the stop reason must be findable from the progress line itself.
|
|
5375
|
+
const reasonNote = artifactPath ? `중단 사유 보존: ${artifactPath}` : `중단 사유 보존 실패: ${artifactError ?? 'unknown error'}`;
|
|
5376
|
+
progress(stage, pushed
|
|
5377
|
+
? `환경 탓 중단 — draft PR 없이 브랜치만 보존: ${wt.branch} · ${reasonNote}`
|
|
5378
|
+
: `환경 탓 중단 — draft PR 없이 로컬 브랜치만 보존(원격 origin 없음): ${wt.branch} · worktree: ${wt.path} · ${reasonNote}`);
|
|
5379
|
+
}
|
|
5172
5380
|
return undefined;
|
|
5173
5381
|
}
|
|
5174
5382
|
progress('pr-opening', '중단 산출물을 draft PR로 보존…');
|
|
@@ -5315,6 +5523,23 @@ async function runSelfImplementInner(
|
|
|
5315
5523
|
await flushPrComments(pr);
|
|
5316
5524
|
return { decision, pr };
|
|
5317
5525
|
};
|
|
5526
|
+
const baselineOnlyGate = (): boolean => {
|
|
5527
|
+
const failures = gate?.baselineFailures;
|
|
5528
|
+
return gate?.passed === false && !!failures?.length && gate.reflectGateFacts?.introduced === 0
|
|
5529
|
+
&& gate.reflectGateFacts.unknown === 0
|
|
5530
|
+
&& failures.every(({ attribution }) => attribution === 'preexisting' || attribution === 'flaky-timeout'
|
|
5531
|
+
|| attribution === 'flaky-rerun' || attribution === 'precondition-unmet');
|
|
5532
|
+
};
|
|
5533
|
+
const noRetryBaseline = (): { terminationReason?: 'blocked-by-baseline' } => {
|
|
5534
|
+
if (!baselineOnlyGate()) return {};
|
|
5535
|
+
const failures = gate!.baselineFailures!;
|
|
5536
|
+
debug.log('self-implement.supervisor', 'no-retry-baseline', {
|
|
5537
|
+
runId,
|
|
5538
|
+
preexisting: failures.filter(({ attribution }) => attribution === 'preexisting').length,
|
|
5539
|
+
flaky: failures.filter(({ attribution }) => attribution === 'flaky-timeout' || attribution === 'flaky-rerun').length,
|
|
5540
|
+
});
|
|
5541
|
+
return { terminationReason: 'blocked-by-baseline' };
|
|
5542
|
+
};
|
|
5318
5543
|
const salvageHardCap = async (hardCapBlockedExtend: boolean, pr?: { number: number }): Promise<'launched' | 'parked'> => {
|
|
5319
5544
|
let evidence: ReworkSalvageEvidence | undefined;
|
|
5320
5545
|
if (hardCapBlockedExtend) {
|
|
@@ -5333,21 +5558,27 @@ async function runSelfImplementInner(
|
|
|
5333
5558
|
...(opts.goalFile ? { goalType: goalTypeFields(opts.goalFile).goalType } : {}),
|
|
5334
5559
|
...(quotaExhaustionAssessment.exhausted ? { quotaExhausted: true } : {}),
|
|
5335
5560
|
...(quotaExhaustionAssessment.accountAvailability ? { quotaAccountAvailability: quotaExhaustionAssessment.accountAvailability } : {}),
|
|
5336
|
-
...(
|
|
5337
|
-
...(
|
|
5338
|
-
...(providerErrorCategory() ? { providerErrorCategory: providerErrorCategory() } : {}),
|
|
5561
|
+
...(hasCurrentCredentialFailure() ? { credentialFailure: true } : {}),
|
|
5562
|
+
...(hasCurrentProviderError() ? { providerError: true } : {}),
|
|
5563
|
+
...(hasCurrentProviderError() && providerErrorCategory() ? { providerErrorCategory: providerErrorCategory() } : {}),
|
|
5339
5564
|
worktreePorcelain: worktree.worktreePorcelain,
|
|
5340
5565
|
...(worktree.gitResidue ? { gitResidue: worktree.gitResidue } : {}),
|
|
5341
5566
|
stage: isReviewRework(reworkKind) ? 'review-blocked' : 'gate-failed',
|
|
5342
5567
|
reviewResultObserved: review !== undefined,
|
|
5343
5568
|
mustFixReported: (review?.mustFix.length ?? 0) > 0,
|
|
5344
5569
|
});
|
|
5570
|
+
observe('rework-salvage-classification', { ...abandonedClassification, branch: wt.branch });
|
|
5571
|
+
// Salvage may resume an observed environment interruption even when a later
|
|
5572
|
+
// gate/review verdict is the terminal classification. Keep its cause distinct.
|
|
5573
|
+
const salvageClassification = abandonedClassification.classification === 'implementation-deficit' && hasObservedProviderError()
|
|
5574
|
+
? hasObservedCredentialFailure() ? 'credential-failure' : 'provider-error'
|
|
5575
|
+
: abandonedClassification.classification;
|
|
5345
5576
|
const decision = decideReworkSalvage({
|
|
5346
5577
|
hardCapBlockedExtend,
|
|
5347
5578
|
goalFile: opts.goalFile,
|
|
5348
5579
|
salvageAttempt: opts.salvageAttempt,
|
|
5349
5580
|
evidence,
|
|
5350
|
-
abandonedClassification:
|
|
5581
|
+
abandonedClassification: salvageClassification,
|
|
5351
5582
|
});
|
|
5352
5583
|
if (decision.action !== 'launch') {
|
|
5353
5584
|
const reason = decision.reason;
|
|
@@ -5360,7 +5591,7 @@ async function runSelfImplementInner(
|
|
|
5360
5591
|
const launchObservation = {
|
|
5361
5592
|
branch: wt.branch,
|
|
5362
5593
|
goalFile: opts.goalFile,
|
|
5363
|
-
...(environmentReason ? { reason: environmentReason, abandonedClassification:
|
|
5594
|
+
...(environmentReason ? { reason: environmentReason, abandonedClassification: salvageClassification } : {}),
|
|
5364
5595
|
...(salvageEvidence ? { clean: salvageEvidence.clean, aheadCommits: salvageEvidence.aheadCommits } : {}),
|
|
5365
5596
|
};
|
|
5366
5597
|
observe('rework-salvage', { action: 'launching', ...launchObservation });
|
|
@@ -5437,36 +5668,48 @@ async function runSelfImplementInner(
|
|
|
5437
5668
|
const judgmentCallLLM = s.judgmentCallLLM;
|
|
5438
5669
|
if (diagnosedDecision?.verdict !== 'CONTRACT-CONFLICT' && !judgmentCallLLM) throw new Error('rework-budget@v1 requires a judgment provider');
|
|
5439
5670
|
const judgmentProvider = judgmentCallLLM ? createReworkBudgetJudgment(judgmentCallLLM) : undefined;
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5671
|
+
try {
|
|
5672
|
+
const result = diagnosedDecision?.verdict === 'CONTRACT-CONFLICT'
|
|
5673
|
+
? undefined
|
|
5674
|
+
: await withStepTimeout(
|
|
5675
|
+
runWorkflowToCompletion(
|
|
5676
|
+
{
|
|
5677
|
+
workflow: reworkBudgetWorkflow,
|
|
5678
|
+
arguments: diagnosis,
|
|
5679
|
+
artifactsDir: '',
|
|
5680
|
+
persistRun: false,
|
|
5681
|
+
judgmentContext: { kind: reworkKind, history: priorHistory },
|
|
5682
|
+
},
|
|
5683
|
+
{
|
|
5684
|
+
callLLM: judgmentCallLLM!,
|
|
5685
|
+
runBash: async () => ({ stdout: '', stderr: '', exitCode: 0 }),
|
|
5686
|
+
runJudgment: judgmentProvider!,
|
|
5687
|
+
},
|
|
5688
|
+
),
|
|
5689
|
+
T.review,
|
|
5690
|
+
'review',
|
|
5691
|
+
);
|
|
5692
|
+
if (result) {
|
|
5693
|
+
const classified = result.outputs['rework-budget'];
|
|
5694
|
+
if (!result.ok || !classified?.ok || typeof classified.output !== 'string') {
|
|
5695
|
+
throw new Error(classified?.error ?? 'rework-budget@v1 judgment failed');
|
|
5696
|
+
}
|
|
5697
|
+
const picked = classified.output === 'EXTEND' || classified.output === 'SUFFICIENT' || classified.output === 'UNCONVERGEABLE'
|
|
5698
|
+
? classified.output
|
|
5699
|
+
: undefined;
|
|
5700
|
+
if (!picked) throw new Error(`rework-budget@v1 returned unsupported class '${String(classified.output)}'`);
|
|
5701
|
+
parsedDecision = { verdict: picked, reason: diagnosedDecision?.reason ?? 'workflow-fabric classification' };
|
|
5464
5702
|
}
|
|
5465
|
-
|
|
5466
|
-
|
|
5703
|
+
consecutiveUnresolvedBudget = 0;
|
|
5704
|
+
} catch (error) {
|
|
5705
|
+
const message = safeErrorDescription(error);
|
|
5706
|
+
if (!message.startsWith('rework-budget@v1 classification did not resolve a supported class')
|
|
5707
|
+
&& !message.startsWith('rework-budget@v1 returned unsupported class')) throw error;
|
|
5708
|
+
consecutiveUnresolvedBudget++;
|
|
5709
|
+
observe('rework-budget-unresolved-fallback', { round, error: message.slice(0, 200), consecutive: consecutiveUnresolvedBudget }, { level: 'warn' });
|
|
5710
|
+
parsedDecision = consecutiveUnresolvedBudget >= 2
|
|
5711
|
+
? { verdict: 'UNCONVERGEABLE', reason: 'rework-budget classification unresolved ×2' }
|
|
5467
5712
|
: undefined;
|
|
5468
|
-
if (!picked) throw new Error(`rework-budget@v1 returned unsupported class '${String(classified.output)}'`);
|
|
5469
|
-
parsedDecision = { verdict: picked, reason: diagnosedDecision?.reason ?? 'workflow-fabric classification' };
|
|
5470
5713
|
}
|
|
5471
5714
|
let fabricObservation: Record<string, unknown> | undefined;
|
|
5472
5715
|
if (s.classifyCallLLM) {
|
|
@@ -5497,7 +5740,7 @@ async function runSelfImplementInner(
|
|
|
5497
5740
|
selfImplementConfig.reworkBudget.maxRounds,
|
|
5498
5741
|
reworkKind,
|
|
5499
5742
|
priorHistory.length,
|
|
5500
|
-
shadowStop,
|
|
5743
|
+
consecutiveUnresolvedBudget >= 2 ? false : shadowStop,
|
|
5501
5744
|
supervisorDecisionHistory.at(-1)?.verdict,
|
|
5502
5745
|
);
|
|
5503
5746
|
effectiveMax = budgetDecision.effectiveMax;
|
|
@@ -5688,9 +5931,11 @@ async function runSelfImplementInner(
|
|
|
5688
5931
|
const quotaExhaustionAssessment = quotaExhaustionAssessmentForRun();
|
|
5689
5932
|
return { ok: false, stage: 'review-blocked', node: 'rework', ...terminal, ...supervisorOutcome, sessionId, worktreePath: wt.path, branch: wt.branch, gate, review, quotaExhaustionAssessment, ...(lastSupervisorReason ? { supervisorReason: lastSupervisorReason } : {}), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: `rework judged unconvergeable after ${round} rework round(s): ${parsedDecision.reason}` };
|
|
5690
5933
|
}
|
|
5691
|
-
const
|
|
5934
|
+
const baselineStop = noRetryBaseline();
|
|
5935
|
+
const reason = baselineStop.terminationReason ?? parsedDecision.reason;
|
|
5936
|
+
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', verdict: parsedDecision.verdict, reason, gate, decomposition: terminalDecomposition, salvageStatusExpected: false });
|
|
5692
5937
|
const quotaExhaustionAssessment = quotaExhaustionAssessmentForRun();
|
|
5693
|
-
return { ok: false, stage: 'gate-failed', node: 'rework', ...terminal, ...supervisorOutcome, sessionId, worktreePath: wt.path, branch: wt.branch, gate, quotaExhaustionAssessment, ...(lastSupervisorReason ? { supervisorReason: lastSupervisorReason } : {}), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: `rework judged unconvergeable after ${round} rework round(s): ${parsedDecision.reason}` };
|
|
5938
|
+
return { ok: false, stage: 'gate-failed', node: 'rework', ...terminal, ...supervisorOutcome, ...baselineStop, sessionId, worktreePath: wt.path, branch: wt.branch, gate, quotaExhaustionAssessment, ...(lastSupervisorReason ? { supervisorReason: lastSupervisorReason } : {}), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: baselineStop.terminationReason ?? `rework judged unconvergeable after ${round} rework round(s): ${parsedDecision.reason}` };
|
|
5694
5939
|
}
|
|
5695
5940
|
} else {
|
|
5696
5941
|
const repeatedBlockingIds = repeatedBlockingFindingIds(currentBlockingFindings, previousBlockingFindings);
|
|
@@ -5699,7 +5944,10 @@ async function runSelfImplementInner(
|
|
|
5699
5944
|
}
|
|
5700
5945
|
} catch (error) {
|
|
5701
5946
|
if (judgmentStarted) throw error;
|
|
5947
|
+
consecutiveUnresolvedBudget = 0;
|
|
5702
5948
|
}
|
|
5949
|
+
} else if (round > 0) {
|
|
5950
|
+
consecutiveUnresolvedBudget = 0;
|
|
5703
5951
|
}
|
|
5704
5952
|
if (round > effectiveMax) {
|
|
5705
5953
|
finalizeSupervisorDeliveries('rework-round-limit');
|
|
@@ -5711,8 +5959,9 @@ async function runSelfImplementInner(
|
|
|
5711
5959
|
const pr = await preserveBlockedArtifacts({ stage: 'review-blocked', verdict: lastReworkVerdict, reason, gate, salvageStatusExpected: false });
|
|
5712
5960
|
return { ok: false, stage: 'review-blocked', node: 'rework', ...terminal, sessionId, worktreePath: wt.path, branch: wt.branch, gate, review, quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(), ...(lastSupervisorVerdict === 'CONTRACT-CONFLICT' ? { supervisorVerdict: lastSupervisorVerdict } : {}), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: reason };
|
|
5713
5961
|
}
|
|
5714
|
-
const
|
|
5715
|
-
|
|
5962
|
+
const baselineStop = noRetryBaseline();
|
|
5963
|
+
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', verdict: lastReworkVerdict, reason: baselineStop.terminationReason ?? reason, gate, salvageStatusExpected: false });
|
|
5964
|
+
return { ok: false, stage: 'gate-failed', node: 'rework', ...terminal, ...baselineStop, sessionId, worktreePath: wt.path, branch: wt.branch, gate, quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(), ...(lastSupervisorVerdict === 'CONTRACT-CONFLICT' ? { supervisorVerdict: lastSupervisorVerdict } : {}), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: baselineStop.terminationReason ?? reason };
|
|
5716
5965
|
}
|
|
5717
5966
|
const terminal = resolveRunOutcome({ termination: 'budget-exhausted', ...(lastReworkVerdict ? { lastVerdict: lastReworkVerdict } : {}) });
|
|
5718
5967
|
// ⛔⭐ **보존(=커밋·push) 뒤에 발사한다.** 종전엔 발사가 먼저라, 인수 자식이 `--base <그 브랜치>`
|
|
@@ -5751,10 +6000,11 @@ async function runSelfImplementInner(
|
|
|
5751
6000
|
const disposition = { ...terminal, ...(salvage ? { salvage } : {}) };
|
|
5752
6001
|
return { ok: false, stage: 'review-blocked', node: 'rework', ...disposition, sessionId, worktreePath: wt.path, branch: wt.branch, gate, review, quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(), ...(lastSupervisorVerdict === 'CONTRACT-CONFLICT' ? { supervisorVerdict: lastSupervisorVerdict } : {}), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: reason };
|
|
5753
6002
|
}
|
|
5754
|
-
const
|
|
5755
|
-
const
|
|
5756
|
-
const
|
|
5757
|
-
const
|
|
6003
|
+
const baselineStop = noRetryBaseline();
|
|
6004
|
+
const reason = baselineStop.terminationReason ?? `gate failed after ${round - 1} rework round(s)`;
|
|
6005
|
+
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', reason, gate, salvageStatusExpected: !baselineStop.terminationReason });
|
|
6006
|
+
const salvage = baselineStop.terminationReason ? 'parked' : await salvageHardCap(canSalvage, pr);
|
|
6007
|
+
const disposition = { ...terminal, ...(salvage ? { salvage } : {}), ...baselineStop };
|
|
5758
6008
|
return { ok: false, stage: 'gate-failed', node: 'rework', ...disposition, sessionId, worktreePath: wt.path, branch: wt.branch, gate, quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(), ...(lastSupervisorVerdict === 'CONTRACT-CONFLICT' ? { supervisorVerdict: lastSupervisorVerdict } : {}), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: reason };
|
|
5759
6009
|
}
|
|
5760
6010
|
|
|
@@ -5787,6 +6037,9 @@ async function runSelfImplementInner(
|
|
|
5787
6037
|
progress('implementing', round === 0
|
|
5788
6038
|
? '구현 중 (헤드리스 goal-loop·수분 소요)…'
|
|
5789
6039
|
: formatReworkProgressLine(round, effectiveMax, escalateTier, attemptOrdinal));
|
|
6040
|
+
if (round > 0) {
|
|
6041
|
+
try { emitDecision(reworkDecision({ runId, round, effectiveMax, escalateTier, kind: reworkKind })); } catch { /* observation must not interrupt rework */ }
|
|
6042
|
+
}
|
|
5790
6043
|
let reworkArtifactPath: string | undefined;
|
|
5791
6044
|
if (round > 0) {
|
|
5792
6045
|
try {
|
|
@@ -6111,7 +6364,9 @@ async function runSelfImplementInner(
|
|
|
6111
6364
|
progress('gated', !runsGate
|
|
6112
6365
|
? `gate 미실행 — 이 그래프(${graphTemplate.graphId})는 gate 노드를 갖지 않는다`
|
|
6113
6366
|
: gate.passed ? 'gate 통과' : `gate 실패(라운드 ${round})`);
|
|
6367
|
+
if (gate.passed) lastGateUnverifiedKey = undefined;
|
|
6114
6368
|
if (!gate.passed) {
|
|
6369
|
+
await onFailureVerdict('gate');
|
|
6115
6370
|
const facts = gate.reflectGateFacts;
|
|
6116
6371
|
const failureDisposition = decideGateFailureDisposition(facts);
|
|
6117
6372
|
// 타임아웃«뿐» — 도입 0 · 미분류 0 · 자식 책임 없음. 재작업으로 보내지 않고 리뷰로 진행한다.
|
|
@@ -6183,6 +6438,23 @@ async function runSelfImplementInner(
|
|
|
6183
6438
|
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', reason, gate, salvageStatusExpected: false });
|
|
6184
6439
|
return { ok: false, stage: 'gate-failed', node: 'rework', ...resolveRunOutcome({ termination: 'abandoned' }), sessionId, worktreePath: wt.path, branch: wt.branch, gate, quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: reason };
|
|
6185
6440
|
}
|
|
6441
|
+
// ⭐ 반복 열쇠 = 미검증 집합. 실패 시험 0건인데 직전 gate 실패와 «같은» 집합이면 재작업이 그 신호를 못 바꾼다
|
|
6442
|
+
// (run-7dd4cce6: 리뷰 지적 비교는 incomparable · 점수 1/3 · 예산 판정 EXTEND 로 헛돌았다).
|
|
6443
|
+
if (isRepeatedUnverifiedOnlyGateFailure({ previousKey: lastGateUnverifiedKey, unverified: gate.unverified, gateLog: gate.log, ...(facts ? { introduced: facts.introduced } : {}) })) {
|
|
6444
|
+
finalizeSupervisorDeliveries('gate-failed-unverified-repeat');
|
|
6445
|
+
const unverifiedFiles = [...new Set(gate.unverified ?? [])].sort();
|
|
6446
|
+
const reason = `gate failed twice in a row with no failing test and the same ${unverifiedFiles.length} unverified file(s); rework cannot change that signal — escalating without rework`;
|
|
6447
|
+
observe('gate-failed-unverified-repeat-escalated', {
|
|
6448
|
+
round,
|
|
6449
|
+
unverified: unverifiedFiles.slice(0, 20),
|
|
6450
|
+
unverifiedCount: unverifiedFiles.length,
|
|
6451
|
+
reason,
|
|
6452
|
+
}, { level: 'warn' });
|
|
6453
|
+
progress('gate-failed', `중단 — 실패 시험 0건 · 같은 미검증 파일 ${unverifiedFiles.length}개가 되풀이(재작업으로 안 바뀐다 · 사람 판단 대기)`);
|
|
6454
|
+
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', reason, gate, salvageStatusExpected: false });
|
|
6455
|
+
return { ok: false, stage: 'gate-failed', node: 'rework', ...resolveRunOutcome({ termination: 'abandoned' }), sessionId, worktreePath: wt.path, branch: wt.branch, gate, quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: reason };
|
|
6456
|
+
}
|
|
6457
|
+
lastGateUnverifiedKey = unverifiedRepeatKey(gate.unverified);
|
|
6186
6458
|
round++;
|
|
6187
6459
|
continue;
|
|
6188
6460
|
}
|
|
@@ -6225,6 +6497,26 @@ async function runSelfImplementInner(
|
|
|
6225
6497
|
path: designCheck.path,
|
|
6226
6498
|
});
|
|
6227
6499
|
}
|
|
6500
|
+
const runFacts = collectRunFacts(wt.path);
|
|
6501
|
+
let designGate: ReviewDiffContext['designGate'];
|
|
6502
|
+
// Git porcelain collapses untracked directories to `site/`; inspect their files too.
|
|
6503
|
+
let untrackedFiles: string[] = [];
|
|
6504
|
+
if (runFacts.changedFiles?.some((file) => file.endsWith('/'))) {
|
|
6505
|
+
try {
|
|
6506
|
+
const untracked = runGitCommand(wt.path, ['ls-files', '--others', '--exclude-standard'], { encoding: 'utf8' });
|
|
6507
|
+
if (untracked.status === 0) untrackedFiles = untracked.stdout.split(/\r?\n/).filter(Boolean);
|
|
6508
|
+
} catch { /* change discovery must not stop review */ }
|
|
6509
|
+
}
|
|
6510
|
+
if ([...(runFacts.changedFiles ?? []), ...(gateRouteFiles ?? []), ...untrackedFiles].some((file) => /\.(?:html|css)$/i.test(file))) {
|
|
6511
|
+
try {
|
|
6512
|
+
designGate = (s.runDesignGate ?? runDesignGate)({ projectDir: wt.path, base: wt.resolvedBase });
|
|
6513
|
+
} catch (error) {
|
|
6514
|
+
designGate = { unmeasured: safeErrorDescription(error) };
|
|
6515
|
+
}
|
|
6516
|
+
observe('design-gate', 'unmeasured' in designGate
|
|
6517
|
+
? { verdict: null, reason: null, p0Total: null, advisoryTotal: null, files: null, unmeasured: designGate.unmeasured }
|
|
6518
|
+
: { verdict: designGate.verdict, reason: designGate.reason ?? null, p0Total: designGate.p0Total, advisoryTotal: designGate.advisoryTotal, files: designGate.files.length });
|
|
6519
|
+
}
|
|
6228
6520
|
let goalDocumentPath: string | undefined;
|
|
6229
6521
|
try {
|
|
6230
6522
|
goalDocumentPath = opts.goalId ? s.goalDocumentPathByGoalId?.(opts.goalId) : undefined;
|
|
@@ -6233,9 +6525,10 @@ async function runSelfImplementInner(
|
|
|
6233
6525
|
}
|
|
6234
6526
|
const reviewContext = {
|
|
6235
6527
|
runId,
|
|
6236
|
-
...
|
|
6528
|
+
...runFacts,
|
|
6237
6529
|
goal: opts.feature,
|
|
6238
6530
|
goalFile: opts.goalFile,
|
|
6531
|
+
...(priorRunFindings.length ? { priorRunFindings } : {}),
|
|
6239
6532
|
...(goalDocumentPath ? { goalDocumentPath } : {}),
|
|
6240
6533
|
round,
|
|
6241
6534
|
...((round === 0 ? carriedAppliedItems : appliedLastRound)?.length
|
|
@@ -6248,6 +6541,7 @@ async function runSelfImplementInner(
|
|
|
6248
6541
|
// ⛔⭐ 하니스가 이미 센 것을 판정자에게 준다(원장 `JDG-S4`·`JDG-S5` — 로그에만 있으면 못 본다).
|
|
6249
6542
|
...(evidenceCoverage ? { evidenceCoverage } : {}),
|
|
6250
6543
|
...(designCheck ? { designCheck } : {}),
|
|
6544
|
+
...(designGate ? { designGate } : {}),
|
|
6251
6545
|
...(gateEvidence ? { gateEvidenceNote: gateEvidence } : {}),
|
|
6252
6546
|
...(gate.baselineFailures?.some((failure) => failure.attribution === 'preexisting')
|
|
6253
6547
|
? { preexistingTestFailures: gate.baselineFailures
|
|
@@ -6274,6 +6568,7 @@ async function runSelfImplementInner(
|
|
|
6274
6568
|
throw error;
|
|
6275
6569
|
}
|
|
6276
6570
|
onReviewFindings(round, review.mustFix);
|
|
6571
|
+
if (review.mustFix.length > 0) await onFailureVerdict('review');
|
|
6277
6572
|
const reviewFindings = snapshotMustFixFindings([...review.mustFix, ...review.shouldFix]);
|
|
6278
6573
|
const reviewMustFixFindings = reviewFindings.slice(0, review.mustFix.length);
|
|
6279
6574
|
observeReviewFindingRecurrence(round, review.mustFix);
|
|
@@ -6507,7 +6802,7 @@ async function runSelfImplementInner(
|
|
|
6507
6802
|
const { latestSignalIncomplete } = signalIncompleteState(roundClassifications);
|
|
6508
6803
|
const autoMerge = autoMergeEnabled(opts);
|
|
6509
6804
|
const gateTimeoutUnmeasured = isTimeoutOnlyUnmeasuredGate(gate.reflectGateFacts);
|
|
6510
|
-
|
|
6805
|
+
let canAuto = !gateTimeoutUnmeasured && autoMerge && reviewReal && review!.verdict !== 'fail' && reviewDiffComplete && !requiredEvidenceMissing && !latestSignalIncomplete && !decisionSignalRed;
|
|
6511
6806
|
// ⭐⭐ 통과의 «이유»를 둘로 가른다 — ⛔ 막지는 «않는다»(대표 판단 2026-08-11: ⓐ 문면만).
|
|
6512
6807
|
// 📏 근거(`JDG-T36` · merge-decision 300건 전수): `verifyByBreaking` 이 실린 8건의 auto 중 ***5건***이
|
|
6513
6808
|
// ***ran=true 인데 distinguishes=0***(아무것도 안 가르는 자기검증)이었고, 그 다섯이 «전부»
|
|
@@ -6518,7 +6813,7 @@ async function runSelfImplementInner(
|
|
|
6518
6813
|
// 그건 `skippedReason` 이 이미 가른다. 그래서 여기 조건에 넣지 않는다.
|
|
6519
6814
|
const verifyInconclusive = gate.verifyByBreaking?.ran === true && (gate.verifyByBreaking.distinguishes ?? 0) === 0;
|
|
6520
6815
|
const verifyNothingAtBase = verifyInconclusive && (gate.verifyByBreaking?.missingAtBase ?? 0) > 0;
|
|
6521
|
-
|
|
6816
|
+
let mergeReason = canAuto ? (verifyNothingAtBase ? 'review-clean-verify-nothing-at-base' : verifyInconclusive ? 'review-clean-verify-inconclusive' : 'review-clean-armed')
|
|
6522
6817
|
: gateTimeoutUnmeasured ? GATE_TIMEOUT_UNMEASURED_MERGE_REASON
|
|
6523
6818
|
: !autoMerge ? 'no-auto-flag'
|
|
6524
6819
|
: requiredEvidenceMissing ? 'required-evidence-uncovered'
|
|
@@ -6528,9 +6823,9 @@ async function runSelfImplementInner(
|
|
|
6528
6823
|
: review!.verdict === 'fail' ? 'review-must-fix'
|
|
6529
6824
|
: review!.diffTruncated === true ? 'review-diff-truncated'
|
|
6530
6825
|
: 'review-diff-budget-unknown';
|
|
6531
|
-
|
|
6532
|
-
if (canAuto)
|
|
6533
|
-
|
|
6826
|
+
let mergeSkipReason = canAuto ? undefined : mergeReason;
|
|
6827
|
+
if (canAuto) onAutoMergeAuthorizedBeforeSync();
|
|
6828
|
+
const mergeDecisionObservation = {
|
|
6534
6829
|
autoMerge, reviewed: reviewReal, verdict: review?.verdict ?? 'none',
|
|
6535
6830
|
decision: canAuto ? 'auto' : 'hitl', reason: mergeReason,
|
|
6536
6831
|
...mergeDecisionEvidenceCoverage(evidenceCoverage),
|
|
@@ -6552,8 +6847,15 @@ async function runSelfImplementInner(
|
|
|
6552
6847
|
...(gate.verifyByBreaking ? { verifyByBreaking: gate.verifyByBreaking } : {}),
|
|
6553
6848
|
...(decisionSignalPress ? { decisionSignalPress, decisionSignalBaselineOnly } : {}),
|
|
6554
6849
|
...(decisionSignalPressReason ? { decisionSignalPressReason } : {}),
|
|
6555
|
-
}
|
|
6850
|
+
};
|
|
6851
|
+
const recordMergeDecision = () => {
|
|
6852
|
+
observe('merge-decision', {
|
|
6853
|
+
...mergeDecisionObservation,
|
|
6854
|
+
decision: canAuto ? 'auto' : 'hitl', reason: mergeReason,
|
|
6855
|
+
});
|
|
6856
|
+
};
|
|
6556
6857
|
if (opts.completion === 'worktree-only' && !decisionSignalRed) {
|
|
6858
|
+
recordMergeDecision();
|
|
6557
6859
|
progress('worktree-completed', '✅ 작업 트리 완료 — PR 생성 없이 worktree 보존');
|
|
6558
6860
|
observe('worktree-completed', { branch: wt.branch, hadApprover: !!s.approvePr });
|
|
6559
6861
|
return {
|
|
@@ -6561,10 +6863,11 @@ async function runSelfImplementInner(
|
|
|
6561
6863
|
detail: 'worktree-only completion: PR creation skipped',
|
|
6562
6864
|
};
|
|
6563
6865
|
}
|
|
6564
|
-
|
|
6866
|
+
let approved = canAuto ? true : (s.approvePr
|
|
6565
6867
|
? await s.approvePr({ branch: wt.branch, ...(gate.log ? { gateLog: gate.log } : {}), implSummary: impl.summary, ...(review ? { review } : {}) })
|
|
6566
6868
|
: false);
|
|
6567
6869
|
if (!approved) {
|
|
6870
|
+
recordMergeDecision();
|
|
6568
6871
|
observe('pr-declined', { branch: wt.branch, hadApprover: !!s.approvePr });
|
|
6569
6872
|
return {
|
|
6570
6873
|
ok: false, stage: 'pr-declined', node: 'open-pr', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...(mergeSkipReason ? { mergeReason: mergeSkipReason } : {}),
|
|
@@ -6585,6 +6888,9 @@ async function runSelfImplementInner(
|
|
|
6585
6888
|
...(resolvedTarget.error === undefined ? {} : { resolveError: resolvedTarget.error }),
|
|
6586
6889
|
});
|
|
6587
6890
|
progress('merge-conflict', '⚠️ 기본 브랜치 해석 실패 — 자동병합 차단(수동 정합 필요·HITL 결정)');
|
|
6891
|
+
canAuto = false;
|
|
6892
|
+
mergeReason = 'default-branch-unresolved';
|
|
6893
|
+
recordMergeDecision();
|
|
6588
6894
|
return { ok: false, stage: 'merge-conflict', node: 'main-sync', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), detail: 'pre-PR main sync default-branch-unresolved' };
|
|
6589
6895
|
}
|
|
6590
6896
|
progress('gating', `최신 ${mergeTarget} 정합 (병렬 드리프트·LLM 충돌해결)…`);
|
|
@@ -6593,6 +6899,9 @@ async function runSelfImplementInner(
|
|
|
6593
6899
|
observe('pre-pr-sync', mainSyncObservation(sync, mergeTarget, opts.base, wt.branch));
|
|
6594
6900
|
if (sync.status === 'conflict-unresolved' || sync.status === 'error') {
|
|
6595
6901
|
progress('merge-conflict', `⚠️ ${mergeTarget} 정합 ${sync.status}${sync.errorStep === undefined ? '' : ` (${sync.errorStep})`} — 자동병합 차단(수동 정합 필요·HITL 결정)`);
|
|
6902
|
+
canAuto = false;
|
|
6903
|
+
mergeReason = `main-sync-${sync.status}`;
|
|
6904
|
+
recordMergeDecision();
|
|
6596
6905
|
return { ok: false, stage: 'merge-conflict', node: 'main-sync', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), detail: `pre-PR main sync ${sync.status}` };
|
|
6597
6906
|
}
|
|
6598
6907
|
if (sync.status === 'llm-resolved' || sync.status === 'merged') {
|
|
@@ -6602,14 +6911,33 @@ async function runSelfImplementInner(
|
|
|
6602
6911
|
: `${mergeTarget} 정합됨 — 통합 결과 full 재-gate…`);
|
|
6603
6912
|
onNodeEntry('regate', round);
|
|
6604
6913
|
const regate = await withStepTimeout(s.gate(wt.path, { runId, mode: 'postsync' }), T.gate, 'gate');
|
|
6914
|
+
if (!regate.passed) await onFailureVerdict('gate');
|
|
6605
6915
|
// `mode` name/meaning stay: `full` = existing gate including tests. Both
|
|
6606
6916
|
// conflict-resolved and clean-merge reuse this same `s.gate` invocation.
|
|
6917
|
+
const timeoutOnlyPostSync = !regate.passed && postSyncTimeoutOnly(regate.reflectGateFacts);
|
|
6607
6918
|
const postSyncPolicy = postSyncGatePolicy(
|
|
6608
6919
|
regate.passed,
|
|
6609
|
-
regate.reflectGateFacts
|
|
6920
|
+
regate.reflectGateFacts,
|
|
6610
6921
|
sync.status,
|
|
6611
6922
|
);
|
|
6612
6923
|
observe('gate.postsync', postSyncGateObservation(regate, wt.branch, hasModuleLoadFailure, sync.status));
|
|
6924
|
+
if (timeoutOnlyPostSync) {
|
|
6925
|
+
const facts = regate.reflectGateFacts!;
|
|
6926
|
+
observe('post-sync-gate-timeout-only-continued', {
|
|
6927
|
+
introduced: facts.introduced, unknown: facts.unknown, timedOut: facts.timedOut ?? 0,
|
|
6928
|
+
}, { level: 'warn' });
|
|
6929
|
+
canAuto = false;
|
|
6930
|
+
mergeReason = GATE_TIMEOUT_UNMEASURED_MERGE_REASON;
|
|
6931
|
+
mergeSkipReason = mergeReason;
|
|
6932
|
+
approved = s.approvePr
|
|
6933
|
+
? await s.approvePr({
|
|
6934
|
+
branch: wt.branch,
|
|
6935
|
+
gateLog: [regate.log, `post-sync gate timeout-only (introduced=${facts.introduced}, unknown=${facts.unknown}, timedOut=${facts.timedOut ?? 'unmeasured'}, flakyRerun=${facts.flakyRerun ?? 'unmeasured'}); merge reason: ${GATE_TIMEOUT_UNMEASURED_MERGE_REASON}`].filter(Boolean).join('\n'),
|
|
6936
|
+
implSummary: impl.summary,
|
|
6937
|
+
...(review ? { review } : {}),
|
|
6938
|
+
})
|
|
6939
|
+
: false;
|
|
6940
|
+
}
|
|
6613
6941
|
if (postSyncPolicy.mustStop) {
|
|
6614
6942
|
progress('gate-failed', sync.status === 'llm-resolved'
|
|
6615
6943
|
? '중단 — main 충돌해결 후 gate 실패(면책 보류·통합 깨짐)'
|
|
@@ -6619,16 +6947,27 @@ async function runSelfImplementInner(
|
|
|
6619
6947
|
: sync.status === 'llm-resolved'
|
|
6620
6948
|
? 'gate failed after main-sync (conflict-resolved integration break)'
|
|
6621
6949
|
: 'gate failed after main-sync (clean-merge integration break)';
|
|
6950
|
+
canAuto = false;
|
|
6951
|
+
mergeReason = 'post-sync-gate-failed';
|
|
6952
|
+
recordMergeDecision();
|
|
6622
6953
|
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', reason, gate: regate, salvageStatusExpected: false });
|
|
6623
6954
|
return { ok: false, stage: 'gate-failed', node: 'regate', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate: regate, quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(), ...(review ? { review } : {}), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: reason };
|
|
6624
6955
|
}
|
|
6625
6956
|
if (!regate.passed) {
|
|
6626
|
-
progress('gating',
|
|
6957
|
+
progress('gating', timeoutOnlyPostSync
|
|
6958
|
+
? 'main 정합 후 gate 타임아웃만 — 사람 확인으로 진행'
|
|
6959
|
+
: 'main 정합 후 gate 실패는 자식 책임 없음으로 면책 — 통합 깨짐으로 중단하지 않고 계속 진행');
|
|
6627
6960
|
}
|
|
6628
6961
|
gate = regate;
|
|
6629
6962
|
}
|
|
6630
6963
|
}
|
|
6631
6964
|
|
|
6965
|
+
recordMergeDecision();
|
|
6966
|
+
if (!approved) {
|
|
6967
|
+
observe('pr-declined', { branch: wt.branch, hadApprover: !!s.approvePr });
|
|
6968
|
+
return { ok: false, stage: 'pr-declined', node: 'open-pr', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), mergeReason, detail: s.approvePr ? 'PR not approved' : 'no approvePr seam — fail-closed(자동승인 금지)' };
|
|
6969
|
+
}
|
|
6970
|
+
if (canAuto) onMergeApprovalReceived();
|
|
6632
6971
|
const extractedOriginalAsk = extractVerbatimOriginalAsk(opts.feature);
|
|
6633
6972
|
const { labels, declineReasons, eligibility } = resolveAutoReviewLabels(!!opts.autoReview, {
|
|
6634
6973
|
objective: opts.feature,
|
|
@@ -6670,8 +7009,8 @@ async function runSelfImplementInner(
|
|
|
6670
7009
|
// 재면 각각 셋·다섯 칸이 «비어» 있었고, 그중 「원장」과 「위험」은 «둘 다» 0이었다.
|
|
6671
7010
|
// `prBody` 는 모든 인자가 optional 이라 비면 그 절이 «조용히 사라진다» — 그래서 결손이
|
|
6672
7011
|
// 정상 산출과 구별되지 않았다. 이 관문이 그 부재를 «이름으로» 말한다.
|
|
6673
|
-
// ⛔
|
|
6674
|
-
//
|
|
7012
|
+
// ⛔ «막지 않는다» — 골의 내용과 무관하게 착지를 죽이지 않는다. ***거절은 항상 관측으로 남는다***.
|
|
7013
|
+
// (차단 스위치 `prEvidenceArtifactEnforce` 는 2026-09-26 설정 졸업으로 지웠다 — 한 번도 기본으로 안 켜졌다.)
|
|
6675
7014
|
const prEvidence = collectPrEvidence({
|
|
6676
7015
|
feature: opts.feature,
|
|
6677
7016
|
goalFile: opts.goalFile,
|
|
@@ -6686,28 +7025,19 @@ async function runSelfImplementInner(
|
|
|
6686
7025
|
provider: activeProvider.provider,
|
|
6687
7026
|
planRevision: lastPlanRevision,
|
|
6688
7027
|
});
|
|
6689
|
-
const prEvidenceDecision = decidePrEvidenceGate(prEvidence
|
|
6690
|
-
enforce: userConfig.tools.selfImplement.prEvidenceArtifactEnforce === true,
|
|
6691
|
-
});
|
|
7028
|
+
const prEvidenceDecision = decidePrEvidenceGate(prEvidence);
|
|
6692
7029
|
observe('pr-evidence-artifact', {
|
|
6693
7030
|
accepted: prEvidenceDecision.missing.length === 0,
|
|
6694
|
-
blocked: prEvidenceDecision.blocked,
|
|
6695
|
-
enforced: prEvidenceDecision.enforced,
|
|
6696
7031
|
axes: PR_EVIDENCE_AXES.length,
|
|
6697
7032
|
missingCount: prEvidenceDecision.missing.length,
|
|
6698
7033
|
missing: prEvidenceDecision.missing,
|
|
6699
7034
|
...(prEvidenceDecision.reason ? { reason: prEvidenceDecision.reason } : {}),
|
|
6700
7035
|
...(prEvidenceDecision.body ? { bodyChars: prEvidenceDecision.body.length } : {}),
|
|
6701
7036
|
});
|
|
6702
|
-
|
|
6703
|
-
// ⛔ 준비 «전»에 멎는다 — 부실한 본문으로 PR 을 열지 않는다. worktree·브랜치는 보존한다.
|
|
6704
|
-
const location = `PR 근거 아티팩트 관문 차단 — ${prEvidenceDecision.reason} (worktree·branch 보존 · ${wt.branch} · ${wt.path})`;
|
|
6705
|
-
progress('aborted', location);
|
|
6706
|
-
throw new Error(location);
|
|
6707
|
-
}
|
|
7037
|
+
const releaseNote = harnessReleaseNote(goalDocumentForReleaseNote(opts.goalFile), prTitle(opts.feature));
|
|
6708
7038
|
const preparedPrBody = preparePrBody(
|
|
6709
7039
|
[
|
|
6710
|
-
prBody(opts.feature, impl.summary, gate.log, review, reviewIntent, declineReasons, harvestedForPr(), opts.goalFile, lastPlanRevision),
|
|
7040
|
+
prBody(opts.feature, impl.summary, gate.log, review, reviewIntent, declineReasons, harvestedForPr(), opts.goalFile, lastPlanRevision, releaseNote),
|
|
6711
7041
|
...(prEvidenceDecision.body ? ['', '---', '', prEvidenceDecision.body] : []),
|
|
6712
7042
|
].join('\n'),
|
|
6713
7043
|
s.persistPrBodyArtifact,
|
|
@@ -6747,7 +7077,7 @@ async function runSelfImplementInner(
|
|
|
6747
7077
|
});
|
|
6748
7078
|
await flushPrComments(pr);
|
|
6749
7079
|
|
|
6750
|
-
if (canAuto && s.mergePr) {
|
|
7080
|
+
if (canAuto && (s.mergePr || opts.mergeByHost)) {
|
|
6751
7081
|
let docsMarkdownDeletions: number | undefined;
|
|
6752
7082
|
let nonDocsMarkdownDeletions: number | undefined;
|
|
6753
7083
|
let checkedHeadCommit: string | undefined;
|
|
@@ -6777,6 +7107,7 @@ async function runSelfImplementInner(
|
|
|
6777
7107
|
guardFailure = `${checkedHeadCommit === undefined ? 'readPrCommitShas' : 'readPrDiff'} failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
6778
7108
|
}
|
|
6779
7109
|
}
|
|
7110
|
+
if (opts.mergeByHost && checkedHeadCommit && !/^[0-9a-f]{40}$/i.test(checkedHeadCommit)) guardFailure = 'checked head SHA is not a full commit hash';
|
|
6780
7111
|
const blocked = guardFailure !== undefined || docsMarkdownDeletions! >= DOCS_MARKDOWN_AUTO_MERGE_DELETION_THRESHOLD;
|
|
6781
7112
|
observe('auto-merge-docs-deletion-guard', {
|
|
6782
7113
|
number: pr.number, threshold: DOCS_MARKDOWN_AUTO_MERGE_DELETION_THRESHOLD, blocked,
|
|
@@ -6795,11 +7126,29 @@ async function runSelfImplementInner(
|
|
|
6795
7126
|
const guardSkipReason = mergeSkipReason ?? (guardFailure ? 'merge-guard-unevaluated' : 'docs-deletion-threshold');
|
|
6796
7127
|
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), mergeReason: guardSkipReason, prUrl: pr.url, prNumber: pr.number, detail };
|
|
6797
7128
|
}
|
|
7129
|
+
if (opts.mergeByHost) {
|
|
7130
|
+
observe('merge-ready', { number: pr.number, checkedHeadCommit });
|
|
7131
|
+
progress('pr-opened', `호스트 재게이트 대기 (#${pr.number})`);
|
|
7132
|
+
return { ok: true, stage: 'merge-ready', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), checkedHeadCommit: checkedHeadCommit!, prUrl: pr.url, prNumber: pr.number };
|
|
7133
|
+
}
|
|
6798
7134
|
onNodeEntry('merge', round);
|
|
6799
7135
|
progress('merging', '자동 병합 (리뷰 clean·squash)…');
|
|
6800
|
-
const m = await withStepTimeout(s.mergePr({ number: pr.number, cwd: wt.path, matchHeadCommit: checkedHeadCommit! }), T.pr, 'pr');
|
|
7136
|
+
const m = await withStepTimeout(s.mergePr!({ number: pr.number, cwd: wt.path, matchHeadCommit: checkedHeadCommit! }), T.pr, 'pr');
|
|
6801
7137
|
observe('merged', { number: pr.number, merged: m.merged, detail: m.detail ?? null });
|
|
6802
7138
|
if (m.merged) {
|
|
7139
|
+
const directory = releaseNotesDir(elanousStateRoot());
|
|
7140
|
+
const fragment: ReleaseNoteFragment = {
|
|
7141
|
+
pr: pr.number,
|
|
7142
|
+
...releaseNote,
|
|
7143
|
+
source: 'harness',
|
|
7144
|
+
...(m.mergeCommit ? { mergeSha: m.mergeCommit } : {}),
|
|
7145
|
+
};
|
|
7146
|
+
try {
|
|
7147
|
+
writeReleaseNote(directory, fragment);
|
|
7148
|
+
} catch (error) {
|
|
7149
|
+
observe('release-note-write-failed', { number: pr.number, prUrl: pr.url, directory, fragment, error: safeErrorDescription(error) }, { level: 'error' });
|
|
7150
|
+
throw new MergedReleaseNoteWriteError(pr.url, directory, fragment, error);
|
|
7151
|
+
}
|
|
6803
7152
|
const mergedBase = m.baseRefName?.trim() || observedPrBase;
|
|
6804
7153
|
const defaultBranch = resolveDefaultBranchTarget(s.defaultBranchRef ?? defaultBranchRef, wt.path).target ?? undefined;
|
|
6805
7154
|
progress('merged', formatAutoMergeSuccessMessage({ prNumber: pr.number, mergedBase, defaultBranch }));
|