elanous 0.2.32 → 0.2.35
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/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.js → 0368f25d-ad84af92fefee68f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +1 -0
- package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +32 -0
- package/apps/pwa/out/_next/static/chunks/{5525.86debf231e181813.js → 1530.0e612369b6fd7ea0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +41 -0
- package/apps/pwa/out/_next/static/chunks/{7391.ebae168025c91b6a.js → 1674.2a65fd5668e1cc5f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +24 -0
- package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +74 -0
- package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7947-d0759430f8042240.js → 1993-c0007b7ad0c0ef41.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{60fb96c9.360b01d8d4927b7b.js → 1c735de4.f993a30bbd3c57c4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.js → 2018.a741297bce759490.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +148 -0
- package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3902.e1e71aaac850a045.js → 2625.5d870aa999f33db1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +77 -0
- package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +62 -0
- package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +90 -0
- package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4174.92ed04922709ac9e.js → 3408.21d1570602f4b6c0.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3589.5444a06bcf6e775c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/359-2250789a2d3499e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +36 -0
- package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9398-6aed28f0a96d0d6f.js → 3677-4215f826f6aa68e5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +79 -0
- package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +122 -0
- package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7371.80c05c653b08e907.js → 4346.8601952e73bf5803.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +286 -0
- package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{2940-619bfd8ef337c611.js → 4705-194e64e47ca0fbdb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.js → 4718-17d2af636796a330.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7502.ccd5b8065545edd0.js → 5101.e32282718f99ed6f.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{2001.6c7e0fd02190886c.js → 5154.a118f3957ed14e36.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +23 -0
- package/apps/pwa/out/_next/static/chunks/{5173-233188df2f42c626.js → 5483-dd5d7697f6bdb106.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +94 -0
- package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3267c0e6.d34854e7b3984a6e.js → 56d372f2.681ab4ec4c998fae.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +287 -0
- package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +1 -0
- package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6433.fc573af22bbc9ab7.js → 6236.e18cced2d5ba6afb.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +8 -0
- package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +27 -0
- package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +93 -0
- package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6544cb48.a87fe20ddf137be2.js → 6b89c8bd.24df687a820500b3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +149 -0
- package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{2871.0bca6137343b3f76.js → 7385.50a308a477bdfc21.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.js → 7644.17e37ba6f1d4226e.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8018.a32663f04a6fc5f9.js → 8219.baa715d1deee80e2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4111.2bfedbb233ad206b.js → 8256.e3ac8421a71f82f4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 8444.4c26b379ca2b9596.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +226 -0
- package/apps/pwa/out/_next/static/chunks/8557-e7898769499cd56f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +64 -0
- package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6092.a7f99e68b188ca66.js → 8637.47f5b35afcae5e6b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3278.2e5d15b53a4091c8.js → 9214.63a510d39178e997.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +115 -0
- package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9221.7d22eaf353a2d4e7.js → 938.66ad1ef0e5abae1c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.js → 9512.5a76207a730e0491.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{69-0a2c8209c6d4a158.js → 967-2aa39b2d04b4c690.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7862.30a8d6482bb238eb.js → 9952.5daf5f94063a2b3e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/{page-a27b1e5a0d1b308f.js → page-406b47745b53f269.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-32866485913d6a04.js → page-47c5d4db587266bd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-04d00ae9b0890349.js → page-dc0a532f5b9196ec.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7a1887c4.f36b88fba31da8fd.js → b2f6ba4d.fb56fdbbf798df33.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/b6705a4f-b9a9047de9eecfd0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b313b242.cb1265eea908db61.js → cbe38a15.5a032598e39970c6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → da5176c6.6773b6c5994e1d99.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +22 -22
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +21 -21
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +22 -22
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +22 -22
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +22 -22
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +21 -21
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +21 -21
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +21 -21
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +21 -21
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +21 -21
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/bin/elanous.mjs +10 -2
- package/catalog/providers/opengateway.yaml +25 -0
- package/docs/goal-context/01-goal-authoring-checks.md +8 -0
- package/docs/goal-context/03-verification-menu.md +24 -0
- package/docs/goal-context/04-mock-scenarios.md +100 -0
- package/docs/goal-context/README.md +5 -0
- package/graphs/catalog/catalog.yaml +1 -1
- package/graphs/default-loop.yaml +76 -5
- package/graphs/document-loop.yaml +71 -4
- package/graphs/implement-loop.yaml +59 -4
- package/graphs/journey/SCENARIOS.md +33 -0
- package/graphs/journey/recipes.yaml +1 -0
- package/graphs/journey/ta-journey.yaml +94 -0
- package/graphs/journey/units/author/author.yaml +20 -0
- package/graphs/journey/units/author/recipes.yaml +2 -0
- package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
- package/graphs/journey/units/author-dialogue/observe.ts +96 -0
- package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
- package/graphs/journey/units/green/green.yaml +20 -0
- package/graphs/journey/units/green/recipes.yaml +2 -0
- package/graphs/journey/units/pr/pr.yaml +20 -0
- package/graphs/journey/units/pr/recipes.yaml +2 -0
- package/graphs/journey/units/remember/recipes.yaml +2 -0
- package/graphs/journey/units/remember/remember.yaml +20 -0
- package/graphs/operate-loop.yaml +71 -4
- package/graphs/overlays/stop-heal-ladder.yaml +1 -1
- package/graphs/release-rehearsal/recipes.yaml +1 -1
- package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
- package/graphs/research-loop.yaml +159 -4
- package/graphs/test-diet/test-diet.yaml +3 -0
- package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
- package/graphs/units/dispatch-pod/recipes.yaml +14 -0
- package/graphs/units/entry/entry.yaml +50 -0
- package/graphs/units/entry/recipes.yaml +14 -0
- package/graphs/units/harvest/harvest.yaml +25 -0
- package/graphs/units/harvest/recipes.yaml +4 -0
- package/graphs/units/land/land.yaml +45 -0
- package/graphs/units/land/recipes.yaml +3 -0
- package/graphs/units/recipes.yaml +7 -0
- package/graphs/units/recover.yaml +39 -0
- package/graphs/units/reflect/recipes.yaml +3 -0
- package/graphs/units/reflect/reflect.yaml +15 -0
- package/graphs/units/task-agent-recover-review.yaml +17 -0
- package/graphs/units/task-agent-recover-wait.yaml +17 -0
- package/graphs/units/verbs/make-doc.yaml +34 -0
- package/graphs/units/verbs/recipes.yaml +33 -0
- package/graphs/units/verbs/verify.yaml +55 -0
- package/graphs/work/recipes.yaml +2 -0
- package/graphs/work/research-report.yaml +28 -0
- package/package.json +1 -1
- package/scripts/ci-typecheck-changed.ts +69 -16
- package/scripts/coord-role-pack.ts +19 -6
- package/scripts/docs/generate-graph-anatomy.ts +19 -2
- package/scripts/graph-harvest-unit.ts +22 -0
- package/scripts/graph-units/journey-stub.ts +6 -0
- package/scripts/graph-units/land-enqueue.ts +78 -0
- package/scripts/graph-units/recover-plan.ts +15 -0
- package/scripts/graph-units/reflect-node.ts +88 -0
- package/scripts/graph-units/ta-journey-observe.ts +109 -0
- package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
- package/scripts/graph-units/verbs/verify-stage.ts +75 -0
- package/scripts/graph-units/verbs-envelope.ts +139 -0
- package/scripts/hq/standby-snapshot.ts +30 -0
- package/scripts/public-export.ts +43 -1
- package/scripts/ratchets/train-side-invariants.sh +45 -0
- package/scripts/release-loop/auto-approve-node.ts +30 -16
- package/scripts/release-loop/docs-land-node.ts +21 -5
- package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
- package/scripts/release-loop/gate-closure.ts +5 -1
- package/scripts/release-loop/gate-diff.ts +1 -1
- package/scripts/release-loop/gate-node.ts +675 -49
- package/scripts/release-loop/gate-partial.ts +68 -14
- package/scripts/release-loop/gate-radius-live.ts +177 -0
- package/scripts/release-loop/gate-radius-shadow.ts +138 -0
- package/scripts/release-loop/gate-traffic-mode.ts +128 -0
- package/scripts/release-loop/gate-triage-node.ts +5 -2
- package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
- package/scripts/release-loop/known-issues-node.ts +77 -8
- package/scripts/release-loop/node-verdict.ts +12 -1
- package/scripts/release-loop/npm-publish-node.ts +66 -12
- package/scripts/release-loop/preflight.ts +93 -7
- package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
- package/scripts/release-loop/publish-node.ts +60 -9
- package/scripts/release-loop/pwa-remote.ts +166 -0
- package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
- package/scripts/release-loop/resume-cap.ts +56 -0
- package/scripts/release-loop/resume-release.ts +155 -19
- package/scripts/release-loop/resume.ts +24 -1
- package/scripts/release-loop/tui-sim-node.ts +8 -2
- package/scripts/release-loop/unattended-release.ts +10 -2
- package/scripts/test-diet/lib.ts +6 -1
- package/scripts/test-diet/node.ts +194 -13
- package/scripts/ux-sim.ts +39 -0
- package/src/acp/core-turn-bridge.ts +20 -5
- package/src/acp/reasoning-thought-buffer.ts +45 -0
- package/src/agent/self-ambient-cache.ts +8 -0
- package/src/agent-substrate/acp-reviewer.ts +90 -15
- package/src/agent-substrate/pr-reviewer.ts +17 -0
- package/src/agent-substrate/review-finding-key.ts +53 -0
- package/src/agent-substrate/self-review-cli.ts +188 -18
- package/src/ask-user-question/pending-questions.ts +1 -1
- package/src/autopilot/pr-manager.ts +393 -65
- package/src/budget/run-usage-rollup.ts +1 -0
- package/src/chat/index.ts +0 -2
- package/src/chat/pickers/modal-runtime.ts +10 -27
- package/src/chat/tool-render/dispatch.ts +62 -10
- package/src/cli/agent-cli.ts +13 -2
- package/src/cli/control-cli.ts +24 -7
- package/src/cli/doctor-cli.ts +4 -1
- package/src/cli/guardian-cli.ts +10 -0
- package/src/cli/light-entry-route.ts +75 -0
- package/src/cli/llm-detect-cli.ts +23 -1
- package/src/cli/pod-cli.ts +77 -3
- package/src/cli/pr-cli.ts +81 -14
- package/src/cli/pr-land-base-read.ts +2 -0
- package/src/cli/pr-land-overlap-evidence.ts +154 -16
- package/src/cli/pr-land-pod-shadow-job.ts +3 -0
- package/src/cli/pr-land-recovery.ts +64 -0
- package/src/cli/pty-takeover-cli.ts +6 -5
- package/src/cli/release-checklist-read-cli.ts +79 -0
- package/src/cli/release-cli.ts +189 -132
- package/src/cli/release-run-if-ready.ts +29 -28
- package/src/cli/release-single-flight.ts +178 -0
- package/src/cli/remote-resolve.ts +1 -1
- package/src/cli/root-tui-entry.ts +48 -0
- package/src/cli/seat-cli.ts +37 -0
- package/src/cli/setup-cli.ts +40 -1
- package/src/cli/sim-cli.ts +22 -0
- package/src/cli/tasks-cli.ts +667 -14
- package/src/cli/usage-cli.ts +13 -11
- package/src/clipboard/history.ts +179 -13
- package/src/config.ts +8 -1
- package/src/control/control-status.ts +8 -3
- package/src/control-plane/ledger.ts +5 -3
- package/src/control-plane/server.ts +5 -3
- package/src/core-turn/short-question.ts +5 -1
- package/src/dashboard/chat/acp-chat.ts +8 -0
- package/src/dashboard/index.ts +114 -77
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
- package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
- package/src/dashboard/input/seat-autowake.ts +56 -3
- package/src/dashboard/render/theme-resolver.ts +33 -4
- package/src/dashboard/seat-boot-preamble.ts +1 -1
- package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
- package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
- package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
- package/src/dashboard/turn-preamble.ts +47 -1
- package/src/dashboard/turn-stream-formatter.ts +34 -1
- package/src/dashboard/turn-stream-runtime.ts +2 -0
- package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
- package/src/domains/guardian-tick.ts +54 -2
- package/src/domains/outbound-alert.ts +3 -2
- package/src/domains/schedule-registry.ts +16 -2
- package/src/extractors.ts +3 -1
- package/src/git-fs/idle-refresh.ts +76 -0
- package/src/git-fs/index.ts +18 -7
- package/src/git-fs/retry.ts +4 -0
- package/src/git-fs/runner.ts +2 -0
- package/src/git-fs/worktree.ts +42 -4
- package/src/graph-kinds/registry.ts +2 -2
- package/src/graph-runner/runner.ts +267 -54
- package/src/grok/credential.ts +15 -3
- package/src/harness/harness-cli-command.ts +151 -38
- package/src/harness/harness-incidents.ts +37 -0
- package/src/harness/harness-pod-dispatch.ts +38 -1
- package/src/harness/harness-salvage-cli.ts +14 -2
- package/src/harness/launch-utterance-ledger.ts +208 -0
- package/src/impl-discipline/detector.ts +16 -4
- package/src/impl-discipline/system-prompt.ts +11 -0
- package/src/impl-discipline/types.ts +2 -2
- package/src/index.ts +683 -146
- package/src/intake-plane/already-built-hint.ts +91 -0
- package/src/intake-plane/requirement-funnel.ts +29 -1
- package/src/knowhow/pack.ts +199 -0
- package/src/light-cli.ts +111 -0
- package/src/llm/opengateway-models.ts +11 -0
- package/src/llm/provider-credentials.ts +14 -0
- package/src/llm/provider-detect.ts +8 -1
- package/src/llm/runtime-model-family.ts +2 -1
- package/src/llm.ts +268 -65
- package/src/loops/budget.ts +95 -0
- package/src/loops/msg-wake.ts +8 -2
- package/src/loops/orchestrator/traffic.ts +132 -1
- package/src/model-tier/llm-tier-map.ts +15 -1
- package/src/mss/logging/log-store.ts +4 -5
- package/src/native-tool-catalog.ts +15 -1
- package/src/nexus/api/graphs-api.ts +22 -3
- package/src/nexus/api/http-server.ts +1 -1
- package/src/nexus/api/loop-resources.ts +13 -1
- package/src/nexus/api/ops-api.ts +12 -0
- package/src/oauth/claude-pty-maturity.ts +66 -0
- package/src/oauth/codex-access-mirror.ts +55 -0
- package/src/oauth/codex.ts +7 -0
- package/src/oauth/fallback-chain.ts +1 -1
- package/src/onboarding/first-run.ts +5 -3
- package/src/onboarding/non-interactive.ts +64 -13
- package/src/onboarding.ts +10 -2
- package/src/ops/overview-collect.ts +54 -4
- package/src/ops/overview.ts +31 -7
- package/src/pr-tool/census.ts +282 -30
- package/src/pr-tool/inflight-registry.ts +160 -7
- package/src/prompt-library/gpt6-family-addendum.ts +14 -1
- package/src/pty-shell/herdr-agent-report.ts +442 -0
- package/src/pty-shell/pty-control-ipc.ts +5 -5
- package/src/pty-shell/pty-manifest.ts +7 -0
- package/src/pty-shell/pty-write-outcome.ts +24 -6
- package/src/pty-shell/tui-run-state.ts +117 -3
- package/src/release-loop/checklist.ts +103 -5
- package/src/release-loop/feature-store.ts +19 -2
- package/src/release-loop/landed-but-yellow.ts +129 -5
- package/src/release-loop/light-rc.ts +1 -0
- package/src/release-loop/placement.ts +10 -3
- package/src/release-loop/rehearsal.ts +205 -25
- package/src/release-loop/rubric.ts +16 -2
- package/src/repl/index.ts +174 -17
- package/src/repl/ops-msg-bridge.ts +32 -0
- package/src/self-dev/ask-launch-flow.ts +44 -5
- package/src/self-dev/cli-help-text.ts +17 -0
- package/src/self-dev/dev-cli.ts +11 -9
- package/src/self-dev/draft-residue.ts +37 -1
- package/src/self-dev/draft-sweep.ts +188 -13
- package/src/self-dev/draft-triage-rules.ts +107 -0
- package/src/self-dev/fleet-reduce.ts +3 -2
- package/src/self-dev/graph-front-nodes.ts +112 -0
- package/src/self-dev/graph-journey-nodes.ts +11 -6
- package/src/self-dev/graph-journey-route.ts +60 -6
- package/src/self-dev/harness-run-cli.ts +3 -15
- package/src/self-dev/orchestrate-cli-text.ts +10 -0
- package/src/self-dev/orchestrate.ts +79 -3
- package/src/self-dev/review-provider-fallback.ts +35 -1
- package/src/self-dev/run-supervisor.ts +107 -12
- package/src/self-dev/run-types.ts +5 -1
- package/src/self-dev/self-orchestrate-runtime.ts +1 -11
- package/src/self-dev/shard-aggregate.ts +42 -5
- package/src/self-dev/shard-run.ts +8 -1
- package/src/self-implement/blocked-draft-policy.ts +20 -0
- package/src/self-implement/classify-shadow.ts +3 -7
- package/src/self-implement/doctor-visit.ts +18 -1
- package/src/self-implement/gate-baseline.ts +95 -12
- package/src/self-implement/gate-cli.ts +1 -0
- package/src/self-implement/gate-remote.ts +40 -25
- package/src/self-implement/goal-author-decompose.ts +275 -47
- package/src/self-implement/goal-author-identity.ts +66 -0
- package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
- package/src/self-implement/goal-author.ts +254 -120
- package/src/self-implement/goal-elaborate.ts +295 -0
- package/src/self-implement/goal-refine.ts +270 -0
- package/src/self-implement/graph-overlay-yaml.ts +28 -2
- package/src/self-implement/graph-unit-flatten.ts +103 -0
- package/src/self-implement/graph-unit-resolver.ts +107 -0
- package/src/self-implement/graph-yaml.ts +151 -1
- package/src/self-implement/headless-elanous-driver.ts +1 -0
- package/src/self-implement/knowhow-pack.ts +103 -0
- package/src/self-implement/orchestrator.ts +160 -45
- package/src/self-implement/pod-warm-pool-profile.ts +45 -0
- package/src/self-implement/review-mustfix-class.ts +203 -0
- package/src/self-implement/rework-budget-judgment.ts +5 -8
- package/src/self-implement/run-stop.ts +17 -2
- package/src/self-implement/running-runs.ts +29 -1
- package/src/self-implement/scope-adjacency.ts +113 -0
- package/src/self-implement/seams.ts +138 -4
- package/src/self-implement/stop-autoheal.ts +112 -2
- package/src/session/chat.ts +27 -0
- package/src/session-runtime/index.ts +1 -1
- package/src/session-runtime/retry-policy.ts +2 -1
- package/src/setup/llm-env-detect.ts +5 -0
- package/src/skills/tools/agent.ts +140 -14
- package/src/skills/tools/msg-ask.ts +100 -0
- package/src/skills/tools/ops-ledger.ts +2 -1
- package/src/skills/tools/schedule-wakeup.ts +66 -17
- package/src/steward/hold-hygiene.ts +24 -6
- package/src/steward/release-day.ts +7 -3
- package/src/steward/triage-budget.ts +194 -0
- package/src/steward/triage.ts +57 -7
- package/src/task-agent/actions.ts +69 -1
- package/src/task-agent/green-sweep.ts +4 -0
- package/src/task-agent/harvest-unit.ts +141 -0
- package/src/task-agent/live-moves.ts +257 -15
- package/src/task-agent/parent-host.ts +216 -6
- package/src/task-agent/postland-card.ts +80 -1
- package/src/task-agent/rejudge-on-head.ts +112 -26
- package/src/task-agent/repair-branch-cas.ts +4 -1
- package/src/task-agent/repair-cycle.ts +16 -3
- package/src/task-agent/run-identity.ts +4 -3
- package/src/task-agent/shadow.ts +19 -3
- package/src/task-agent/task-hand.ts +96 -36
- package/src/task-agent/tier-split.ts +127 -0
- package/src/task-agent/work-order-build.ts +24 -0
- package/src/task-agent/work-order.ts +3 -2
- package/src/task-orchestrator/generator-prompt.ts +60 -11
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +72 -3
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-command-job.ts +47 -8
- package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
- package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
- package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
- package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +8 -2
- package/src/task-orchestrator/surfaces/pod-pool.ts +73 -17
- package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -0
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +72 -4
- package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +32 -5
- package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +3 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +421 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +2 -1
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +588 -71
- package/src/task-orchestrator/surfaces/self-implement.ts +106 -2
- package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
- package/src/tool-runtime/truncation-store.ts +4 -0
- package/src/tui/README.md +2 -0
- package/src/tui/chat/background-job-status.ts +54 -0
- package/src/tui/chat/log-view.ts +80 -0
- package/src/tui/entry.ts +406 -0
- package/src/tui/input/composer.ts +144 -0
- package/src/tui/seat-mail-boot.ts +59 -0
- package/src/tui/slash/compact.ts +100 -0
- package/src/tui/slash/new-session.ts +35 -0
- package/src/tui-client/dashboard-session.ts +10 -1
- package/src/tui-client/local-chat-turn.ts +239 -0
- package/src/tui-client/local-harness-command.ts +63 -0
- package/src/tui-client/local-provider-command.ts +184 -0
- package/src/user-config/coercion.ts +36 -0
- package/src/user-config.ts +22 -43
- package/src/ux-sim/event-monkey.ts +378 -0
- package/src/ux-sim/fake-bin.ts +42 -7
- package/src/ux-sim/fault-nextmove-dispatch.ts +266 -0
- package/src/ux-sim/fault-pod-codex-503.ts +211 -0
- package/src/ux-sim/fault-scope-escape-lift.ts +189 -0
- package/src/ux-sim/scenario.ts +72 -13
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
- package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
- package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
- package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
- package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
- package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
- package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
- package/apps/pwa/out/_next/static/chunks/3541-ce3a5424ed5ad7f1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
- package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
- package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +0 -226
- package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
- package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
- package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5543.a438b8ab5a13ea47.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
- package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
- package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
- package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
- package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
- package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
- package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
- package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
- package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +0 -24
- package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9989.3694300e5f000b14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-c219f2ed171131be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
- package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
- package/src/cli/g6a-registration-probe.ts +0 -16
- /package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
package/src/cli/pod-cli.ts
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
// 산출 경로를 한 줄로 알리고 명령의 종료 코드로 끝난다. `--deadline` 생략 시 기존 Pod Job 상한.
|
|
3
3
|
|
|
4
4
|
import type { Command } from 'commander';
|
|
5
|
+
import { randomUUID } from 'node:crypto';
|
|
6
|
+
import { hostname } from 'node:os';
|
|
7
|
+
import { basename, join } from 'node:path';
|
|
8
|
+
import { readFileSync } from 'node:fs';
|
|
9
|
+
import { putPodShelfImage, listPodShelfImages, type PodShelfImage } from '../task-orchestrator/surfaces/pod-image-source.js';
|
|
10
|
+
import { defaultRemoteRun } from '../task-orchestrator/surfaces/pod-pool.js';
|
|
5
11
|
import { debug } from '../debug/log.js';
|
|
6
12
|
import { readPodMemoryAdvice } from './pod-memory-advice.js';
|
|
7
13
|
import { getUserConfig } from '../user-config.js';
|
|
@@ -28,6 +34,10 @@ export interface PodCliDeps {
|
|
|
28
34
|
poolSpec?: (explicit?: string) => string | null;
|
|
29
35
|
harnessPool?: () => string | undefined;
|
|
30
36
|
memoryAdvice?: (logsDb?: string) => ReturnType<typeof readPodMemoryAdvice>;
|
|
37
|
+
shelfConfig?: () => { harness?: { imageCommit?: unknown } };
|
|
38
|
+
shelfPut?: (ref: string, pool: string) => Promise<PodShelfImage>;
|
|
39
|
+
shelfList?: (pool: string) => Promise<string[]> | string[];
|
|
40
|
+
shelfTail?: (artifactsDir: string) => string;
|
|
31
41
|
}
|
|
32
42
|
|
|
33
43
|
const HELP = `elanous pod run [--pool <스펙>] [--skill <이름,…>] [--llm grok] [--clone] [--deadline <초>] -- <명령…>
|
|
@@ -63,6 +73,57 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
|
|
|
63
73
|
};
|
|
64
74
|
const run = deps.run ?? ((options: RunPodCommandOptions) => runPodCommand(options));
|
|
65
75
|
const pod = program.command('pod').description('Pod 명령 Job — 하니스 없이 명령 하나를 돌리고 산출을 돌려받는다');
|
|
76
|
+
const shelf = pod.command('shelf').description('임의 PR·SHA·가지의 격리 하니스 이미지와 명령 Job');
|
|
77
|
+
const shelfPool = (explicit?: string) => {
|
|
78
|
+
const config = (deps.shelfConfig ?? getUserConfig)();
|
|
79
|
+
const spec = explicit || process.env.ELANOUS_POD_POOL || ('podPool' in (config.harness ?? {}) ? (config.harness as { podPool?: string }).podPool : undefined) || (config as { pod?: { pool?: string } }).pod?.pool;
|
|
80
|
+
if (!spec) throw new Error('pod shelf: remote pool is not configured');
|
|
81
|
+
return spec;
|
|
82
|
+
};
|
|
83
|
+
shelf.command('put <ref>').description('ref head 이미지를 빌드하거나 레지스트리 태그 재사용')
|
|
84
|
+
.option('--pool <spec>', '단일 원격 레지스트리 풀 멤버')
|
|
85
|
+
.action(async (ref: string, opts: { pool?: string }) => {
|
|
86
|
+
try {
|
|
87
|
+
const image = await (deps.shelfPut ?? putPodShelfImage)(ref, shelfPool(opts.pool));
|
|
88
|
+
io.log(`${image.image} (${image.action})`); io.exit(0);
|
|
89
|
+
} catch (err) { io.error(err instanceof Error ? err.message : String(err)); io.exit(1); }
|
|
90
|
+
});
|
|
91
|
+
shelf.command('ls').description('레지스트리의 커밋 이미지 태그 목록')
|
|
92
|
+
.option('--pool <spec>', '단일 원격 레지스트리 풀 멤버')
|
|
93
|
+
.action(async (opts: { pool?: string }) => {
|
|
94
|
+
try {
|
|
95
|
+
const images = await (deps.shelfList ?? ((pool) => listPodShelfImages(pool, defaultRemoteRun)))(shelfPool(opts.pool));
|
|
96
|
+
for (const image of images) io.log(image);
|
|
97
|
+
io.exit(0);
|
|
98
|
+
} catch (err) { io.error(err instanceof Error ? err.message : String(err)); io.exit(1); }
|
|
99
|
+
});
|
|
100
|
+
shelf.command('run <ref>').description('ref 이미지로 명령 Job 실행 · rc 와 출력 꼬리 반환')
|
|
101
|
+
.option('--pool <spec>', '단일 원격 레지스트리 풀 멤버')
|
|
102
|
+
.allowUnknownOption(true).allowExcessArguments(true)
|
|
103
|
+
.action(async (ref: string, opts: { pool?: string }) => {
|
|
104
|
+
const argv = process.argv.slice(2);
|
|
105
|
+
const sep = argv.indexOf('--');
|
|
106
|
+
const args = sep < 0 ? [] : argv.slice(sep + 1);
|
|
107
|
+
if (!args.length) { io.error('pod shelf run: `--` 뒤에 명령이 없다'); io.exit(2); return; }
|
|
108
|
+
try {
|
|
109
|
+
const pool = shelfPool(opts.pool);
|
|
110
|
+
const image = await (deps.shelfPut ?? putPodShelfImage)(ref, pool);
|
|
111
|
+
const seat = process.env.ELANOUS_SEAT?.trim();
|
|
112
|
+
const actor = seat || process.env.USER?.trim() || process.env.LOGNAME?.trim();
|
|
113
|
+
if (!actor) throw new Error('pod provenance actor missing: ELANOUS_SEAT or USER/LOGNAME required');
|
|
114
|
+
const runId = randomUUID();
|
|
115
|
+
const result = await run({ pool, image: image.image, shelfImage: image.image, imageCommit: image.commit,
|
|
116
|
+
clone: true, source: { kind: 'commit', sha: image.commit }, command: args, runId, returnLogs: true,
|
|
117
|
+
provenance: { actorKind: seat ? 'seat' : 'human', actor, character: 'command-runner', launchHost: hostname(),
|
|
118
|
+
entrance: 'pod-shelf-run', kind: 'command', run: runId, phase: 'exec', requestedAt: new Date().toISOString(), reason: 'unknown', argv: basename(args[0]!) },
|
|
119
|
+
});
|
|
120
|
+
io.error(`[pod shelf] image ${result.image ?? image.image} · rc ${result.exitCode} · job ${result.job}`);
|
|
121
|
+
io.log(result.artifactsDir);
|
|
122
|
+
const tail = (deps.shelfTail ?? ((dir) => readFileSync(join(dir, 'child.log'), 'utf8')))(result.artifactsDir);
|
|
123
|
+
io.log(tail.slice(-4096));
|
|
124
|
+
io.exit(result.exitCode);
|
|
125
|
+
} catch (err) { io.error(err instanceof Error ? err.message : String(err)); io.exit(1); }
|
|
126
|
+
});
|
|
66
127
|
pod.command('memory').description('실측 기반 Pod 메모리 권고 (읽기 전용)')
|
|
67
128
|
.command('advise').description('골 종류별 standard 16Gi / high 32Gi 권고와 근거')
|
|
68
129
|
.option('--json', '권고와 측정 근거를 JSON 으로')
|
|
@@ -110,7 +171,9 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
|
|
|
110
171
|
// This explicit observation runs after the admission calculation. A slow or failed external
|
|
111
172
|
// probe can never change recommended/limitedBy or slow the ordinary lease status path.
|
|
112
173
|
const externalGitHub = opts.githubEgress ? Object.fromEntries(members.map((member) => {
|
|
113
|
-
try {
|
|
174
|
+
try {
|
|
175
|
+
return [member.context, (deps.externalGitHub ?? probePoolGitHub)(member.context, kubectl)];
|
|
176
|
+
}
|
|
114
177
|
catch { return [member.context, { externalDns: null, githubHttps: null, measuredAt: null, reason: 'probe failed' }]; }
|
|
115
178
|
})) : undefined;
|
|
116
179
|
const result = { pool: spec, ...measure, accounts, perAccount, ...decision, reserved: host.reserved, waitingJobs,
|
|
@@ -132,8 +195,10 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
|
|
|
132
195
|
}
|
|
133
196
|
io.log(`예약(저작 중) ${host.reserved} · 대기 Job ${waitingJobs ?? '?'} · 실행 ${decision.running ?? '?'}`);
|
|
134
197
|
io.log(`임대 없는 실행 ${decision.unleasedRunning ?? '?'}`);
|
|
135
|
-
if (externalGitHub) for (const [context, probe] of Object.entries(externalGitHub))
|
|
136
|
-
io.log(`GitHub 외부망 ${context}: DNS=${probe.externalDns ?? '?'} HTTPS=${probe.githubHttps ?? '?'} 측정=${probe.measuredAt ?? '?'}${probe.reason ? ` · ${probe.reason}` : ''}`);
|
|
198
|
+
if (externalGitHub) for (const [context, probe] of Object.entries(externalGitHub)) {
|
|
199
|
+
io.log(`GitHub 외부망 ${context}: DNS=${probe.externalDns ?? '?'} HTTPS=${probe.githubHttps ?? '?'} 측정=${probe.measuredAt ?? '?'}${probe.reason ? ` · ${probe.reason}` : ''}${probe.podName ? ` · Pod=${probe.podName}` : ''}`);
|
|
200
|
+
if (probe.podLog !== undefined) io.log(`GitHub 탐침 로그 ${probe.podName ?? context}: ${JSON.stringify(probe.podLog)}`);
|
|
201
|
+
}
|
|
137
202
|
io.log(`capacity: ${decision.capacitySlots ?? '?'} 칸 (상한 ${members.reduce((sum, m) => sum + m.capacity, 0)} − Running ${decision.running ?? '?'} − Pending ${decision.pending ?? '?'}; 권장 수에서 건강한 멤버의 임대 없는 실행 차감)`);
|
|
138
203
|
io.log(`memory: ${decision.memorySlots ?? '?'} 칸 (할당 가능 − Running 하니스 상한 합; 골당 16Gi · 모든 네임스페이스의 노드별 기존 예약을 반영해 배치 가능 ${decision.placeableSlots ?? '?'} 칸)`);
|
|
139
204
|
io.log(`lite: ${decision.liteMemorySlots ?? '?'} 칸 (같은 여유를 lite 골 2Gi 로 센 값 · 관측만 — 권장 수는 위 standard 기준)`);
|
|
@@ -186,8 +251,17 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
|
|
|
186
251
|
debug.log('pod.run', 'clone-without-install', { argv0: commandArgs[0], argv1: commandArgs[1] });
|
|
187
252
|
}
|
|
188
253
|
try {
|
|
254
|
+
const seat = process.env.ELANOUS_SEAT?.trim();
|
|
255
|
+
const user = process.env.USER?.trim() || process.env.LOGNAME?.trim();
|
|
256
|
+
const actor = seat || user;
|
|
257
|
+
if (!actor) throw new Error('pod provenance actor missing: ELANOUS_SEAT or USER/LOGNAME required');
|
|
258
|
+
const runId = randomUUID();
|
|
189
259
|
const result = await run({
|
|
190
260
|
command: commandArgs,
|
|
261
|
+
runId,
|
|
262
|
+
provenance: { actorKind: seat ? 'seat' : 'human', actor,
|
|
263
|
+
character: 'command-runner', launchHost: hostname(), entrance: 'pod-run', kind: 'command', run: runId,
|
|
264
|
+
phase: 'exec', requestedAt: new Date().toISOString(), reason: 'unknown', argv: basename(commandArgs[0] || '') },
|
|
191
265
|
returnLogs: true,
|
|
192
266
|
...(opts.pool ? { pool: opts.pool } : {}),
|
|
193
267
|
...(skills.length ? { skills } : {}),
|
package/src/cli/pr-cli.ts
CHANGED
|
@@ -30,6 +30,7 @@ import { queryRunningRuns, type RunningRunsResult } from '../self-implement/runn
|
|
|
30
30
|
import { debug } from '../debug/log.js';
|
|
31
31
|
import { runGitCommand } from '../git-fs/runner.js';
|
|
32
32
|
import {
|
|
33
|
+
defaultCensusParallelRunner,
|
|
33
34
|
defaultCmdRunner,
|
|
34
35
|
makePrManager,
|
|
35
36
|
resolveDeliverableBase,
|
|
@@ -58,10 +59,11 @@ import { branchLineageSlug, findSiblingPrs } from './pr-lineage.js';
|
|
|
58
59
|
import { parseReleaseNoteSection } from '../release-loop/release-note.js';
|
|
59
60
|
import { landingFreezeMessage } from '../release-loop/landing-freeze.js';
|
|
60
61
|
import { admitLandingMerge } from '../self-implement/frozen-merges.js';
|
|
61
|
-
import { verifyAllSameHeadReviews, verifyAncestorAutoPass, verifyOverlapEvidence, verifyOverlapEvidenceVirtualRebase } from './pr-land-overlap-evidence.js';
|
|
62
|
+
import { resolveOverlapEvidencePath, verifyAllSameHeadReviews, verifyAncestorAutoPass, verifyOverlapEvidence, verifyOverlapEvidenceVirtualRebase } from './pr-land-overlap-evidence.js';
|
|
62
63
|
import type { VerifyOverlapEvidenceInput } from './pr-land-overlap-evidence.js';
|
|
63
64
|
import { verifyVirtualRebasePatch } from './pr-land-virtual-rebase.js';
|
|
64
65
|
import { observeDirectPrLandRefusal, observePrLandRefusal } from './pr-land-refusal.js';
|
|
66
|
+
import { planPrLandRecovery } from './pr-land-recovery.js';
|
|
65
67
|
import { ensurePrLandHeavyRemote, type HeavyRemoteInput, type HeavyRemoteResult } from './pr-land-heavy-remote.js';
|
|
66
68
|
import { readPrBaseNameWithRetry } from './pr-land-base-read.js';
|
|
67
69
|
import { runHeavyOnPodShadow } from './pr-land-pod-shadow.js';
|
|
@@ -70,7 +72,7 @@ import { readTaskAgentState, taskAgentStatePath, type TaskCard } from '../task-a
|
|
|
70
72
|
import { INFLIGHT_REGISTRY_FILE, removeInflightForPr } from '../pr-tool/inflight-registry.js';
|
|
71
73
|
import { PR_LABEL_NAMES } from '../github/pr-labels.js';
|
|
72
74
|
import { enqueueL8ShadowQueue, runL8ShadowQueue, shadowPrNumber, statusL8ShadowQueue, type L8ShadowQueueDeps } from '../self-implement/l8-merge-queue.js';
|
|
73
|
-
import { censusOpenPrs, guardNewPr, parseDiffHunks, readOpenPrs, type Seat } from '../pr-tool/census.js';
|
|
75
|
+
import { censusOpenPrs, guardNewPr, parseDiffHunks, readOpenPrs, sharedCensusDiffCache, type Seat } from '../pr-tool/census.js';
|
|
74
76
|
|
|
75
77
|
export { branchLineageSlug, findSiblingPrs };
|
|
76
78
|
|
|
@@ -117,6 +119,8 @@ export const PR_LAND_MERGEABLE_UNKNOWN_WAIT_MS = 5_000;
|
|
|
117
119
|
|
|
118
120
|
export interface PrLandDeps {
|
|
119
121
|
manager?: PrManager;
|
|
122
|
+
/** Confirmed merge cleanup; failures are observed and never undo the merge. */
|
|
123
|
+
onMergedSupersede?: (number: number, cwd: string) => Promise<void>;
|
|
120
124
|
/** 병합 재시도 사이 대기(시험 주입용 · 기본 실제 대기). */
|
|
121
125
|
sleep?: (ms: number) => Promise<void>;
|
|
122
126
|
run?: CmdRunner;
|
|
@@ -271,14 +275,14 @@ export async function decideOverlapLanding(input: {
|
|
|
271
275
|
|
|
272
276
|
const liveOut = { log: (message: string) => console.log(message), error: (message: string) => console.error(message) };
|
|
273
277
|
|
|
274
|
-
function runPrLandTypecheckGate(out: { log: (message: string) => void; error: (message: string) => void }, cwd: string
|
|
278
|
+
function runPrLandTypecheckGate(out: { log: (message: string) => void; error: (message: string) => void }, cwd: string): boolean {
|
|
275
279
|
let failed = false;
|
|
276
280
|
const exit = ((code: number): never => {
|
|
277
281
|
failed = code !== 0;
|
|
278
282
|
throw new Error(`ci-typecheck-changed exited ${code}`);
|
|
279
283
|
});
|
|
280
284
|
try {
|
|
281
|
-
runChangedTypecheckGate({ log: out.log, warn: out.error, error: out.error, exit, cwd });
|
|
285
|
+
runChangedTypecheckGate({ log: out.log, warn: out.error, error: out.error, exit, cwd: resolve(cwd), allowMissingCheckoutDependencies: true });
|
|
282
286
|
} catch (error) {
|
|
283
287
|
if (!failed) throw error;
|
|
284
288
|
}
|
|
@@ -1087,7 +1091,7 @@ export function verifyPinnedOverlapDecision(input: {
|
|
|
1087
1091
|
if (decision === 'unavailable' && opts.overlapEvidence !== undefined) {
|
|
1088
1092
|
const ref = resolveRemoteBranchRef(run, cwd, base);
|
|
1089
1093
|
const evidenceInput: VerifyOverlapEvidenceInput = {
|
|
1090
|
-
evidencePath: opts.overlapEvidence, pr: Number(opts.pr), expectedHead: opts.expectedHead!,
|
|
1094
|
+
evidencePath: resolveOverlapEvidencePath(opts.overlapEvidence, cwd), pr: Number(opts.pr), expectedHead: opts.expectedHead!,
|
|
1091
1095
|
remote: ref.remote, branch: ref.branch, cwd, run, readFile,
|
|
1092
1096
|
reviewResultsDir: deps.reviewResultsDir ?? join(dirname(taskAgentStatePath()), 'review-results'),
|
|
1093
1097
|
listDir: (dir) => readdirSync(dir), reviewMtime: (path) => statSync(path).mtimeMs,
|
|
@@ -1318,6 +1322,19 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1318
1322
|
const refuse = (message: string, context: { isDraft?: boolean } = {}): void => {
|
|
1319
1323
|
out.error(message);
|
|
1320
1324
|
observePrLandRefusal(message, context);
|
|
1325
|
+
const pr = Number(opts.pr);
|
|
1326
|
+
if (Number.isSafeInteger(pr) && pr > 0 && opts.expectedHead) {
|
|
1327
|
+
try {
|
|
1328
|
+
const plan = planPrLandRecovery({ refusal: message, pr, head: opts.expectedHead, isDraft: context.isDraft });
|
|
1329
|
+
debug.log('pr.land', 'recover-shadow', {
|
|
1330
|
+
pr, head: opts.expectedHead, label: plan.evidence.label, route: plan.evidence.route,
|
|
1331
|
+
outcome: plan.outcome, action: plan.result.action, reason: plan.result.reason,
|
|
1332
|
+
delayMs: plan.result.delayMs ?? null, execution: 'none',
|
|
1333
|
+
});
|
|
1334
|
+
} catch {
|
|
1335
|
+
// Recovery observation must never replace the original landing refusal.
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1321
1338
|
};
|
|
1322
1339
|
const refuseDirect = (message: string): void => {
|
|
1323
1340
|
out.error(message);
|
|
@@ -1885,14 +1902,22 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1885
1902
|
const baseRead = await readPrBaseNameWithRetry({
|
|
1886
1903
|
pr: String(opts.pr), cwd, run,
|
|
1887
1904
|
sleep: deps.sleep ?? ((ms) => new Promise<void>((resolve) => setTimeout(resolve, ms))),
|
|
1905
|
+
onUnreadable: (attempt, stderr) => {
|
|
1906
|
+
if (stderr?.trim()) out.error(`⚠ heavy-remote: gh pr view base read attempt ${attempt}/3 stderr: ${stderr.trim()}`);
|
|
1907
|
+
},
|
|
1888
1908
|
});
|
|
1889
1909
|
const baseName = baseRead.baseRefName;
|
|
1890
1910
|
record('heavy-remote-pr-base-read', baseName !== null, {
|
|
1891
1911
|
pr: Number(opts.pr), baseRefName: baseName, attempts: baseRead.attempts,
|
|
1892
1912
|
});
|
|
1913
|
+
if (baseName === null) {
|
|
1914
|
+
record('heavy-remote-pr-base', false, { pr: Number(opts.pr), baseRefName: null, attempts: baseRead.attempts, reason: 'unreadable' });
|
|
1915
|
+
refuseDirect(`✗ heavy-remote: PR base 조회 불가 (${baseRead.attempts}회) — 통과한 head/main 쌍을 확인하지 못했다. 병합하지 않는다.`);
|
|
1916
|
+
return 1;
|
|
1917
|
+
}
|
|
1893
1918
|
if (baseName !== 'main') {
|
|
1894
|
-
record('heavy-remote-pr-base', false, { pr: Number(opts.pr), baseRefName: baseName, attempts: baseRead.attempts });
|
|
1895
|
-
refuseDirect(`✗ heavy-remote: PR base=${baseName
|
|
1919
|
+
record('heavy-remote-pr-base', false, { pr: Number(opts.pr), baseRefName: baseName, attempts: baseRead.attempts, reason: 'non-main' });
|
|
1920
|
+
refuseDirect(`✗ heavy-remote: PR base=${baseName} ≠ main — 재타기팅된 PR은 통과한 head/main 쌍이 아니다. 병합하지 않는다.`);
|
|
1896
1921
|
return 1;
|
|
1897
1922
|
}
|
|
1898
1923
|
return undefined;
|
|
@@ -1951,7 +1976,8 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1951
1976
|
}
|
|
1952
1977
|
return recheckOverlapAtBase(currentBase);
|
|
1953
1978
|
};
|
|
1954
|
-
|
|
1979
|
+
// The production gate must receive this land invocation's --cwd, never the launching shell's cwd.
|
|
1980
|
+
const typecheckOk = opts.heavyRemote || (deps.runTypecheckGate ? deps.runTypecheckGate(out) : runPrLandTypecheckGate(out, cwd));
|
|
1955
1981
|
record('typecheck', typecheckOk);
|
|
1956
1982
|
if (!typecheckOk) {
|
|
1957
1983
|
// ⛔⭐ 「왜 막혔나」를 «단정하지 않는다» — 이 게이트는 불리언만 돌려주므로 여기서는 이유를 모른다.
|
|
@@ -2374,6 +2400,13 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
2374
2400
|
}
|
|
2375
2401
|
if (opts.forceFreeze) debug.log('release-loop.freeze', 'force-merge', { pr: prNumber, reason: opts.forceFreeze.trim() });
|
|
2376
2402
|
record('merge', true, { result: merged.kind, ...(merged.remoteBranchDeletion ? { remoteBranchDeletion: merged.remoteBranchDeletion.detail } : {}) });
|
|
2403
|
+
if (Number.isSafeInteger(prNumber) && prNumber > 0 && deps.onMergedSupersede) {
|
|
2404
|
+
try { await deps.onMergedSupersede(prNumber, cwd); }
|
|
2405
|
+
catch (error) {
|
|
2406
|
+
try { debug.log('drafts.cleanup', 'same-cell-hook-failed', { merged: prNumber, error: String(error) }, { level: 'warn' }); }
|
|
2407
|
+
catch { /* a cleanup observation cannot undo a confirmed merge */ }
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2377
2410
|
// INFLIGHT-REGISTRY — 착지하면 비행 중 등록부의 그 런 줄을 지운다(색인 실패는 착지를 막지 않는다).
|
|
2378
2411
|
try {
|
|
2379
2412
|
const statePath = deps.taskStatePath ?? taskAgentStatePath();
|
|
@@ -2437,12 +2470,30 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
2437
2470
|
out.log(`✓ heavy-remote: post-merge host=${post.host ?? 'unknown'} head=${opts.expectedHead!.slice(0, 12)} main=${firstParent.slice(0, 12)} source=${post.source}`);
|
|
2438
2471
|
}
|
|
2439
2472
|
}
|
|
2440
|
-
const
|
|
2473
|
+
const finalBaseRead = upsert.reused && opts.heavyRemote
|
|
2474
|
+
? await readPrBaseNameWithRetry({
|
|
2475
|
+
pr: upsert.url, cwd, run,
|
|
2476
|
+
sleep: deps.sleep ?? ((ms) => new Promise<void>((resolve) => setTimeout(resolve, ms))),
|
|
2477
|
+
onUnreadable: (attempt, stderr) => {
|
|
2478
|
+
if (stderr?.trim()) out.error(`⚠ heavy-remote: final gh pr view base read attempt ${attempt}/3 stderr: ${stderr.trim()}`);
|
|
2479
|
+
},
|
|
2480
|
+
})
|
|
2481
|
+
: undefined;
|
|
2482
|
+
const baseRef = upsert.reused && !opts.heavyRemote
|
|
2441
2483
|
? run('gh', ['pr', 'view', upsert.url, '--json', 'baseRefName', '--jq', '.baseRefName'], { cwd })
|
|
2442
2484
|
: undefined;
|
|
2443
|
-
const landingBase =
|
|
2444
|
-
?
|
|
2445
|
-
:
|
|
2485
|
+
const landingBase = finalBaseRead
|
|
2486
|
+
? finalBaseRead.baseRefName ?? '<base unavailable>'
|
|
2487
|
+
: baseRef
|
|
2488
|
+
? (baseRef.ok && baseRef.out.trim() ? baseRef.out.trim() : '<base unavailable>')
|
|
2489
|
+
: base;
|
|
2490
|
+
if (finalBaseRead?.baseRefName && finalBaseRead.baseRefName !== 'main') {
|
|
2491
|
+
out.error(`✗ heavy-remote: PR base=${finalBaseRead.baseRefName} ≠ main — 병합된 base를 확인했습니다.`);
|
|
2492
|
+
return 1;
|
|
2493
|
+
}
|
|
2494
|
+
if (finalBaseRead?.baseRefName === null) {
|
|
2495
|
+
out.log(`⚠ heavy-remote: final PR base 조회 불가 (${finalBaseRead.attempts}회) — 병합 결과를 실패 처리하지 않습니다.`);
|
|
2496
|
+
}
|
|
2446
2497
|
out.log(`✓ merge: squash ${upsert.url} → ${landingBase}`);
|
|
2447
2498
|
if (landingBase === '<base unavailable>') {
|
|
2448
2499
|
out.log('⚠ local HEAD does not contain the landed result; the landed base is unavailable, so no branch command can be provided.');
|
|
@@ -2458,6 +2509,20 @@ export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queu
|
|
|
2458
2509
|
const prToolRun = deps.run ?? defaultCmdRunner;
|
|
2459
2510
|
const prToolOut = deps.out ?? liveOut;
|
|
2460
2511
|
const prToolExit = deps.setExitCode ?? ((code: number) => { process.exitCode = code; });
|
|
2512
|
+
const supersedeMerged = deps.onMergedSupersede ?? (async (number: number, cwd: string): Promise<void> => {
|
|
2513
|
+
const { supersedeMergedGoalDrafts } = await import('../harness/harness-cli-command.js');
|
|
2514
|
+
await supersedeMergedGoalDrafts(number, cwd, undefined, undefined, { onlyExplicitSameCell: true });
|
|
2515
|
+
});
|
|
2516
|
+
pr.command('supersede-drafts')
|
|
2517
|
+
.description('확인된 병합 PR의 명시 Supersedes 같은 칸 draft만 정리')
|
|
2518
|
+
.requiredOption('--pr <number>', '병합 PR 번호')
|
|
2519
|
+
.option('--cwd <path>', '저장소 경로')
|
|
2520
|
+
.action(async (opts: { pr: string; cwd?: string }) => {
|
|
2521
|
+
const number = Number(opts.pr);
|
|
2522
|
+
if (!Number.isSafeInteger(number) || number < 1) { prToolOut.error('✗ supersede-drafts: 올바른 --pr 번호 필요'); prToolExit(1); return; }
|
|
2523
|
+
try { await supersedeMerged(number, opts.cwd ?? process.cwd()); }
|
|
2524
|
+
catch (error) { prToolOut.error(`✗ supersede-drafts: ${String(error)}`); prToolExit(1); }
|
|
2525
|
+
});
|
|
2461
2526
|
pr.command('census')
|
|
2462
2527
|
.description('열린 PR 전체·골 문서만·2일 무커밋 draft·미닫힌 superseded 집계')
|
|
2463
2528
|
.option('--cwd <path>', '저장소 경로')
|
|
@@ -2478,7 +2543,9 @@ export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queu
|
|
|
2478
2543
|
const diff = prToolRun('git', ['-C', cwd, 'diff', '--name-only', '-z', `${opts.base}...HEAD`]);
|
|
2479
2544
|
const files = diff.ok ? diff.out.split('\0').filter(Boolean) : null;
|
|
2480
2545
|
const patch = prToolRun('git', ['-C', cwd, 'diff', '--unified=0', `${opts.base}...HEAD`]);
|
|
2481
|
-
|
|
2546
|
+
// PR-CENSUS-PARALLEL: the real runner fans `gh pr diff` out (cap 6); an injected runner stays one by one.
|
|
2547
|
+
const inventory = readOpenPrs(prToolRun, { cwd, ...(files ? { candidateFiles: files } : {}),
|
|
2548
|
+
...(deps.run ? {} : { runParallel: defaultCensusParallelRunner, diffCache: sharedCensusDiffCache }) });
|
|
2482
2549
|
const result = guardNewPr({ files: patch.ok ? files : null, seat: opts.seat as Seat | undefined, seatCap: Number(opts.seatCap), cellId: opts.cell, hunks: patch.ok ? parseDiffHunks(patch.out) : undefined }, inventory);
|
|
2483
2550
|
// Inspection never spends the three-creation unmeasured allowance.
|
|
2484
2551
|
// Only pr-manager records an actual new-PR attempt in that ledger.
|
|
@@ -2532,7 +2599,7 @@ export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queu
|
|
|
2532
2599
|
const { registerStandaloneLogSink } = await import('../domains/standalone-log-sink.js');
|
|
2533
2600
|
await registerStandaloneLogSink('pr-land');
|
|
2534
2601
|
} catch { /* fail-open */ }
|
|
2535
|
-
const code = await runPrLand(opts, deps);
|
|
2602
|
+
const code = await runPrLand(opts, { ...deps, onMergedSupersede: supersedeMerged });
|
|
2536
2603
|
if (code !== 0) (deps.setExitCode ?? ((exitCode: number) => { process.exitCode = exitCode; }))(code);
|
|
2537
2604
|
});
|
|
2538
2605
|
pr.command('granularity')
|
|
@@ -14,6 +14,7 @@ export async function readPrBaseNameWithRetry(input: {
|
|
|
14
14
|
cwd: string;
|
|
15
15
|
run: CmdRunner;
|
|
16
16
|
sleep: (ms: number) => Promise<void>;
|
|
17
|
+
onUnreadable?: (attempt: number, stderr: string | undefined) => void;
|
|
17
18
|
}): Promise<PrBaseReadResult> {
|
|
18
19
|
for (let attempt = 1; attempt <= PR_LAND_BASE_READ_RETRIES + 1; attempt += 1) {
|
|
19
20
|
const viewed = input.run('gh', ['pr', 'view', input.pr, '--json', 'baseRefName,url'], { cwd: input.cwd });
|
|
@@ -28,6 +29,7 @@ export async function readPrBaseNameWithRetry(input: {
|
|
|
28
29
|
} catch { /* Retry unreadable responses; do not treat them as main. */ }
|
|
29
30
|
|
|
30
31
|
if (baseRefName !== null) return { baseRefName, attempts: attempt };
|
|
32
|
+
input.onUnreadable?.(attempt, viewed.err);
|
|
31
33
|
if (attempt <= PR_LAND_BASE_READ_RETRIES) await input.sleep(PR_LAND_BASE_READ_RETRY_DELAY_MS);
|
|
32
34
|
}
|
|
33
35
|
return { baseRefName: null, attempts: PR_LAND_BASE_READ_RETRIES + 1 };
|
|
@@ -36,7 +36,7 @@ interface OverlapEvidenceFile {
|
|
|
36
36
|
gate?: { head: string; baseCommit: string; passed: boolean };
|
|
37
37
|
/** `self review --json` stdout 을 받은 파일(TA: `<state>/review-results/<card>-<pr>-<head접두 10~40>.json`); 내용의 전체 head도 확인한다. */
|
|
38
38
|
reviewResult: string;
|
|
39
|
-
/**
|
|
39
|
+
/** Evidence-file override for explicitly replaced failed reviews. Each reason is the verifier's refusal reason. */
|
|
40
40
|
supersedes?: { reviewResult: string; reason: string }[];
|
|
41
41
|
/** OPEN follow-up PR that owns the findings intentionally split from this landing. */
|
|
42
42
|
followupPr?: number;
|
|
@@ -48,6 +48,11 @@ export type OverlapEvidenceVerdict =
|
|
|
48
48
|
| { ok: true; mode: 'base-advanced-disjoint'; baseTip: string; gateBase: string; windowCommits: number; reviewResult: string }
|
|
49
49
|
| { ok: false; reason: string; baseTip?: string };
|
|
50
50
|
|
|
51
|
+
/** Resolve CLI-supplied evidence against the selected repository, not the caller's shell cwd. */
|
|
52
|
+
export function resolveOverlapEvidencePath(evidencePath: string, cwd: string): string {
|
|
53
|
+
return resolve(cwd, evidencePath);
|
|
54
|
+
}
|
|
55
|
+
|
|
51
56
|
export interface VerifyOverlapEvidenceInput {
|
|
52
57
|
evidencePath: string;
|
|
53
58
|
pr: number;
|
|
@@ -99,8 +104,12 @@ function checkSelectedReviewAttempts(input: VerifyOverlapEvidenceInput, e: Parti
|
|
|
99
104
|
const entries = e.supersedes;
|
|
100
105
|
if (entries !== undefined && (!Array.isArray(entries) || entries.length === 0)) return { ok: false, reason: 'review-supersedes-invalid' };
|
|
101
106
|
const superseded = new Map<string, string>();
|
|
107
|
+
const resolvedPriorAccepted: string[] = [];
|
|
102
108
|
let selectedTime: number | undefined;
|
|
103
|
-
|
|
109
|
+
let selectedRecord: Record<string, unknown> | undefined;
|
|
110
|
+
try { selectedRecord = lastReviewRecord(input.readFile(selected)); } catch { return { ok: false, reason: 'review-unreadable' }; }
|
|
111
|
+
const hasResolvedPrior = hasResolvedPriorDeclaration(selectedRecord);
|
|
112
|
+
if (entries?.length || hasResolvedPrior) {
|
|
104
113
|
try { selectedTime = input.reviewMtime(selected); } catch { return { ok: false, reason: 'review-attempt-time-unmeasured' }; }
|
|
105
114
|
if (!Number.isFinite(selectedTime)) return { ok: false, reason: 'review-attempt-time-unmeasured' };
|
|
106
115
|
}
|
|
@@ -123,9 +132,22 @@ function checkSelectedReviewAttempts(input: VerifyOverlapEvidenceInput, e: Parti
|
|
|
123
132
|
if (superseded.has(path)) return { ok: false, reason: 'review-supersedes-passing' };
|
|
124
133
|
continue;
|
|
125
134
|
}
|
|
126
|
-
if (superseded.
|
|
127
|
-
|
|
128
|
-
|
|
135
|
+
if (superseded.has(path)) {
|
|
136
|
+
if (superseded.get(path) !== review.reason) return { ok: false, reason: `review-attempt-not-superseded: ${basename(path)} (${review.reason})` };
|
|
137
|
+
if (!/^review-(verdict-fail|must-fix-[1-9][0-9]*)$/.test(review.reason)) {
|
|
138
|
+
return { ok: false, reason: `review-supersedes-not-failed: ${basename(path)} (${review.reason})` };
|
|
139
|
+
}
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (!/^review-(verdict-fail|must-fix-[1-9][0-9]*)$/.test(review.reason)
|
|
143
|
+
|| !selectedRecord || !reviewAttemptExplicitlyResolved(input, selectedRecord, path, head)) {
|
|
144
|
+
return { ok: false, reason: `review-attempt-not-superseded: ${basename(path)} (${review.reason})` };
|
|
145
|
+
}
|
|
146
|
+
resolvedPriorAccepted.push(path);
|
|
147
|
+
let failedTime: number;
|
|
148
|
+
try { failedTime = input.reviewMtime(path); } catch { return { ok: false, reason: 'review-attempt-time-unmeasured' }; }
|
|
149
|
+
if (!Number.isFinite(failedTime) || selectedTime === undefined || failedTime >= selectedTime) {
|
|
150
|
+
return { ok: false, reason: 'review-selected-not-later-than-failure' };
|
|
129
151
|
}
|
|
130
152
|
}
|
|
131
153
|
if (entries?.length) {
|
|
@@ -145,11 +167,137 @@ function checkSelectedReviewAttempts(input: VerifyOverlapEvidenceInput, e: Parti
|
|
|
145
167
|
head,
|
|
146
168
|
selected,
|
|
147
169
|
superseded: [...superseded.entries()].map(([reviewResult, reason]) => ({ reviewResult, reason })),
|
|
170
|
+
resolvedPriorAccepted,
|
|
148
171
|
followupPr: e.followupPr ?? null,
|
|
149
172
|
});
|
|
150
173
|
return { ok: true };
|
|
151
174
|
}
|
|
152
175
|
|
|
176
|
+
function lastReviewRecord(text: string): Record<string, unknown> | undefined {
|
|
177
|
+
const lines = text.split('\n').reverse();
|
|
178
|
+
for (const line of lines) {
|
|
179
|
+
if (!line.trim().startsWith('{')) continue;
|
|
180
|
+
let value: unknown;
|
|
181
|
+
try { value = JSON.parse(line); } catch { continue; }
|
|
182
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) continue;
|
|
183
|
+
const result = value as Record<string, unknown>;
|
|
184
|
+
if (result.pr !== undefined && (('verdict' in result && Array.isArray(result.mustFix)) || typeof result.error === 'string')) return result;
|
|
185
|
+
}
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function hasResolvedPriorDeclaration(review: Record<string, unknown> | undefined): boolean {
|
|
190
|
+
if (!review) return false;
|
|
191
|
+
const value = review.resolvedPrior;
|
|
192
|
+
if (Array.isArray(value) && value.length > 0) return true;
|
|
193
|
+
if (value && typeof value === 'object' && Object.keys(value).length > 0) return true;
|
|
194
|
+
return [review.intent, review.intentBlock, review.reviewIntent, review.reviewIntentBlock]
|
|
195
|
+
.some((intent) => typeof intent === 'string' && /resolved prior|prior review findings resolved/i.test(intent));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function normalizedFinding(value: string): string {
|
|
199
|
+
return value.trim().replace(/\s+/g, ' ').toLowerCase();
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function containsUnresolvedClaim(value: string): boolean {
|
|
203
|
+
return /\b(?:unresolved|not(?:\s+yet)?[\s-]+resolved|not(?:\s+yet)?[\s-]+fixed|not(?:\s+yet)?[\s-]+addressed|still[\s-]+open|remains?[\s-]+open|still[\s-]+present|status\s*[:=]\s*(?:open|unresolved|pending|in[- ]progress))\b/i.test(value);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function containsUnresolvedDeclaration(value: unknown): boolean {
|
|
207
|
+
if (typeof value === 'string') return containsUnresolvedClaim(value);
|
|
208
|
+
if (Array.isArray(value)) return value.some(containsUnresolvedDeclaration);
|
|
209
|
+
if (!value || typeof value !== 'object') return false;
|
|
210
|
+
const record = value as Record<string, unknown>;
|
|
211
|
+
if (record.resolved === false || (typeof record.status === 'string' && /^(?:open|unresolved|pending|in[- ]progress)$/i.test(record.status))) return true;
|
|
212
|
+
return Object.values(record).some(containsUnresolvedDeclaration);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function referencesReview(value: unknown, path: string): boolean {
|
|
216
|
+
return typeof value === 'string' && (value === path || value === basename(path));
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function findingList(value: unknown): string[] {
|
|
220
|
+
const values = Array.isArray(value) ? value : typeof value === 'string' ? [value] : [];
|
|
221
|
+
return values.filter((entry): entry is string => typeof entry === 'string' && entry.trim().length > 0);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** A later same-head pass/mf0 review may resolve prior attempts only when it names every finding explicitly. */
|
|
225
|
+
function reviewAttemptExplicitlyResolved(input: VerifyOverlapEvidenceInput, selected: Record<string, unknown>, failedPath: string, head: string): boolean {
|
|
226
|
+
let failed: Record<string, unknown> | undefined;
|
|
227
|
+
try { failed = lastReviewRecord(input.readFile(failedPath)); } catch { return false; }
|
|
228
|
+
if (!failed || failed.pr === undefined || String(failed.pr) !== String(input.pr)
|
|
229
|
+
|| (typeof failed.headCommit === 'string' && failed.headCommit.toLowerCase() !== head)
|
|
230
|
+
|| (typeof failed.currentHeadCommit === 'string' && failed.currentHeadCommit.toLowerCase() !== head)) return false;
|
|
231
|
+
const rawFindings = findingList(failed.mustFix).map((finding) => finding.trim());
|
|
232
|
+
const findings = rawFindings.map(normalizedFinding);
|
|
233
|
+
if (findings.length === 0) return false;
|
|
234
|
+
|
|
235
|
+
const declared = selected.resolvedPrior;
|
|
236
|
+
if (declared !== undefined && containsUnresolvedDeclaration(declared)) return false;
|
|
237
|
+
const intentBlocks = [selected.intent, selected.intentBlock, selected.reviewIntent, selected.reviewIntentBlock]
|
|
238
|
+
.filter((value): value is string => typeof value === 'string');
|
|
239
|
+
// A resolution in one field cannot override an OPEN/PENDING declaration in another.
|
|
240
|
+
if (intentBlocks.some(containsUnresolvedClaim)) return false;
|
|
241
|
+
|
|
242
|
+
let resolved: string[] = [];
|
|
243
|
+
if (Array.isArray(declared)) {
|
|
244
|
+
for (const entry of declared) {
|
|
245
|
+
if (typeof entry === 'string') {
|
|
246
|
+
if (containsUnresolvedClaim(entry)) continue;
|
|
247
|
+
// A string can be an exact finding axis or an explicit "filename: finding" row.
|
|
248
|
+
const line = entry.trim();
|
|
249
|
+
if (rawFindings.includes(line)) resolved.push(line);
|
|
250
|
+
const prefix = `${basename(failedPath)}: `;
|
|
251
|
+
if (line.startsWith(prefix)) {
|
|
252
|
+
const declaredFinding = line.slice(prefix.length).trim();
|
|
253
|
+
const index = rawFindings.indexOf(declaredFinding);
|
|
254
|
+
if (index >= 0) resolved.push(findings[index]!);
|
|
255
|
+
}
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) continue;
|
|
259
|
+
const item = entry as Record<string, unknown>;
|
|
260
|
+
const ref = item.reviewResult ?? item.review ?? item.path;
|
|
261
|
+
if (ref !== undefined && !referencesReview(ref, failedPath)) continue;
|
|
262
|
+
if (item.head !== undefined && (typeof item.head !== 'string' || item.head.toLowerCase() !== head)) continue;
|
|
263
|
+
if (item.headCommit !== undefined && (typeof item.headCommit !== 'string' || item.headCommit.toLowerCase() !== head)) continue;
|
|
264
|
+
if (item.resolved === false || item.status === 'unresolved'
|
|
265
|
+
|| Object.values(item).some((value) => typeof value === 'string' && containsUnresolvedClaim(value))) continue;
|
|
266
|
+
const listed = findingList(item.mustFix ?? item.resolvedMustFix ?? item.findings ?? item.axes ?? item.finding ?? item.axis);
|
|
267
|
+
if (listed.some(containsUnresolvedClaim)) continue;
|
|
268
|
+
if (ref === undefined && listed.every((finding) => rawFindings.includes(finding.trim()))) {
|
|
269
|
+
resolved.push(...listed.filter((finding) => rawFindings.includes(finding.trim())));
|
|
270
|
+
} else if (ref !== undefined) {
|
|
271
|
+
resolved.push(...listed.filter((finding) => rawFindings.includes(finding.trim())));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
} else if (declared && typeof declared === 'object') {
|
|
275
|
+
const record = declared as Record<string, unknown>;
|
|
276
|
+
const value = record[failedPath] ?? record[basename(failedPath)];
|
|
277
|
+
resolved.push(...findingList(value).filter((finding) => !containsUnresolvedClaim(finding) && rawFindings.includes(finding.trim())));
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
for (const intent of intentBlocks) {
|
|
281
|
+
const lines = intent.split(/\r?\n/);
|
|
282
|
+
const header = lines.findIndex((line) => /^resolved prior review findings:\s*$/i.test(line.trim()));
|
|
283
|
+
if (header < 0) continue;
|
|
284
|
+
// Only explicit rows under the resolution header count. A finding quoted in
|
|
285
|
+
// background prose is evidence of context, not a declaration of repair.
|
|
286
|
+
const prefix = `- ${basename(failedPath)}:`;
|
|
287
|
+
for (const raw of lines.slice(header + 1)) {
|
|
288
|
+
const line = raw.trim();
|
|
289
|
+
if (!line) continue;
|
|
290
|
+
if (!line.startsWith('- ')) break;
|
|
291
|
+
if (!line.startsWith(prefix)) continue;
|
|
292
|
+
const declaredFinding = line.slice(prefix.length).trim();
|
|
293
|
+
const index = rawFindings.indexOf(declaredFinding);
|
|
294
|
+
if (index >= 0) resolved.push(findings[index]!);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
const resolvedSet = new Set(resolved.map(normalizedFinding));
|
|
298
|
+
return findings.every((finding) => resolvedSet.has(finding));
|
|
299
|
+
}
|
|
300
|
+
|
|
153
301
|
type Checked = { ok: false; reason: string; baseTip?: string; gateBase?: string; windowCommits?: number }
|
|
154
302
|
| (OverlapEvidenceVerdict & { ok: true; baseTip?: string });
|
|
155
303
|
|
|
@@ -176,17 +324,7 @@ function checkReview(input: Pick<VerifyOverlapEvidenceInput, 'pr' | 'readFile'>,
|
|
|
176
324
|
if (review.pr !== input.pr) return { ok: false, reason: 'review-pr-mismatch', baseTip };
|
|
177
325
|
if (!review.head || review.head.toLowerCase() !== head) return { ok: false, reason: 'review-head-mismatch', baseTip };
|
|
178
326
|
// The capture parser projects away model provenance; inspect the same last result-shaped line here.
|
|
179
|
-
|
|
180
|
-
for (const line of text.split('\n').reverse()) {
|
|
181
|
-
if (!line.trim().startsWith('{')) continue;
|
|
182
|
-
let value: unknown;
|
|
183
|
-
try { value = JSON.parse(line); } catch { continue; }
|
|
184
|
-
if (!value || typeof value !== 'object' || Array.isArray(value)) continue;
|
|
185
|
-
const result = value as Record<string, unknown>;
|
|
186
|
-
if (result.pr === undefined || !(('verdict' in result && Array.isArray(result.mustFix)) || typeof result.error === 'string')) continue;
|
|
187
|
-
raw = result;
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
327
|
+
const raw = lastReviewRecord(text);
|
|
190
328
|
if (raw) {
|
|
191
329
|
const actualBackend = typeof raw.actualBackend === 'string' ? raw.actualBackend.trim().toLowerCase() : '';
|
|
192
330
|
const model = typeof raw.model === 'string' ? raw.model.trim().toLowerCase() : '';
|
|
@@ -63,6 +63,9 @@ export async function runLandingPodShadowJob(input: LandingPodShadowInput, deps:
|
|
|
63
63
|
// Wait for the runner to observe abort and finish Job/Secret/lease cleanup before landing continues.
|
|
64
64
|
job = await (deps.runPod ?? runPodCommand)({
|
|
65
65
|
command: ['bash', '-lc', script], clone: true, source: { kind: 'commit', sha: input.head },
|
|
66
|
+
provenance: { actorKind: 'loop', actor: 'pr-land-shadow', kind: 'land-shadow',
|
|
67
|
+
run: input.head, phase: 'land-shadow', requestedAt: new Date().toISOString(),
|
|
68
|
+
entrance: 'pr-land', commit: input.head, reason: 'landing typecheck and changed gate shadow' },
|
|
66
69
|
returnLogs: true, deadlineSeconds: 45 * 60,
|
|
67
70
|
statusUnreadableMs: LANDING_POD_SHADOW_STATUS_UNREADABLE_MS,
|
|
68
71
|
hostDeadlineAtMs: Date.now() + LANDING_POD_SHADOW_HOST_TIMEOUT_MS,
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { classifyPrLandRefusal } from './pr-land-refusal.js';
|
|
2
|
+
import { readJourneyEdge } from '../self-dev/graph-journey-route.js';
|
|
3
|
+
|
|
4
|
+
/** A recover unit selects a next action. The train or TA still owns every effect. */
|
|
5
|
+
export interface PrLandRecoveryContext {
|
|
6
|
+
refusal: string;
|
|
7
|
+
pr?: number;
|
|
8
|
+
head?: string;
|
|
9
|
+
isDraft?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface PrLandRecoveryPlan {
|
|
13
|
+
outcome: 'rework' | 'needs-human' | 'failed';
|
|
14
|
+
result: { action: 'wait-retry' | 'request-review' | 'needs-human' | 'none'; pr?: number; head?: string; delayMs?: number; reason: string };
|
|
15
|
+
evidence: { refusal: string; label: string; route: string | null; source: string };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function planPrLandRecovery(context: PrLandRecoveryContext): PrLandRecoveryPlan {
|
|
19
|
+
const raw = typeof context.refusal === 'string' ? context.refusal : '';
|
|
20
|
+
const lines = raw.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
21
|
+
// Callers must extract exactly one refusal line. A second diagnostic may be
|
|
22
|
+
// unmarked (for example `error: review-missing`), so never select a line
|
|
23
|
+
// from a larger transcript and mistake it for the whole verdict.
|
|
24
|
+
const refusal = lines.length === 1 ? lines[0]! : raw.trim();
|
|
25
|
+
const label = classifyPrLandRefusal(refusal, { isDraft: context.isDraft });
|
|
26
|
+
const route = readJourneyEdge('merge', label);
|
|
27
|
+
const evidence = { refusal: refusal.slice(0, 500), label, route: route.to, source: route.source };
|
|
28
|
+
const pr = Number.isSafeInteger(context.pr) && context.pr! > 0 ? context.pr : undefined;
|
|
29
|
+
const head = typeof context.head === 'string' && /^[0-9a-f]{40}$/i.test(context.head) ? context.head.toLowerCase() : undefined;
|
|
30
|
+
if (!refusal || !pr || !head) return { outcome: 'failed', result: { action: 'none', reason: 'pinned PR, head and refusal are required' }, evidence };
|
|
31
|
+
if (lines.length !== 1 || !refusal.startsWith('✗')) return { outcome: 'needs-human', result: { action: 'needs-human', pr, head, reason: `expected one marked refusal line, observed ${lines.length} nonempty lines` }, evidence };
|
|
32
|
+
if (route.source !== 'graph') return { outcome: 'needs-human', result: { action: 'needs-human', pr, head, reason: 'refusal has no declared graph route' }, evidence };
|
|
33
|
+
if (label === 'gate-host-busy' && route.to === 'next-move') {
|
|
34
|
+
return { outcome: 'rework', result: { action: 'wait-retry', pr, head, delayMs: 30_000, reason: 'remote gate host busy; retry through existing admission after delay' }, evidence };
|
|
35
|
+
}
|
|
36
|
+
if (label === 'review-missing' && route.to === 'review') {
|
|
37
|
+
return { outcome: 'rework', result: { action: 'request-review', pr, head, reason: 'request exact-head review through existing review gate' }, evidence };
|
|
38
|
+
}
|
|
39
|
+
return { outcome: 'needs-human', result: { action: 'needs-human', pr, head, reason: `${label} requires the existing ${route.to ?? 'unknown'} admission before another landing` }, evidence };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** A graph call_entry cannot turn one refusal into another action. */
|
|
43
|
+
export function planPrLandRecoveryForEntry(context: PrLandRecoveryContext, entry: string): PrLandRecoveryPlan {
|
|
44
|
+
const plan = planPrLandRecovery(context);
|
|
45
|
+
// The default entry keeps the original read-only planner contract.
|
|
46
|
+
if (entry === 'plan') return plan;
|
|
47
|
+
if (entry === 'human-review') {
|
|
48
|
+
if (plan.outcome === 'needs-human' && plan.result.action === 'needs-human') return plan;
|
|
49
|
+
return { outcome: 'failed', result: { action: 'none', reason: `recover entry ${entry} does not match ${plan.result.action}` }, evidence: plan.evidence };
|
|
50
|
+
}
|
|
51
|
+
if (entry === 'request-review' || entry === 'wait-retry') {
|
|
52
|
+
if (plan.outcome === 'rework' && plan.result.action === entry) return plan;
|
|
53
|
+
return {
|
|
54
|
+
outcome: 'failed',
|
|
55
|
+
result: { action: 'none', reason: `recover entry ${entry} does not match ${plan.result.action}` },
|
|
56
|
+
evidence: plan.evidence,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
outcome: 'failed',
|
|
61
|
+
result: { action: 'none', reason: `unknown recover entry: ${entry}` },
|
|
62
|
+
evidence: plan.evidence,
|
|
63
|
+
};
|
|
64
|
+
}
|