elanous 0.2.0 → 0.2.5
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 +17 -15
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/06ef2eba-d1b99ac6d2ea663c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1413-7179a49332db5a80.js +1 -0
- package/apps/pwa/out/_next/static/chunks/150-25c277137a9638ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1640-bc99ec23bbe29d12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1751.50b96ea9c37b49b6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2300-de059d0ab2a16630.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2684-05b0a81e75298c16.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3026-2ed7e317d9b02102.js +25 -0
- package/apps/pwa/out/_next/static/chunks/3611-77496ada38cd6358.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3717-68957c4dc9ceec90.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3929-46ba9af6f9d895cc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4015-62c5a3744698a8da.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4217-3c4317a7905f9eeb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4240-3230f230fae2d7d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4271-e53e075ebd48593b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4377.3b125fef79576dfd.js +5 -0
- package/apps/pwa/out/_next/static/chunks/4440-18bb160d95819f4e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4853-35fdbe6bdbcdc0fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2a79f15a-2013e4d421d6df88.js → 4daa2798-1363d725c79f3593.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5007-6a3b30e23ff68a6e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5244-12b424c42070f5ff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5348-bbf838e119661eee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5391-8793f88b03b30161.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5611-df00af3e4e4a61bb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5890-dca2321773be829a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6123-37c9dc57ddaa7ab0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6588-b7975304a302ab91.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6604-c03961962b6273b6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7109-cf8c87e968e83a65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7178-30f77877525a2efb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7262-871563fc9663730b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7294-f0eeebb92aa93459.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7429-881af44deed6958f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5927.8378481a12cc8044.js → 7527.943753b6ed829f09.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/764-a01e858525a190c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7868-e35d5f7985ecd3f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8320-51484af7b01fdfa5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6804.8ed6ab492bc5fc0a.js → 8617.465ca22a319c95b3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{320-d7013ec072863e5e.js → 8918-482b30ce2a8ebf4c.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/9131-52f5fad51cceca04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2598.814f64e3268634e7.js → 9238.2cd5f47f4bf7a2c3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9704-3221c102623c8d73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-70c404c7bb6d7f0f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-3ffd80166b1050aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f89e9a303515a033.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-4f403cd060442c95.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-0ac5d053f0444d21.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-4bcc63e272ae8205.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-880734bd07d62882.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-72bd384898d88955.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-1018bbc9586ecae5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-de86f8c38076dd7b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-70c404c7bb6d7f0f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-cd6447196d8bafe6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-e733630c47fa102b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-d1c1a8357b161875.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-60c514128e81d787.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8b637b7e325e13c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-bccce0babceae30f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-63301d11dbe73836.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-a8cf0dc472060db2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-02fba54881ccfa49.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-d5e8e90f0038f8de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-b1ef6824f494466a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-d589bb0f233b1009.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c9bbaebef4cda059.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-3639ce7916b92fed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7450ae7478955653.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-70c404c7bb6d7f0f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-b41ca4abfd618452.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-b333dd79ebee3fa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-8be1227492793655.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-6e03e9371b552e0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-911411e9fca18d03.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-792170e649b37088.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-c40463466937bc91.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-509c798b80384536.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-1cac2aa21d77c417.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-9626799d9b4a2cd1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-84cd419494e16b0f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/f6f3850d-7f324c6566002113.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-361487d2da603917.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-607f5beb94cb2e07.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-d0222d219e29dddf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-a26980a31126decc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-edb2b37decf23e4d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-2bf59c720fe9542c.js +1 -0
- package/apps/pwa/out/_next/static/css/eaa74e8bb2f62269.css +1 -0
- package/apps/pwa/out/_next/static/ktMqfrBbf8BMGac0jqLrb/_buildManifest.js +1 -0
- package/apps/pwa/out/approvals/index.html +1 -0
- package/apps/pwa/out/approvals/index.txt +32 -0
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +29 -26
- package/apps/pwa/out/board/index.html +1 -0
- package/apps/pwa/out/board/index.txt +32 -0
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +26 -23
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +26 -23
- package/apps/pwa/out/chat/index.html +1 -2
- package/apps/pwa/out/chat/index.txt +26 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +29 -26
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +29 -26
- package/apps/pwa/out/editor/index.html +1 -0
- package/apps/pwa/out/editor/index.txt +33 -0
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/icons/elanous-16.png +0 -0
- package/apps/pwa/out/icons/elanous-180.png +0 -0
- package/apps/pwa/out/icons/elanous-192.png +0 -0
- package/apps/pwa/out/icons/elanous-32.png +0 -0
- package/apps/pwa/out/icons/elanous-512.png +0 -0
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +26 -23
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +29 -26
- package/apps/pwa/out/live/index.html +1 -0
- package/apps/pwa/out/live/index.txt +32 -0
- package/apps/pwa/out/manifest.webmanifest +5 -2
- package/apps/pwa/out/market/index.html +1 -0
- package/apps/pwa/out/market/index.txt +29 -0
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +26 -23
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +29 -26
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +29 -26
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +27 -24
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +29 -26
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +26 -23
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +29 -26
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +29 -26
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +29 -26
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +29 -26
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +29 -26
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +26 -23
- package/apps/pwa/out/sw-strategies.js +44 -0
- package/apps/pwa/out/sw.js +6 -44
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +29 -26
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +29 -26
- package/apps/pwa/out/trace/index.html +1 -0
- package/apps/pwa/out/trace/index.txt +32 -0
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +29 -26
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +29 -26
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +29 -27
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +29 -26
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +29 -26
- package/catalog/resources.yaml +14 -17
- 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 +42 -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 +45 -0
- package/graphs/release/release-loop.yaml +45 -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/README.md +1 -0
- package/graphs/video/broll-line.yaml +54 -0
- package/graphs/video/explainer-line.yaml +58 -0
- package/package.json +9 -5
- package/plugins/job-coach/.agents/plugins/marketplace.json +12 -0
- package/plugins/job-coach/.codex-plugin/plugin.json +23 -0
- package/plugins/job-coach/.mcp.json +9 -0
- package/plugins/job-coach/README.md +32 -0
- package/plugins/job-coach/connectors/ncs/server.ts +90 -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/gap-judge.ts +44 -0
- package/plugins/job-coach/graphs/recipes.yaml +45 -0
- package/plugins/job-coach/graphs/report-enterprise.yaml +28 -0
- package/plugins/job-coach/graphs/report.yaml +20 -0
- package/plugins/job-coach/graphs/run-step.ts +302 -0
- package/plugins/job-coach/plugin.json +26 -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/enterprise-ai-fit/SKILL.md +8 -0
- package/plugins/job-coach/skills/enterprise-competency/SKILL.md +8 -0
- package/plugins/job-coach/skills/enterprise-needs/SKILL.md +8 -0
- package/plugins/job-coach/skills/enterprise-roadmap/SKILL.md +8 -0
- package/plugins/job-coach/skills/enterprise-task-analysis/SKILL.md +8 -0
- package/plugins/job-coach/skills/interview-to-profile/SKILL.md +23 -0
- package/plugins/job-coach/skills/run-report/SKILL.md +15 -0
- package/scripts/backup/elanous-backup.sh +143 -14
- package/scripts/backup/elanous-restore.sh +122 -0
- package/scripts/build-docs-site.ts +4 -3
- 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 +28 -9
- package/scripts/coord-post.sh +49 -12
- package/scripts/coord-tracks.json +6 -5
- 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/eval-bot-vs-grok.ts +79 -0
- package/scripts/eval-grok-live-baseline.ts +36 -0
- package/scripts/fixtures/front-route-corpus.sample.json +17 -0
- package/scripts/fleet/node-setup.sh +80 -7
- 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 +63 -0
- package/scripts/landing-heal/run-mission.ts +195 -0
- package/scripts/lib/front-route-measurement.ts +131 -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/lib/tui-sim-keys.ts +42 -0
- package/scripts/market/db-check.ts +212 -0
- package/scripts/market-posture-cycle.ts +63 -4
- package/scripts/measure-front-route-classifier.ts +56 -0
- package/scripts/media/ocr-leak-scan.sh +21 -0
- 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-export.ts +2 -3
- package/scripts/public-import-pr.ts +80 -6
- package/scripts/public-leak-baseline.txt +0 -7
- package/scripts/publish-internal-dist.ts +118 -0
- package/scripts/pwa-scenarios.ts +106 -0
- package/scripts/rebrand-elanous.ts +1 -1
- package/scripts/red-sweep-diff.ts +1 -1
- package/scripts/release-loop/auto-approve-node.ts +72 -0
- 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 +641 -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 +61 -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 +109 -0
- package/scripts/release-loop/test-durations.ts +63 -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 +26 -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-audit-coverage-per-file.sh +16 -0
- package/scripts/test-audit-meaningless.ts +88 -0
- package/scripts/test-audit-overlap-and-weak.ts +73 -0
- package/scripts/test-deterministic.ts +29 -6
- package/scripts/tui-sim.ts +59 -14
- package/scripts/uninstall.sh +10 -3
- package/scripts/ux/bump-installed.sh +20 -0
- package/scripts/ux/lib/cdp.ts +72 -0
- package/scripts/ux/record-page.ts +50 -0
- 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/explainer-video/SKILL.md +99 -0
- package/skills/explainer-video/engine/brand/elanous-mark-on-dark.svg +1 -0
- package/skills/explainer-video/engine/build.mjs +431 -0
- package/skills/explainer-video/engine/vo.ts +37 -0
- package/skills/explainer-video/examples/elanous-0.2.5/script.json +155 -0
- 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/nested-agent-env.ts +1 -0
- 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 +900 -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 +25 -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 +235 -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/acp-token.ts +16 -0
- package/src/auth/github-app-token.ts +112 -0
- 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/gh-rest-fallback.ts +177 -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/pr-manager.ts +51 -4
- 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 +18 -18
- 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/boot/daemon-tools/web-search.ts +2 -1
- package/src/boot/ws-bridge.ts +11 -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 +57 -52
- package/src/chat/input-text-key.ts +2 -2
- package/src/chat/log-scroll-key.ts +12 -0
- 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/submit-trace.ts +30 -0
- 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 +726 -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/decisions-cli.ts +94 -0
- package/src/cli/docs-cli.ts +38 -0
- package/src/cli/doctor-cli.ts +262 -77
- 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 +23 -28
- 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 +52 -13
- package/src/cli/mcp-gateway-cli.ts +94 -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 +201 -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/pr-lineage.ts +2 -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 +102 -27
- package/src/cli/pwa-test.ts +201 -96
- package/src/cli/release-cli.ts +177 -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 +103 -12
- 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 +240 -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 +14 -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 +331 -2562
- 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/input/no-provider-reply.ts +13 -0
- 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/slash-runtime/unknown-slash-reply.ts +78 -0
- package/src/dashboard/stale-install-check.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/decisions/decision-ledger.ts +404 -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 +24 -6
- 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/domains/telegram-kind-route.ts +21 -0
- package/src/element-registry/address.ts +1 -3
- package/src/execution-loop/dispatch-task.ts +139 -0
- package/src/execution-loop/gate-decision-summary.ts +29 -0
- package/src/execution-loop/gates.ts +197 -0
- 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/installed-plugin-nodes.ts +95 -0
- package/src/graph-kinds/plugin-nodes.ts +68 -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 +487 -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 +121 -0
- package/src/harness/harness-cli-command.ts +415 -23
- package/src/harness/harness-pod-dispatch.ts +116 -0
- package/src/harness/harness-stop.ts +260 -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 +233 -0
- package/src/harness/self-send-target.ts +22 -1
- package/src/harness/shell-relay.ts +5 -0
- package/src/harness/worktree-branch-prefix.ts +4 -3
- 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 +712 -3409
- 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 +46 -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 +91 -0
- package/src/intake-plane/digest.ts +111 -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 +180 -0
- package/src/llm/provider-detect.ts +247 -0
- package/src/llm/provider-probe.ts +57 -0
- package/src/llm/usable-llm.ts +32 -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 +196 -0
- package/src/market/official-keys.ts +5 -0
- package/src/market/publish.ts +329 -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 +66 -345
- 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-approvals.ts +125 -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 +328 -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 +42 -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 +31 -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 +307 -0
- package/src/nexus/api/meta-api.ts +18 -0
- package/src/nexus/api/next-fluent-wiring.ts +7 -9
- package/src/nexus/api/plugins-credentials-api.ts +47 -0
- package/src/nexus/api/plugins-market.ts +209 -0
- package/src/nexus/api/pod-credential-api.ts +187 -0
- package/src/nexus/api/public-routes.ts +87 -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 +405 -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 +135 -16
- package/src/nexus/daemon-endpoint.ts +85 -0
- package/src/nexus/default-port.ts +1 -0
- package/src/nexus/index.ts +362 -143
- package/src/nexus/onboarding/pwa-share-prompt.ts +31 -8
- package/src/nexus/onboarding/tailscale-probe.ts +9 -1
- package/src/nexus/outbound/router.ts +1 -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 +27 -4
- 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 +108 -4
- package/src/plugins/core/manifest.ts +104 -7
- package/src/plugins/install/market-fetch.ts +250 -0
- package/src/plugins/install/plugin-credentials.ts +106 -0
- package/src/plugins/install/plugin-install.ts +518 -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/prompt-library/universal-preamble.ts +8 -2
- 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/checklist.ts +191 -0
- package/src/release-loop/manifest.ts +65 -0
- package/src/release-loop/release-note.ts +177 -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 +290 -159
- package/src/self-dev/dev-pipeline.ts +157 -9
- 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 +35 -2
- 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 +41 -3
- 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 +244 -0
- package/src/self-implement/non-git-consent.ts +23 -0
- package/src/self-implement/orchestrator.ts +488 -134
- 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 +207 -40
- 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 +45 -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/steward-cards.ts +45 -0
- package/src/steward/triage.ts +239 -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 +194 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +369 -0
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +207 -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 +147 -0
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +129 -0
- package/src/task-orchestrator/surfaces/pod-source-spec.ts +77 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +930 -45
- 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 +14 -7
- 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/acp-transport-ws-client.ts +72 -5
- package/src/tui-client/headless-core-guard.ts +0 -1
- package/src/tui.ts +11 -7
- package/src/typecheck-ratchet.ts +15 -0
- package/src/ui/hover-presenter.ts +3 -7
- package/src/user-config.ts +453 -190
- package/src/util/spawn-sync-output.ts +15 -0
- package/src/version/code-revision.ts +34 -9
- 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/free.ts +77 -0
- package/src/web-search/index.ts +7 -5
- package/src/web-terminal/preview-tap-registry.ts +152 -43
- package/src/workflow-runtime/deps-bridge.ts +4 -3
- 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 +166 -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 +76 -5
- 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/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/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 → ktMqfrBbf8BMGac0jqLrb}/_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
|
|
|
@@ -3240,9 +3307,14 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3240
3307
|
if (opts.childLlm && (typeof opts.childLlm.provider !== 'string' || !opts.childLlm.provider.trim() || typeof opts.childLlm.model !== 'string' || !opts.childLlm.model.trim())) {
|
|
3241
3308
|
throw new Error('childLlm.provider and childLlm.model must both be non-empty');
|
|
3242
3309
|
}
|
|
3243
|
-
const branch = opts.branchName ?? plannedSelfImplBranch(opts.feature, opts.goalId);
|
|
3244
3310
|
const identity = resolveRunIdentity({ explicit: opts.runId });
|
|
3245
3311
|
const { runId } = identity;
|
|
3312
|
+
const branch = opts.branchName ?? plannedSelfImplBranch(opts.feature, opts.goalId, runId);
|
|
3313
|
+
try {
|
|
3314
|
+
debug.log('self-implement.branch', 'planned', {
|
|
3315
|
+
runId, goalId: opts.goalId, branch, runSuffix: opts.branchName === undefined ? branch.match(/-r[a-z0-9]{6}$/)?.[0] ?? null : null,
|
|
3316
|
+
});
|
|
3317
|
+
} catch { /* observation must not block the run */ }
|
|
3246
3318
|
const attemptOrdinal = incrementRunAttemptOrdinal(runId);
|
|
3247
3319
|
const shardIdentity = parseRunShardIdentity(opts.feature);
|
|
3248
3320
|
const observeOuter = makeRunObserver(runId, opts.goalId, debug.log.bind(debug), opts.seams.writeRunLedger, shardIdentity);
|
|
@@ -3314,13 +3386,30 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3314
3386
|
};
|
|
3315
3387
|
let loopRegistered = false;
|
|
3316
3388
|
let mergeApprovalReceived = false;
|
|
3389
|
+
let autoMergeAuthorizedBeforeSync = false;
|
|
3317
3390
|
let lastParsedSupervisorVerdict: ReworkBudgetVerdict | undefined;
|
|
3318
3391
|
let lastParsedSupervisorReason: string | undefined;
|
|
3319
3392
|
let providerErrorCount = 0;
|
|
3320
3393
|
let credentialFailureCount = 0;
|
|
3394
|
+
let failureSequence = 0;
|
|
3395
|
+
let lastProviderErrorSeq = 0;
|
|
3396
|
+
let lastCredentialFailureSeq = 0;
|
|
3397
|
+
let lastFailedGateSeq = 0;
|
|
3398
|
+
let lastMustFixReviewSeq = 0;
|
|
3399
|
+
const recordFailureVerdict = async (kind: 'gate' | 'review'): Promise<void> => {
|
|
3400
|
+
// Capture child errors at the verdict boundary, not when terminal reporting eventually reads them.
|
|
3401
|
+
await mergeChildProviderErrors();
|
|
3402
|
+
if (kind === 'gate') lastFailedGateSeq = ++failureSequence;
|
|
3403
|
+
else lastMustFixReviewSeq = ++failureSequence;
|
|
3404
|
+
};
|
|
3405
|
+
const latestVerdictSeq = (): number => Math.max(lastFailedGateSeq, lastMustFixReviewSeq);
|
|
3406
|
+
const hasCurrentProviderError = (): boolean => providerErrorCount > 0 && lastProviderErrorSeq > latestVerdictSeq();
|
|
3407
|
+
const hasCurrentCredentialFailure = (): boolean => credentialFailureCount > 0 && lastCredentialFailureSeq > latestVerdictSeq();
|
|
3321
3408
|
let lastProviderError: { provider?: string; message?: string } | undefined;
|
|
3322
3409
|
let lastCredentialFailure: { provider?: string; message?: string } | undefined;
|
|
3323
3410
|
let childProviderErrorQueryStatus: 'found' | 'none' | 'unavailable' | 'not-configured' = 'not-configured';
|
|
3411
|
+
let queriedProviderErrorCount = 0;
|
|
3412
|
+
let queriedCredentialFailureCount = 0;
|
|
3324
3413
|
const providerErrorsForResult = (): Pick<SelfImplementResult, 'providerErrors'> => {
|
|
3325
3414
|
if (providerErrorCount === 0) return {};
|
|
3326
3415
|
const message = lastProviderError?.message ?? '';
|
|
@@ -3340,8 +3429,14 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3340
3429
|
const result = await query({ runId, sinceMs: startedAtMs, untilMs: Date.now() });
|
|
3341
3430
|
childProviderErrorQueryStatus = result.status;
|
|
3342
3431
|
if (result.status !== 'found') return;
|
|
3343
|
-
|
|
3344
|
-
|
|
3432
|
+
const newProviderErrors = Math.max(0, result.providerErrorCount - queriedProviderErrorCount);
|
|
3433
|
+
const newCredentialFailures = Math.max(0, result.credentialFailureCount - queriedCredentialFailureCount);
|
|
3434
|
+
providerErrorCount += newProviderErrors;
|
|
3435
|
+
credentialFailureCount += newCredentialFailures;
|
|
3436
|
+
if (newProviderErrors > 0) lastProviderErrorSeq = ++failureSequence;
|
|
3437
|
+
if (newCredentialFailures > 0) lastCredentialFailureSeq = newProviderErrors > 0 ? lastProviderErrorSeq : ++failureSequence;
|
|
3438
|
+
queriedProviderErrorCount = Math.max(queriedProviderErrorCount, result.providerErrorCount);
|
|
3439
|
+
queriedCredentialFailureCount = Math.max(queriedCredentialFailureCount, result.credentialFailureCount);
|
|
3345
3440
|
lastProviderError = result.lastProviderError ?? lastProviderError;
|
|
3346
3441
|
lastCredentialFailure = result.lastCredentialFailure ?? lastCredentialFailure;
|
|
3347
3442
|
} catch {
|
|
@@ -3356,6 +3451,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3356
3451
|
if (!data || typeof data !== 'object') return;
|
|
3357
3452
|
const { provider, message } = data as Record<string, unknown>;
|
|
3358
3453
|
providerErrorCount++;
|
|
3454
|
+
lastProviderErrorSeq = ++failureSequence;
|
|
3359
3455
|
lastProviderError = {
|
|
3360
3456
|
...(typeof provider === 'string' ? { provider } : {}),
|
|
3361
3457
|
...(typeof message === 'string' ? { message } : {}),
|
|
@@ -3371,6 +3467,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3371
3467
|
// 여기서 문면 정규식으로 다시 재면 소비자마다 다른 답이 나온다.
|
|
3372
3468
|
if ((data as Record<string, unknown>).authRejected === true) {
|
|
3373
3469
|
credentialFailureCount++;
|
|
3470
|
+
lastCredentialFailureSeq = lastProviderErrorSeq;
|
|
3374
3471
|
lastCredentialFailure = { ...lastProviderError };
|
|
3375
3472
|
}
|
|
3376
3473
|
},
|
|
@@ -3379,6 +3476,15 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3379
3476
|
const progressDelivery = { delivered: 0, unwired: 0, callbackFailed: 0 };
|
|
3380
3477
|
let capturedPrNumber: number | undefined;
|
|
3381
3478
|
let openPrInvoked = false;
|
|
3479
|
+
const defaultProviderName = opts.seams.currentProviderName?.() ?? currentProviderName();
|
|
3480
|
+
const runProviderName = opts.childLlm?.provider ?? defaultProviderName;
|
|
3481
|
+
const logQuotaProvider = (assessment: QuotaExhaustionAssessment | undefined): void => {
|
|
3482
|
+
try {
|
|
3483
|
+
debug.log('self-implement.abandoned', 'quota-provider', {
|
|
3484
|
+
runProvider: runProviderName, defaultProvider: defaultProviderName, used: assessment?.exhausted !== undefined,
|
|
3485
|
+
});
|
|
3486
|
+
} catch { /* observation must not change the terminal result */ }
|
|
3487
|
+
};
|
|
3382
3488
|
const instrumentedOpts: SelfImplementOptions = {
|
|
3383
3489
|
...opts,
|
|
3384
3490
|
seams: {
|
|
@@ -3418,6 +3524,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3418
3524
|
/** ⭐ 방문 예산을 읽으려면 «지금 도는 선언»이 필요하다 — 신원과 «같은 패턴»으로 한 번 심는다.
|
|
3419
3525
|
* ⛔ 걸음(`traversedNodes`)은 이 스코프에 있고 선언은 안쪽에서 정해지므로, 둘을 잇는 자리가 여기다. */
|
|
3420
3526
|
let runGraphTemplate: GraphTemplate | undefined;
|
|
3527
|
+
let runContract: RunContract | undefined;
|
|
3421
3528
|
let runGraphIdentity: { graphId: string; graphVersion: string } | undefined;
|
|
3422
3529
|
const setRunGraphIdentity = (identity: { graphId: string; graphVersion: string }): void => {
|
|
3423
3530
|
runGraphIdentity = identity;
|
|
@@ -3469,6 +3576,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3469
3576
|
traversedNodes.push(node);
|
|
3470
3577
|
if (node === 'implement') roundCount++;
|
|
3471
3578
|
const fallbackGraphIdentity = observedGraphIdentity();
|
|
3579
|
+
const contractAtNode = runContract === undefined ? undefined : runContractAtNode(runContract);
|
|
3472
3580
|
observePipeline('pipeline-node-entry', {
|
|
3473
3581
|
...pipelineNodeEntryPayload(
|
|
3474
3582
|
runGraphTemplate ?? { graphId: fallbackGraphIdentity.graphId, version: fallbackGraphIdentity.graphVersion, nodes: [] },
|
|
@@ -3476,7 +3584,15 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3476
3584
|
),
|
|
3477
3585
|
node,
|
|
3478
3586
|
round,
|
|
3587
|
+
...contractAtNode,
|
|
3479
3588
|
});
|
|
3589
|
+
if (contractAtNode?.contractHonored === false) {
|
|
3590
|
+
observeOuter('graph-contract-violation', {
|
|
3591
|
+
node, round,
|
|
3592
|
+
contractSubstrate: contractAtNode.contractSubstrate,
|
|
3593
|
+
actualSubstrate: contractAtNode.actualSubstrate,
|
|
3594
|
+
}, { level: 'warn' });
|
|
3595
|
+
}
|
|
3480
3596
|
};
|
|
3481
3597
|
const observeRoundClassification = (classification: LifecycleScreenComparison): void => {
|
|
3482
3598
|
roundClassifications.push(classification);
|
|
@@ -3731,29 +3847,37 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3731
3847
|
}),
|
|
3732
3848
|
instrumentedOpts.seams.reworkBudgetReviewFindingRecurrence ?? (() => null),
|
|
3733
3849
|
() => { mergeApprovalReceived = true; },
|
|
3850
|
+
() => { autoMergeAuthorizedBeforeSync = true; },
|
|
3734
3851
|
(verdict) => { lastParsedSupervisorVerdict = verdict; },
|
|
3735
3852
|
(reason) => { lastParsedSupervisorReason = reason; },
|
|
3736
3853
|
(base) => { resolvedBase = base ?? undefined; },
|
|
3737
3854
|
(basis) => { observationMeasurementBasis = basis; },
|
|
3738
3855
|
(timeout) => { clarificationTimeout = timeout; },
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
() => providerErrorsForResult().providerErrors?.category,
|
|
3856
|
+
hasCurrentProviderError,
|
|
3857
|
+
hasCurrentCredentialFailure,
|
|
3858
|
+
() => hasCurrentProviderError() ? providerErrorsForResult().providerErrors?.category : undefined,
|
|
3742
3859
|
(rejectedCount) => { reviewReflectRejectedCount = (reviewReflectRejectedCount ?? 0) + rejectedCount; },
|
|
3743
3860
|
observeOuter,
|
|
3744
3861
|
(active) => { runActiveProvider = active; },
|
|
3745
3862
|
(sessionId) => { terminalSessionId = sessionId; },
|
|
3863
|
+
(contract) => { runContract = contract; },
|
|
3864
|
+
recordFailureVerdict,
|
|
3865
|
+
() => providerErrorCount > 0,
|
|
3866
|
+
() => credentialFailureCount > 0,
|
|
3867
|
+
hasCurrentProviderError,
|
|
3868
|
+
hasCurrentCredentialFailure,
|
|
3746
3869
|
);
|
|
3747
3870
|
terminalNode = result.node;
|
|
3748
3871
|
await mergeChildProviderErrors();
|
|
3749
3872
|
const addressedResult = attachAbandonedClassification(
|
|
3750
3873
|
attachReviewReflectionOutcome({ ...result, ...providerErrorsForResult(), runId, ...(lastParsedSupervisorReason ? { supervisorReason: lastParsedSupervisorReason } : {}), ...(mergeApprovalReceived ? { mergeApprovalReceived: true } : {}) }),
|
|
3751
3874
|
opts.goalFile,
|
|
3752
|
-
|
|
3753
|
-
|
|
3875
|
+
hasCurrentProviderError(),
|
|
3876
|
+
hasCurrentCredentialFailure(),
|
|
3754
3877
|
opts.seams.inspectCodexRotation,
|
|
3755
|
-
|
|
3878
|
+
runProviderName,
|
|
3756
3879
|
);
|
|
3880
|
+
if (isAbandonedClassificationOutcome(addressedResult.outcome)) logQuotaProvider(addressedResult.quotaExhaustionAssessment);
|
|
3757
3881
|
observeOuter('child-provider-error-query', { status: childProviderErrorQueryStatus });
|
|
3758
3882
|
if (lastProviderError) {
|
|
3759
3883
|
observeOuter('provider-error-observed', { count: providerErrorCount, ...lastProviderError });
|
|
@@ -3823,14 +3947,15 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3823
3947
|
branch,
|
|
3824
3948
|
...(worktreePath ? { worktreePath } : {}),
|
|
3825
3949
|
...(lastParsedSupervisorReason ? { supervisorReason: lastParsedSupervisorReason } : {}),
|
|
3826
|
-
...(mergeApprovalReceived ? { mergeApprovalReceived: true } : {}),
|
|
3950
|
+
...(mergeApprovalReceived || (e.step === 'merge' && autoMergeAuthorizedBeforeSync) ? { mergeApprovalReceived: true } : {}),
|
|
3827
3951
|
detail: worktreePath
|
|
3828
3952
|
? `자율 단계 '${e.step}' wall-clock ${e.ms}ms 초과 — hang 방지 종결(worktree 회수 경로: ${worktreePath})`
|
|
3829
3953
|
: `자율 단계 '${e.step}' wall-clock ${e.ms}ms 초과 — hang 방지 종결(worktree 생성 전)`,
|
|
3830
3954
|
};
|
|
3831
3955
|
terminalNode = result.node;
|
|
3832
3956
|
await mergeChildProviderErrors();
|
|
3833
|
-
const addressedResult = attachAbandonedClassification(attachReviewReflectionOutcome({ ...result, ...providerErrorsForResult() }), opts.goalFile,
|
|
3957
|
+
const addressedResult = attachAbandonedClassification(attachReviewReflectionOutcome({ ...result, ...providerErrorsForResult() }), opts.goalFile, hasCurrentProviderError(), hasCurrentCredentialFailure(), opts.seams.inspectCodexRotation, runProviderName);
|
|
3958
|
+
logQuotaProvider(addressedResult.quotaExhaustionAssessment);
|
|
3834
3959
|
observeOuter('child-provider-error-query', { status: childProviderErrorQueryStatus });
|
|
3835
3960
|
if (lastProviderError) {
|
|
3836
3961
|
observeOuter('provider-error-observed', { count: providerErrorCount, ...lastProviderError });
|
|
@@ -4012,12 +4137,24 @@ export function readQuotaExhausted(
|
|
|
4012
4137
|
// ⛔⭐⭐⭐ 그리고 이 신호는 **codex 전용**이다(2R must-fix) — provider 를 «안 보면»
|
|
4013
4138
|
// Claude·Grok 으로 돈 런까지 codex 쿼터로 «오분류»한다. 그건 이 PR 이 고치려던
|
|
4014
4139
|
// 「잡통」의 «반대 방향» 오류다.
|
|
4015
|
-
//
|
|
4016
|
-
//
|
|
4140
|
+
// 호출자는 구현 자식 provider 를 우선 넘긴다. 자식 선택이 없으면 프로세스 기본 provider 로 귀속한다.
|
|
4141
|
+
// 부모(리뷰·감독)의 별도 폴백이나 자식 내부 전환은 이 평가의 범위 밖이다.
|
|
4017
4142
|
const snapshot = rotationInspector();
|
|
4018
4143
|
// ⭐ 좁히지 않는다 — 스냅샷이 «이미 아는» 것을 증거로 그대로 옮긴다(`quotaAvailabilityEvidence`).
|
|
4019
4144
|
// ⛔⭐ 「언제 읽었나」를 «값으로» 박는다 — 이 읽기는 런이 «끝난 뒤»다(타입 머리말 참조).
|
|
4020
|
-
|
|
4145
|
+
const evidence = { ...quotaAvailabilityEvidence(snapshot), readPoint: 'postmortem' as const };
|
|
4146
|
+
// ⛔⭐ 정본 스토어가 아는 계정이 «0개»면 회전이 구성되지 않은 것이다 — 「쓸 계정 없음」을 소진으로 읽지 않는다.
|
|
4147
|
+
// 🩸 P6(2026-09-26 Pod 실물): Pod 는 계정 사본 하나만 받고 회전 목록이 없어 no-candidate → 「할당량 소진」으로
|
|
4148
|
+
// 분류됐다. 진짜 원인(게이트의 tsc 127 · P5)이 그 오분류에 가려졌다. 호스트의 진짜 소진(계정은 있는데 전부 찼다)은 그대로다.
|
|
4149
|
+
if (snapshot.knownAccountCount === 0) return { exhausted: undefined, accountAvailability: evidence };
|
|
4150
|
+
// ⛔⭐ 아는 계정이 «하나»뿐이면 no-candidate 는 «돌릴 곳이 원래 없다»는 뜻이지 «찼다»가 아니다.
|
|
4151
|
+
// 🩸 P2 #20869(2026-09-27 Pod 실물): Pod 는 배분받은 계정 사본 «하나»(third · 잔량 넉넉)만 갖고 그 계정의 사용률 신호가
|
|
4152
|
+
// 없었다 → 회전은 no-candidate → 「할당량 소진」으로 분류돼 진짜 원인(리뷰 UNCONVERGEABLE)을 가렸다.
|
|
4153
|
+
// ⇒ 그 한 계정의 사용률도 도달 신호도 없으면 «모름». 사용률을 알면 종전 판정(임계 미만=false · 이상=true)에 맡긴다.
|
|
4154
|
+
if (snapshot.knownAccountCount === 1 && evidence.reason === 'no-candidate' && snapshot.currentUsedPercent === undefined && snapshot.currentReached !== true) {
|
|
4155
|
+
return { exhausted: undefined, accountAvailability: evidence };
|
|
4156
|
+
}
|
|
4157
|
+
return assessQuotaExhaustion(providerName, evidence);
|
|
4021
4158
|
} catch {
|
|
4022
4159
|
return { exhausted: undefined, accountAvailability: undefined }; // fail-soft — 관측은 결론을 막지 않는다
|
|
4023
4160
|
}
|
|
@@ -4085,7 +4222,7 @@ export function attachAbandonedClassification(
|
|
|
4085
4222
|
...(quotaExhaustionAssessment.accountAvailability ? { quotaAccountAvailability: quotaExhaustionAssessment.accountAvailability } : {}),
|
|
4086
4223
|
...(credentialFailure ? { credentialFailure: true } : {}),
|
|
4087
4224
|
...(providerError ? { providerError: true } : {}),
|
|
4088
|
-
...(result.providerErrors?.category ? { providerErrorCategory: result.providerErrors.category } : {}),
|
|
4225
|
+
...(providerError && result.providerErrors?.category ? { providerErrorCategory: result.providerErrors.category } : {}),
|
|
4089
4226
|
worktreePorcelain: worktree.worktreePorcelain,
|
|
4090
4227
|
...(worktree.gitResidue ? { gitResidue: worktree.gitResidue } : {}),
|
|
4091
4228
|
...(result.completionDisposition ? { completionDisposition: result.completionDisposition } : {}),
|
|
@@ -4268,6 +4405,7 @@ async function runSelfImplementInner(
|
|
|
4268
4405
|
* 이제 null 이면 measureReviewFindingRecurrence 가 «실제로» 잰다. */
|
|
4269
4406
|
reworkBudgetReviewFindingRecurrence: () => ReviewFindingRecurrence | null = () => null,
|
|
4270
4407
|
onMergeApprovalReceived: () => void = () => {},
|
|
4408
|
+
onAutoMergeAuthorizedBeforeSync: () => void = () => {},
|
|
4271
4409
|
onSupervisorVerdictParsed: (verdict: ReworkBudgetVerdict) => void = () => {},
|
|
4272
4410
|
onSupervisorReasonParsed: (reason: string | undefined) => void = () => {},
|
|
4273
4411
|
onResolvedBase: (base: string | null) => void = () => {},
|
|
@@ -4282,16 +4420,20 @@ async function runSelfImplementInner(
|
|
|
4282
4420
|
* (그러면 「런이 끝날 무렵의 provider」가 되어 `F45` 를 그대로 밟는다). 시작 시점 값을 넘긴다. */
|
|
4283
4421
|
onActiveProvider: (active: { provider?: string; model?: string; auth?: string }) => void = () => {},
|
|
4284
4422
|
onSessionCreated: (sessionId: string) => void = () => {},
|
|
4423
|
+
onRunContractResolved: (contract: RunContract) => void = () => {},
|
|
4424
|
+
onFailureVerdict: (kind: 'gate' | 'review') => Promise<void> = async () => {},
|
|
4425
|
+
hasObservedProviderError: () => boolean = hasProviderError,
|
|
4426
|
+
hasObservedCredentialFailure: () => boolean = hasCredentialFailure,
|
|
4427
|
+
hasCurrentProviderError: () => boolean = hasProviderError,
|
|
4428
|
+
hasCurrentCredentialFailure: () => boolean = hasCredentialFailure,
|
|
4285
4429
|
): Promise<Omit<SelfImplementResult, 'runId'>> {
|
|
4286
4430
|
const s = opts.seams;
|
|
4287
4431
|
const pipelineStartedAtMs = Date.now();
|
|
4288
|
-
// Graph authority
|
|
4432
|
+
// Graph authority is always ON; retain the resolved event with default provenance.
|
|
4289
4433
|
// For research documents, its declared docs-only routing intentionally skips the gate.
|
|
4290
|
-
const
|
|
4291
|
-
const graphAuthority = resolveGraphAuthorityForUserConfig(userConfig, opts.graphAuthoritative);
|
|
4434
|
+
const graphAuthority = resolveGraphAuthorityForUserConfig();
|
|
4292
4435
|
// ⛔ 골 파일이 «없을 수» 있다 — 그때는 골 종류를 모르므로 implement-loop 으로 간다(없는 길로 안 보낸다).
|
|
4293
4436
|
// ⭐ 대표 지시 ② «변형» — 「최초 결정 시 해당 템플릿 변형을 한다」.
|
|
4294
|
-
// ⛔ 승격이 꺼져 있으면 `decideTemplate` 은 `activeTemplate` 과 «같은 값»을 낸다(고르지도 않는다).
|
|
4295
4437
|
const graphGoalType = opts.goalFile === undefined ? undefined : (goalTypeFields(opts.goalFile).goalType as GoalType | undefined);
|
|
4296
4438
|
// ⛔ 오버레이는 «한 번» 읽는다 — 라운드마다 디스크를 읽으면 도는 중에 파일이 바뀌어 걸음이 갈린다.
|
|
4297
4439
|
// ⛔ 이름이 `graph`인 이유: launch(②)·runtime(③) «둘 다» 이 목록에서 고른다. 단계는 인자로 갈린다.
|
|
@@ -4308,24 +4450,28 @@ async function runSelfImplementInner(
|
|
|
4308
4450
|
// ⛔⭐ `let` 인 이유는 ③ «다이나믹»이다 — 라운드마다 runtime 오버레이가 «앞을 보는 것»만 바꾼다.
|
|
4309
4451
|
// ⛔ 지난 노드를 재정의하지 않는다(RFC §6: 그러면 원장을 사후에 해석할 수 없다).
|
|
4310
4452
|
let graphTemplate = graphDecision.template;
|
|
4311
|
-
/** 단계 이름 → 그 템플릿의 노드 이름.
|
|
4453
|
+
/** 단계 이름 → 그 템플릿의 노드 이름. */
|
|
4312
4454
|
const node = (stage: PipelineNodeId): PipelineNodeId => nodeNameForStage(stage, graphTemplate) as PipelineNodeId;
|
|
4313
4455
|
// ⛔⭐ 맥락이 정해진 «직후» 관측기에 심는다 — 이 줄이 없으면 걸음은 YAML 을 따르고 «신원은 안 따른다».
|
|
4314
4456
|
onGraphResolved(graphIdentityOf(graphTemplate));
|
|
4315
|
-
//
|
|
4316
|
-
// 🩸 2026-09-08: 이 값은 `gate-skipped-by-graph` «한 자리»에서만 났고, 그 사건은
|
|
4317
|
-
// research-loop 이 문서만 바꿨을 때만 난다 ⇒ ***대부분의 런에서 「무엇이 켰나」가 원장에 없었다***.
|
|
4318
|
-
// ⛔ 그래서 A/B 의 관문(「두 팔이 갈렸나」)이 «원리상» 답을 못 얻었다.
|
|
4319
|
-
// ⛔ 「켜짐」만 남기지 않는다 — `source` 가 「안 켰다」와 「켰는데 안 먹었다」를 가른다.
|
|
4457
|
+
// 권위는 항상 켜지지만 이벤트의 필드 모양은 유지하고 출처를 default로 기록한다.
|
|
4320
4458
|
observe('graph-authority-resolved', graphAuthorityFields(graphAuthority, graphTemplate));
|
|
4459
|
+
// ⭐ 런 계약 — 런 시작 «한 번» 해석한다(대표 2026-09-26 «초반 계약을 노드가 준수»). 해석 출처(source)와
|
|
4460
|
+
// 실제 칸(actualSubstrate)을 같이 남겨 「계약이 Pod 인데 로컬에서 돌았나」를 원장이 답하게 한다.
|
|
4461
|
+
// 노드 진입 대조는 관측만 하며 실행을 막지 않는다.
|
|
4462
|
+
{
|
|
4463
|
+
const { resolveRunContract } = await import('./graph-run-contract.js');
|
|
4464
|
+
const runContract = resolveRunContract({ ...(graphTemplate.runContract ? { graph: graphTemplate.runContract } : {}), env: process.env });
|
|
4465
|
+
onRunContractResolved(runContract);
|
|
4466
|
+
observe('graph-run-contract-resolved', { ...graphIdentityOf(graphTemplate), ...runContract, ...runContractAtNode(runContract) });
|
|
4467
|
+
}
|
|
4321
4468
|
// ⛔ 승격이 꺼져 있으면 «심지 않는다» — 그러면 예산 관측도 안 난다(운영 원장이 오늘과 같다).
|
|
4322
4469
|
if (graphAuthority.enabled) onGraphTemplateResolved(graphTemplate);
|
|
4323
4470
|
// ⛔ 선택을 «전부» 싣는다 — 얹힌 것만 실으면 「왜 안 얹혔나」를 사후에 못 묻는다.
|
|
4324
|
-
// ⛔ 「없음」과 「안 봤음」을 가른다: 승격이 꺼졌으면 selections 가 «빈 배열»이고 그것이 값이다.
|
|
4325
4471
|
/** ⭐ ③ «다이나믹» — 라운드마다 runtime 오버레이를 다시 고른다.
|
|
4326
4472
|
* ⛔ **매번 «기준 선언»에서 다시 얹는다** — 이전 라운드 결과 위에 겹쳐 얹으면
|
|
4327
4473
|
* 「이 걸음을 무엇이 만들었나」가 «누적»이 되어 사후에 못 푼다.
|
|
4328
|
-
*
|
|
4474
|
+
* 오버레이 적용은 기존 실행 경로를 그대로 따른다. */
|
|
4329
4475
|
const applyRuntimeOverlays = (round: number): void => {
|
|
4330
4476
|
if (!graphAuthority.enabled) return;
|
|
4331
4477
|
// ⛔ 「지금 아는 것」만 준다 — 없는 값을 0 으로 지어내지 않는다(key-absent 가 그것을 말한다).
|
|
@@ -4376,8 +4522,8 @@ async function runSelfImplementInner(
|
|
|
4376
4522
|
roundClassifications.push(classification);
|
|
4377
4523
|
onRoundClassification(classification);
|
|
4378
4524
|
};
|
|
4379
|
-
const branch = opts.branchName ?? plannedSelfImplBranch(opts.feature, opts.goalId);
|
|
4380
4525
|
const { runId, source: runIdSource } = identity ?? resolveRunIdentity({ explicit: opts.runId });
|
|
4526
|
+
const branch = opts.branchName ?? plannedSelfImplBranch(opts.feature, opts.goalId, runId);
|
|
4381
4527
|
try {
|
|
4382
4528
|
debug.log('run-identity', 'own', {
|
|
4383
4529
|
runId, branch, source: runIdSource, nestDepth: nestInfo().depth, ...originObservationFields(),
|
|
@@ -4406,11 +4552,13 @@ async function runSelfImplementInner(
|
|
|
4406
4552
|
// ⭐ 관측 이벤트와 «같은 값»을 원장으로도 보낸다 — 로그에만 있으면 원장 질의가 못 센다(`F12`).
|
|
4407
4553
|
try { onActiveProvider(activeProvider); } catch { /* 보조 기록이 런을 죽이지 않는다 */ }
|
|
4408
4554
|
const boundedFeature = boundReadableText(opts.feature, RUN_START_FEATURE_MAX_CHARS);
|
|
4555
|
+
const launchCwd = resolve(process.cwd());
|
|
4409
4556
|
observe('start', {
|
|
4410
4557
|
feature: boundedFeature.text, featureTruncated: boundedFeature.truncated, featureOriginalChars: boundedFeature.originalChars,
|
|
4411
4558
|
branch, base: opts.base ?? null, draft: opts.draft ?? true,
|
|
4412
4559
|
willFork: !!(opts.parentSessionId && s.forkSession), parentSessionId: opts.parentSessionId ?? null,
|
|
4413
|
-
nestDepth: nestInfo().depth, goalSource, goalFile: opts.goalFile
|
|
4560
|
+
nestDepth: nestInfo().depth, goalSource, goalFile: opts.goalFile === undefined ? null : resolve(launchCwd, opts.goalFile),
|
|
4561
|
+
targetRoot: gitRootOf(launchCwd) ?? launchCwd, ...originObservationFields(),
|
|
4414
4562
|
provider: activeProvider.provider ?? null, model: activeProvider.model ?? null, auth: activeProvider.auth ?? null,
|
|
4415
4563
|
...(opts.correlationId !== undefined ? { correlationId: opts.correlationId } : {}),
|
|
4416
4564
|
});
|
|
@@ -4777,12 +4925,15 @@ async function runSelfImplementInner(
|
|
|
4777
4925
|
return occurrencePattern.test(reason) && roundsPattern.test(reason);
|
|
4778
4926
|
};
|
|
4779
4927
|
const failCounts: number[] = [];
|
|
4928
|
+
// 직전 gate 실패 라운드의 미검증 집합(정렬 키). 통과하면 비운다 — «연속» 반복만 센다.
|
|
4929
|
+
let lastGateUnverifiedKey: string | undefined;
|
|
4780
4930
|
const reworkHistory: string[] = [];
|
|
4781
4931
|
const supervisorDecisionHistory: Array<{ round: number; verdict: ReworkBudgetVerdict; reason: string }> = [];
|
|
4782
4932
|
let judgedEffectiveMax: number | undefined;
|
|
4783
4933
|
let lastReworkVerdict: ReworkBudgetVerdict | undefined;
|
|
4784
4934
|
let lastSupervisorVerdict: ReworkBudgetVerdict | undefined;
|
|
4785
4935
|
let lastSupervisorReason: string | undefined;
|
|
4936
|
+
let consecutiveUnresolvedBudget = 0;
|
|
4786
4937
|
let pendingPlanRevision: ReworkPlanRevision | undefined;
|
|
4787
4938
|
let lastPlanRevision: ReworkPlanRevision | undefined;
|
|
4788
4939
|
const isReviewRework = (source: SupervisionReworkSource): boolean => {
|
|
@@ -4818,8 +4969,23 @@ async function runSelfImplementInner(
|
|
|
4818
4969
|
observe('review-context-carried', { base: opts.base, basePrLocated: false, carriedItems: 0, headlineComments: 0, source: 'unavailable', error: true, reason: 'lookup-failed' }, { level: 'warn' });
|
|
4819
4970
|
}
|
|
4820
4971
|
}
|
|
4972
|
+
const goalTitle = opts.goalFile ? goalTitleFromTargetGoalFile(opts.goalFile, wt.path) : undefined;
|
|
4973
|
+
let priorRunFindings: Awaited<ReturnType<typeof collectPriorDraftFindings>> = [];
|
|
4974
|
+
if (goalTitle) {
|
|
4975
|
+
try {
|
|
4976
|
+
priorRunFindings = await (s.collectPriorDraftFindings ?? collectPriorDraftFindings)({ goalTitle, currentRunId: runId, repoPath: wt.path });
|
|
4977
|
+
} catch (error) {
|
|
4978
|
+
observe('prior-findings.unreadable', { error: error instanceof Error ? error.message : String(error) });
|
|
4979
|
+
}
|
|
4980
|
+
}
|
|
4981
|
+
if (priorRunFindings.length) {
|
|
4982
|
+
observe('prior-findings.loaded', {
|
|
4983
|
+
prs: priorRunFindings.length,
|
|
4984
|
+
items: priorRunFindings.reduce((sum, finding) => sum + finding.items.length, 0),
|
|
4985
|
+
});
|
|
4986
|
+
}
|
|
4821
4987
|
let appliedLastRound: string[] | undefined;
|
|
4822
|
-
let reviewIntent = buildReviewIntent({ goal: opts.feature, goalFile: opts.goalFile });
|
|
4988
|
+
let reviewIntent = buildReviewIntent({ goal: opts.feature, goalFile: opts.goalFile, ...(priorRunFindings.length ? { priorRunFindings } : {}) });
|
|
4823
4989
|
// ⛔⭐ 리뷰 루프가 만든 마지막 컨텍스트를 잡아 둔다 — PR 본문 조립 직전에 **최종 커밋**의
|
|
4824
4990
|
// 런 사실로 갱신하기 위해서다(3R must-fix). 루프 안 수집은 `openPr` 단계가 만드는 커밋을
|
|
4825
4991
|
// 못 본다: 자식은 파일만 남기고 실제 커밋은 `commitWork` 가 루프 뒤에서 만든다.
|
|
@@ -4996,9 +5162,10 @@ async function runSelfImplementInner(
|
|
|
4996
5162
|
}
|
|
4997
5163
|
};
|
|
4998
5164
|
let preservationBase = wt.resolvedBase;
|
|
5165
|
+
const runProviderName = opts.childLlm?.provider ?? (s.currentProviderName?.() ?? currentProviderName());
|
|
4999
5166
|
let cachedQuotaExhaustionAssessment: QuotaExhaustionAssessment | undefined;
|
|
5000
5167
|
const quotaExhaustionAssessmentForRun = (): QuotaExhaustionAssessment => {
|
|
5001
|
-
cachedQuotaExhaustionAssessment ??= readQuotaExhausted(s.inspectCodexRotation,
|
|
5168
|
+
cachedQuotaExhaustionAssessment ??= readQuotaExhausted(s.inspectCodexRotation, runProviderName);
|
|
5002
5169
|
return cachedQuotaExhaustionAssessment;
|
|
5003
5170
|
};
|
|
5004
5171
|
const classifyUnfinishedRun = (stage: SelfImplementStage, verdict?: ReworkBudgetVerdict, decomposition?: TerminalDecomposition): AbandonedClassificationResult => {
|
|
@@ -5008,9 +5175,9 @@ async function runSelfImplementInner(
|
|
|
5008
5175
|
...(opts.goalFile ? { goalType: goalTypeFields(opts.goalFile).goalType } : {}),
|
|
5009
5176
|
...(quotaExhaustionAssessment.exhausted ? { quotaExhausted: true } : {}),
|
|
5010
5177
|
...(quotaExhaustionAssessment.accountAvailability ? { quotaAccountAvailability: quotaExhaustionAssessment.accountAvailability } : {}),
|
|
5011
|
-
...(
|
|
5012
|
-
...(
|
|
5013
|
-
...(providerErrorCategory() ? { providerErrorCategory: providerErrorCategory() } : {}),
|
|
5178
|
+
...(hasCurrentCredentialFailure() ? { credentialFailure: true } : {}),
|
|
5179
|
+
...(hasCurrentProviderError() ? { providerError: true } : {}),
|
|
5180
|
+
...(hasCurrentProviderError() && providerErrorCategory() ? { providerErrorCategory: providerErrorCategory() } : {}),
|
|
5014
5181
|
worktreePorcelain: worktree.worktreePorcelain,
|
|
5015
5182
|
...(worktree.gitResidue ? { gitResidue: worktree.gitResidue } : {}),
|
|
5016
5183
|
...(impl.completionDisposition ? { completionDisposition: impl.completionDisposition } : {}),
|
|
@@ -5145,30 +5312,76 @@ async function runSelfImplementInner(
|
|
|
5145
5312
|
opts.goalFile,
|
|
5146
5313
|
s.persistPrBodyArtifact,
|
|
5147
5314
|
);
|
|
5148
|
-
// worktree-only
|
|
5149
|
-
|
|
5150
|
-
|
|
5315
|
+
// no-changes wins; worktree-only remains local even for environment stops.
|
|
5316
|
+
const environmentStop = blockedDraftDisposition(classificationRecord.classification) === 'preserve-branch';
|
|
5317
|
+
const worktreeOnly = opts.completion === 'worktree-only';
|
|
5318
|
+
if (worktreeOnly || environmentStop) {
|
|
5151
5319
|
let artifactPath: string | undefined;
|
|
5152
5320
|
let artifactError: string | undefined;
|
|
5153
5321
|
try {
|
|
5154
5322
|
artifactPath = persistFullPrBody(s.persistPrBodyArtifact, {
|
|
5155
|
-
origin: 'self-implement-blocked-draft-pr-worktree-only',
|
|
5323
|
+
origin: worktreeOnly ? 'self-implement-blocked-draft-pr-worktree-only' : 'self-implement-blocked-draft-pr-environment-stop',
|
|
5156
5324
|
body: assembled.body,
|
|
5157
5325
|
originalChars: assembled.originalChars,
|
|
5158
5326
|
});
|
|
5159
5327
|
} catch (persistenceError) {
|
|
5160
5328
|
artifactError = persistenceError instanceof Error ? persistenceError.message : String(persistenceError);
|
|
5161
5329
|
}
|
|
5330
|
+
let pushed = false;
|
|
5331
|
+
let committed = false;
|
|
5332
|
+
let pushError: Error | undefined;
|
|
5333
|
+
let preservationErrorStep: 'worktree' | 'commit' | 'push' | undefined;
|
|
5334
|
+
if (environmentStop && !worktreeOnly) {
|
|
5335
|
+
try {
|
|
5336
|
+
if (!s.preserveBlockedBranch && !existsSync(wt.path)) {
|
|
5337
|
+
preservationErrorStep = 'worktree';
|
|
5338
|
+
throw new Error(`worktree not found: ${wt.path}`);
|
|
5339
|
+
}
|
|
5340
|
+
if (s.preserveBlockedBranch) {
|
|
5341
|
+
pushed = await s.preserveBlockedBranch({ cwd: wt.path, branch: wt.branch, title: prTitle(opts.feature) });
|
|
5342
|
+
if (!pushed) throw new Error('브랜치 push가 성공하지 않았음');
|
|
5343
|
+
} else {
|
|
5344
|
+
preservationErrorStep = 'commit';
|
|
5345
|
+
const commit = commitWorktree(wt.path, prTitle(opts.feature));
|
|
5346
|
+
if (!commit.ok && !/nothing to commit/.test(commit.out)) throw new Error(commit.out);
|
|
5347
|
+
committed = commit.ok;
|
|
5348
|
+
if (runGitCommand(wt.path, ['remote', 'get-url', 'origin']).status === 0) {
|
|
5349
|
+
preservationErrorStep = 'push';
|
|
5350
|
+
const push = runGitCommand(wt.path, ['push', '-u', 'origin', `HEAD:refs/heads/${wt.branch}`]);
|
|
5351
|
+
if (push.status !== 0) throw new Error(push.stderr || push.stdout);
|
|
5352
|
+
pushed = true;
|
|
5353
|
+
}
|
|
5354
|
+
}
|
|
5355
|
+
} catch (error) {
|
|
5356
|
+
pushError = error instanceof Error ? error : new Error(String(error));
|
|
5357
|
+
}
|
|
5358
|
+
}
|
|
5162
5359
|
observe('rework-blocked-draft-pr', {
|
|
5163
5360
|
...observation,
|
|
5164
|
-
skipped: 'worktree-only',
|
|
5361
|
+
skipped: worktreeOnly ? 'worktree-only' : 'environment-stop',
|
|
5362
|
+
...(!worktreeOnly && environmentStop ? { pushed, committed } : {}),
|
|
5165
5363
|
worktreePath: wt.path,
|
|
5364
|
+
...(pushError ? { pushError: pushError.message, preservationErrorStep: preservationErrorStep ?? 'push' } : {}),
|
|
5166
5365
|
...(artifactPath ? { prBodyArtifactPath: artifactPath } : {}),
|
|
5167
5366
|
...(artifactError ? { prBodyArtifactError: artifactError } : {}),
|
|
5168
|
-
});
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5367
|
+
}, pushError ? { level: 'warn' } : undefined);
|
|
5368
|
+
if (pushError) {
|
|
5369
|
+
const failure = preservationErrorStep === 'worktree' ? '워크트리 부재로 보존 실패' : preservationErrorStep === 'commit' ? '로컬 브랜치 커밋 실패' : '원격 브랜치 보존 실패';
|
|
5370
|
+
progress('aborted', `환경 탓 중단 — ${failure}: ${wt.branch} (${pushError.message}; worktree: ${wt.path})`);
|
|
5371
|
+
if (preservationErrorStep === 'worktree') return undefined;
|
|
5372
|
+
throw new Error(`환경 탓 중단 — ${failure}: ${wt.branch} (worktree: ${wt.path})`, { cause: pushError });
|
|
5373
|
+
}
|
|
5374
|
+
if (worktreeOnly) {
|
|
5375
|
+
progress(stage, artifactPath
|
|
5376
|
+
? `worktree-only 완료: draft PR을 열지 않음(worktree·branch 보존 · 중단 사유 보존: ${artifactPath} · worktree: ${wt.path} · branch: ${wt.branch})`
|
|
5377
|
+
: `worktree-only 완료: draft PR을 열지 않음(worktree·branch 보존 · 중단 사유 보존 실패: ${artifactError ?? 'unknown error'} · worktree: ${wt.path} · branch: ${wt.branch})`);
|
|
5378
|
+
} else {
|
|
5379
|
+
// No draft PR on this path, so the stop reason must be findable from the progress line itself.
|
|
5380
|
+
const reasonNote = artifactPath ? `중단 사유 보존: ${artifactPath}` : `중단 사유 보존 실패: ${artifactError ?? 'unknown error'}`;
|
|
5381
|
+
progress(stage, pushed
|
|
5382
|
+
? `환경 탓 중단 — draft PR 없이 브랜치만 보존: ${wt.branch} · ${reasonNote}`
|
|
5383
|
+
: `환경 탓 중단 — draft PR 없이 로컬 브랜치만 보존(원격 origin 없음): ${wt.branch} · worktree: ${wt.path} · ${reasonNote}`);
|
|
5384
|
+
}
|
|
5172
5385
|
return undefined;
|
|
5173
5386
|
}
|
|
5174
5387
|
progress('pr-opening', '중단 산출물을 draft PR로 보존…');
|
|
@@ -5315,6 +5528,23 @@ async function runSelfImplementInner(
|
|
|
5315
5528
|
await flushPrComments(pr);
|
|
5316
5529
|
return { decision, pr };
|
|
5317
5530
|
};
|
|
5531
|
+
const baselineOnlyGate = (): boolean => {
|
|
5532
|
+
const failures = gate?.baselineFailures;
|
|
5533
|
+
return gate?.passed === false && !!failures?.length && gate.reflectGateFacts?.introduced === 0
|
|
5534
|
+
&& gate.reflectGateFacts.unknown === 0
|
|
5535
|
+
&& failures.every(({ attribution }) => attribution === 'preexisting' || attribution === 'flaky-timeout'
|
|
5536
|
+
|| attribution === 'flaky-rerun' || attribution === 'precondition-unmet');
|
|
5537
|
+
};
|
|
5538
|
+
const noRetryBaseline = (): { terminationReason?: 'blocked-by-baseline' } => {
|
|
5539
|
+
if (!baselineOnlyGate()) return {};
|
|
5540
|
+
const failures = gate!.baselineFailures!;
|
|
5541
|
+
debug.log('self-implement.supervisor', 'no-retry-baseline', {
|
|
5542
|
+
runId,
|
|
5543
|
+
preexisting: failures.filter(({ attribution }) => attribution === 'preexisting').length,
|
|
5544
|
+
flaky: failures.filter(({ attribution }) => attribution === 'flaky-timeout' || attribution === 'flaky-rerun').length,
|
|
5545
|
+
});
|
|
5546
|
+
return { terminationReason: 'blocked-by-baseline' };
|
|
5547
|
+
};
|
|
5318
5548
|
const salvageHardCap = async (hardCapBlockedExtend: boolean, pr?: { number: number }): Promise<'launched' | 'parked'> => {
|
|
5319
5549
|
let evidence: ReworkSalvageEvidence | undefined;
|
|
5320
5550
|
if (hardCapBlockedExtend) {
|
|
@@ -5333,21 +5563,27 @@ async function runSelfImplementInner(
|
|
|
5333
5563
|
...(opts.goalFile ? { goalType: goalTypeFields(opts.goalFile).goalType } : {}),
|
|
5334
5564
|
...(quotaExhaustionAssessment.exhausted ? { quotaExhausted: true } : {}),
|
|
5335
5565
|
...(quotaExhaustionAssessment.accountAvailability ? { quotaAccountAvailability: quotaExhaustionAssessment.accountAvailability } : {}),
|
|
5336
|
-
...(
|
|
5337
|
-
...(
|
|
5338
|
-
...(providerErrorCategory() ? { providerErrorCategory: providerErrorCategory() } : {}),
|
|
5566
|
+
...(hasCurrentCredentialFailure() ? { credentialFailure: true } : {}),
|
|
5567
|
+
...(hasCurrentProviderError() ? { providerError: true } : {}),
|
|
5568
|
+
...(hasCurrentProviderError() && providerErrorCategory() ? { providerErrorCategory: providerErrorCategory() } : {}),
|
|
5339
5569
|
worktreePorcelain: worktree.worktreePorcelain,
|
|
5340
5570
|
...(worktree.gitResidue ? { gitResidue: worktree.gitResidue } : {}),
|
|
5341
5571
|
stage: isReviewRework(reworkKind) ? 'review-blocked' : 'gate-failed',
|
|
5342
5572
|
reviewResultObserved: review !== undefined,
|
|
5343
5573
|
mustFixReported: (review?.mustFix.length ?? 0) > 0,
|
|
5344
5574
|
});
|
|
5575
|
+
observe('rework-salvage-classification', { ...abandonedClassification, branch: wt.branch });
|
|
5576
|
+
// Salvage may resume an observed environment interruption even when a later
|
|
5577
|
+
// gate/review verdict is the terminal classification. Keep its cause distinct.
|
|
5578
|
+
const salvageClassification = abandonedClassification.classification === 'implementation-deficit' && hasObservedProviderError()
|
|
5579
|
+
? hasObservedCredentialFailure() ? 'credential-failure' : 'provider-error'
|
|
5580
|
+
: abandonedClassification.classification;
|
|
5345
5581
|
const decision = decideReworkSalvage({
|
|
5346
5582
|
hardCapBlockedExtend,
|
|
5347
5583
|
goalFile: opts.goalFile,
|
|
5348
5584
|
salvageAttempt: opts.salvageAttempt,
|
|
5349
5585
|
evidence,
|
|
5350
|
-
abandonedClassification:
|
|
5586
|
+
abandonedClassification: salvageClassification,
|
|
5351
5587
|
});
|
|
5352
5588
|
if (decision.action !== 'launch') {
|
|
5353
5589
|
const reason = decision.reason;
|
|
@@ -5360,7 +5596,7 @@ async function runSelfImplementInner(
|
|
|
5360
5596
|
const launchObservation = {
|
|
5361
5597
|
branch: wt.branch,
|
|
5362
5598
|
goalFile: opts.goalFile,
|
|
5363
|
-
...(environmentReason ? { reason: environmentReason, abandonedClassification:
|
|
5599
|
+
...(environmentReason ? { reason: environmentReason, abandonedClassification: salvageClassification } : {}),
|
|
5364
5600
|
...(salvageEvidence ? { clean: salvageEvidence.clean, aheadCommits: salvageEvidence.aheadCommits } : {}),
|
|
5365
5601
|
};
|
|
5366
5602
|
observe('rework-salvage', { action: 'launching', ...launchObservation });
|
|
@@ -5437,36 +5673,48 @@ async function runSelfImplementInner(
|
|
|
5437
5673
|
const judgmentCallLLM = s.judgmentCallLLM;
|
|
5438
5674
|
if (diagnosedDecision?.verdict !== 'CONTRACT-CONFLICT' && !judgmentCallLLM) throw new Error('rework-budget@v1 requires a judgment provider');
|
|
5439
5675
|
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
|
-
|
|
5676
|
+
try {
|
|
5677
|
+
const result = diagnosedDecision?.verdict === 'CONTRACT-CONFLICT'
|
|
5678
|
+
? undefined
|
|
5679
|
+
: await withStepTimeout(
|
|
5680
|
+
runWorkflowToCompletion(
|
|
5681
|
+
{
|
|
5682
|
+
workflow: reworkBudgetWorkflow,
|
|
5683
|
+
arguments: diagnosis,
|
|
5684
|
+
artifactsDir: '',
|
|
5685
|
+
persistRun: false,
|
|
5686
|
+
judgmentContext: { kind: reworkKind, history: priorHistory },
|
|
5687
|
+
},
|
|
5688
|
+
{
|
|
5689
|
+
callLLM: judgmentCallLLM!,
|
|
5690
|
+
runBash: async () => ({ stdout: '', stderr: '', exitCode: 0 }),
|
|
5691
|
+
runJudgment: judgmentProvider!,
|
|
5692
|
+
},
|
|
5693
|
+
),
|
|
5694
|
+
T.review,
|
|
5695
|
+
'review',
|
|
5696
|
+
);
|
|
5697
|
+
if (result) {
|
|
5698
|
+
const classified = result.outputs['rework-budget'];
|
|
5699
|
+
if (!result.ok || !classified?.ok || typeof classified.output !== 'string') {
|
|
5700
|
+
throw new Error(classified?.error ?? 'rework-budget@v1 judgment failed');
|
|
5701
|
+
}
|
|
5702
|
+
const picked = classified.output === 'EXTEND' || classified.output === 'SUFFICIENT' || classified.output === 'UNCONVERGEABLE'
|
|
5703
|
+
? classified.output
|
|
5704
|
+
: undefined;
|
|
5705
|
+
if (!picked) throw new Error(`rework-budget@v1 returned unsupported class '${String(classified.output)}'`);
|
|
5706
|
+
parsedDecision = { verdict: picked, reason: diagnosedDecision?.reason ?? 'workflow-fabric classification' };
|
|
5464
5707
|
}
|
|
5465
|
-
|
|
5466
|
-
|
|
5708
|
+
consecutiveUnresolvedBudget = 0;
|
|
5709
|
+
} catch (error) {
|
|
5710
|
+
const message = safeErrorDescription(error);
|
|
5711
|
+
if (!message.startsWith('rework-budget@v1 classification did not resolve a supported class')
|
|
5712
|
+
&& !message.startsWith('rework-budget@v1 returned unsupported class')) throw error;
|
|
5713
|
+
consecutiveUnresolvedBudget++;
|
|
5714
|
+
observe('rework-budget-unresolved-fallback', { round, error: message.slice(0, 200), consecutive: consecutiveUnresolvedBudget }, { level: 'warn' });
|
|
5715
|
+
parsedDecision = consecutiveUnresolvedBudget >= 2
|
|
5716
|
+
? { verdict: 'UNCONVERGEABLE', reason: 'rework-budget classification unresolved ×2' }
|
|
5467
5717
|
: 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
5718
|
}
|
|
5471
5719
|
let fabricObservation: Record<string, unknown> | undefined;
|
|
5472
5720
|
if (s.classifyCallLLM) {
|
|
@@ -5497,7 +5745,7 @@ async function runSelfImplementInner(
|
|
|
5497
5745
|
selfImplementConfig.reworkBudget.maxRounds,
|
|
5498
5746
|
reworkKind,
|
|
5499
5747
|
priorHistory.length,
|
|
5500
|
-
shadowStop,
|
|
5748
|
+
consecutiveUnresolvedBudget >= 2 ? false : shadowStop,
|
|
5501
5749
|
supervisorDecisionHistory.at(-1)?.verdict,
|
|
5502
5750
|
);
|
|
5503
5751
|
effectiveMax = budgetDecision.effectiveMax;
|
|
@@ -5688,9 +5936,11 @@ async function runSelfImplementInner(
|
|
|
5688
5936
|
const quotaExhaustionAssessment = quotaExhaustionAssessmentForRun();
|
|
5689
5937
|
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
5938
|
}
|
|
5691
|
-
const
|
|
5939
|
+
const baselineStop = noRetryBaseline();
|
|
5940
|
+
const reason = baselineStop.terminationReason ?? parsedDecision.reason;
|
|
5941
|
+
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', verdict: parsedDecision.verdict, reason, gate, decomposition: terminalDecomposition, salvageStatusExpected: false });
|
|
5692
5942
|
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}` };
|
|
5943
|
+
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
5944
|
}
|
|
5695
5945
|
} else {
|
|
5696
5946
|
const repeatedBlockingIds = repeatedBlockingFindingIds(currentBlockingFindings, previousBlockingFindings);
|
|
@@ -5699,7 +5949,10 @@ async function runSelfImplementInner(
|
|
|
5699
5949
|
}
|
|
5700
5950
|
} catch (error) {
|
|
5701
5951
|
if (judgmentStarted) throw error;
|
|
5952
|
+
consecutiveUnresolvedBudget = 0;
|
|
5702
5953
|
}
|
|
5954
|
+
} else if (round > 0) {
|
|
5955
|
+
consecutiveUnresolvedBudget = 0;
|
|
5703
5956
|
}
|
|
5704
5957
|
if (round > effectiveMax) {
|
|
5705
5958
|
finalizeSupervisorDeliveries('rework-round-limit');
|
|
@@ -5711,8 +5964,9 @@ async function runSelfImplementInner(
|
|
|
5711
5964
|
const pr = await preserveBlockedArtifacts({ stage: 'review-blocked', verdict: lastReworkVerdict, reason, gate, salvageStatusExpected: false });
|
|
5712
5965
|
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
5966
|
}
|
|
5714
|
-
const
|
|
5715
|
-
|
|
5967
|
+
const baselineStop = noRetryBaseline();
|
|
5968
|
+
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', verdict: lastReworkVerdict, reason: baselineStop.terminationReason ?? reason, gate, salvageStatusExpected: false });
|
|
5969
|
+
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
5970
|
}
|
|
5717
5971
|
const terminal = resolveRunOutcome({ termination: 'budget-exhausted', ...(lastReworkVerdict ? { lastVerdict: lastReworkVerdict } : {}) });
|
|
5718
5972
|
// ⛔⭐ **보존(=커밋·push) 뒤에 발사한다.** 종전엔 발사가 먼저라, 인수 자식이 `--base <그 브랜치>`
|
|
@@ -5751,10 +6005,11 @@ async function runSelfImplementInner(
|
|
|
5751
6005
|
const disposition = { ...terminal, ...(salvage ? { salvage } : {}) };
|
|
5752
6006
|
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
6007
|
}
|
|
5754
|
-
const
|
|
5755
|
-
const
|
|
5756
|
-
const
|
|
5757
|
-
const
|
|
6008
|
+
const baselineStop = noRetryBaseline();
|
|
6009
|
+
const reason = baselineStop.terminationReason ?? `gate failed after ${round - 1} rework round(s)`;
|
|
6010
|
+
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', reason, gate, salvageStatusExpected: !baselineStop.terminationReason });
|
|
6011
|
+
const salvage = baselineStop.terminationReason ? 'parked' : await salvageHardCap(canSalvage, pr);
|
|
6012
|
+
const disposition = { ...terminal, ...(salvage ? { salvage } : {}), ...baselineStop };
|
|
5758
6013
|
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
6014
|
}
|
|
5760
6015
|
|
|
@@ -5787,6 +6042,9 @@ async function runSelfImplementInner(
|
|
|
5787
6042
|
progress('implementing', round === 0
|
|
5788
6043
|
? '구현 중 (헤드리스 goal-loop·수분 소요)…'
|
|
5789
6044
|
: formatReworkProgressLine(round, effectiveMax, escalateTier, attemptOrdinal));
|
|
6045
|
+
if (round > 0) {
|
|
6046
|
+
try { emitDecision(reworkDecision({ runId, round, effectiveMax, escalateTier, kind: reworkKind })); } catch { /* observation must not interrupt rework */ }
|
|
6047
|
+
}
|
|
5790
6048
|
let reworkArtifactPath: string | undefined;
|
|
5791
6049
|
if (round > 0) {
|
|
5792
6050
|
try {
|
|
@@ -6111,7 +6369,9 @@ async function runSelfImplementInner(
|
|
|
6111
6369
|
progress('gated', !runsGate
|
|
6112
6370
|
? `gate 미실행 — 이 그래프(${graphTemplate.graphId})는 gate 노드를 갖지 않는다`
|
|
6113
6371
|
: gate.passed ? 'gate 통과' : `gate 실패(라운드 ${round})`);
|
|
6372
|
+
if (gate.passed) lastGateUnverifiedKey = undefined;
|
|
6114
6373
|
if (!gate.passed) {
|
|
6374
|
+
await onFailureVerdict('gate');
|
|
6115
6375
|
const facts = gate.reflectGateFacts;
|
|
6116
6376
|
const failureDisposition = decideGateFailureDisposition(facts);
|
|
6117
6377
|
// 타임아웃«뿐» — 도입 0 · 미분류 0 · 자식 책임 없음. 재작업으로 보내지 않고 리뷰로 진행한다.
|
|
@@ -6183,6 +6443,23 @@ async function runSelfImplementInner(
|
|
|
6183
6443
|
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', reason, gate, salvageStatusExpected: false });
|
|
6184
6444
|
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
6445
|
}
|
|
6446
|
+
// ⭐ 반복 열쇠 = 미검증 집합. 실패 시험 0건인데 직전 gate 실패와 «같은» 집합이면 재작업이 그 신호를 못 바꾼다
|
|
6447
|
+
// (run-7dd4cce6: 리뷰 지적 비교는 incomparable · 점수 1/3 · 예산 판정 EXTEND 로 헛돌았다).
|
|
6448
|
+
if (isRepeatedUnverifiedOnlyGateFailure({ previousKey: lastGateUnverifiedKey, unverified: gate.unverified, gateLog: gate.log, ...(facts ? { introduced: facts.introduced } : {}) })) {
|
|
6449
|
+
finalizeSupervisorDeliveries('gate-failed-unverified-repeat');
|
|
6450
|
+
const unverifiedFiles = [...new Set(gate.unverified ?? [])].sort();
|
|
6451
|
+
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`;
|
|
6452
|
+
observe('gate-failed-unverified-repeat-escalated', {
|
|
6453
|
+
round,
|
|
6454
|
+
unverified: unverifiedFiles.slice(0, 20),
|
|
6455
|
+
unverifiedCount: unverifiedFiles.length,
|
|
6456
|
+
reason,
|
|
6457
|
+
}, { level: 'warn' });
|
|
6458
|
+
progress('gate-failed', `중단 — 실패 시험 0건 · 같은 미검증 파일 ${unverifiedFiles.length}개가 되풀이(재작업으로 안 바뀐다 · 사람 판단 대기)`);
|
|
6459
|
+
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', reason, gate, salvageStatusExpected: false });
|
|
6460
|
+
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 };
|
|
6461
|
+
}
|
|
6462
|
+
lastGateUnverifiedKey = unverifiedRepeatKey(gate.unverified);
|
|
6186
6463
|
round++;
|
|
6187
6464
|
continue;
|
|
6188
6465
|
}
|
|
@@ -6225,6 +6502,26 @@ async function runSelfImplementInner(
|
|
|
6225
6502
|
path: designCheck.path,
|
|
6226
6503
|
});
|
|
6227
6504
|
}
|
|
6505
|
+
const runFacts = collectRunFacts(wt.path);
|
|
6506
|
+
let designGate: ReviewDiffContext['designGate'];
|
|
6507
|
+
// Git porcelain collapses untracked directories to `site/`; inspect their files too.
|
|
6508
|
+
let untrackedFiles: string[] = [];
|
|
6509
|
+
if (runFacts.changedFiles?.some((file) => file.endsWith('/'))) {
|
|
6510
|
+
try {
|
|
6511
|
+
const untracked = runGitCommand(wt.path, ['ls-files', '--others', '--exclude-standard'], { encoding: 'utf8' });
|
|
6512
|
+
if (untracked.status === 0) untrackedFiles = untracked.stdout.split(/\r?\n/).filter(Boolean);
|
|
6513
|
+
} catch { /* change discovery must not stop review */ }
|
|
6514
|
+
}
|
|
6515
|
+
if ([...(runFacts.changedFiles ?? []), ...(gateRouteFiles ?? []), ...untrackedFiles].some((file) => /\.(?:html|css)$/i.test(file))) {
|
|
6516
|
+
try {
|
|
6517
|
+
designGate = (s.runDesignGate ?? runDesignGate)({ projectDir: wt.path, base: wt.resolvedBase });
|
|
6518
|
+
} catch (error) {
|
|
6519
|
+
designGate = { unmeasured: safeErrorDescription(error) };
|
|
6520
|
+
}
|
|
6521
|
+
observe('design-gate', 'unmeasured' in designGate
|
|
6522
|
+
? { verdict: null, reason: null, p0Total: null, advisoryTotal: null, files: null, unmeasured: designGate.unmeasured }
|
|
6523
|
+
: { verdict: designGate.verdict, reason: designGate.reason ?? null, p0Total: designGate.p0Total, advisoryTotal: designGate.advisoryTotal, files: designGate.files.length });
|
|
6524
|
+
}
|
|
6228
6525
|
let goalDocumentPath: string | undefined;
|
|
6229
6526
|
try {
|
|
6230
6527
|
goalDocumentPath = opts.goalId ? s.goalDocumentPathByGoalId?.(opts.goalId) : undefined;
|
|
@@ -6233,9 +6530,10 @@ async function runSelfImplementInner(
|
|
|
6233
6530
|
}
|
|
6234
6531
|
const reviewContext = {
|
|
6235
6532
|
runId,
|
|
6236
|
-
...
|
|
6533
|
+
...runFacts,
|
|
6237
6534
|
goal: opts.feature,
|
|
6238
6535
|
goalFile: opts.goalFile,
|
|
6536
|
+
...(priorRunFindings.length ? { priorRunFindings } : {}),
|
|
6239
6537
|
...(goalDocumentPath ? { goalDocumentPath } : {}),
|
|
6240
6538
|
round,
|
|
6241
6539
|
...((round === 0 ? carriedAppliedItems : appliedLastRound)?.length
|
|
@@ -6248,6 +6546,7 @@ async function runSelfImplementInner(
|
|
|
6248
6546
|
// ⛔⭐ 하니스가 이미 센 것을 판정자에게 준다(원장 `JDG-S4`·`JDG-S5` — 로그에만 있으면 못 본다).
|
|
6249
6547
|
...(evidenceCoverage ? { evidenceCoverage } : {}),
|
|
6250
6548
|
...(designCheck ? { designCheck } : {}),
|
|
6549
|
+
...(designGate ? { designGate } : {}),
|
|
6251
6550
|
...(gateEvidence ? { gateEvidenceNote: gateEvidence } : {}),
|
|
6252
6551
|
...(gate.baselineFailures?.some((failure) => failure.attribution === 'preexisting')
|
|
6253
6552
|
? { preexistingTestFailures: gate.baselineFailures
|
|
@@ -6274,6 +6573,7 @@ async function runSelfImplementInner(
|
|
|
6274
6573
|
throw error;
|
|
6275
6574
|
}
|
|
6276
6575
|
onReviewFindings(round, review.mustFix);
|
|
6576
|
+
if (review.mustFix.length > 0) await onFailureVerdict('review');
|
|
6277
6577
|
const reviewFindings = snapshotMustFixFindings([...review.mustFix, ...review.shouldFix]);
|
|
6278
6578
|
const reviewMustFixFindings = reviewFindings.slice(0, review.mustFix.length);
|
|
6279
6579
|
observeReviewFindingRecurrence(round, review.mustFix);
|
|
@@ -6507,7 +6807,7 @@ async function runSelfImplementInner(
|
|
|
6507
6807
|
const { latestSignalIncomplete } = signalIncompleteState(roundClassifications);
|
|
6508
6808
|
const autoMerge = autoMergeEnabled(opts);
|
|
6509
6809
|
const gateTimeoutUnmeasured = isTimeoutOnlyUnmeasuredGate(gate.reflectGateFacts);
|
|
6510
|
-
|
|
6810
|
+
let canAuto = !gateTimeoutUnmeasured && autoMerge && reviewReal && review!.verdict !== 'fail' && reviewDiffComplete && !requiredEvidenceMissing && !latestSignalIncomplete && !decisionSignalRed;
|
|
6511
6811
|
// ⭐⭐ 통과의 «이유»를 둘로 가른다 — ⛔ 막지는 «않는다»(대표 판단 2026-08-11: ⓐ 문면만).
|
|
6512
6812
|
// 📏 근거(`JDG-T36` · merge-decision 300건 전수): `verifyByBreaking` 이 실린 8건의 auto 중 ***5건***이
|
|
6513
6813
|
// ***ran=true 인데 distinguishes=0***(아무것도 안 가르는 자기검증)이었고, 그 다섯이 «전부»
|
|
@@ -6518,7 +6818,7 @@ async function runSelfImplementInner(
|
|
|
6518
6818
|
// 그건 `skippedReason` 이 이미 가른다. 그래서 여기 조건에 넣지 않는다.
|
|
6519
6819
|
const verifyInconclusive = gate.verifyByBreaking?.ran === true && (gate.verifyByBreaking.distinguishes ?? 0) === 0;
|
|
6520
6820
|
const verifyNothingAtBase = verifyInconclusive && (gate.verifyByBreaking?.missingAtBase ?? 0) > 0;
|
|
6521
|
-
|
|
6821
|
+
let mergeReason = canAuto ? (verifyNothingAtBase ? 'review-clean-verify-nothing-at-base' : verifyInconclusive ? 'review-clean-verify-inconclusive' : 'review-clean-armed')
|
|
6522
6822
|
: gateTimeoutUnmeasured ? GATE_TIMEOUT_UNMEASURED_MERGE_REASON
|
|
6523
6823
|
: !autoMerge ? 'no-auto-flag'
|
|
6524
6824
|
: requiredEvidenceMissing ? 'required-evidence-uncovered'
|
|
@@ -6528,9 +6828,9 @@ async function runSelfImplementInner(
|
|
|
6528
6828
|
: review!.verdict === 'fail' ? 'review-must-fix'
|
|
6529
6829
|
: review!.diffTruncated === true ? 'review-diff-truncated'
|
|
6530
6830
|
: 'review-diff-budget-unknown';
|
|
6531
|
-
|
|
6532
|
-
if (canAuto)
|
|
6533
|
-
|
|
6831
|
+
let mergeSkipReason = canAuto ? undefined : mergeReason;
|
|
6832
|
+
if (canAuto) onAutoMergeAuthorizedBeforeSync();
|
|
6833
|
+
const mergeDecisionObservation = {
|
|
6534
6834
|
autoMerge, reviewed: reviewReal, verdict: review?.verdict ?? 'none',
|
|
6535
6835
|
decision: canAuto ? 'auto' : 'hitl', reason: mergeReason,
|
|
6536
6836
|
...mergeDecisionEvidenceCoverage(evidenceCoverage),
|
|
@@ -6552,8 +6852,15 @@ async function runSelfImplementInner(
|
|
|
6552
6852
|
...(gate.verifyByBreaking ? { verifyByBreaking: gate.verifyByBreaking } : {}),
|
|
6553
6853
|
...(decisionSignalPress ? { decisionSignalPress, decisionSignalBaselineOnly } : {}),
|
|
6554
6854
|
...(decisionSignalPressReason ? { decisionSignalPressReason } : {}),
|
|
6555
|
-
}
|
|
6855
|
+
};
|
|
6856
|
+
const recordMergeDecision = () => {
|
|
6857
|
+
observe('merge-decision', {
|
|
6858
|
+
...mergeDecisionObservation,
|
|
6859
|
+
decision: canAuto ? 'auto' : 'hitl', reason: mergeReason,
|
|
6860
|
+
});
|
|
6861
|
+
};
|
|
6556
6862
|
if (opts.completion === 'worktree-only' && !decisionSignalRed) {
|
|
6863
|
+
recordMergeDecision();
|
|
6557
6864
|
progress('worktree-completed', '✅ 작업 트리 완료 — PR 생성 없이 worktree 보존');
|
|
6558
6865
|
observe('worktree-completed', { branch: wt.branch, hadApprover: !!s.approvePr });
|
|
6559
6866
|
return {
|
|
@@ -6561,10 +6868,11 @@ async function runSelfImplementInner(
|
|
|
6561
6868
|
detail: 'worktree-only completion: PR creation skipped',
|
|
6562
6869
|
};
|
|
6563
6870
|
}
|
|
6564
|
-
|
|
6871
|
+
let approved = canAuto ? true : (s.approvePr
|
|
6565
6872
|
? await s.approvePr({ branch: wt.branch, ...(gate.log ? { gateLog: gate.log } : {}), implSummary: impl.summary, ...(review ? { review } : {}) })
|
|
6566
6873
|
: false);
|
|
6567
6874
|
if (!approved) {
|
|
6875
|
+
recordMergeDecision();
|
|
6568
6876
|
observe('pr-declined', { branch: wt.branch, hadApprover: !!s.approvePr });
|
|
6569
6877
|
return {
|
|
6570
6878
|
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 +6893,9 @@ async function runSelfImplementInner(
|
|
|
6585
6893
|
...(resolvedTarget.error === undefined ? {} : { resolveError: resolvedTarget.error }),
|
|
6586
6894
|
});
|
|
6587
6895
|
progress('merge-conflict', '⚠️ 기본 브랜치 해석 실패 — 자동병합 차단(수동 정합 필요·HITL 결정)');
|
|
6896
|
+
canAuto = false;
|
|
6897
|
+
mergeReason = 'default-branch-unresolved';
|
|
6898
|
+
recordMergeDecision();
|
|
6588
6899
|
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
6900
|
}
|
|
6590
6901
|
progress('gating', `최신 ${mergeTarget} 정합 (병렬 드리프트·LLM 충돌해결)…`);
|
|
@@ -6593,6 +6904,9 @@ async function runSelfImplementInner(
|
|
|
6593
6904
|
observe('pre-pr-sync', mainSyncObservation(sync, mergeTarget, opts.base, wt.branch));
|
|
6594
6905
|
if (sync.status === 'conflict-unresolved' || sync.status === 'error') {
|
|
6595
6906
|
progress('merge-conflict', `⚠️ ${mergeTarget} 정합 ${sync.status}${sync.errorStep === undefined ? '' : ` (${sync.errorStep})`} — 자동병합 차단(수동 정합 필요·HITL 결정)`);
|
|
6907
|
+
canAuto = false;
|
|
6908
|
+
mergeReason = `main-sync-${sync.status}`;
|
|
6909
|
+
recordMergeDecision();
|
|
6596
6910
|
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
6911
|
}
|
|
6598
6912
|
if (sync.status === 'llm-resolved' || sync.status === 'merged') {
|
|
@@ -6602,14 +6916,33 @@ async function runSelfImplementInner(
|
|
|
6602
6916
|
: `${mergeTarget} 정합됨 — 통합 결과 full 재-gate…`);
|
|
6603
6917
|
onNodeEntry('regate', round);
|
|
6604
6918
|
const regate = await withStepTimeout(s.gate(wt.path, { runId, mode: 'postsync' }), T.gate, 'gate');
|
|
6919
|
+
if (!regate.passed) await onFailureVerdict('gate');
|
|
6605
6920
|
// `mode` name/meaning stay: `full` = existing gate including tests. Both
|
|
6606
6921
|
// conflict-resolved and clean-merge reuse this same `s.gate` invocation.
|
|
6922
|
+
const timeoutOnlyPostSync = !regate.passed && postSyncTimeoutOnly(regate.reflectGateFacts);
|
|
6607
6923
|
const postSyncPolicy = postSyncGatePolicy(
|
|
6608
6924
|
regate.passed,
|
|
6609
|
-
regate.reflectGateFacts
|
|
6925
|
+
regate.reflectGateFacts,
|
|
6610
6926
|
sync.status,
|
|
6611
6927
|
);
|
|
6612
6928
|
observe('gate.postsync', postSyncGateObservation(regate, wt.branch, hasModuleLoadFailure, sync.status));
|
|
6929
|
+
if (timeoutOnlyPostSync) {
|
|
6930
|
+
const facts = regate.reflectGateFacts!;
|
|
6931
|
+
observe('post-sync-gate-timeout-only-continued', {
|
|
6932
|
+
introduced: facts.introduced, unknown: facts.unknown, timedOut: facts.timedOut ?? 0,
|
|
6933
|
+
}, { level: 'warn' });
|
|
6934
|
+
canAuto = false;
|
|
6935
|
+
mergeReason = GATE_TIMEOUT_UNMEASURED_MERGE_REASON;
|
|
6936
|
+
mergeSkipReason = mergeReason;
|
|
6937
|
+
approved = s.approvePr
|
|
6938
|
+
? await s.approvePr({
|
|
6939
|
+
branch: wt.branch,
|
|
6940
|
+
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'),
|
|
6941
|
+
implSummary: impl.summary,
|
|
6942
|
+
...(review ? { review } : {}),
|
|
6943
|
+
})
|
|
6944
|
+
: false;
|
|
6945
|
+
}
|
|
6613
6946
|
if (postSyncPolicy.mustStop) {
|
|
6614
6947
|
progress('gate-failed', sync.status === 'llm-resolved'
|
|
6615
6948
|
? '중단 — main 충돌해결 후 gate 실패(면책 보류·통합 깨짐)'
|
|
@@ -6619,16 +6952,27 @@ async function runSelfImplementInner(
|
|
|
6619
6952
|
: sync.status === 'llm-resolved'
|
|
6620
6953
|
? 'gate failed after main-sync (conflict-resolved integration break)'
|
|
6621
6954
|
: 'gate failed after main-sync (clean-merge integration break)';
|
|
6955
|
+
canAuto = false;
|
|
6956
|
+
mergeReason = 'post-sync-gate-failed';
|
|
6957
|
+
recordMergeDecision();
|
|
6622
6958
|
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', reason, gate: regate, salvageStatusExpected: false });
|
|
6623
6959
|
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
6960
|
}
|
|
6625
6961
|
if (!regate.passed) {
|
|
6626
|
-
progress('gating',
|
|
6962
|
+
progress('gating', timeoutOnlyPostSync
|
|
6963
|
+
? 'main 정합 후 gate 타임아웃만 — 사람 확인으로 진행'
|
|
6964
|
+
: 'main 정합 후 gate 실패는 자식 책임 없음으로 면책 — 통합 깨짐으로 중단하지 않고 계속 진행');
|
|
6627
6965
|
}
|
|
6628
6966
|
gate = regate;
|
|
6629
6967
|
}
|
|
6630
6968
|
}
|
|
6631
6969
|
|
|
6970
|
+
recordMergeDecision();
|
|
6971
|
+
if (!approved) {
|
|
6972
|
+
observe('pr-declined', { branch: wt.branch, hadApprover: !!s.approvePr });
|
|
6973
|
+
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(자동승인 금지)' };
|
|
6974
|
+
}
|
|
6975
|
+
if (canAuto) onMergeApprovalReceived();
|
|
6632
6976
|
const extractedOriginalAsk = extractVerbatimOriginalAsk(opts.feature);
|
|
6633
6977
|
const { labels, declineReasons, eligibility } = resolveAutoReviewLabels(!!opts.autoReview, {
|
|
6634
6978
|
objective: opts.feature,
|
|
@@ -6670,8 +7014,8 @@ async function runSelfImplementInner(
|
|
|
6670
7014
|
// 재면 각각 셋·다섯 칸이 «비어» 있었고, 그중 「원장」과 「위험」은 «둘 다» 0이었다.
|
|
6671
7015
|
// `prBody` 는 모든 인자가 optional 이라 비면 그 절이 «조용히 사라진다» — 그래서 결손이
|
|
6672
7016
|
// 정상 산출과 구별되지 않았다. 이 관문이 그 부재를 «이름으로» 말한다.
|
|
6673
|
-
// ⛔
|
|
6674
|
-
//
|
|
7017
|
+
// ⛔ «막지 않는다» — 골의 내용과 무관하게 착지를 죽이지 않는다. ***거절은 항상 관측으로 남는다***.
|
|
7018
|
+
// (차단 스위치 `prEvidenceArtifactEnforce` 는 2026-09-26 설정 졸업으로 지웠다 — 한 번도 기본으로 안 켜졌다.)
|
|
6675
7019
|
const prEvidence = collectPrEvidence({
|
|
6676
7020
|
feature: opts.feature,
|
|
6677
7021
|
goalFile: opts.goalFile,
|
|
@@ -6686,28 +7030,19 @@ async function runSelfImplementInner(
|
|
|
6686
7030
|
provider: activeProvider.provider,
|
|
6687
7031
|
planRevision: lastPlanRevision,
|
|
6688
7032
|
});
|
|
6689
|
-
const prEvidenceDecision = decidePrEvidenceGate(prEvidence
|
|
6690
|
-
enforce: userConfig.tools.selfImplement.prEvidenceArtifactEnforce === true,
|
|
6691
|
-
});
|
|
7033
|
+
const prEvidenceDecision = decidePrEvidenceGate(prEvidence);
|
|
6692
7034
|
observe('pr-evidence-artifact', {
|
|
6693
7035
|
accepted: prEvidenceDecision.missing.length === 0,
|
|
6694
|
-
blocked: prEvidenceDecision.blocked,
|
|
6695
|
-
enforced: prEvidenceDecision.enforced,
|
|
6696
7036
|
axes: PR_EVIDENCE_AXES.length,
|
|
6697
7037
|
missingCount: prEvidenceDecision.missing.length,
|
|
6698
7038
|
missing: prEvidenceDecision.missing,
|
|
6699
7039
|
...(prEvidenceDecision.reason ? { reason: prEvidenceDecision.reason } : {}),
|
|
6700
7040
|
...(prEvidenceDecision.body ? { bodyChars: prEvidenceDecision.body.length } : {}),
|
|
6701
7041
|
});
|
|
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
|
-
}
|
|
7042
|
+
const releaseNote = harnessReleaseNote(goalDocumentForReleaseNote(opts.goalFile), prTitle(opts.feature));
|
|
6708
7043
|
const preparedPrBody = preparePrBody(
|
|
6709
7044
|
[
|
|
6710
|
-
prBody(opts.feature, impl.summary, gate.log, review, reviewIntent, declineReasons, harvestedForPr(), opts.goalFile, lastPlanRevision),
|
|
7045
|
+
prBody(opts.feature, impl.summary, gate.log, review, reviewIntent, declineReasons, harvestedForPr(), opts.goalFile, lastPlanRevision, releaseNote),
|
|
6711
7046
|
...(prEvidenceDecision.body ? ['', '---', '', prEvidenceDecision.body] : []),
|
|
6712
7047
|
].join('\n'),
|
|
6713
7048
|
s.persistPrBodyArtifact,
|
|
@@ -6747,7 +7082,7 @@ async function runSelfImplementInner(
|
|
|
6747
7082
|
});
|
|
6748
7083
|
await flushPrComments(pr);
|
|
6749
7084
|
|
|
6750
|
-
if (canAuto && s.mergePr) {
|
|
7085
|
+
if (canAuto && (s.mergePr || opts.mergeByHost)) {
|
|
6751
7086
|
let docsMarkdownDeletions: number | undefined;
|
|
6752
7087
|
let nonDocsMarkdownDeletions: number | undefined;
|
|
6753
7088
|
let checkedHeadCommit: string | undefined;
|
|
@@ -6777,6 +7112,7 @@ async function runSelfImplementInner(
|
|
|
6777
7112
|
guardFailure = `${checkedHeadCommit === undefined ? 'readPrCommitShas' : 'readPrDiff'} failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
6778
7113
|
}
|
|
6779
7114
|
}
|
|
7115
|
+
if (opts.mergeByHost && checkedHeadCommit && !/^[0-9a-f]{40}$/i.test(checkedHeadCommit)) guardFailure = 'checked head SHA is not a full commit hash';
|
|
6780
7116
|
const blocked = guardFailure !== undefined || docsMarkdownDeletions! >= DOCS_MARKDOWN_AUTO_MERGE_DELETION_THRESHOLD;
|
|
6781
7117
|
observe('auto-merge-docs-deletion-guard', {
|
|
6782
7118
|
number: pr.number, threshold: DOCS_MARKDOWN_AUTO_MERGE_DELETION_THRESHOLD, blocked,
|
|
@@ -6795,11 +7131,29 @@ async function runSelfImplementInner(
|
|
|
6795
7131
|
const guardSkipReason = mergeSkipReason ?? (guardFailure ? 'merge-guard-unevaluated' : 'docs-deletion-threshold');
|
|
6796
7132
|
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
7133
|
}
|
|
7134
|
+
if (opts.mergeByHost) {
|
|
7135
|
+
observe('merge-ready', { number: pr.number, checkedHeadCommit });
|
|
7136
|
+
progress('pr-opened', `호스트 재게이트 대기 (#${pr.number})`);
|
|
7137
|
+
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 };
|
|
7138
|
+
}
|
|
6798
7139
|
onNodeEntry('merge', round);
|
|
6799
7140
|
progress('merging', '자동 병합 (리뷰 clean·squash)…');
|
|
6800
|
-
const m = await withStepTimeout(s.mergePr({ number: pr.number, cwd: wt.path, matchHeadCommit: checkedHeadCommit! }), T.pr, 'pr');
|
|
7141
|
+
const m = await withStepTimeout(s.mergePr!({ number: pr.number, cwd: wt.path, matchHeadCommit: checkedHeadCommit! }), T.pr, 'pr');
|
|
6801
7142
|
observe('merged', { number: pr.number, merged: m.merged, detail: m.detail ?? null });
|
|
6802
7143
|
if (m.merged) {
|
|
7144
|
+
const directory = releaseNotesDir(elanousStateRoot());
|
|
7145
|
+
const fragment: ReleaseNoteFragment = {
|
|
7146
|
+
pr: pr.number,
|
|
7147
|
+
...releaseNote,
|
|
7148
|
+
source: 'harness',
|
|
7149
|
+
...(m.mergeCommit ? { mergeSha: m.mergeCommit } : {}),
|
|
7150
|
+
};
|
|
7151
|
+
try {
|
|
7152
|
+
writeReleaseNote(directory, fragment);
|
|
7153
|
+
} catch (error) {
|
|
7154
|
+
observe('release-note-write-failed', { number: pr.number, prUrl: pr.url, directory, fragment, error: safeErrorDescription(error) }, { level: 'error' });
|
|
7155
|
+
throw new MergedReleaseNoteWriteError(pr.url, directory, fragment, error);
|
|
7156
|
+
}
|
|
6803
7157
|
const mergedBase = m.baseRefName?.trim() || observedPrBase;
|
|
6804
7158
|
const defaultBranch = resolveDefaultBranchTarget(s.defaultBranchRef ?? defaultBranchRef, wt.path).target ?? undefined;
|
|
6805
7159
|
progress('merged', formatAutoMergeSuccessMessage({ prNumber: pr.number, mergedBase, defaultBranch }));
|