elanous 0.2.20 → 0.2.21
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/MObU8ujkMciAKr6ljAV05/_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-77fad80cf54477c6.js → 1307-c97eba9fb72a9a5e.js} +1 -1
- 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/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/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/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-59fedea50d13c762.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-f1762140ef9a96b1.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-7581825d511a64c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +23 -0
- package/apps/pwa/out/_next/static/chunks/9497-b0e758d1cd4ae8d7.js +1 -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-937c92292a4ab4f0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/{page-85b316bb4235980b.js → page-d781be3e3a9cfd74.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/board/{page-9b2b26a33cb2cd42.js → page-b0a80997903852d8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-c9955fde67b1bcb5.js → page-2b1263165630d9c8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/{page-7a852956c74015a3.js → page-ea998f7f5d156bea.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-33c328b64ca508f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/{page-4ba4abe096b6c2a8.js → page-e2d6bed48ac20120.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/{page-575d4a8b4f7becb2.js → page-111cabe4d1fd69ae.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/control/{page-f5d56ff5f45ad164.js → page-544dd4bd4847eeb7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/{page-2260e9eef0357421.js → page-3ee191319bf97d87.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e4bcb2c503dab04b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-300897dcbbd5ed76.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/{page-466bf0ee16ad1432.js → page-a449f1ed472b81c2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/field/{page-a23bc71713bcc08f.js → page-9045094d6d3b5cd0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-c06673596849ef45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-103fa3191c1b2e08.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-9f81233f29dcd409.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-be8b4615c919e36c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-c685b104e0dfa609.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-8d693331cfbb6add.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-cef4f30a4c22fae1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66ea1b54fc83fa15.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-ec102c9b8b691e37.js → page-7a12f61be4a579d1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-c85b0589591a99c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-725a4da02dd129eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/{page-f6055495e9ed7ea8.js → page-8cc707bd09a497d9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-90b55be1f15ce0e8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cb16606e08be65db.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-16dc64b74ed6a40a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-21bec4afeb2f0917.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/{page-db03ae3589a81c9e.js → page-dc39ee7a36d26385.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/{page-4a6463b97f0ad94f.js → page-84ae759f76053672.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/{page-75bffecc9aa1004e.js → page-3db58ddb61fe2be9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c5315e30f3528dc4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/{page-31d5b875760bb62d.js → page-2fe368efb6de3b6a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/{page-c26fa10aac6c21c4.js → page-8d04132dd0ac5e10.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/{page-68793c6e10331d66.js → page-f23484de467c9ea3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/share/{page-46d5201d2207a511.js → page-c69762987b751174.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-5456692bda39aafb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/{page-be1c4e8697f22360.js → page-d75f7cd65845ce98.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-5603f5e568b25ce3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-d2cc0f4e89f42028.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/{page-0fd895fab9b62c1b.js → page-a6eb73b8a4840f1c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-c0a3f4d10edb83fa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/{page-c6e4364d9de8f717.js → page-6c0b88068c143f15.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/{page-0acc8e198f7b0dfb.js → page-7f8d7fcdf058a845.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/{page-34882c84f84021c5.js → page-22163556cd38bc88.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-141436fd26dd56fc.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/e81df11490b4413b.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/drafts/recipes.yaml +4 -4
- package/graphs/implement-loop.yaml +277 -5
- package/package.json +1 -1
- package/scripts/coord-channel-watch.sh +31 -4
- package/scripts/docs-lint.ts +4 -1
- package/scripts/marketing/generate-ax-brief.ts +18 -1
- package/scripts/measure-nl-routing-corpus.ts +11 -3
- package/scripts/release-loop/gate-node.ts +5 -5
- package/scripts/release-loop/shard-plan.ts +50 -5
- package/scripts/rhythm/daily.ts +2 -1
- package/src/browser-cdp/client.ts +10 -5
- 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/tasks-cli.ts +106 -0
- package/src/dashboard/index.ts +40 -4
- package/src/esc-abort-gate.ts +3 -1
- package/src/graph-runner/graph-cli.ts +57 -0
- package/src/graph-runner/graph-run-api.ts +13 -0
- package/src/graph-wizard/archetypes.ts +88 -0
- package/src/graph-wizard/generate.ts +545 -0
- package/src/graph-wizard/saved-steps.ts +120 -0
- package/src/graph-wizard/steps.ts +193 -0
- package/src/harness/harness-cli-command.ts +68 -12
- package/src/index.ts +7 -4
- package/src/intake-plane/digest.ts +18 -11
- package/src/maturity/feature-maturity.ts +2 -1
- package/src/nexus/api/draft-metrics.ts +114 -0
- package/src/nexus/api/graph-wizard-api.ts +53 -0
- package/src/nexus/api/graphs-api.ts +50 -12
- package/src/nexus/api/harness-traversal.ts +205 -0
- package/src/nexus/api/http-server.ts +31 -0
- package/src/nexus/outbound/router.ts +28 -8
- 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/release-loop/gate-shards.ts +7 -2
- package/src/self-dev/ask-launch-flow.ts +4 -2
- package/src/self-dev/ask-launch-io.ts +3 -1
- 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/release-path-guard.ts +7 -4
- package/src/self-implement/frozen-merges.ts +23 -0
- package/src/self-implement/goal-author.ts +14 -0
- package/src/self-implement/heal-intake.ts +3 -0
- package/src/self-implement/orchestrator.ts +16 -1
- package/src/self-implement/seams.ts +3 -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 +17 -3
- package/src/task-agent/card-evidence.ts +6 -0
- package/src/task-agent/parent-host.ts +315 -0
- package/src/task-agent/task-hand.ts +9 -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/self-implement-pod.ts +39 -6
- package/src/tool-runtime/browser-runtime.ts +87 -3
- package/src/tool-runtime/index.ts +1 -0
- package/src/user-config.ts +20 -4
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/Bam1YziK2iH9bN4K0utGk/_buildManifest.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/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/approvals/page-c855c24de7db74fe.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/loops/page-35bfec2e631d3eae.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/missions/[id]/page-f9ccb1b1adbea14d.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/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/showroom/page-d81c07a7b4f618ae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-cf0a4b4abead71ea.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/vault/page-8b6c1454a8e8f306.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 → MObU8ujkMciAKr6ljAV05}/_ssgManifest.js +0 -0
- /package/skills/project-onboarding/{skill.md → SKILL.md} +0 -0
|
@@ -538,6 +538,9 @@ export interface LaunchPreflightInput {
|
|
|
538
538
|
readonly askTargetPaths?: readonly string[];
|
|
539
539
|
/** 대상 경로 라벨이 «있는데» 거부된 조각. 0건 막음 문면이 그 이유를 말하게 한다(판정은 안 바꾼다). */
|
|
540
540
|
readonly askTargetPathRejections?: readonly AskTargetPathHintRejection[];
|
|
541
|
+
/** AUTO-TARGET: machine-suggested target paths dropped because the goal is NOT-GROUNDED (no persistent evidence).
|
|
542
|
+
* Non-empty = the goal is a scope card and must not launch an implementation. */
|
|
543
|
+
readonly notGroundedDroppedTargetPaths?: readonly string[];
|
|
541
544
|
/** ask 원문 경로. 있으면 ask-outside-path 경고만 이 목록과 최종 대상을 비교한다. */
|
|
542
545
|
readonly askOutsidePathHints?: readonly string[];
|
|
543
546
|
/** 이번에 쏠 골의 브랜치 이름. 없으면 형제 PR 축의 경고를 내지 않는다. */
|
|
@@ -559,19 +562,31 @@ function emitAskMarkerObservation(result: LaunchPreflightResult): void {
|
|
|
559
562
|
emittedAskMarkerObservations.add(result);
|
|
560
563
|
}
|
|
561
564
|
|
|
565
|
+
/** AUTO-TARGET: blocker name for a NOT-GROUNDED goal whose only target paths were machine-suggested (a scope card). */
|
|
566
|
+
export const NOT_GROUNDED_SCOPE_CARD_BLOCKER = '(NOT-GROUNDED 범위 카드)';
|
|
567
|
+
|
|
562
568
|
export function evaluateLaunchPreflight(input: LaunchPreflightInput): LaunchPreflightResult {
|
|
563
569
|
const paths = [...new Set(input.paths.filter((path) => path.trim().length > 0))];
|
|
564
570
|
const blockers: LaunchPreflightBlocker[] = [];
|
|
565
571
|
const warnings: LaunchPreflightBlocker[] = [];
|
|
566
572
|
|
|
573
|
+
// AUTO-TARGET (10-08 canary · TSC-HEAP): a NOT-GROUNDED goal whose only target paths came from the
|
|
574
|
+
// harness candidate search is a scope card — refuse it with that reason, not the generic «no label» text.
|
|
575
|
+
const notGroundedDropped = input.notGroundedDroppedTargetPaths ?? [];
|
|
576
|
+
const notGroundedDetail = notGroundedDropped.length > 0
|
|
577
|
+
? `골이 NOT-GROUNDED(영속 근거 0)라 하니스 후보 검색이 넣은 대상 경로 ${notGroundedDropped.length}개(${notGroundedDropped.slice(0, 3).join(' · ')}${notGroundedDropped.length > 3 ? ' …' : ''})를 대상으로 쓰지 않는다 — 범위 카드: 구현 발사 대상이 아니다 · ask 첫 줄에 사람이 「대상 경로: <파일>」을 적거나 접지 근거를 복구한 뒤 다시 저작`
|
|
578
|
+
: undefined;
|
|
579
|
+
if (notGroundedDetail !== undefined && paths.length > 0) {
|
|
580
|
+
blockers.push({ kind: 'no-target-paths', name: NOT_GROUNDED_SCOPE_CARD_BLOCKER, detail: notGroundedDetail });
|
|
581
|
+
}
|
|
567
582
|
// ① 모집단이 0이면 «통과»가 아니라 «막는 사유»다(METHOD v32 를 이 코드에도 적용).
|
|
568
583
|
if (paths.length === 0) {
|
|
569
584
|
blockers.push({
|
|
570
585
|
kind: 'no-target-paths',
|
|
571
|
-
name: '(대상 경로 0)',
|
|
586
|
+
name: notGroundedDetail !== undefined ? NOT_GROUNDED_SCOPE_CARD_BLOCKER : '(대상 경로 0)',
|
|
572
587
|
// ⛔ 2026-09-23 — 라벨이 «있는데» 조각이 거부된 경우를 「라벨을 넣어라」로 뭉개면 「거부됐다」를 「없다」로 읽게 된다
|
|
573
588
|
// (실측: `대상 경로: README.md — 설명…` 한 줄 → has-whitespace 로 통째 거부 · 문면은 「넣어라」뿐이었다).
|
|
574
|
-
detail: (input.askTargetPathRejections?.length
|
|
589
|
+
detail: notGroundedDetail !== undefined ? notGroundedDetail : (input.askTargetPathRejections?.length
|
|
575
590
|
? `대상 경로 라벨은 있는데 조각 ${input.askTargetPathRejections.length}개가 거부됐다: ${input.askTargetPathRejections.slice(0, 3).map((r) => `「${r.fragment.length > 40 ? `${r.fragment.slice(0, 40)}…` : r.fragment}」(${r.reason})`).join(' · ')} — 그 줄에는 «경로만» 둔다(설명은 다음 줄)`
|
|
576
591
|
: '골에서 대상 경로를 하나도 못 뽑았다 — ask 첫 줄에 「대상 경로: <파일> · <파일>」을 넣어라')
|
|
577
592
|
+ ' — 이 상태의 「위반 0」은 「검사했다」가 아니다 — elanous self author --inspect-target-paths "<문면>"',
|
|
@@ -1192,6 +1207,9 @@ export interface AskPreflightDeps {
|
|
|
1192
1207
|
readonly askTargetPaths?: (document: string) => readonly string[];
|
|
1193
1208
|
/** 대상 경로 라벨 «안»에서 거부된 조각(이유 포함). 0건 막음 문면이 「라벨이 없다」와 「있는데 거부됐다」를 가르게 한다. */
|
|
1194
1209
|
readonly askTargetPathRejections?: (document: string) => readonly AskTargetPathHintRejection[];
|
|
1210
|
+
/** AUTO-TARGET: true when the authored goal is NOT-GROUNDED with no persistent evidence (a scope card).
|
|
1211
|
+
* Omitted = this distinction is not made (existing behavior). Production wires `isNotGroundedWithoutPersistentEvidence`. */
|
|
1212
|
+
readonly notGroundedWithoutPersistentEvidence?: (document: string) => boolean;
|
|
1195
1213
|
}
|
|
1196
1214
|
|
|
1197
1215
|
export interface AskPreflightOptions {
|
|
@@ -1212,6 +1230,10 @@ export interface AskPreflightOptions {
|
|
|
1212
1230
|
readonly plannedBranch?: string;
|
|
1213
1231
|
/** 저작 전 ask 원문. 주면 기존 ask-marker-check로 형식을 관측하되 발사를 막지 않는다. */
|
|
1214
1232
|
readonly askText?: string;
|
|
1233
|
+
/** AUTO-TARGET: target paths the harness put into the ask (candidate search), not the human.
|
|
1234
|
+
* If the authored goal is NOT-GROUNDED without persistent evidence, these paths are dropped and the
|
|
1235
|
+
* goal stops before launch (`no-target-paths` blocker naming the reason). */
|
|
1236
|
+
readonly machineSuggestedTargetPaths?: readonly string[];
|
|
1215
1237
|
}
|
|
1216
1238
|
|
|
1217
1239
|
export type PlannedBranchResolution =
|
|
@@ -1539,7 +1561,24 @@ export function decideAskPreflight(
|
|
|
1539
1561
|
}
|
|
1540
1562
|
}
|
|
1541
1563
|
// ⛔ 저작 전에는 pathsOverride 자체가 ask 대상 힌트다. 저작 뒤에는 골에서 뽑은 대상만 역할로 쓴다.
|
|
1542
|
-
const
|
|
1564
|
+
const declaredAskTargetPaths = opts.pathsOverride ?? (goalDocument && deps.askTargetPaths ? deps.askTargetPaths(goalDocument) : []);
|
|
1565
|
+
// AUTO-TARGET: a NOT-GROUNDED goal (no persistent evidence) carries no machine-suggested target path.
|
|
1566
|
+
const machineSuggested = new Set((opts.machineSuggestedTargetPaths ?? []).map((path) => path.trim()).filter(Boolean));
|
|
1567
|
+
let notGroundedGoal = false;
|
|
1568
|
+
if (!opts.pathsOverride && goalDocument !== null && machineSuggested.size > 0 && deps.notGroundedWithoutPersistentEvidence) {
|
|
1569
|
+
try { notGroundedGoal = deps.notGroundedWithoutPersistentEvidence(goalDocument); } catch { notGroundedGoal = false; }
|
|
1570
|
+
}
|
|
1571
|
+
const notGroundedDroppedTargetPaths = notGroundedGoal ? declaredAskTargetPaths.filter((path) => machineSuggested.has(path)) : [];
|
|
1572
|
+
const askTargetPaths = notGroundedDroppedTargetPaths.length > 0
|
|
1573
|
+
? declaredAskTargetPaths.filter((path) => !machineSuggested.has(path))
|
|
1574
|
+
: declaredAskTargetPaths;
|
|
1575
|
+
if (notGroundedDroppedTargetPaths.length > 0) {
|
|
1576
|
+
try {
|
|
1577
|
+
debug.log('harness.preflight', 'not-grounded-target-paths-dropped', { goalFile: opts.goalFile, dropped: notGroundedDroppedTargetPaths });
|
|
1578
|
+
} catch {
|
|
1579
|
+
// Observation never changes the launch decision.
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1543
1582
|
// 저작 뒤에는 접지가 읽은 경로와 선언 대상 경로를 함께 검사한다. 저작 전 pathsOverride는 그대로 쓴다.
|
|
1544
1583
|
const paths = opts.pathsOverride ?? [...new Set([...tracedPaths, ...askTargetPaths])];
|
|
1545
1584
|
const askMarkerInspection = opts.askText === undefined
|
|
@@ -1677,6 +1716,7 @@ export function decideAskPreflight(
|
|
|
1677
1716
|
...(goalRulersUnknownReason ? { goalRulersUnknownReason } : {}),
|
|
1678
1717
|
preexistingFailures,
|
|
1679
1718
|
...(askTargetPaths.length > 0 ? { askTargetPaths } : {}),
|
|
1719
|
+
...(notGroundedDroppedTargetPaths.length > 0 ? { notGroundedDroppedTargetPaths } : {}),
|
|
1680
1720
|
...(askTargetPaths.length === 0 && goalDocument && deps.askTargetPathRejections
|
|
1681
1721
|
? { askTargetPathRejections: deps.askTargetPathRejections(goalDocument) }
|
|
1682
1722
|
: {}),
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
// Release path =
|
|
2
|
-
//
|
|
3
|
-
|
|
1
|
+
// Release path = release scripts and graph, manifest, notes and cut schedule, plus gate execution modules
|
|
2
|
+
// imported by scripts/release-loop/gate-node.ts (pod-command-job → pod-pool → pod-lease; pod-bun-cache; pod-install-slots; gate-shards).
|
|
3
|
+
// The checklist store (`checklist.ts`, `feature-store.ts`) remains shared ops ledger code (OP 10-03).
|
|
4
|
+
export const RELEASE_PATH_PREFIXES = ['scripts/release-loop/', 'graphs/release/', 'src/release-loop/manifest', 'src/release-loop/release-note', 'src/release-loop/release-schedule',
|
|
5
|
+
'src/task-orchestrator/surfaces/pod-command-job.ts', 'src/task-orchestrator/surfaces/pod-pool.ts', 'src/task-orchestrator/surfaces/pod-lease.ts',
|
|
6
|
+
'src/task-orchestrator/surfaces/pod-bun-cache.ts', 'src/task-orchestrator/surfaces/pod-install-slots.ts', 'src/release-loop/gate-shards.ts'] as const;
|
|
4
7
|
export const RELEASE_PATH_LABEL = 'elanous:release-path';
|
|
5
8
|
|
|
6
9
|
/** Flatten every GitHub PR file page, including the source of a rename. */
|
|
@@ -35,7 +38,7 @@ export function releaseGitDiffPaths(output: string): string[] {
|
|
|
35
38
|
|
|
36
39
|
/** Evaluate the paths from the opened PR, not the requested goal or local working tree. */
|
|
37
40
|
export function releasePathHold(paths: readonly string[]): string | undefined {
|
|
38
|
-
return paths.find((path) => RELEASE_PATH_PREFIXES.some((prefix) => path.startsWith(prefix)));
|
|
41
|
+
return paths.find((path) => RELEASE_PATH_PREFIXES.some((prefix) => prefix.endsWith('.ts') ? path === prefix : path.startsWith(prefix)));
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
/** Fixed opening of the hold comment — also how a PR held by several merge surfaces (or polls) is recognised, so it is posted once. */
|
|
@@ -4,6 +4,8 @@ import { createHash } from 'node:crypto';
|
|
|
4
4
|
import { dirname, join, resolve } from 'node:path';
|
|
5
5
|
import { effectiveInstanceRoot, prodInstanceRoot } from '../instance/resolve.js';
|
|
6
6
|
import { debug } from '../debug/log.js';
|
|
7
|
+
import { enterJourneyNode, exitJourneyNode, passJourneyNode, withJourneyNodeSync } from '../self-dev/graph-journey-nodes.js';
|
|
8
|
+
import { routeJourneyEdge } from '../self-dev/graph-journey-route.js';
|
|
7
9
|
import { beginLandingMerge, type LandingFreeze } from '../release-loop/landing-freeze.js';
|
|
8
10
|
|
|
9
11
|
/** `manual`: the owning repository could not be determined — a sweep never resumes it; a person does. */
|
|
@@ -183,6 +185,26 @@ export function admitLandingMerge(
|
|
|
183
185
|
hooks: { afterQueue?: () => void } = {},
|
|
184
186
|
claimKey?: { prNumber: number; repoRoot: string; headCommit?: string },
|
|
185
187
|
opts: { prodFreezeRoot?: string; forceReason?: string } = {},
|
|
188
|
+
): LandingAdmission {
|
|
189
|
+
// HARNESS-FULL-GRAPH — 병합 직전 한 곳의 동결 검사가 그래프 노드 freeze-check(출구: open | frozen | taken)이고,
|
|
190
|
+
// 동결이면 보류 대기열이 노드 hold 다. 판정은 바꾸지 않는다 — 관측만.
|
|
191
|
+
const pr = claimKey?.prNumber;
|
|
192
|
+
enterJourneyNode('freeze-check', { provenance: 'admit-landing-merge', ...(pr === undefined ? {} : { data: { pr } }) });
|
|
193
|
+
const admission = withJourneyNodeSync('freeze-check', { provenance: 'admit-landing-merge', ...(pr === undefined ? {} : { data: { pr } }) },
|
|
194
|
+
() => admitLandingMergeUnobserved(heldEntry, root, hooks, claimKey, opts));
|
|
195
|
+
const freezeLabel = admission.kind === 'merge' ? 'open' : admission.kind === 'held' ? 'frozen' : 'taken';
|
|
196
|
+
exitJourneyNode('freeze-check', { provenance: 'admit-landing-merge', outcome: freezeLabel, ...(pr === undefined ? {} : { data: { pr } }) });
|
|
197
|
+
// 2판: 간선 판독을 남긴다(관측). 승인 요구(open→hold) 강제는 0.2.22 — 보류 사유 값이 먼저다(RFC §3).
|
|
198
|
+
routeJourneyEdge('freeze-check', freezeLabel, { freeze: freezeLabel });
|
|
199
|
+
return admission;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function admitLandingMergeUnobserved(
|
|
203
|
+
heldEntry: FrozenMerge | null | (() => FrozenMerge | null),
|
|
204
|
+
root: string,
|
|
205
|
+
hooks: { afterQueue?: () => void },
|
|
206
|
+
claimKey: { prNumber: number; repoRoot: string; headCommit?: string } | undefined,
|
|
207
|
+
opts: { prodFreezeRoot?: string; forceReason?: string },
|
|
186
208
|
): LandingAdmission {
|
|
187
209
|
let entry: FrozenMerge | null | undefined;
|
|
188
210
|
const prodFreezeRoot = opts.prodFreezeRoot ?? prodInstanceRoot();
|
|
@@ -223,6 +245,7 @@ export function admitLandingMerge(
|
|
|
223
245
|
if (entry === undefined) entry = typeof heldEntry === 'function' ? heldEntry() : heldEntry; // only built when frozen
|
|
224
246
|
if (!entry) return { kind: 'held', freeze: landing.frozen };
|
|
225
247
|
queueFrozenMerge(entry, root);
|
|
248
|
+
passJourneyNode('hold', { provenance: 'admit-landing-merge', outcome: 'queued', data: { pr: entry.prNumber } });
|
|
226
249
|
hooks.afterQueue?.();
|
|
227
250
|
const afterQueue = beginLandingMerge(root, new Date(), prodFreezeRoot, opts.forceReason);
|
|
228
251
|
if (afterQueue.frozen) return { kind: 'held', freeze: afterQueue.frozen };
|
|
@@ -1363,6 +1363,20 @@ export function tracedPathReferences(document: string): TracedPathReference[] {
|
|
|
1363
1363
|
return references;
|
|
1364
1364
|
}
|
|
1365
1365
|
|
|
1366
|
+
/**
|
|
1367
|
+
* AUTO-TARGET (10-08 canary · TSC-HEAP run-446cdc71): an authored goal whose `## PROBLEM` Situation line says
|
|
1368
|
+
* NOT-GROUNDED has no persistent (Read-verified) evidence — `scqaNarrative` writes NOT-GROUNDED exactly when that
|
|
1369
|
+
* channel is empty, and `## TRACED PATHS` then carries no path. Such a goal is a scope card, not an implementation
|
|
1370
|
+
* goal: any target path it carries was not verified by grounding. Callers that know a path was machine-suggested
|
|
1371
|
+
* (not written by the human) must not launch on it. Lite goals have no Situation line and return false.
|
|
1372
|
+
*/
|
|
1373
|
+
export function isNotGroundedWithoutPersistentEvidence(document: string): boolean {
|
|
1374
|
+
const problem = markdownSection(document, 'PROBLEM');
|
|
1375
|
+
if (problem === null) return false;
|
|
1376
|
+
const situation = problem.split(/\r?\n/).find((line) => line.startsWith('Situation: '));
|
|
1377
|
+
return situation !== undefined && situation.startsWith('Situation: NOT-GROUNDED') && tracedPathReferences(document).length === 0;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1366
1380
|
/** Inspect supplied goal text and branch name, optionally validating traced paths through an injected reader. */
|
|
1367
1381
|
/**
|
|
1368
1382
|
* Lint findings plus the number of inline invariant markers recognized for judgment candidates.
|
|
@@ -3,6 +3,7 @@ import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmdir
|
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
5
5
|
import { debug } from '../debug/log.js';
|
|
6
|
+
import { passJourneyNode } from '../self-dev/graph-journey-nodes.js';
|
|
6
7
|
import { getUserConfig } from '../user-config.js';
|
|
7
8
|
import { psProcessStartMs, START_TOLERANCE_MS } from '../harness/harness-stop.js';
|
|
8
9
|
|
|
@@ -184,6 +185,8 @@ export function recordFailureEvent(event: FailureEvent, root = effectiveInstance
|
|
|
184
185
|
return false;
|
|
185
186
|
});
|
|
186
187
|
debug.log('heal.intake', 'recorded', { source: event.source, kind: event.kind, ref: event.ref, folded });
|
|
188
|
+
// HARNESS-FULL-GRAPH — 하니스 런 실패 사건의 접수가 그래프 노드 heal 이다(출구: started | folded).
|
|
189
|
+
if (event.source === 'harness-run') passJourneyNode('heal', { provenance: 'heal-intake', outcome: folded ? 'folded' : 'started', data: { kind: event.kind, ref: event.ref } });
|
|
187
190
|
if (!folded) {
|
|
188
191
|
const runId = healRunId(event);
|
|
189
192
|
void Promise.resolve().then(() => startLoop(HEAL_GRAPH, { runId, input: { failureEvent: event }, deps: { root } }))
|
|
@@ -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';
|
|
@@ -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`)은 항상 채운다.
|
|
@@ -3805,6 +3808,8 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3805
3808
|
const attemptOrdinal = readRunAttemptOrdinal(runId);
|
|
3806
3809
|
const identified = {
|
|
3807
3810
|
...graphIdentity,
|
|
3811
|
+
// HARNESS-FULL-GRAPH — 앞단 여정 걸음(runId 없음)과 이 런의 걸음을 잇는 조인 키.
|
|
3812
|
+
...journeyJoinFields(),
|
|
3808
3813
|
...data,
|
|
3809
3814
|
attemptOrdinal,
|
|
3810
3815
|
};
|
|
@@ -5019,6 +5024,9 @@ async function runSelfImplementInner(
|
|
|
5019
5024
|
// 그래서 getHarnessSpace() 만 보면 운영에서 늘 undefined 이고 정지 확인이 «한 번도» 안 돈다(#20040 착지 직후 실측).
|
|
5020
5025
|
// `self send <space> --stop` 이 겨냥하는 것은 자식의 공간 = 워크트리 이름이다(아래 activeChildInboxId 와 같은 식 · dev-cli.ts recordRestart 폴백과 같다).
|
|
5021
5026
|
const parentSoftStopSpaceId = s.parentSoftStopSpaceId || getHarnessSpace()?.id || normalizeSpaceId(basename(wt.path)) || undefined;
|
|
5027
|
+
if (parentSoftStopSpaceId) {
|
|
5028
|
+
try { s.onSoftStopSpaceReady?.(parentSoftStopSpaceId); } catch { /* UI registration must not break execution */ }
|
|
5029
|
+
}
|
|
5022
5030
|
const readParentSoftStop = s.readSoftStopRequestStatus ?? readSoftStopRequestStatus;
|
|
5023
5031
|
const honorParentSoftStop = (
|
|
5024
5032
|
beforeNode: 'gate' | 'review' | 'rework' | 'open-pr',
|
|
@@ -8088,7 +8096,14 @@ async function runSelfImplementInner(
|
|
|
8088
8096
|
}
|
|
8089
8097
|
const defaultBranch = resolveDefaultBranchTarget(s.defaultBranchRef ?? defaultBranchRef, wt.path).target ?? undefined;
|
|
8090
8098
|
progress('merged', formatAutoMergeSuccessMessage({ prNumber: pr.number, mergedBase, defaultBranch }));
|
|
8091
|
-
|
|
8099
|
+
// HARNESS-FULL-GRAPH — 회수도 그래프 노드(cleanup)다. 결과 = completed | preserved | failed.
|
|
8100
|
+
let cleanupOutcome = 'completed';
|
|
8101
|
+
enterJourneyNode('cleanup', { provenance: 'post-merge', runId });
|
|
8102
|
+
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) => {
|
|
8103
|
+
if (event.startsWith('post-merge-cleanup-')) cleanupOutcome = event.slice('post-merge-cleanup-'.length);
|
|
8104
|
+
observe(event, data);
|
|
8105
|
+
}));
|
|
8106
|
+
exitJourneyNode('cleanup', { provenance: 'post-merge', runId, outcome: cleanupOutcome });
|
|
8092
8107
|
const mergedLedger = (() => {
|
|
8093
8108
|
try { return loadRunLedger(runId); } catch { return null; }
|
|
8094
8109
|
})();
|
|
@@ -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']). */
|
|
@@ -1394,6 +1396,7 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
|
|
|
1394
1396
|
};
|
|
1395
1397
|
return {
|
|
1396
1398
|
...(o.onProgress ? { onProgress: o.onProgress } : {}),
|
|
1399
|
+
...(o.onSoftStopSpaceReady ? { onSoftStopSpaceReady: o.onSoftStopSpaceReady } : {}),
|
|
1397
1400
|
...(escalateGoalClarifications ? { escalateGoalClarifications } : {}),
|
|
1398
1401
|
queryChildProviderErrors,
|
|
1399
1402
|
persistPrBodyArtifact: (input) => createArtifactStore().put('block', input.body, {
|
|
@@ -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,6 +55,11 @@ 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;
|
|
@@ -126,6 +131,7 @@ export function runPrintenvCapture(): Record<string, string> | null {
|
|
|
126
131
|
env: seedEnv,
|
|
127
132
|
encoding: 'utf8',
|
|
128
133
|
timeout: TIMEOUT_MS,
|
|
134
|
+
killSignal: TIMEOUT_SIGNAL,
|
|
129
135
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
130
136
|
// Don't inherit our stdio — rc files that run `clear` or issue
|
|
131
137
|
// OSC sequences would corrupt our TUI output otherwise.
|
|
@@ -133,6 +139,8 @@ export function runPrintenvCapture(): Record<string, string> | null {
|
|
|
133
139
|
} catch {
|
|
134
140
|
return null;
|
|
135
141
|
}
|
|
142
|
+
// ETIMEDOUT with status 0 = the shell outlived the timeout; never trust a late capture.
|
|
143
|
+
if (res.error) return null;
|
|
136
144
|
if (res.status !== 0 && res.status !== null) return null;
|
|
137
145
|
if (res.signal) return null;
|
|
138
146
|
return acceptCapture(typeof res.stdout === 'string' ? res.stdout : '');
|
|
@@ -149,10 +157,16 @@ export async function warmCapturedEnv(spawn: typeof Bun.spawn = Bun.spawn): Prom
|
|
|
149
157
|
const start = Date.now();
|
|
150
158
|
try {
|
|
151
159
|
const proc = spawn([seed.shell, '-l', '-i', '-c', 'printenv'], { env: seed.seedEnv as Record<string, string>, stdin: 'ignore', stdout: 'pipe', stderr: 'ignore' });
|
|
152
|
-
|
|
153
|
-
|
|
160
|
+
// A grandchild (e.g. a pyenv rehash) can keep the stdout pipe open after the shell is killed,
|
|
161
|
+
// so the timeout settles the race itself instead of waiting for EOF.
|
|
162
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
163
|
+
const timedOut = new Promise<null>((resolve) => {
|
|
164
|
+
timer = setTimeout(() => { proc.kill(TIMEOUT_SIGNAL); resolve(null); }, TIMEOUT_MS);
|
|
165
|
+
});
|
|
166
|
+
const finished = Promise.all([new Response(proc.stdout as ReadableStream).text(), proc.exited]);
|
|
167
|
+
const result = await Promise.race([finished, timedOut]);
|
|
154
168
|
clearTimeout(timer);
|
|
155
|
-
const parsed =
|
|
169
|
+
const parsed = result && result[1] === 0 ? acceptCapture(result[0]) : null;
|
|
156
170
|
if (captured) return cached !== null; // a synchronous capture won the race
|
|
157
171
|
if (!parsed) return false;
|
|
158
172
|
cached = parsed;
|
|
@@ -139,6 +139,12 @@ async function defaultLoadLedger(): Promise<(runId: string) => RunLedgerEntry[]
|
|
|
139
139
|
// 연합 목록을 못 읽으면 이 우주만 읽되, 여기서 못 찾으면 «없음»이 아니라 실패로 올린다(card-bind-failed).
|
|
140
140
|
let federationFailure: unknown;
|
|
141
141
|
try { dirs = [...new Set([...dirs, ...resolveFederatedRunLedgerDirectories({})])]; } catch (error) { federationFailure = new Error(`federated run-ledger lookup failed: ${error instanceof Error ? error.message : String(error)}`); }
|
|
142
|
+
// HARNESS-PARENT-ON-MSB1: 원격 부모 런의 원장 거울(`tasks show` 가 ssh 로 당긴다) — 이 우주 ⊕ 연합 «뒤»에만 붙는다.
|
|
143
|
+
try {
|
|
144
|
+
const { remoteLedgerMirrorDirs } = await import('./parent-host.js');
|
|
145
|
+
const { prodInstanceRoot } = await import('../instance/resolve.js');
|
|
146
|
+
dirs = [...new Set([...dirs, ...remoteLedgerMirrorDirs(prodInstanceRoot())])];
|
|
147
|
+
} catch { /* 거울이 없으면 종전 그대로 */ }
|
|
142
148
|
return ledgerLoader(dirs, (runId, dir) => loadRunLedger(runId, dir), federationFailure);
|
|
143
149
|
}
|
|
144
150
|
|