elanous 0.2.20 → 0.2.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/aBi6EyMtLsrl7J8eH4kF7/_buildManifest.js +1 -0
- package/apps/pwa/out/_next/static/chunks/088d8e8a.8069543d082bec12.js +160 -0
- package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +148 -0
- package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +32 -0
- package/apps/pwa/out/_next/static/chunks/119fc678.6f591cdb84ca5791.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +309 -0
- package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +122 -0
- package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +149 -0
- package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +79 -0
- package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +24 -0
- package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +27 -0
- package/apps/pwa/out/_next/static/chunks/1948.5f35b39eef222a94.js +5 -0
- package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +36 -0
- package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +286 -0
- package/apps/pwa/out/_next/static/chunks/{2489-ff55a35b202c0f94.js → 2489-d238d3e2eb5b2bf5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +94 -0
- package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3522-1de1319d028ac89c.js +25 -0
- package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +74 -0
- package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +34 -0
- package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +115 -0
- package/apps/pwa/out/_next/static/chunks/4588.ad3364cb7fb97ada.js +86 -0
- package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +77 -0
- package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +90 -0
- package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +1 -0
- package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{6158.af2e93b7adff709b.js → 6158.566c890adc06a459.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +64 -0
- package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +287 -0
- package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +226 -0
- package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6767.8e6c5f6e744fcd9f.js +38 -0
- package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7175-350f4ce2873bc038.js +1 -0
- package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +41 -0
- package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7630.2b9a68659053ff4e.js +193 -0
- package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7899.597af4a9996c907f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/79b78388.663188133449d707.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8194.484f51e273d9abd2.js +217 -0
- package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +104 -0
- package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +1 -0
- package/apps/pwa/out/_next/static/chunks/88729267.9c6c000157c83f2f.js +62 -0
- package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +93 -0
- package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +23 -0
- package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +62 -0
- package/apps/pwa/out/_next/static/chunks/9832.2ab2e818013574c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/a9f2b54d-40c16bd0efdb04b8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/{page-c855c24de7db74fe.js → page-88459e0903da2803.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/{page-85b316bb4235980b.js → page-d85c43f46f58716b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/board/{page-9b2b26a33cb2cd42.js → page-4e645600579ae952.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-c9955fde67b1bcb5.js → page-87edbfd19117823b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/{page-4ba4abe096b6c2a8.js → page-cbaf66b1e1804adf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/{page-575d4a8b4f7becb2.js → page-80ed511e02c81412.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/control/{page-f5d56ff5f45ad164.js → page-9f5610caaa06178c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/{page-2260e9eef0357421.js → page-ec8f3575e339de74.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/{page-466bf0ee16ad1432.js → page-2a19c5cd3b562580.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/field/{page-a23bc71713bcc08f.js → page-b6a09cde2e07521a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/{page-35bfec2e631d3eae.js → page-abd86cd832aaa011.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/{page-f9ccb1b1adbea14d.js → page-8c3f168fc3f91939.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-ec102c9b8b691e37.js → page-786fb4504d0f2fa9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/{page-db03ae3589a81c9e.js → page-7ec8e289b4c14df6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/{page-4a6463b97f0ad94f.js → page-8c8ac17d52be2a79.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/{page-75bffecc9aa1004e.js → page-d359ab048d63a9d9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/{page-31d5b875760bb62d.js → page-f151cc10ad026940.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/{page-46d5201d2207a511.js → page-bf495a1e284f4e00.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-cf0a4b4abead71ea.js → page-9abcfac07e02a542.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/{page-0acc8e198f7b0dfb.js → page-69cb93d1a2e57e0e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/{page-34882c84f84021c5.js → page-72ec543928d67c3e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/d70879db.c66c56a95a91efc6.js +66 -0
- package/apps/pwa/out/_next/static/chunks/f8626309.a4e5d362b1d55e59.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +1 -0
- package/apps/pwa/out/_next/static/css/{d3427996da11e480.css → b9d8151e48998417.css} +1 -1
- package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +14 -14
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +14 -14
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +14 -14
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +14 -14
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +14 -14
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +14 -14
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +14 -14
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +14 -14
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +14 -14
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +14 -14
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +14 -14
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +15 -15
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +14 -14
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +14 -14
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +14 -14
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +15 -15
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +14 -14
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +14 -14
- package/apps/pwa/out/live-run/index.html +1 -0
- package/apps/pwa/out/live-run/index.txt +35 -0
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +14 -14
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +14 -14
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +14 -14
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +14 -14
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +14 -14
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +14 -14
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +14 -14
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +14 -14
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +14 -14
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +15 -15
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +14 -14
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +14 -14
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +14 -14
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +14 -14
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +14 -14
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +14 -14
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +14 -14
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +14 -14
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +14 -14
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +14 -14
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +14 -14
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +14 -14
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +14 -14
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +14 -14
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +14 -14
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +14 -14
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +14 -14
- package/graphs/catalog/catalog.yaml +1 -1
- package/graphs/drafts/recipes.yaml +6 -6
- package/graphs/implement-loop.yaml +277 -5
- package/graphs/test-diet/recipes.yaml +3 -0
- package/graphs/test-diet/test-diet.yaml +3 -1
- package/package.json +1 -1
- package/scripts/coord-channel-watch.sh +31 -4
- package/scripts/docs-lint.ts +4 -1
- package/scripts/f-session-monitor.ts +69 -0
- package/scripts/hq/standby-snapshot.ts +7 -3
- package/scripts/knowledge-compress.ts +11 -0
- package/scripts/marketing/generate-ax-brief.ts +18 -1
- package/scripts/measure-nl-routing-corpus.ts +11 -3
- package/scripts/nightly-docops.ts +90 -3
- package/scripts/release-loop/gate-node.ts +5 -5
- package/scripts/release-loop/shard-plan.ts +50 -5
- package/scripts/research-coo-admin-dates.ts +39 -0
- package/scripts/rhythm/daily.ts +2 -1
- package/scripts/skills/public-check.ts +7 -2
- package/scripts/smart-merge/resync-shadow.ts +5 -3
- package/scripts/test-diet/lib.ts +81 -1
- package/scripts/test-diet/node.ts +48 -2
- package/scripts/verify-coo-admin-evidence.ts +83 -0
- package/src/acp/client.ts +4 -2
- package/src/agent/run-context.ts +4 -0
- package/src/agent-env/profile.ts +25 -5
- package/src/agent-mission/driver.ts +26 -12
- package/src/agent-mission/supervisor-metrics.ts +17 -2
- package/src/agent-substrate/acp-reviewer.ts +12 -5
- package/src/agent-substrate/pr-reviewer.ts +11 -4
- package/src/agent-substrate/review-intent.ts +102 -3
- package/src/autopilot/build/llm-conflict-merge.ts +22 -8
- package/src/autopilot/pr-manager.ts +18 -8
- package/src/away/release-watch.ts +47 -8
- package/src/briefing/brief-items.ts +104 -11
- package/src/browser-cdp/client.ts +10 -5
- package/src/chat/index.ts +1 -0
- package/src/cli/brief-cli.ts +20 -2
- package/src/cli/config-classify.ts +83 -0
- package/src/cli/control-cli.ts +14 -0
- package/src/cli/decisions-cli.ts +26 -16
- package/src/cli/logs-model-input.ts +1 -1
- package/src/cli/ops-cli.ts +11 -0
- package/src/cli/ops-overview-cli.ts +50 -0
- package/src/cli/pod-cli.ts +1 -0
- package/src/cli/pr-cli.ts +65 -8
- package/src/cli/release-cli.ts +21 -4
- package/src/cli/tasks-cli.ts +214 -1
- package/src/connectors/types.ts +6 -6
- package/src/context-bus/context-now-surfaces.ts +18 -0
- package/src/context-bus/coord-events.ts +32 -4
- package/src/context-bus/long-term-memory.ts +23 -6
- package/src/context-bus/nightly-condense.ts +169 -21
- package/src/control/control-status.ts +87 -0
- package/src/control-plane/light-member.ts +5 -3
- package/src/control-plane/member.ts +172 -7
- package/src/core-turn/run-goal-loop.ts +22 -1
- package/src/dashboard/index.ts +40 -4
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +9 -0
- package/src/decisions/decision-cards.ts +20 -1
- package/src/decisions/decision-ledger.ts +11 -8
- package/src/decisions/web-push-decision-cards.ts +19 -3
- package/src/discord-self-message.ts +2 -2
- package/src/domains/coo-admin-dates.evidence.json +876 -0
- package/src/domains/coo-admin-tool.ts +48 -14
- package/src/domains/ops-status.ts +53 -0
- package/src/domains/outbound-alert.ts +24 -1
- package/src/esc-abort-gate.ts +3 -1
- package/src/exec-requests/planner.ts +6 -0
- package/src/graph-kinds/registry.ts +6 -6
- package/src/graph-runner/graph-cli.ts +91 -2
- package/src/graph-runner/graph-run-api.ts +20 -0
- package/src/graph-runner/graph-tick.ts +73 -12
- package/src/graph-runner/runner.ts +43 -11
- package/src/graph-unify/wf-to-graph.ts +79 -0
- package/src/graph-wizard/archetypes.ts +88 -0
- package/src/graph-wizard/generate.ts +577 -0
- package/src/graph-wizard/saved-steps.ts +120 -0
- package/src/graph-wizard/steps.ts +206 -0
- package/src/harness/harness-cli-command.ts +186 -32
- package/src/harness/harness-queue.ts +58 -14
- package/src/harness/launch-advice.ts +23 -0
- package/src/index.ts +43 -11
- package/src/intake-plane/digest.ts +18 -11
- package/src/knowledge/conclusion-compress.ts +93 -0
- package/src/knowledge/know-find.ts +9 -2
- package/src/knowledge/query.ts +20 -0
- package/src/llm.ts +26 -16
- package/src/loops/neighbor-runtime.ts +88 -0
- package/src/loops/orchestrator/author-depth.ts +29 -11
- package/src/loops/orchestrator/overlap.ts +7 -1
- package/src/loops/orchestrator/resync-shadow.ts +1 -1
- package/src/loops/orchestrator/tick.ts +35 -2
- package/src/loops/orchestrator/traffic.ts +2 -0
- package/src/loops/registry.ts +5 -0
- package/src/market/publish.ts +17 -1
- package/src/maturity/feature-maturity.ts +4 -2
- package/src/mss/logging/redaction.ts +17 -0
- package/src/nexus/api/draft-metrics.ts +128 -0
- package/src/nexus/api/graph-peer-edit.ts +77 -0
- package/src/nexus/api/graph-wizard-api.ts +61 -0
- package/src/nexus/api/graphs-api.ts +193 -17
- package/src/nexus/api/harness-traversal.ts +205 -0
- package/src/nexus/api/http-server.ts +122 -6
- package/src/nexus/api/plugins-market.ts +24 -0
- package/src/nexus/index.ts +3 -2
- package/src/nexus/outbound/router.ts +28 -8
- package/src/oauth/claude-pty-maturity.ts +24 -0
- package/src/oauth/fallback-chain.ts +27 -14
- package/src/onboarding/first-run.ts +3 -0
- package/src/ops/overview-collect.ts +345 -0
- package/src/ops/overview-seat-era.ts +90 -0
- package/src/ops/overview.ts +223 -0
- package/src/plugins/maker/market-bundle.ts +9 -0
- package/src/plugins/maker/plugin-maker.ts +9 -3
- package/src/plugins/maker/wizard-generate.ts +73 -9
- package/src/policy/llm-policy.ts +11 -6
- package/src/release-loop/checklist-board.ts +27 -0
- package/src/release-loop/checklist.ts +38 -0
- package/src/release-loop/gate-shards.ts +7 -2
- package/src/seat-address/seat-address.ts +1 -0
- package/src/seat-loop/seat-loop.ts +174 -20
- package/src/seat-loop/seat-report.ts +29 -1
- package/src/self-dev/ask-launch-flow.ts +4 -2
- package/src/self-dev/ask-launch-io.ts +3 -1
- package/src/self-dev/dev-cli.ts +90 -8
- package/src/self-dev/dev-pipeline.ts +20 -1
- package/src/self-dev/draft-sweep.ts +45 -8
- package/src/self-dev/graph-journey-nodes.ts +157 -0
- package/src/self-dev/graph-journey-route.ts +105 -0
- package/src/self-dev/launch-preflight.ts +43 -3
- package/src/self-dev/orchestrate.ts +3 -0
- package/src/self-dev/release-path-guard.ts +7 -4
- package/src/self-dev/review-provider-fallback.ts +83 -0
- package/src/self-dev/run-supervisor.ts +5 -1
- package/src/self-implement/frozen-merges.ts +23 -0
- package/src/self-implement/goal-author.ts +14 -0
- package/src/self-implement/harness-policy-gates.ts +7 -5
- package/src/self-implement/heal-intake.ts +3 -0
- package/src/self-implement/host-regate.ts +28 -14
- package/src/self-implement/l8-merge-queue.ts +80 -8
- package/src/self-implement/orchestrator.ts +84 -28
- package/src/self-implement/seams.ts +8 -3
- package/src/self-implement/self-implement-cli.ts +4 -0
- package/src/self-implement/self-implement-runtime.ts +12 -0
- package/src/session-runtime/index.ts +5 -3
- package/src/shell-env-bootstrap.ts +35 -6
- package/src/steward/triage.ts +25 -8
- package/src/storage/file-lock.ts +33 -4
- package/src/task-agent/card-evidence.ts +6 -0
- package/src/task-agent/completion-evidence.ts +31 -3
- package/src/task-agent/cover.ts +61 -0
- package/src/task-agent/live-moves.ts +126 -3
- package/src/task-agent/parent-host.ts +315 -0
- package/src/task-agent/shadow.ts +19 -4
- package/src/task-agent/task-hand.ts +11 -2
- package/src/task-orchestrator/surfaces/pod-command-job.ts +41 -6
- package/src/task-orchestrator/surfaces/pod-gate-deps.ts +123 -0
- package/src/task-orchestrator/surfaces/pod-pool.ts +138 -15
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +39 -6
- package/src/task-orchestrator/surfaces/self-implement.ts +7 -0
- package/src/telegram-commands.ts +8 -0
- package/src/telegram-project-command.ts +6 -0
- package/src/telegram.ts +2 -2
- package/src/tool-runtime/browser-runtime.ts +87 -3
- package/src/tool-runtime/index.ts +1 -0
- package/src/typecheck-ratchet.ts +2 -1
- package/src/user-config.ts +55 -8
- package/src/version/packed-revision.json +1 -1
- package/src/workflow-runtime/executor.ts +24 -2
- package/src/workflow-runtime/triggers/registry.ts +27 -0
- package/src/workflow-runtime/triggers/schedule-source.ts +30 -3
- package/apps/pwa/out/_next/static/Bam1YziK2iH9bN4K0utGk/_buildManifest.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1307-77fad80cf54477c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1612-f60c0c93ec773f81.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1844-9ec4b1d12f6e80eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1866-e7a6999f25548b30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1948.15f356b15a625597.js +0 -5
- package/apps/pwa/out/_next/static/chunks/2116-6429c188eb846ab8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/224-e7be8f762fe74986.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2549-89c518a4c8ed4d00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2957-96ffab3d521fb08f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5360-be1f1d8f9fcc9755.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5755-ea7ed88eb956f47b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5977-94ed6f78e9814b2b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7748-6e51bfe927019f5c.js +0 -25
- package/apps/pwa/out/_next/static/chunks/9247-c1753a059e7bac08.js +0 -1
- package/apps/pwa/out/_next/static/chunks/a9f2b54d-33c0689b70ed8cf3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-7a852956c74015a3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c5a5c621be0e04ae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-7c058069c5e7fa63.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-dc5da0b8a2edb8a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-ed4a6f799f005d09.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-9cd565005b93aca6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-55f0f40c6db95f15.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-474cb5888ea0e8f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-9ca21f9ad3208a61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-a9c2cfa8dda922a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-6da35144878feb6d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-f6055495e9ed7ea8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-25204694fa9984a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-a60e035f151d84d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-189c587f36874538.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-c56634bde705a65d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a8d2fe0c669e0de4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c26fa10aac6c21c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-68793c6e10331d66.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-d81c07a7b4f618ae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-be1c4e8697f22360.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-a4717e2c4bf7a28f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-0fd895fab9b62c1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-8b6c1454a8e8f306.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c6e4364d9de8f717.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-0506a1e0e4bdb2f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-c260571513bf43c2.js +0 -1
- package/apps/pwa/out/_next/static/css/c23d959d3ee15e57.css +0 -1
- /package/apps/pwa/out/_next/static/{Bam1YziK2iH9bN4K0utGk → aBi6EyMtLsrl7J8eH4kF7}/_ssgManifest.js +0 -0
- /package/skills/project-onboarding/{skill.md → SKILL.md} +0 -0
|
@@ -72,6 +72,7 @@ import { basename, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
|
72
72
|
import { homedir } from 'node:os';
|
|
73
73
|
import { enqueueControlMemo, readSoftStopRequestStatus, type SoftStopRequestRead } from '../harness/control-inbox.js';
|
|
74
74
|
import { debug } from '../debug/log.js';
|
|
75
|
+
import { enterJourneyNode, exitJourneyNode, journeyJoinFields, withJourneyNode } from '../self-dev/graph-journey-nodes.js';
|
|
75
76
|
import { classifyGateEnvDeficit, DEFAULT_GATE_ENV_RETRY, GATE_ENV_DEFICIT_HARVESTABLE_MARK, type GateEnvDeficitKind } from './gate-env-retry.js';
|
|
76
77
|
import { recordFailureEvent } from './heal-intake.js';
|
|
77
78
|
import { classifyReworkCapExhaustion, type ReworkCapHealDecision } from './heal-triage.js';
|
|
@@ -433,7 +434,7 @@ function resolveDefaultBranchTarget(
|
|
|
433
434
|
* 🔑 실패일 때만 두 칸을 더한다 — 성공 경로 payload 를 바꾸면 기존 소비자가 흔들린다.
|
|
434
435
|
* `moduleLoadFailure` 는 ***「산출이 상했다」와 「그 순간 트리가 불일치했다」***를 가르는 값이다.
|
|
435
436
|
*/
|
|
436
|
-
type PostSyncStatus = 'merged' | 'llm-resolved';
|
|
437
|
+
type PostSyncStatus = 'merged' | 'llm-resolved' | 'deterministic-resolved';
|
|
437
438
|
|
|
438
439
|
type PostSyncGatePolicy = {
|
|
439
440
|
exempted: boolean;
|
|
@@ -494,7 +495,7 @@ function postSyncGatePolicy(
|
|
|
494
495
|
&& !introduced && childResponsibility === 'none'
|
|
495
496
|
&& syncStatus === 'llm-resolved';
|
|
496
497
|
const exempted = !passed
|
|
497
|
-
&& (timeoutOnly || (!introduced && childResponsibility === 'none' && syncStatus === 'merged'));
|
|
498
|
+
&& (timeoutOnly || (!introduced && childResponsibility === 'none' && (syncStatus === 'merged' || syncStatus === 'deterministic-resolved')));
|
|
498
499
|
return {
|
|
499
500
|
exempted,
|
|
500
501
|
exemptionWithheld,
|
|
@@ -975,6 +976,8 @@ export interface SelfImplementSeams {
|
|
|
975
976
|
readSoftStopRequestStatus?: (spaceId: string) => SoftStopRequestRead;
|
|
976
977
|
/** Parent harness space whose durable stop marker is read. Tests inject this; production uses `getHarnessSpace()`. */
|
|
977
978
|
parentSoftStopSpaceId?: string;
|
|
979
|
+
/** Real, created worktree's soft-stop target; observation only, never guesses a space. */
|
|
980
|
+
onSoftStopSpaceReady?: (spaceId: string) => void;
|
|
978
981
|
/** disposable worktree 생성 → 경로·브랜치 ⊕ **어디서 갈랐나**(관측용).
|
|
979
982
|
* ⚠️ 관측 3필드는 **선택**이다 — 시임은 주입점이고, 테스트 더블에게 git SHA 를 지어내라고
|
|
980
983
|
* 요구하면 계약이 아니라 부담이 된다. 실 시임(`defaultSeams`)은 항상 채운다.
|
|
@@ -2253,6 +2256,8 @@ export interface SelfImplementResult {
|
|
|
2253
2256
|
branch?: string;
|
|
2254
2257
|
gate?: SelfImplementGateResult;
|
|
2255
2258
|
review?: SelfImplementReview;
|
|
2259
|
+
/** Worktree commit observed while this review ran; not inferred from the later PR head. */
|
|
2260
|
+
reviewedHeadCommit?: string;
|
|
2256
2261
|
completionDisposition?: SelfImplementCompletionDisposition;
|
|
2257
2262
|
/** Explicit supervisor rework verdict retained independently of workflow execution verdicts. */
|
|
2258
2263
|
supervisorVerdict?: ReworkBudgetVerdict;
|
|
@@ -2359,7 +2364,18 @@ function truncatePrTitle(text: string): string {
|
|
|
2359
2364
|
return points.length <= 72 ? text : `${points.slice(0, 69).join('')}...`;
|
|
2360
2365
|
}
|
|
2361
2366
|
|
|
2362
|
-
export function
|
|
2367
|
+
export function goalChecklistIds(feature: string, goalFile?: string): string[] {
|
|
2368
|
+
const document = goalFile ? goalDocumentForReleaseNote(goalFile) : feature;
|
|
2369
|
+
const declaration = document.split(/\r?\n/).find((line) => line.startsWith('- 칸 id: '));
|
|
2370
|
+
const declared = declaration?.slice('- 칸 id: '.length).trim();
|
|
2371
|
+
if (declared && declared !== 'not declared') {
|
|
2372
|
+
return [...new Set(declared.split(' · ').map((id) => id.trim()).filter(Boolean))];
|
|
2373
|
+
}
|
|
2374
|
+
const firstLine = feature.split(/\r?\n/, 1)[0] ?? '';
|
|
2375
|
+
return [...new Set(Array.from(firstLine.matchAll(/\b[A-Z][A-Z0-9]+-[A-Z0-9]+\b/g), (match) => match[0]))];
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
function prTitleWithoutChecklistId(feature: string): string {
|
|
2363
2379
|
const proseTitle = parseAskProseTitle(feature);
|
|
2364
2380
|
if (proseTitle) return truncatePrTitle(proseTitle);
|
|
2365
2381
|
|
|
@@ -2402,6 +2418,13 @@ export function prTitle(feature: string): string {
|
|
|
2402
2418
|
return truncatePrTitle(firstFileName);
|
|
2403
2419
|
}
|
|
2404
2420
|
|
|
2421
|
+
export function prTitle(feature: string, goalFile?: string): string {
|
|
2422
|
+
const title = prTitleWithoutChecklistId(feature);
|
|
2423
|
+
const id = goalChecklistIds(feature, goalFile)[0];
|
|
2424
|
+
if (!id) return title;
|
|
2425
|
+
return truncatePrTitle(title.startsWith(`${id}: `) ? title : `${id}: ${title}`);
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2405
2428
|
const BLOCKED_DRAFT_PR_HUMAN_JUDGMENT_ANCHOR = '## 사람 판단 필요';
|
|
2406
2429
|
|
|
2407
2430
|
/** 사람이 읽는 중단 사유 상한. 관측 `reason.slice(0, 240)` 과 같은 길이라 표시가 앞부분을 버리지 않는다. */
|
|
@@ -2662,6 +2685,7 @@ function prBody(feature: string, implSummary: string, gateLog?: string, review?:
|
|
|
2662
2685
|
? ['', '## 감독 수용 기준 완화', `- 대상: ${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}`] : [])]
|
|
2663
2686
|
: [];
|
|
2664
2687
|
return [
|
|
2688
|
+
`칸: ${goalChecklistIds(feature, goalFile).join(' · ') || '없음'}`,
|
|
2665
2689
|
'## 요청',
|
|
2666
2690
|
...(goalFile ? [`- 골 파일: ${formatGoalFileForPrBody(goalFile)}`] : []),
|
|
2667
2691
|
feature.trim(),
|
|
@@ -2879,6 +2903,7 @@ export function formatBlockedDraftClassificationSection(
|
|
|
2879
2903
|
|
|
2880
2904
|
function blockedDraftPrBody(feature: string, implSummary: string, state: BlockedDraftPrState, goalFile?: string): string {
|
|
2881
2905
|
return [
|
|
2906
|
+
`칸: ${goalChecklistIds(feature, goalFile).join(' · ') || '없음'}`,
|
|
2882
2907
|
BLOCKED_DRAFT_PR_HUMAN_JUDGMENT_ANCHOR,
|
|
2883
2908
|
state.salvageStatusExpected
|
|
2884
2909
|
? BLOCKED_DRAFT_PR_SALVAGE_STATUS_INSTRUCTION
|
|
@@ -3635,7 +3660,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3635
3660
|
}
|
|
3636
3661
|
try {
|
|
3637
3662
|
const pushed = opts.seams.preserveBlockedBranch
|
|
3638
|
-
? await opts.seams.preserveBlockedBranch({ cwd: worktreePath, branch, title: prTitle(opts.feature), commit: preSyncCommit })
|
|
3663
|
+
? await opts.seams.preserveBlockedBranch({ cwd: worktreePath, branch, title: prTitle(opts.feature, opts.goalFile), commit: preSyncCommit })
|
|
3639
3664
|
: runGitCommand(worktreePath, ['push', '-u', 'origin', `${preSyncCommit}:refs/heads/${branch}`]).status === 0;
|
|
3640
3665
|
if (!pushed) throw new Error('branch push failed');
|
|
3641
3666
|
// The worktree is left untouched: a late merge may still be writing it. The harvest source is the pinned commit.
|
|
@@ -3805,6 +3830,8 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3805
3830
|
const attemptOrdinal = readRunAttemptOrdinal(runId);
|
|
3806
3831
|
const identified = {
|
|
3807
3832
|
...graphIdentity,
|
|
3833
|
+
// HARNESS-FULL-GRAPH — 앞단 여정 걸음(runId 없음)과 이 런의 걸음을 잇는 조인 키.
|
|
3834
|
+
...journeyJoinFields(),
|
|
3808
3835
|
...data,
|
|
3809
3836
|
attemptOrdinal,
|
|
3810
3837
|
};
|
|
@@ -4958,7 +4985,7 @@ async function runSelfImplementInner(
|
|
|
4958
4985
|
role: describeRole({ role: 'executor', executorKind: 'self' }),
|
|
4959
4986
|
entry: siEntry, capabilities: [...siCaps.active], enhanceActive,
|
|
4960
4987
|
});
|
|
4961
|
-
progress('start', `🔨 self-implement 시작 — ${prTitle(opts.feature)}`);
|
|
4988
|
+
progress('start', `🔨 self-implement 시작 — ${prTitle(opts.feature, opts.goalFile)}`);
|
|
4962
4989
|
|
|
4963
4990
|
let sessionId: string | undefined;
|
|
4964
4991
|
if (opts.parentSessionId && s.forkSession) {
|
|
@@ -5019,6 +5046,9 @@ async function runSelfImplementInner(
|
|
|
5019
5046
|
// 그래서 getHarnessSpace() 만 보면 운영에서 늘 undefined 이고 정지 확인이 «한 번도» 안 돈다(#20040 착지 직후 실측).
|
|
5020
5047
|
// `self send <space> --stop` 이 겨냥하는 것은 자식의 공간 = 워크트리 이름이다(아래 activeChildInboxId 와 같은 식 · dev-cli.ts recordRestart 폴백과 같다).
|
|
5021
5048
|
const parentSoftStopSpaceId = s.parentSoftStopSpaceId || getHarnessSpace()?.id || normalizeSpaceId(basename(wt.path)) || undefined;
|
|
5049
|
+
if (parentSoftStopSpaceId) {
|
|
5050
|
+
try { s.onSoftStopSpaceReady?.(parentSoftStopSpaceId); } catch { /* UI registration must not break execution */ }
|
|
5051
|
+
}
|
|
5022
5052
|
const readParentSoftStop = s.readSoftStopRequestStatus ?? readSoftStopRequestStatus;
|
|
5023
5053
|
const honorParentSoftStop = (
|
|
5024
5054
|
beforeNode: 'gate' | 'review' | 'rework' | 'open-pr',
|
|
@@ -5194,6 +5224,7 @@ async function runSelfImplementInner(
|
|
|
5194
5224
|
/** GATE-ENV-RETRY: 재시도 뒤에도 남은 환경 결손의 종류. 정의되면 이 라운드의 gate 실패는 «수확 대기»로 끝난다. */
|
|
5195
5225
|
let gateEnvDeficitKind: GateEnvDeficitKind | undefined;
|
|
5196
5226
|
let review: SelfImplementReview | undefined;
|
|
5227
|
+
let reviewedHeadCommit: string | undefined;
|
|
5197
5228
|
/** Review-budget leftovers and the body that carried them, so a later merge drafts from the same text. */
|
|
5198
5229
|
let preparedReviewBudgetPrBody: string | undefined;
|
|
5199
5230
|
const reviewMustFixCountHistory: number[] = [];
|
|
@@ -5783,11 +5814,11 @@ async function runSelfImplementInner(
|
|
|
5783
5814
|
throw new Error(`worktree not found: ${wt.path}`);
|
|
5784
5815
|
}
|
|
5785
5816
|
if (s.preserveBlockedBranch) {
|
|
5786
|
-
pushed = await s.preserveBlockedBranch({ cwd: wt.path, branch: wt.branch, title: prTitle(opts.feature) });
|
|
5817
|
+
pushed = await s.preserveBlockedBranch({ cwd: wt.path, branch: wt.branch, title: prTitle(opts.feature, opts.goalFile) });
|
|
5787
5818
|
if (!pushed) throw new Error('브랜치 push가 성공하지 않았음');
|
|
5788
5819
|
} else {
|
|
5789
5820
|
preservationErrorStep = 'commit';
|
|
5790
|
-
const commit = commitWorktree(wt.path, prTitle(opts.feature));
|
|
5821
|
+
const commit = commitWorktree(wt.path, prTitle(opts.feature, opts.goalFile));
|
|
5791
5822
|
if (!commit.ok && !/nothing to commit/.test(commit.out)) throw new Error(commit.out);
|
|
5792
5823
|
committed = commit.ok;
|
|
5793
5824
|
if (runGitCommand(wt.path, ['remote', 'get-url', 'origin']).status === 0) {
|
|
@@ -5867,10 +5898,10 @@ async function runSelfImplementInner(
|
|
|
5867
5898
|
let salvageError: string | undefined;
|
|
5868
5899
|
try {
|
|
5869
5900
|
if (s.preserveBlockedBranch) {
|
|
5870
|
-
if (!await s.preserveBlockedBranch({ cwd: wt.path, branch: salvageBranch, title: prTitle(opts.feature) })) throw new Error('수확 가지 push가 성공하지 않았음');
|
|
5901
|
+
if (!await s.preserveBlockedBranch({ cwd: wt.path, branch: salvageBranch, title: prTitle(opts.feature, opts.goalFile) })) throw new Error('수확 가지 push가 성공하지 않았음');
|
|
5871
5902
|
} else {
|
|
5872
5903
|
if (!existsSync(wt.path)) throw new Error(`worktree not found: ${wt.path}`);
|
|
5873
|
-
const commit = commitWorktree(wt.path, prTitle(opts.feature));
|
|
5904
|
+
const commit = commitWorktree(wt.path, prTitle(opts.feature, opts.goalFile));
|
|
5874
5905
|
if (!commit.ok && !/nothing to commit/.test(commit.out)) throw new Error(`로컬 커밋 실패: ${commit.out}`);
|
|
5875
5906
|
const push = runGitCommand(wt.path, ['push', 'origin', `HEAD:refs/heads/${salvageBranch}`]);
|
|
5876
5907
|
if (push.status !== 0) throw new Error(push.stderr || push.stdout || 'git push failed');
|
|
@@ -5907,10 +5938,10 @@ async function runSelfImplementInner(
|
|
|
5907
5938
|
let pushed = false;
|
|
5908
5939
|
try {
|
|
5909
5940
|
if (s.preserveBlockedBranch) {
|
|
5910
|
-
pushed = await s.preserveBlockedBranch({ cwd: wt.path, branch: wt.branch, title: prTitle(opts.feature) });
|
|
5941
|
+
pushed = await s.preserveBlockedBranch({ cwd: wt.path, branch: wt.branch, title: prTitle(opts.feature, opts.goalFile) });
|
|
5911
5942
|
} else {
|
|
5912
5943
|
if (commitFirst) {
|
|
5913
|
-
const commit = commitWorktree(wt.path, prTitle(opts.feature));
|
|
5944
|
+
const commit = commitWorktree(wt.path, prTitle(opts.feature, opts.goalFile));
|
|
5914
5945
|
if (!commit.ok && !/nothing to commit/.test(commit.out)) throw new Error(`로컬 브랜치 커밋 실패: ${commit.out}`);
|
|
5915
5946
|
}
|
|
5916
5947
|
const push = runGitCommand(wt.path, ['push', '-u', 'origin', `HEAD:refs/heads/${wt.branch}`]);
|
|
@@ -5934,7 +5965,7 @@ async function runSelfImplementInner(
|
|
|
5934
5965
|
if (stage === 'review-blocked' && podReviewBlockedDraft) {
|
|
5935
5966
|
let commitError: string | undefined;
|
|
5936
5967
|
try {
|
|
5937
|
-
const commit = commitWorktree(wt.path, prTitle(opts.feature));
|
|
5968
|
+
const commit = commitWorktree(wt.path, prTitle(opts.feature, opts.goalFile));
|
|
5938
5969
|
if (!commit.ok && !/nothing to commit/.test(commit.out)) commitError = commit.out.trim() || 'git commit failed';
|
|
5939
5970
|
} catch (error) {
|
|
5940
5971
|
commitError = safeErrorDescription(error);
|
|
@@ -5946,7 +5977,7 @@ async function runSelfImplementInner(
|
|
|
5946
5977
|
let pr: { url: string; number: number };
|
|
5947
5978
|
try {
|
|
5948
5979
|
pr = await withStepTimeout(s.openPr({
|
|
5949
|
-
title: prTitle(opts.feature),
|
|
5980
|
+
title: prTitle(opts.feature, opts.goalFile),
|
|
5950
5981
|
body: assembled.body,
|
|
5951
5982
|
head: wt.branch,
|
|
5952
5983
|
...(opts.base ? { base: opts.base } : {}),
|
|
@@ -6102,7 +6133,7 @@ async function runSelfImplementInner(
|
|
|
6102
6133
|
);
|
|
6103
6134
|
preparedReviewBudgetPrBody = preparedPrBody.body;
|
|
6104
6135
|
const pr = await withStepTimeout(s.openPr({
|
|
6105
|
-
title: prTitle(opts.feature),
|
|
6136
|
+
title: prTitle(opts.feature, opts.goalFile),
|
|
6106
6137
|
body: preparedPrBody.body,
|
|
6107
6138
|
head: wt.branch,
|
|
6108
6139
|
...(opts.base ? { base: opts.base } : {}),
|
|
@@ -6818,7 +6849,7 @@ async function runSelfImplementInner(
|
|
|
6818
6849
|
&& targets.some((target) => changedFileIsInsideDeclaredTarget(path, target)));
|
|
6819
6850
|
if (eligible.length) {
|
|
6820
6851
|
inspectStaleReverts(revertGuardTargetPaths(opts.feature, goalDocument));
|
|
6821
|
-
const message = `self-implement: ${prTitle(opts.feature)}`;
|
|
6852
|
+
const message = `self-implement: ${prTitle(opts.feature, opts.goalFile)}`;
|
|
6822
6853
|
let outcome: { ok: boolean; out: string };
|
|
6823
6854
|
try {
|
|
6824
6855
|
outcome = (s.commitFinishedChildWork ?? ((cwd, paths, title) => {
|
|
@@ -7339,6 +7370,7 @@ async function runSelfImplementInner(
|
|
|
7339
7370
|
lastReviewContext = reviewContext;
|
|
7340
7371
|
reviewIntent = buildReviewIntent(reviewContext);
|
|
7341
7372
|
|
|
7373
|
+
reviewedHeadCommit = undefined;
|
|
7342
7374
|
if (s.reviewDiff) {
|
|
7343
7375
|
try {
|
|
7344
7376
|
const stoppedBeforeReview = honorParentSoftStop('review');
|
|
@@ -7348,7 +7380,18 @@ async function runSelfImplementInner(
|
|
|
7348
7380
|
}
|
|
7349
7381
|
onNodeEntry(node('review'), round);
|
|
7350
7382
|
progress('reviewing', '내부 리뷰 (리뷰어 비평)…');
|
|
7383
|
+
const readReviewHead = s.headCommit ?? ((cwd: string) => {
|
|
7384
|
+
const commit = runGitCommand(cwd, ['rev-parse', '--verify', 'HEAD'], { encoding: 'utf8', timeout: 10_000 });
|
|
7385
|
+
return commit.status === 0 ? commit.stdout.trim() : undefined;
|
|
7386
|
+
});
|
|
7387
|
+
const headBeforeReview = readReviewHead(wt.path);
|
|
7388
|
+
const statusBeforeReview = runGitCommand(wt.path, ['status', '--porcelain'], { encoding: 'utf8', timeout: 10_000 });
|
|
7351
7389
|
review = await withStepTimeout(s.reviewDiff(wt.path, reviewContext), T.review, 'review');
|
|
7390
|
+
const statusAfterReview = runGitCommand(wt.path, ['status', '--porcelain'], { encoding: 'utf8', timeout: 10_000 });
|
|
7391
|
+
reviewedHeadCommit = review.reviewed && headBeforeReview && /^[0-9a-f]{40}$/i.test(headBeforeReview)
|
|
7392
|
+
&& statusBeforeReview.status === 0 && statusBeforeReview.stdout.trim() === ''
|
|
7393
|
+
&& statusAfterReview.status === 0 && statusAfterReview.stdout.trim() === ''
|
|
7394
|
+
&& headBeforeReview === readReviewHead(wt.path) ? headBeforeReview : undefined;
|
|
7352
7395
|
} catch (error) {
|
|
7353
7396
|
finalizeSupervisorDeliveries(error instanceof StepTimeoutError ? 'next-round-review-timeout' : 'next-round-review-failed');
|
|
7354
7397
|
throw error;
|
|
@@ -7587,6 +7630,7 @@ async function runSelfImplementInner(
|
|
|
7587
7630
|
? { completionDisposition }
|
|
7588
7631
|
: {};
|
|
7589
7632
|
const reviewReal = !!review?.reviewed;
|
|
7633
|
+
const reviewedHeadResult = reviewReal && reviewedHeadCommit ? { reviewedHeadCommit } : {};
|
|
7590
7634
|
const reviewDiffComplete = review?.diffTruncated === false;
|
|
7591
7635
|
const requiredEvidenceMissing = evidenceCoverage !== undefined && evidenceCoverage.uncoveredCount > 0;
|
|
7592
7636
|
const { latestSignalIncomplete } = signalIncompleteState(roundClassifications);
|
|
@@ -7672,7 +7716,7 @@ async function runSelfImplementInner(
|
|
|
7672
7716
|
try { goalDocument = readFileSync(opts.goalFile, 'utf8'); } catch { /* no documented targets */ }
|
|
7673
7717
|
}
|
|
7674
7718
|
inspectStaleReverts(revertGuardTargetPaths(opts.feature, goalDocument));
|
|
7675
|
-
s.commitWork(wt.path, prTitle(opts.feature));
|
|
7719
|
+
s.commitWork(wt.path, prTitle(opts.feature, opts.goalFile));
|
|
7676
7720
|
// ⛔⭐ resume 경로와 «같은» 해석기를 쓴다 — 두 자리가 갈리면 같은 원인이 다른 얼굴로 나온다.
|
|
7677
7721
|
const resolvedTarget = resolveDefaultBranchTarget(s.defaultBranchRef ?? defaultBranchRef, wt.path);
|
|
7678
7722
|
const mergeTarget = resolvedTarget.target;
|
|
@@ -7717,9 +7761,9 @@ async function runSelfImplementInner(
|
|
|
7717
7761
|
&& await preserveMergeHarvest(sync.reason, sync.inputChars);
|
|
7718
7762
|
return { ok: false, stage: 'merge-conflict', node: 'main-sync', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...(harvestable ? { harvestable: true } : {}), detail: harvestable ? sync.reason === 'conflict-input-too-large' ? `충돌 큼 — 사람 수확 (${wt.branch}, 입력 ${sync.inputChars}자)` : `충돌 해결 중단 — 사람 수확 (${wt.branch})` : `pre-PR main sync ${sync.status}` };
|
|
7719
7763
|
}
|
|
7720
|
-
if (sync.status === 'llm-resolved' || sync.status === 'merged') {
|
|
7764
|
+
if (sync.status === 'llm-resolved' || sync.status === 'merged' || sync.status === 'deterministic-resolved') {
|
|
7721
7765
|
preservationBase = opts.base ?? mergeTarget;
|
|
7722
|
-
progress('gating', sync.status === 'llm-resolved'
|
|
7766
|
+
progress('gating', sync.status === 'llm-resolved' || sync.status === 'deterministic-resolved'
|
|
7723
7767
|
? `${mergeTarget} 충돌해결됨 — ${formatLlmMergeOutcome(sync)} — 통합 결과 full 재-gate…`
|
|
7724
7768
|
: `${mergeTarget} 정합됨 — 통합 결과 full 재-gate…`);
|
|
7725
7769
|
onNodeEntry('regate', round);
|
|
@@ -7872,7 +7916,7 @@ async function runSelfImplementInner(
|
|
|
7872
7916
|
let pr: { url: string; number: number };
|
|
7873
7917
|
try {
|
|
7874
7918
|
pr = await withStepTimeout(s.openPr({
|
|
7875
|
-
title: prTitle(opts.feature),
|
|
7919
|
+
title: prTitle(opts.feature, opts.goalFile),
|
|
7876
7920
|
body: preparedPrBody.body,
|
|
7877
7921
|
head: wt.branch,
|
|
7878
7922
|
...(opts.base ? { base: opts.base } : {}),
|
|
@@ -7894,6 +7938,11 @@ async function runSelfImplementInner(
|
|
|
7894
7938
|
progress('aborted', formatPrOpenFailedProgress(location, prErrorFirstLine));
|
|
7895
7939
|
throw new Error(`${location}\n${prError}`);
|
|
7896
7940
|
}
|
|
7941
|
+
// PR creation may commit generated body/release notes or sync the base after review. Never bind an old review to that new head.
|
|
7942
|
+
if (reviewedHeadCommit) {
|
|
7943
|
+
const current = runGitCommand(wt.path, ['rev-parse', '--verify', 'HEAD'], { encoding: 'utf8', timeout: 10_000 });
|
|
7944
|
+
if (current.status !== 0 || current.stdout.trim() !== reviewedHeadCommit) delete reviewedHeadResult.reviewedHeadCommit;
|
|
7945
|
+
}
|
|
7897
7946
|
observe('pr-opened', {
|
|
7898
7947
|
url: pr.url,
|
|
7899
7948
|
number: pr.number,
|
|
@@ -7943,7 +7992,7 @@ async function runSelfImplementInner(
|
|
|
7943
7992
|
}
|
|
7944
7993
|
recordMergeDecision();
|
|
7945
7994
|
progress('pr-opened', `OP 승인 대기 (#${pr.number}): ${releaseHoldPath}`);
|
|
7946
|
-
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, prUrl: pr.url, prNumber: pr.number, detail: `OP approval required: ${releaseHoldPath}` };
|
|
7995
|
+
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 } : {}), ...reviewedHeadResult, mergeReason, prUrl: pr.url, prNumber: pr.number, detail: `OP approval required: ${releaseHoldPath}` };
|
|
7947
7996
|
}
|
|
7948
7997
|
if (!releasePathInspectionError && labels?.includes(AUTO_REVIEW_LABEL)) {
|
|
7949
7998
|
try {
|
|
@@ -7961,7 +8010,7 @@ async function runSelfImplementInner(
|
|
|
7961
8010
|
: 'release-path-inspection-failed';
|
|
7962
8011
|
recordMergeDecision();
|
|
7963
8012
|
progress('pr-opened', `OP 승인 대기 (#${pr.number}): PR 경로 조회 실패`);
|
|
7964
|
-
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, prUrl: pr.url, prNumber: pr.number };
|
|
8013
|
+
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 } : {}), ...reviewedHeadResult, mergeReason, prUrl: pr.url, prNumber: pr.number };
|
|
7965
8014
|
}
|
|
7966
8015
|
|
|
7967
8016
|
if (canAuto && (s.mergePr || opts.mergeByHost)) {
|
|
@@ -8011,12 +8060,12 @@ async function runSelfImplementInner(
|
|
|
8011
8060
|
// 판정(mergeReason)이 아니라 «집행 직전 가드»가 막았으므로 그 사실을 값으로 말한다.
|
|
8012
8061
|
// ⛔ 안 그러면 마지막 줄이 침묵하고, 그건 이 착지가 없애려던 상태다(리뷰 must-fix 2R).
|
|
8013
8062
|
const guardSkipReason = mergeSkipReason ?? (guardFailure ? 'merge-guard-unevaluated' : 'docs-deletion-threshold');
|
|
8014
|
-
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 };
|
|
8063
|
+
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 } : {}), ...reviewedHeadResult, mergeReason: guardSkipReason, prUrl: pr.url, prNumber: pr.number, detail };
|
|
8015
8064
|
}
|
|
8016
8065
|
if (opts.mergeByHost) {
|
|
8017
8066
|
observe('merge-ready', { number: pr.number, checkedHeadCommit });
|
|
8018
8067
|
progress('pr-opened', `호스트 재게이트 대기 (#${pr.number})`);
|
|
8019
|
-
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 };
|
|
8068
|
+
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 } : {}), ...reviewedHeadResult, checkedHeadCommit: checkedHeadCommit!, prUrl: pr.url, prNumber: pr.number };
|
|
8020
8069
|
}
|
|
8021
8070
|
// Landing freeze: the in-flight marker is written before the freeze is read, so a `freeze on` racing this merge waits.
|
|
8022
8071
|
// The resume sweep merges from the repository that owns the run worktree (the worktree itself may be cleaned up).
|
|
@@ -8028,13 +8077,13 @@ async function runSelfImplementInner(
|
|
|
8028
8077
|
};
|
|
8029
8078
|
const landing = admitLandingMerge(heldEntry, undefined, {}, { prNumber: pr.number, repoRoot: owningRepoRoot(wt.path) ?? wt.path, ...(checkedHeadCommit ? { headCommit: checkedHeadCommit } : {}) });
|
|
8030
8079
|
if (landing.kind === 'held' && !(checkedHeadCommit && /^[0-9a-f]{40}$/i.test(checkedHeadCommit))) {
|
|
8031
|
-
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: 'merge-guard-unevaluated', prUrl: pr.url, prNumber: pr.number, detail: 'freeze: checked head SHA unavailable; PR left ready for review' };
|
|
8080
|
+
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 } : {}), ...reviewedHeadResult, mergeReason: 'merge-guard-unevaluated', prUrl: pr.url, prNumber: pr.number, detail: 'freeze: checked head SHA unavailable; PR left ready for review' };
|
|
8032
8081
|
}
|
|
8033
8082
|
if (landing.kind !== 'merge') {
|
|
8034
8083
|
const detail = landing.kind === 'held' ? landingFreezeMessage(landing.freeze) : 'freeze lifted; a resume sweep is merging this PR';
|
|
8035
8084
|
debug.log('harness.merge', 'frozen', { pr: pr.number, ...(landing.kind === 'held' ? { reason: landing.freeze.reason, until: landing.freeze.until } : { resumedElsewhere: true }) });
|
|
8036
8085
|
progress('pr-opened', `#${pr.number} ready · ${detail}`);
|
|
8037
|
-
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: landing.kind === 'held' ? 'frozen' : 'resumed-elsewhere', prUrl: pr.url, prNumber: pr.number, detail };
|
|
8086
|
+
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 } : {}), ...reviewedHeadResult, mergeReason: landing.kind === 'held' ? 'frozen' : 'resumed-elsewhere', prUrl: pr.url, prNumber: pr.number, detail };
|
|
8038
8087
|
}
|
|
8039
8088
|
// The marker and claim live until the merge call itself settles — a step timeout does not stop a merge already
|
|
8040
8089
|
// sent — and anything that throws before the merge call is made releases them.
|
|
@@ -8088,7 +8137,14 @@ async function runSelfImplementInner(
|
|
|
8088
8137
|
}
|
|
8089
8138
|
const defaultBranch = resolveDefaultBranchTarget(s.defaultBranchRef ?? defaultBranchRef, wt.path).target ?? undefined;
|
|
8090
8139
|
progress('merged', formatAutoMergeSuccessMessage({ prNumber: pr.number, mergedBase, defaultBranch }));
|
|
8091
|
-
|
|
8140
|
+
// HARNESS-FULL-GRAPH — 회수도 그래프 노드(cleanup)다. 결과 = completed | preserved | failed.
|
|
8141
|
+
let cleanupOutcome = 'completed';
|
|
8142
|
+
enterJourneyNode('cleanup', { provenance: 'post-merge', runId });
|
|
8143
|
+
await withJourneyNode('cleanup', { provenance: 'post-merge', runId }, () => runPostMergeCleanup(s.postMergeCleanup, wt.path, wt.branch, opts.goalFile, mergedBase && defaultBranch && displayBranchName(mergedBase) === displayBranchName(defaultBranch) ? defaultBranch : undefined, (event, data) => {
|
|
8144
|
+
if (event.startsWith('post-merge-cleanup-')) cleanupOutcome = event.slice('post-merge-cleanup-'.length);
|
|
8145
|
+
observe(event, data);
|
|
8146
|
+
}));
|
|
8147
|
+
exitJourneyNode('cleanup', { provenance: 'post-merge', runId, outcome: cleanupOutcome });
|
|
8092
8148
|
const mergedLedger = (() => {
|
|
8093
8149
|
try { return loadRunLedger(runId); } catch { return null; }
|
|
8094
8150
|
})();
|
|
@@ -8117,10 +8173,10 @@ async function runSelfImplementInner(
|
|
|
8117
8173
|
// 그대로 두면 마지막 산출 줄이 «침묵»한다 — 이 착지가 없애려던 바로 그 상태다(리뷰 must-fix).
|
|
8118
8174
|
// ⇒ 판정이 아니라 «집행»에서 막힌 것이므로 그 사실을 별도 값으로 말한다.
|
|
8119
8175
|
const mergeAttemptSkipReason = mergeSkipReason ?? 'merge-attempt-failed';
|
|
8120
|
-
return { ok: true, stage: 'pr-opened', node: 'merge', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), mergeReason: mergeAttemptSkipReason, merged: false, prUrl: pr.url, prNumber: pr.number, ...(m.detail ? { detail: m.detail } : {}) };
|
|
8176
|
+
return { ok: true, stage: 'pr-opened', node: 'merge', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason: mergeAttemptSkipReason, merged: false, prUrl: pr.url, prNumber: pr.number, ...(m.detail ? { detail: m.detail } : {}) };
|
|
8121
8177
|
}
|
|
8122
8178
|
progress('pr-opened', `✅ PR 개설 (#${pr.number})`);
|
|
8123
|
-
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 } : {}), ...(lastSupervisorReason ? { supervisorReason: lastSupervisorReason } : {}), ...(mergeSkipReason ? { mergeReason: mergeSkipReason } : {}), prUrl: pr.url, prNumber: pr.number };
|
|
8179
|
+
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 } : {}), ...reviewedHeadResult, ...(lastSupervisorReason ? { supervisorReason: lastSupervisorReason } : {}), ...(mergeSkipReason ? { mergeReason: mergeSkipReason } : {}), prUrl: pr.url, prNumber: pr.number };
|
|
8124
8180
|
}
|
|
8125
8181
|
|
|
8126
8182
|
/** 결정적 요청 거부 — 같은 요청을 다시 보내면 «같은» 답이 온다(BACKLOG B6).
|
|
@@ -972,6 +972,8 @@ export interface DefaultSeamsOptions {
|
|
|
972
972
|
signal?: AbortSignal;
|
|
973
973
|
/** Parent-surface progress receiver supplied by the dev pipeline. */
|
|
974
974
|
onProgress?: SelfImplementSeams['onProgress'];
|
|
975
|
+
/** Relay the actual worktree soft-stop target to the invoking surface. */
|
|
976
|
+
onSoftStopSpaceReady?: SelfImplementSeams['onSoftStopSpaceReady'];
|
|
975
977
|
/** ⑤ HITL — PR 승인 게이트. ★fail-closed: 생략 시 PR 안 열림(자동 승인 없음). 실전 필수. */
|
|
976
978
|
approvePr?: SelfImplementSeams['approvePr'];
|
|
977
979
|
/** gate 스텝(기본 ['test']). */
|
|
@@ -984,7 +986,7 @@ export interface DefaultSeamsOptions {
|
|
|
984
986
|
runAndroidUnitTestGate?: (io: { args: readonly string[]; cwd: string }) => number;
|
|
985
987
|
runIosUnitTestGate?: (io: { args: readonly string[]; cwd: string }) => number;
|
|
986
988
|
/** Source-policy gate adapter for focused seam tests. */
|
|
987
|
-
runHarnessPolicyGates?: typeof runHarnessPolicyGates
|
|
989
|
+
runHarnessPolicyGates?: (input: Parameters<typeof runHarnessPolicyGates>[0]) => Awaited<ReturnType<typeof runHarnessPolicyGates>> | ReturnType<typeof runHarnessPolicyGates>;
|
|
988
990
|
runExposeGate?: typeof runExposeGate;
|
|
989
991
|
/** Dependency-wide validation adapter for focused seam tests. */
|
|
990
992
|
runDependencyChangeGate?: typeof runDependencyChangeGate;
|
|
@@ -1018,6 +1020,8 @@ export interface DefaultSeamsOptions {
|
|
|
1018
1020
|
* agent-substrate·staged 하니스와 동일 엔진) 배선. 미주입 시 reviewDiff 미노출(gate 통과=바로 병합결정·
|
|
1019
1021
|
* 리뷰 스킵). dev-harness 의 llmReview 와 동일 형태(streamLLM 래퍼). */
|
|
1020
1022
|
llmReview?: (prompt: string) => Promise<string>;
|
|
1023
|
+
/** Optional independent reviewer for reviewDiff only; other judgment calls retain llmReview. */
|
|
1024
|
+
subscriptionReviewLLM?: (prompt: string) => Promise<string>;
|
|
1021
1025
|
/**
|
|
1022
1026
|
* 이 리뷰 심이 파일을 스스로 읽을 수 있나. **선택 선언** — 안 주면 reviewDiff 가 칸을 만들지 않고
|
|
1023
1027
|
* 오케스트레이터 관측은 `'unknown'` 이다(`false` 와 같은 값으로 접지 않는다).
|
|
@@ -1394,6 +1398,7 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
|
|
|
1394
1398
|
};
|
|
1395
1399
|
return {
|
|
1396
1400
|
...(o.onProgress ? { onProgress: o.onProgress } : {}),
|
|
1401
|
+
...(o.onSoftStopSpaceReady ? { onSoftStopSpaceReady: o.onSoftStopSpaceReady } : {}),
|
|
1397
1402
|
...(escalateGoalClarifications ? { escalateGoalClarifications } : {}),
|
|
1398
1403
|
queryChildProviderErrors,
|
|
1399
1404
|
persistPrBodyArtifact: (input) => createArtifactStore().put('block', input.body, {
|
|
@@ -2070,7 +2075,7 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
|
|
|
2070
2075
|
// tsc-깨짐(F1 refFacts 미정의)을 결정론 차단. 변경 전체(.ts·테스트 포함)를 tsc 로 검사(변경 경로만 카운트).
|
|
2071
2076
|
const tc = changedFileTypecheck(cwd, changedAll);
|
|
2072
2077
|
debug.log('self-implement', 'gate.tsc', { checked: tc.checked, passed: tc.passed, errors: tc.errors, exempted: tc.exempted, noInspectionReason: tc.noInspectionReason }, { level: tc.passed ? 'info' : 'warn' });
|
|
2073
|
-
const policy = (o.runHarnessPolicyGates ?? runHarnessPolicyGates)({ cwd, changedFiles: changedAll });
|
|
2078
|
+
const policy = await (o.runHarnessPolicyGates ?? runHarnessPolicyGates)({ cwd, changedFiles: changedAll });
|
|
2074
2079
|
debug.log('self-implement', 'gate.policy', {
|
|
2075
2080
|
passed: policy.passed, failures: policy.failures.map((failure) => failure.gate), skipped: policy.skipped,
|
|
2076
2081
|
});
|
|
@@ -2527,7 +2532,7 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
|
|
|
2527
2532
|
...(ctx.round !== undefined ? { round: ctx.round } : {}),
|
|
2528
2533
|
},
|
|
2529
2534
|
} : {}),
|
|
2530
|
-
}, o.llmReview!);
|
|
2535
|
+
}, o.subscriptionReviewLLM ?? o.llmReview!);
|
|
2531
2536
|
debug.log('self-implement', 'review.done', {
|
|
2532
2537
|
verdict: rr.verdict, reviewed: rr.reviewed ?? false, mustFix: rr.mustFix.length, shouldFix: rr.shouldFix.length,
|
|
2533
2538
|
gateEvidenceLines: evidenceNote?.split(/\r?\n/).length ?? 0,
|
|
@@ -111,6 +111,7 @@ export function singleRunAsJobResult(feature: string, r: SelfImplementResultWith
|
|
|
111
111
|
...(r.harvestable === true && r.branch ? { harvestable: true } : {}),
|
|
112
112
|
...(r.worktreePath ? { worktreePath: r.worktreePath } : {}),
|
|
113
113
|
...(r.prUrl ? { prUrl: r.prUrl } : {}),
|
|
114
|
+
...(r.prNumber !== undefined ? { prNumber: r.prNumber } : {}),
|
|
114
115
|
// TA-LIVE-REVIEW-POD — 작업 트리 없는 런(Pod)의 live review 가 «런이 낸 PR 머리»를 확인하는 근거.
|
|
115
116
|
...(r.checkedHeadCommit !== undefined ? { checkedHeadCommit: r.checkedHeadCommit } : {}),
|
|
116
117
|
...(r.merged !== undefined ? { merged: r.merged } : {}),
|
|
@@ -121,6 +122,9 @@ export function singleRunAsJobResult(feature: string, r: SelfImplementResultWith
|
|
|
121
122
|
...(r.decomposeProposal ? { decomposeProposal: r.decomposeProposal } : {}),
|
|
122
123
|
...(r.goalPlanRevision ? { goalPlanRevision: r.goalPlanRevision } : {}),
|
|
123
124
|
...(r.salvage !== undefined ? { salvage: r.salvage } : {}),
|
|
125
|
+
...(r.review?.reviewed === true && r.review.verdict === 'pass'
|
|
126
|
+
&& r.reviewedHeadCommit && /^[0-9a-f]{40}$/i.test(r.reviewedHeadCommit)
|
|
127
|
+
? { selfReview: { verdict: r.review.verdict, head: r.reviewedHeadCommit } } : {}),
|
|
124
128
|
...(r.review?.reviewed !== undefined ? { reviewed: r.review.reviewed } : {}),
|
|
125
129
|
...(r.review?.failureReason !== undefined ? { reviewReason: r.review.failureReason } : {}),
|
|
126
130
|
// ⭐ 대표 지시(2026-09-08) — 걸음을 슈퍼바이저까지 나른다.
|
|
@@ -55,6 +55,13 @@ interface SelfImplementRuntimeDeps {
|
|
|
55
55
|
}
|
|
56
56
|
let runtimeDeps: SelfImplementRuntimeDeps = {};
|
|
57
57
|
|
|
58
|
+
// TUI-only observer. The tool call id is furnished by the actual dispatcher;
|
|
59
|
+
// other surfaces and calls without an id cannot register a stop target.
|
|
60
|
+
let softStopSpaceObserver: ((toolCallId: string, spaceId: string) => void) | null = null;
|
|
61
|
+
export function setSelfImplementSoftStopSpaceObserver(observer: typeof softStopSpaceObserver): void {
|
|
62
|
+
softStopSpaceObserver = observer;
|
|
63
|
+
}
|
|
64
|
+
|
|
58
65
|
/** 자식 헤드리스 elanous 의 config/state 격리 + 구현 대기 상한을 주입. */
|
|
59
66
|
export function setSelfImplementRuntimeDeps(d: SelfImplementRuntimeDeps | null): void {
|
|
60
67
|
runtimeDeps = d ?? {};
|
|
@@ -711,6 +718,11 @@ export const selfImplementRuntime: ToolRuntime<SelfImplementRuntimeRequest, Self
|
|
|
711
718
|
...(runtimeDeps.implementMaxWaitSec ? { implementMaxWaitSec: runtimeDeps.implementMaxWaitSec } : {}),
|
|
712
719
|
...(approvePr ? { approvePr } : {}),
|
|
713
720
|
onProgress: resolveHarnessProgressSink(ctx),
|
|
721
|
+
...(ctx.surface === 'tui' && ctx.toolCallId && softStopSpaceObserver ? {
|
|
722
|
+
onSoftStopSpaceReady: (spaceId: string) => {
|
|
723
|
+
try { softStopSpaceObserver?.(ctx.toolCallId!, spaceId); } catch { /* UI observer cannot break harness */ }
|
|
724
|
+
},
|
|
725
|
+
} : {}),
|
|
714
726
|
});
|
|
715
727
|
|
|
716
728
|
const runnableDocumentReferences = documentReferences.filter(({ result }) => result.kind !== 'outside-repository');
|
|
@@ -162,6 +162,8 @@ export interface SessionPostureSnapshot {
|
|
|
162
162
|
|
|
163
163
|
export interface SessionRuntimeDispatchDeps {
|
|
164
164
|
signal?: AbortSignal;
|
|
165
|
+
/** Current LLM tool call, for correlating a foreground harness stop target with the TUI call. */
|
|
166
|
+
toolCallId?: string;
|
|
165
167
|
userText?: string;
|
|
166
168
|
modelFamily?: ModelFamily;
|
|
167
169
|
/** Parent Agent capability context for an inline runtime fallback. */
|
|
@@ -183,7 +185,7 @@ export interface SessionRuntimeDispatchDeps {
|
|
|
183
185
|
// scheduler-retirement R1 의 LLM tool unwire 후 모두 no-op stub 였고
|
|
184
186
|
// 본 PR 에서 정식 폐기.
|
|
185
187
|
getToolRuntime(name: string): ToolRuntime<Record<string, unknown>, ToolRunResult> | undefined;
|
|
186
|
-
dispatchToolRuntime(name: string, args: Record<string, unknown
|
|
188
|
+
dispatchToolRuntime(name: string, args: Record<string, unknown>, toolCallId?: string): Promise<unknown>;
|
|
187
189
|
dispatchPluginTool(name: string, args: Record<string, unknown>): Promise<
|
|
188
190
|
{ ok: true; result: unknown } | { ok: false; error: string }
|
|
189
191
|
>;
|
|
@@ -2166,7 +2168,7 @@ export async function dispatchSessionRuntimeTool(
|
|
|
2166
2168
|
// registered runtimes) and drops `pathPolicy` on the floor.
|
|
2167
2169
|
const nativeRuntime = nativeRule?.preferRuntime ? deps.getToolRuntime(name) : undefined;
|
|
2168
2170
|
if (nativeRuntime) {
|
|
2169
|
-
const result = await deps.dispatchToolRuntime(name, normalizedArgs);
|
|
2171
|
+
const result = await deps.dispatchToolRuntime(name, normalizedArgs, deps.toolCallId);
|
|
2170
2172
|
rememberCandidateListingResult(name, normalizedArgs, result, scopedAnalysis, deps.searchPlannerState);
|
|
2171
2173
|
return result;
|
|
2172
2174
|
}
|
|
@@ -2201,7 +2203,7 @@ export async function dispatchSessionRuntimeTool(
|
|
|
2201
2203
|
if (rt) {
|
|
2202
2204
|
const isPtyTool = name.startsWith('PtyShell') || name.startsWith('pty_shell');
|
|
2203
2205
|
if (!isPtyTool || deps.ptyDashboardOn) {
|
|
2204
|
-
const result = await deps.dispatchToolRuntime(name, normalizedArgs);
|
|
2206
|
+
const result = await deps.dispatchToolRuntime(name, normalizedArgs, deps.toolCallId);
|
|
2205
2207
|
rememberCandidateListingResult(name, normalizedArgs, result, scopedAnalysis, deps.searchPlannerState);
|
|
2206
2208
|
return result;
|
|
2207
2209
|
}
|
|
@@ -55,11 +55,22 @@ import { basename } from 'node:path';
|
|
|
55
55
|
import { debug } from './debug/log.js';
|
|
56
56
|
|
|
57
57
|
const TIMEOUT_MS = 3000;
|
|
58
|
+
// An interactive shell (`-i`) ignores SIGTERM, so the default timeout signal never ends it: the
|
|
59
|
+
// capture then blocks until the rc files finish. 10-08 TUI-BOOT-60: a stale pyenv rehash lock made
|
|
60
|
+
// every `zsh -l -i` wait 60 s, and the «3 s» capture held the TUI boot for ~65 s. SIGKILL makes the
|
|
61
|
+
// timeout real.
|
|
62
|
+
const TIMEOUT_SIGNAL = 'SIGKILL' as const;
|
|
58
63
|
const POSIX_SHELLS = new Set(['zsh', 'bash', 'fish', 'sh', 'dash', 'ksh']);
|
|
59
64
|
|
|
60
65
|
let cached: Record<string, string> | null = null;
|
|
61
66
|
let captured = false;
|
|
62
67
|
|
|
68
|
+
// Both the daemon warm path (nexus/index.ts) and PTY's first synchronous capture
|
|
69
|
+
// pass through here. Keep the existing capture events intact; these are additive timings.
|
|
70
|
+
function logBootPhase(phase: string, start: number, outcome: string): void {
|
|
71
|
+
debug.log('boot.phase', phase, { ms: performance.now() - start, outcome });
|
|
72
|
+
}
|
|
73
|
+
|
|
63
74
|
/** Parse `KEY=VALUE\n` output from `printenv`. Tolerates values that
|
|
64
75
|
* themselves contain `=`; does not attempt to unescape newlines
|
|
65
76
|
* (bash/zsh `printenv` emits them literally, which is fine for
|
|
@@ -116,26 +127,33 @@ function acceptCapture(stdout: string): Record<string, string> | null {
|
|
|
116
127
|
}
|
|
117
128
|
|
|
118
129
|
export function runPrintenvCapture(): Record<string, string> | null {
|
|
130
|
+
const seedStart = performance.now();
|
|
119
131
|
const seed = captureSeed();
|
|
132
|
+
logBootPhase('login-env.seed', seedStart, seed ? 'ready' : 'unavailable');
|
|
120
133
|
if (!seed) return null;
|
|
121
134
|
const { shell, seedEnv } = seed;
|
|
122
135
|
|
|
136
|
+
const shellStart = performance.now();
|
|
123
137
|
let res: ReturnType<typeof spawnSync>;
|
|
124
138
|
try {
|
|
125
139
|
res = spawnSync(shell, ['-l', '-i', '-c', 'printenv'], {
|
|
126
140
|
env: seedEnv,
|
|
127
141
|
encoding: 'utf8',
|
|
128
142
|
timeout: TIMEOUT_MS,
|
|
143
|
+
killSignal: TIMEOUT_SIGNAL,
|
|
129
144
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
130
145
|
// Don't inherit our stdio — rc files that run `clear` or issue
|
|
131
146
|
// OSC sequences would corrupt our TUI output otherwise.
|
|
132
147
|
});
|
|
133
148
|
} catch {
|
|
149
|
+
logBootPhase('login-env.shell', shellStart, 'error');
|
|
134
150
|
return null;
|
|
135
151
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
152
|
+
// ETIMEDOUT with status 0 = the shell outlived the timeout; never trust a late capture.
|
|
153
|
+
const parsed = !res.error && (res.status === 0 || res.status === null) && !res.signal
|
|
154
|
+
? acceptCapture(typeof res.stdout === 'string' ? res.stdout : '') : null;
|
|
155
|
+
logBootPhase('login-env.shell', shellStart, parsed ? 'ok' : 'failed');
|
|
156
|
+
return parsed;
|
|
139
157
|
}
|
|
140
158
|
|
|
141
159
|
/** Fill the login-env cache off the event loop (daemon boot). The first web-terminal spawn otherwise ran the
|
|
@@ -144,15 +162,25 @@ export function runPrintenvCapture(): Record<string, string> | null {
|
|
|
144
162
|
export async function warmCapturedEnv(spawn: typeof Bun.spawn = Bun.spawn): Promise<boolean> {
|
|
145
163
|
if (captured) return cached !== null;
|
|
146
164
|
if (process.env.ELANOUS_SKIP_LOGIN_ENV === '1' || process.env.TERM_PROGRAM === 'monad-agent-nested') return false;
|
|
165
|
+
const seedStart = performance.now();
|
|
147
166
|
const seed = captureSeed();
|
|
167
|
+
logBootPhase('login-env.seed', seedStart, seed ? 'ready' : 'unavailable');
|
|
148
168
|
if (!seed) return false;
|
|
149
169
|
const start = Date.now();
|
|
170
|
+
const shellStart = performance.now();
|
|
150
171
|
try {
|
|
151
172
|
const proc = spawn([seed.shell, '-l', '-i', '-c', 'printenv'], { env: seed.seedEnv as Record<string, string>, stdin: 'ignore', stdout: 'pipe', stderr: 'ignore' });
|
|
152
|
-
|
|
153
|
-
|
|
173
|
+
// A grandchild (e.g. a pyenv rehash) can keep the stdout pipe open after the shell is killed,
|
|
174
|
+
// so the timeout settles the race itself instead of waiting for EOF.
|
|
175
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
176
|
+
const timedOut = new Promise<null>((resolve) => {
|
|
177
|
+
timer = setTimeout(() => { proc.kill(TIMEOUT_SIGNAL); resolve(null); }, TIMEOUT_MS);
|
|
178
|
+
});
|
|
179
|
+
const finished = Promise.all([new Response(proc.stdout as ReadableStream).text(), proc.exited]);
|
|
180
|
+
const result = await Promise.race([finished, timedOut]);
|
|
154
181
|
clearTimeout(timer);
|
|
155
|
-
const parsed =
|
|
182
|
+
const parsed = result && result[1] === 0 ? acceptCapture(result[0]) : null;
|
|
183
|
+
logBootPhase('login-env.shell', shellStart, parsed ? 'ok' : result ? 'failed' : 'timeout');
|
|
156
184
|
if (captured) return cached !== null; // a synchronous capture won the race
|
|
157
185
|
if (!parsed) return false;
|
|
158
186
|
cached = parsed;
|
|
@@ -160,6 +188,7 @@ export async function warmCapturedEnv(spawn: typeof Bun.spawn = Bun.spawn): Prom
|
|
|
160
188
|
debug.log('shell.envbootstrap.capture', 'warmed', { ok: true, ms: Date.now() - start, keyCount: Object.keys(parsed).length });
|
|
161
189
|
return true;
|
|
162
190
|
} catch {
|
|
191
|
+
logBootPhase('login-env.shell', shellStart, 'error');
|
|
163
192
|
return false;
|
|
164
193
|
}
|
|
165
194
|
}
|