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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CLAIM_IDLE_HOURS, PR_LABELS, STALLED_DRAFT_HOURS } from '../github/pr-labels.js';
|
|
2
2
|
import { debug } from '../debug/log.js';
|
|
3
|
-
import { decideDraft, draftClaimComment, draftClaimState, draftReleaseComment, laterMergedTwins, sameGoalPr, type DraftTriagePr } from './draft-triage-rules.js';
|
|
3
|
+
import { assessDraftTriage, decideDraft, draftClaimComment, draftClaimState, draftReleaseComment, laterMergedTwins, sameGoalPr, PROTECTED_LABELS, type DraftTriageAssessment, type DraftTriagePr, type DraftTriageReviewState } from './draft-triage-rules.js';
|
|
4
|
+
import { cellIdFromBody } from '../pr-tool/census.js';
|
|
4
5
|
import { cardPrNumber, draftTaskOwner, type TaskCard } from '../task-agent/task-hand.js';
|
|
5
6
|
import type { PrTerminalRecord } from './draft-residue.js';
|
|
6
7
|
import { branchLineageSlug } from '../cli/pr-lineage.js';
|
|
@@ -25,6 +26,8 @@ export interface SweepMergedPr extends DraftTriagePr {
|
|
|
25
26
|
export interface DraftSweepAdapters {
|
|
26
27
|
/** Each call returns one complete page; a rejection must not be mistaken for an empty page. */
|
|
27
28
|
listDrafts(page: number, perPage: number, repository: string): Promise<readonly SweepDraft[]>;
|
|
29
|
+
/** Head commit time is fetched only for explicit triage, where it gates idle/close recommendations. */
|
|
30
|
+
getHeadCommitTime?(repository: string, number: number): Promise<string | undefined>;
|
|
28
31
|
listMerged(page: number, perPage: number, repository: string): Promise<readonly SweepMergedPr[]>;
|
|
29
32
|
/** Complete closed PR inventory for the creation cohort (including closed without merge). */
|
|
30
33
|
listRecentClosed?(repository: string, createdSince: Date): Promise<readonly SweepMergedPr[]>;
|
|
@@ -47,6 +50,8 @@ export interface DraftSweepAdapters {
|
|
|
47
50
|
/** Host ledger terminal records; undefined means the ledger could not be read. */
|
|
48
51
|
listPrTerminals?(): Promise<readonly PrTerminalRecord[] | undefined>;
|
|
49
52
|
commentDraft?(repository: string, number: number, body: string): Promise<void>;
|
|
53
|
+
/** Complete issue-comment inventory for idempotent merge-time same-cell cleanup. */
|
|
54
|
+
listIssueComments?(repository: string, number: number): Promise<readonly string[]>;
|
|
50
55
|
removeLabel?(repository: string, number: number, label: string): Promise<void>;
|
|
51
56
|
/** Whether the current owned run has a self-implement.result final observation, even if its worktree remains. */
|
|
52
57
|
hasFinalRunResult?(draft: SweepDraft, repository: string): Promise<boolean | undefined>;
|
|
@@ -74,6 +79,8 @@ export interface SweepReviewGate {
|
|
|
74
79
|
readonly review?: 'pass' | 'fail';
|
|
75
80
|
readonly mustFix?: boolean;
|
|
76
81
|
readonly gate?: 'pass' | 'fail';
|
|
82
|
+
/** Exact-head review posture for triage; unknown stays distinct from legacy census posture. */
|
|
83
|
+
readonly triageReview?: DraftTriageReviewState;
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
export interface DraftSweepOptions {
|
|
@@ -86,6 +93,8 @@ export interface DraftSweepOptions {
|
|
|
86
93
|
closeCapSource?: DraftSweepCloseCapSource;
|
|
87
94
|
/** Closes already made this tick by the pod-terminal replay — they count against the same cap. */
|
|
88
95
|
alreadyClosed?: number;
|
|
96
|
+
/** Include evidence-backed next-action recommendations in JSON output; never authorizes writes. */
|
|
97
|
+
includeTriage?: boolean;
|
|
89
98
|
}
|
|
90
99
|
|
|
91
100
|
export interface DraftSweepEntry {
|
|
@@ -104,6 +113,7 @@ export interface DraftSweepResult {
|
|
|
104
113
|
apply: boolean;
|
|
105
114
|
complete: boolean;
|
|
106
115
|
entries: DraftSweepEntry[];
|
|
116
|
+
triage?: { entries: Array<{ number: number; assessment: DraftTriageAssessment }>; counts: Record<string, number> };
|
|
107
117
|
counts: Record<string, number>;
|
|
108
118
|
/** Drafts whose run could not be observed from here (kept, or closed by the idle rule). */
|
|
109
119
|
unobserved?: number;
|
|
@@ -133,6 +143,11 @@ export interface DraftSweepLineageCounts {
|
|
|
133
143
|
closed: number;
|
|
134
144
|
harvestableClosed: number;
|
|
135
145
|
fallThrough: Record<string, number>;
|
|
146
|
+
/**
|
|
147
|
+
* Of `closed`, the ones the 칸 (cell) key decided instead of the branch lineage key. Absent while the 칸 rule
|
|
148
|
+
* closes nothing, so every existing lineage count and log line keeps its exact shape.
|
|
149
|
+
*/
|
|
150
|
+
cellClosed?: number;
|
|
136
151
|
}
|
|
137
152
|
|
|
138
153
|
/** A review counts as passed only on an observed PASS with no must-fix left. */
|
|
@@ -587,12 +602,14 @@ export function resolveDraftSweepCloseCap(input: { flag?: unknown; config?: unkn
|
|
|
587
602
|
return { closeCap: DRAFT_SWEEP_CLOSE_CAP, closeCapSource: 'default', warnings };
|
|
588
603
|
}
|
|
589
604
|
|
|
590
|
-
/** Post-merge
|
|
605
|
+
/** Post-merge cleanup: an explicit same-cell successor or the existing verified-goal decision can authorize a close. */
|
|
591
606
|
export async function supersedeDraftsOnMerge(input: {
|
|
592
607
|
repository: string;
|
|
593
608
|
merged: SweepMergedPr & { createdAt: string; mergedAt: string };
|
|
609
|
+
/** `pr land` and HQ train invoke only the explicit same-cell successor path. */
|
|
610
|
+
onlyExplicitSameCell?: boolean;
|
|
594
611
|
adapters: Pick<DraftSweepAdapters, 'listDrafts' | 'listLiveBranches' | 'getRunStatus' | 'setLabels' | 'closeDraft'>
|
|
595
|
-
& Pick<Partial<DraftSweepAdapters>, 'getLatestFileChanges' | 'getPrFiles'>;
|
|
612
|
+
& Pick<Partial<DraftSweepAdapters>, 'getLatestFileChanges' | 'getPrFiles' | 'commentDraft' | 'listIssueComments'>;
|
|
596
613
|
}): Promise<{ closed: number[]; kept: number[] }> {
|
|
597
614
|
const { repository, merged, adapters } = input;
|
|
598
615
|
const closed: number[] = [];
|
|
@@ -611,6 +628,43 @@ export async function supersedeDraftsOnMerge(input: {
|
|
|
611
628
|
|| !Number.isFinite(Date.parse(merged.createdAt)) || !Number.isFinite(Date.parse(merged.mergedAt))
|
|
612
629
|
|| drafts.some((pr) => !Number.isInteger(pr.number) || !pr.branch || !Array.isArray(pr.labels)
|
|
613
630
|
|| !Number.isFinite(Date.parse(pr.createdAt)))) throw new Error('Incomplete merge draft inventory');
|
|
631
|
+
// The conflicting-PR path writes this exact marker. A marker by itself is not authority:
|
|
632
|
+
// both PR bodies must identify the same cell, and the old PR must still be an open draft.
|
|
633
|
+
const markers = [...(merged.body ?? '').matchAll(/^Supersedes:\s*#(\d+)\s*$/gm)];
|
|
634
|
+
const markedNumber = markers.length === 1 ? Number(markers[0]![1]) : null;
|
|
635
|
+
const explicitOld = Number.isSafeInteger(markedNumber) && markedNumber! > 0 ? markedNumber : null;
|
|
636
|
+
const mergedCell = cellIdFromBody(merged.body ?? '');
|
|
637
|
+
if (explicitOld && explicitOld !== merged.number && mergedCell) {
|
|
638
|
+
const old = drafts.find((draft) => draft.number === explicitOld);
|
|
639
|
+
if (old && cellIdFromBody(old.body ?? '') === mergedCell
|
|
640
|
+
&& Date.parse(old.createdAt) < Date.parse(merged.mergedAt)
|
|
641
|
+
&& !old.labels.some((label) => PROTECTED_LABELS.has(label))
|
|
642
|
+
&& PR_LABELS.filter((label) => label.axis === 'state' && old.labels.includes(label.name)).length <= 1) {
|
|
643
|
+
const marker = `<!-- elanous:same-cell-superseded #${old.number} -> #${merged.number} -->`;
|
|
644
|
+
const comment = `${marker}\nSame-cell draft superseded by merged PR #${merged.number} (https://github.com/${repository}/pull/${merged.number}). Branch preserved.`;
|
|
645
|
+
try {
|
|
646
|
+
if (!adapters.listIssueComments || !adapters.commentDraft) throw new Error('same-cell comment inventory unavailable');
|
|
647
|
+
const comments = await adapters.listIssueComments(repository, old.number);
|
|
648
|
+
if (!Array.isArray(comments)) throw new Error('same-cell comment inventory incomplete');
|
|
649
|
+
const remove = stateLabels.filter((label) => old.labels.includes(label.name) && label.name !== supersededLabel).map((label) => label.name);
|
|
650
|
+
if (!old.labels.includes(supersededLabel)) await adapters.setLabels(repository, old.number, { add: supersededLabel, remove });
|
|
651
|
+
if (!comments.some((body) => body.includes(marker))) await adapters.commentDraft(repository, old.number, comment);
|
|
652
|
+
await adapters.closeDraft(repository, old.number);
|
|
653
|
+
closed.push(old.number);
|
|
654
|
+
closeAttempts += 1;
|
|
655
|
+
} catch (failure) {
|
|
656
|
+
failed.push(old.number);
|
|
657
|
+
error = String(failure);
|
|
658
|
+
debug.log('drafts.cleanup', 'same-cell-supersede-failed', { merged: merged.number, old: old.number, error });
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
if (input.onlyExplicitSameCell) {
|
|
663
|
+
kept.push(...drafts.map((draft) => draft.number).filter((number) => !closed.includes(number)));
|
|
664
|
+
debug.log('drafts.cleanup', 'superseded-on-merge', { merged: merged.number, closed, kept,
|
|
665
|
+
...(failed.length ? { failed } : {}), ...(error ? { error } : {}) });
|
|
666
|
+
return { closed, kept };
|
|
667
|
+
}
|
|
614
668
|
const statuses = new Map<number, string | undefined>();
|
|
615
669
|
const latestChanges = new Map<number, Readonly<Record<string, string>> | undefined>();
|
|
616
670
|
const mergedFiles = await adapters.getPrFiles?.(repository, merged.number);
|
|
@@ -625,7 +679,14 @@ export async function supersedeDraftsOnMerge(input: {
|
|
|
625
679
|
}
|
|
626
680
|
}
|
|
627
681
|
for (const listedDraft of drafts) {
|
|
682
|
+
if (closed.includes(listedDraft.number)) continue;
|
|
628
683
|
const draft = { ...listedDraft, latestFileChanges: latestChanges.get(listedDraft.number) };
|
|
684
|
+
// The same-cell route is never inferred from a title, goal, or file overlap.
|
|
685
|
+
// A failed explicit cleanup also stays open for a later retry instead of falling through to generic triage.
|
|
686
|
+
if (draft.number === explicitOld || (mergedCell && cellIdFromBody(draft.body ?? '') === mergedCell)) {
|
|
687
|
+
kept.push(draft.number);
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
629
690
|
if (draft.number === merged.number || !draft.branch.startsWith('self-impl/') || liveBranches.has(draft.branch)
|
|
630
691
|
|| Date.parse(draft.createdAt) >= Date.parse(merged.mergedAt)) {
|
|
631
692
|
kept.push(draft.number);
|
|
@@ -724,6 +785,30 @@ export function newerLineageDraft(draft: SweepDraft, openDrafts: readonly SweepD
|
|
|
724
785
|
.sort((a, b) => Date.parse(b.createdAt) - Date.parse(a.createdAt) || b.number - a.number)[0];
|
|
725
786
|
}
|
|
726
787
|
|
|
788
|
+
/**
|
|
789
|
+
* The newest open draft of the same 칸 (cell) that was created strictly after `draft` and belongs to a different
|
|
790
|
+
* goal lineage — two runs of different goals working the same cell are duplicates of one deliverable.
|
|
791
|
+
* Reads the canonical cell identity (`cellIdFromBody`, the same `칸: <CELL>` marker the PR creation guard uses),
|
|
792
|
+
* never a re-derived marker, and keeps `branchLineageKey` byte-compatible: only a *different* key is a cell match.
|
|
793
|
+
* ⛔ A draft whose body names no 칸 never matches (keep), and a same-칸 draft of the same goal is `newerLineageDraft`.
|
|
794
|
+
*/
|
|
795
|
+
export function newerSameCellDraft(draft: SweepDraft, openDrafts: readonly SweepDraft[]): SweepDraft | undefined {
|
|
796
|
+
const cellId = cellIdFromBody(draft.body ?? '');
|
|
797
|
+
const created = Date.parse(draft.createdAt);
|
|
798
|
+
if (cellId === null || !Number.isFinite(created)) return undefined;
|
|
799
|
+
const key = branchLineageKey(draft.branch);
|
|
800
|
+
// A missing goal id is not evidence of a different goal. Keep unknown lineage on either side.
|
|
801
|
+
if (key === null) return undefined;
|
|
802
|
+
return openDrafts
|
|
803
|
+
.filter((pr) => {
|
|
804
|
+
const openKey = branchLineageKey(pr.branch);
|
|
805
|
+
return pr.number !== draft.number && cellIdFromBody(pr.body ?? '') === cellId
|
|
806
|
+
&& openKey !== null && openKey !== key
|
|
807
|
+
&& Number.isFinite(Date.parse(pr.createdAt)) && Date.parse(pr.createdAt) > created;
|
|
808
|
+
})
|
|
809
|
+
.sort((a, b) => Date.parse(b.createdAt) - Date.parse(a.createdAt) || b.number - a.number)[0];
|
|
810
|
+
}
|
|
811
|
+
|
|
727
812
|
/**
|
|
728
813
|
* Census of harness drafts older than 24h. Same-goal landing uses `sameGoalPr` unchanged.
|
|
729
814
|
* A draft counts as closable when a same-goal merged PR exists, harvestable when review PASS and the gate passed,
|
|
@@ -751,7 +836,7 @@ export function draftSweepDaily(
|
|
|
751
836
|
}
|
|
752
837
|
|
|
753
838
|
/** A failed inventory or liveness lookup is never treated as proof that a draft can be closed. */
|
|
754
|
-
export async function runDraftSweep({ repository, adapters, apply = false, now = new Date(), closeCap: requestedCap, closeCapSource: requestedSource, alreadyClosed = 0 }: DraftSweepOptions): Promise<DraftSweepResult> {
|
|
839
|
+
export async function runDraftSweep({ repository, adapters, apply = false, now = new Date(), closeCap: requestedCap, closeCapSource: requestedSource, alreadyClosed = 0, includeTriage = false }: DraftSweepOptions): Promise<DraftSweepResult> {
|
|
755
840
|
const validCap = validCloseCap(requestedCap);
|
|
756
841
|
const closeCap = validCap ?? DRAFT_SWEEP_CLOSE_CAP;
|
|
757
842
|
const closeCapSource: DraftSweepCloseCapSource = validCap === undefined ? 'default' : requestedSource ?? 'flag';
|
|
@@ -829,7 +914,7 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
|
|
|
829
914
|
const reviewGate = new Map<number, SweepReviewGate | undefined>();
|
|
830
915
|
if (adapters.getReviewGate) {
|
|
831
916
|
// Review/gate posture only feeds the daily census, which only counts harness drafts older than 24h.
|
|
832
|
-
const censused = drafts.filter((draft) => dailyCensusDraft(draft, now));
|
|
917
|
+
const censused = includeTriage ? drafts : drafts.filter((draft) => dailyCensusDraft(draft, now));
|
|
833
918
|
try {
|
|
834
919
|
await mapBounded(censused, DRAFT_SWEEP_CONCURRENCY, async (draft) => {
|
|
835
920
|
reviewGate.set(draft.number, await adapters.getReviewGate!(draft, repository));
|
|
@@ -845,12 +930,89 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
|
|
|
845
930
|
// Card and terminal inventories are observations, not closing authority. An unreadable source cannot mint a claim.
|
|
846
931
|
let cards: readonly TaskCard[] | undefined;
|
|
847
932
|
let terminals: readonly PrTerminalRecord[] | undefined;
|
|
848
|
-
if (apply) {
|
|
933
|
+
if (apply || includeTriage) {
|
|
849
934
|
try { cards = await adapters.listTaskCards?.(); if (cards && !Array.isArray(cards)) cards = undefined; }
|
|
850
935
|
catch (error) { debug.log('draft.residue', 'claim-skipped', { prNumber: null, owner: null, runId: null, reason: `cards-unreadable: ${sweepFailureReason(error)}` }); }
|
|
851
936
|
try { terminals = await adapters.listPrTerminals?.(); if (terminals && !Array.isArray(terminals)) terminals = undefined; }
|
|
852
937
|
catch (error) { debug.log('draft.residue', 'claim-skipped', { prNumber: null, owner: null, runId: null, reason: `terminals-unreadable: ${sweepFailureReason(error)}` }); }
|
|
853
938
|
}
|
|
939
|
+
if (includeTriage) {
|
|
940
|
+
const latestCommitTimes = new Map<number, string | undefined>();
|
|
941
|
+
if (adapters.getHeadCommitTime) {
|
|
942
|
+
await mapBounded(drafts, DRAFT_SWEEP_CONCURRENCY, async (draft) => {
|
|
943
|
+
latestCommitTimes.set(draft.number, draft.latestCommitAt ?? await adapters.getHeadCommitTime!(repository, draft.number).catch(() => undefined));
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
const triageDrafts = drafts.map((draft) => ({ ...draft,
|
|
947
|
+
...(latestCommitTimes.has(draft.number) ? { latestCommitAt: latestCommitTimes.get(draft.number) } : {}),
|
|
948
|
+
}));
|
|
949
|
+
const triageRows: Array<{ number: number; assessment: DraftTriageAssessment }> = [];
|
|
950
|
+
const initial = triageDrafts.map((draft) => {
|
|
951
|
+
const posture = reviewGate.get(draft.number);
|
|
952
|
+
return assessDraftTriage({ draft, now, runStatus: statuses.get(draft.number),
|
|
953
|
+
...(posture?.gate ? { gate: posture.gate } : {}),
|
|
954
|
+
...(posture?.triageReview ? { review: posture.triageReview } : {}),
|
|
955
|
+
});
|
|
956
|
+
});
|
|
957
|
+
const activeOwnerObservations = new Map<number, { owner?: string; observed: boolean }>();
|
|
958
|
+
if (adapters.getActiveClaimOwner) {
|
|
959
|
+
const ownerLookupDrafts = triageDrafts.filter((draft) => !(cards && draftTaskOwner(cards, draft)));
|
|
960
|
+
await mapBounded(ownerLookupDrafts, DRAFT_SWEEP_CONCURRENCY, async (draft) => {
|
|
961
|
+
try {
|
|
962
|
+
activeOwnerObservations.set(draft.number, { owner: await adapters.getActiveClaimOwner!(repository, draft.number), observed: true });
|
|
963
|
+
} catch {
|
|
964
|
+
activeOwnerObservations.set(draft.number, { observed: false });
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
for (let index = 0; index < drafts.length; index++) {
|
|
969
|
+
const draft = triageDrafts[index]!;
|
|
970
|
+
const identity = initial[index]!;
|
|
971
|
+
// A generic sweep can target any repository, while the checklist is machine-wide.
|
|
972
|
+
// Until checklist observations are repository-bound, leave cell status unknown so close-a stays human.
|
|
973
|
+
const draftCreatedAt = Date.parse(draft.createdAt);
|
|
974
|
+
let newerSameCellSameCard: boolean | undefined;
|
|
975
|
+
if (identity.origin && identity.cellId && identity.cardId && Number.isFinite(draftCreatedAt)) {
|
|
976
|
+
let uncertainMatch = false;
|
|
977
|
+
newerSameCellSameCard = false;
|
|
978
|
+
for (let otherIndex = 0; otherIndex < triageDrafts.length; otherIndex++) {
|
|
979
|
+
if (otherIndex === index) continue;
|
|
980
|
+
const other = triageDrafts[otherIndex]!;
|
|
981
|
+
const otherIdentity = initial[otherIndex];
|
|
982
|
+
const otherCreatedAt = Date.parse(other.createdAt);
|
|
983
|
+
if (Number.isFinite(otherCreatedAt) && otherCreatedAt <= draftCreatedAt) continue;
|
|
984
|
+
if (otherIdentity?.origin && otherIdentity.origin !== identity.origin) continue;
|
|
985
|
+
if (otherIdentity?.cellId && otherIdentity.cellId !== identity.cellId) continue;
|
|
986
|
+
if (otherIdentity?.cardId && otherIdentity.cardId !== identity.cardId) continue;
|
|
987
|
+
if (!Number.isFinite(otherCreatedAt) || !otherIdentity?.origin || !otherIdentity.cellId || !otherIdentity.cardId) {
|
|
988
|
+
uncertainMatch = true;
|
|
989
|
+
continue;
|
|
990
|
+
}
|
|
991
|
+
newerSameCellSameCard = true;
|
|
992
|
+
break;
|
|
993
|
+
}
|
|
994
|
+
if (newerSameCellSameCard !== true && uncertainMatch) newerSameCellSameCard = undefined;
|
|
995
|
+
}
|
|
996
|
+
const ownerCard = cards ? draftTaskOwner(cards, draft) : undefined;
|
|
997
|
+
// A cell can have several cards and PRs. Terminal evidence belongs to this draft only by exact PR number;
|
|
998
|
+
// the terminal `card` field can identify the cell, not this card.
|
|
999
|
+
const cellTerminals = terminals?.filter((terminal) => terminal.repository === repository && terminal.prNumber === draft.number);
|
|
1000
|
+
const activeOwnerObservation = ownerCard ? undefined : activeOwnerObservations.get(draft.number);
|
|
1001
|
+
const posture = reviewGate.get(draft.number);
|
|
1002
|
+
const assessment = assessDraftTriage({ draft, now, runStatus: statuses.get(draft.number),
|
|
1003
|
+
...(posture?.gate ? { gate: posture.gate } : {}),
|
|
1004
|
+
...(posture?.triageReview ? { review: posture.triageReview } : {}),
|
|
1005
|
+
newerSameCellSameCard,
|
|
1006
|
+
ownerConfirmed: ownerCard?.seat ? true : !activeOwnerObservation?.observed ? undefined : Boolean(activeOwnerObservation.owner?.trim()),
|
|
1007
|
+
});
|
|
1008
|
+
const terminalEvidence = terminals === undefined ? 'PrTerminalRecord 미관측'
|
|
1009
|
+
: `PrTerminalRecord: cell=${identity.cellId ?? 'unknown'} matched=${cellTerminals?.length ?? 0}`;
|
|
1010
|
+
triageRows.push({ number: draft.number, assessment: { ...assessment, evidence: [...assessment.evidence, terminalEvidence] } });
|
|
1011
|
+
}
|
|
1012
|
+
const triageCounts: Record<string, number> = {};
|
|
1013
|
+
for (const row of triageRows) triageCounts[row.assessment.nextAction] = (triageCounts[row.assessment.nextAction] ?? 0) + 1;
|
|
1014
|
+
result.triage = { entries: triageRows, counts: triageCounts };
|
|
1015
|
+
}
|
|
854
1016
|
result.complete = true;
|
|
855
1017
|
let closes = Number.isSafeInteger(alreadyClosed) && alreadyClosed > 0 ? alreadyClosed : 0;
|
|
856
1018
|
let unobserved = 0;
|
|
@@ -858,6 +1020,8 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
|
|
|
858
1020
|
let claimExpired = 0;
|
|
859
1021
|
const lineageCounts: DraftSweepLineageCounts = { closed: 0, harvestableClosed: 0, fallThrough: {} };
|
|
860
1022
|
result.lineage = lineageCounts;
|
|
1023
|
+
// 칸-keyed closes this tick; published on `lineageCounts` only when the 칸 rule fires (existing shapes stay byte-identical).
|
|
1024
|
+
let cellClosed = 0;
|
|
861
1025
|
// Review posture for the harvestable lineage check, reusing the census lookups (one lookup per PR per tick).
|
|
862
1026
|
const postureFor = async (pr: SweepDraft): Promise<SweepReviewGate | undefined> => {
|
|
863
1027
|
if (!reviewGate.has(pr.number)) reviewGate.set(pr.number, await adapters.getReviewGate!(pr, repository));
|
|
@@ -980,7 +1144,11 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
|
|
|
980
1144
|
// reruns open until the 24h idle expiry. It is still protected when its own review passed and the newer one's did not.
|
|
981
1145
|
const harvestable = draft.labels.includes(harvestableLabel);
|
|
982
1146
|
const lineageNewer = contradiction ? undefined : newerLineageDraft(draft, drafts);
|
|
983
|
-
|
|
1147
|
+
// A different goal working the same 칸 is invisible to the branch lineage key, so the canonical 칸 identity decides it.
|
|
1148
|
+
// The lineage key keeps priority: a same-goal rerun stays a lineage outcome even when both drafts share the 칸.
|
|
1149
|
+
const cellNewer = contradiction || lineageNewer ? undefined : newerSameCellDraft(draft, drafts);
|
|
1150
|
+
const duplicateNewer = lineageNewer ?? cellNewer;
|
|
1151
|
+
if (duplicateNewer) {
|
|
984
1152
|
const base = decideDraft({ draft, runStatus, mergedTwins: merged, openDrafts: drafts, liveBranches,
|
|
985
1153
|
finalRunResult, ageHours: runStatus ? ageHours : idleHours });
|
|
986
1154
|
if (!base.reason.startsWith('label:') && !base.reason.startsWith('superseded-by #') && !base.reason.startsWith('duplicate-of-open #')) {
|
|
@@ -988,12 +1156,14 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
|
|
|
988
1156
|
|| (status !== 'self-implement.result final' && liveBranches.has(branch));
|
|
989
1157
|
const runLive = live(runStatus, draft.branch);
|
|
990
1158
|
const lineageKey = branchLineageKey(draft.branch);
|
|
991
|
-
const
|
|
1159
|
+
const cellId = cellNewer ? cellIdFromBody(draft.body ?? '') : null;
|
|
1160
|
+
const duplicateOf = cellNewer ? `cell ${cellId}` : `lineage ${lineageKey}`;
|
|
1161
|
+
const reason = `duplicate-of-open #${duplicateNewer.number} (${duplicateOf})${runLive ? ` · stop run ${draft.runId ?? 'unknown'}` : ''}`;
|
|
992
1162
|
// Every lineage outcome that does not close falls through to the existing rules (preservation contract):
|
|
993
1163
|
// a duplicate this rule cannot settle is decided exactly as it was before this rule existed.
|
|
994
1164
|
const fallThrough = (why: string) => {
|
|
995
1165
|
lineageCounts.fallThrough[why] = (lineageCounts.fallThrough[why] ?? 0) + 1;
|
|
996
|
-
try { debug.log('self-dev.draft-sweep', 'lineage-fall-through', { number: draft.number, newer:
|
|
1166
|
+
try { debug.log('self-dev.draft-sweep', 'lineage-fall-through', { number: draft.number, newer: duplicateNewer.number, lineageKey, ...(cellId === null ? {} : { cellId }), why, harvestable }); } catch { /* fail-soft */ }
|
|
997
1167
|
};
|
|
998
1168
|
// A harvestable draft yields only to a newer draft at least as complete: an observed review PASS on the old one
|
|
999
1169
|
// is kept unless the newer one passed review too. Unobservable review posture keeps the old draft (fail-closed).
|
|
@@ -1002,17 +1172,19 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
|
|
|
1002
1172
|
if (!adapters.getReviewGate) harvestProtection = 'lineage-harvestable-review-unobserved';
|
|
1003
1173
|
else {
|
|
1004
1174
|
try {
|
|
1005
|
-
const [oldPosture, newPosture] = [await postureFor(draft), await postureFor(
|
|
1175
|
+
const [oldPosture, newPosture] = [await postureFor(draft), await postureFor(duplicateNewer)];
|
|
1006
1176
|
if (oldPosture === undefined) harvestProtection = 'lineage-harvestable-review-unobserved';
|
|
1007
1177
|
else if (reviewPassed(oldPosture) && !reviewPassed(newPosture)) harvestProtection = 'lineage-harvestable-review-pass-protected';
|
|
1008
1178
|
} catch { harvestProtection = 'lineage-harvestable-review-unobserved'; }
|
|
1009
1179
|
}
|
|
1010
1180
|
}
|
|
1011
1181
|
if (harvestProtection) fallThrough(harvestProtection);
|
|
1182
|
+
// `supersedeRun` is same-lineage authority only: a live 칸 duplicate is kept for the existing rules instead.
|
|
1183
|
+
else if (cellNewer && runLive) fallThrough('cell-duplicate-run-live');
|
|
1012
1184
|
else if (runLive && !adapters.supersedeRun) fallThrough('lineage-duplicate-run-live');
|
|
1013
1185
|
// Safety (OP 10-11): a live run is stopped only when the newer run of the same lineage is itself live —
|
|
1014
1186
|
// never trade a running attempt for one that already ended or was never observed running.
|
|
1015
|
-
else if (runLive && !live(statuses.get(
|
|
1187
|
+
else if (runLive && !live(statuses.get(duplicateNewer.number), duplicateNewer.branch)) fallThrough('lineage-newer-run-not-live');
|
|
1016
1188
|
else if (closes >= closeCap) {
|
|
1017
1189
|
record({ number: draft.number, action: 'keep', reason: 'close-cap', applied: false });
|
|
1018
1190
|
continue;
|
|
@@ -1020,9 +1192,9 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
|
|
|
1020
1192
|
let stopFailed = false;
|
|
1021
1193
|
// --apply only: the run is stopped before anything is written; a stop that cannot be confirmed writes nothing.
|
|
1022
1194
|
if (apply && runLive) {
|
|
1023
|
-
const observed = { number: draft.number, newer:
|
|
1195
|
+
const observed = { number: draft.number, newer: duplicateNewer.number, runId: draft.runId ?? null, newerRunId: duplicateNewer.runId ?? null, lineageKey };
|
|
1024
1196
|
try {
|
|
1025
|
-
await adapters.supersedeRun!(draft, repository,
|
|
1197
|
+
await adapters.supersedeRun!(draft, repository, duplicateNewer);
|
|
1026
1198
|
try { debug.log('self-dev.draft-sweep', 'supersede-run', observed); } catch { /* fail-soft */ }
|
|
1027
1199
|
} catch (error) {
|
|
1028
1200
|
stopFailed = true;
|
|
@@ -1035,6 +1207,7 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
|
|
|
1035
1207
|
closes += 1;
|
|
1036
1208
|
lineageCounts.closed += 1;
|
|
1037
1209
|
if (harvestable) lineageCounts.harvestableClosed += 1;
|
|
1210
|
+
if (cellNewer) cellClosed += 1;
|
|
1038
1211
|
const entry: DraftSweepEntry = { number: draft.number, action: 'close', reason, statusLabel: supersededLabel, applied: false };
|
|
1039
1212
|
record(entry);
|
|
1040
1213
|
if (!apply) continue;
|
|
@@ -1054,6 +1227,7 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
|
|
|
1054
1227
|
closes -= 1;
|
|
1055
1228
|
lineageCounts.closed -= 1;
|
|
1056
1229
|
if (harvestable) lineageCounts.harvestableClosed -= 1;
|
|
1230
|
+
if (cellNewer) cellClosed -= 1;
|
|
1057
1231
|
}
|
|
1058
1232
|
entry.error = String(error);
|
|
1059
1233
|
}
|
|
@@ -1163,6 +1337,7 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
|
|
|
1163
1337
|
}
|
|
1164
1338
|
}
|
|
1165
1339
|
timing('decide', drafts.length);
|
|
1340
|
+
if (cellClosed > 0) lineageCounts.cellClosed = cellClosed;
|
|
1166
1341
|
try { debug.log('self-dev.draft-sweep', 'lineage-summary', { ...lineageCounts, apply }); } catch { /* fail-soft */ }
|
|
1167
1342
|
try { debug.log('self-dev.draft-sweep', 'timing', { phase: 'total', ms: Date.now() - started, count: drafts.length, closed: closes, closeCap, closeCapSource }); } catch { /* fail-soft */ }
|
|
1168
1343
|
result.unobserved = unobserved;
|
|
@@ -30,6 +30,113 @@ export interface DraftTriagePr {
|
|
|
30
30
|
changedFiles?: readonly string[];
|
|
31
31
|
/** Latest change to each draft file, from the draft branch's commit history. Missing is not creation time. */
|
|
32
32
|
latestFileChanges?: Readonly<Record<string, string>>;
|
|
33
|
+
/** Latest head commit, separate from PR updatedAt (labels/comments also update that). */
|
|
34
|
+
latestCommitAt?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type DraftTriageNextAction = 'close-a' | 'close-c' | 'human';
|
|
38
|
+
export type DraftTriageReviewState = 'approved' | 'changes-requested' | 'commented' | 'dismissed' | 'pending' | 'unknown';
|
|
39
|
+
export type DraftTriageCheck = { state: 'yes' | 'no' | 'unknown'; evidence: string };
|
|
40
|
+
export interface DraftTriageAssessment {
|
|
41
|
+
origin: string | null;
|
|
42
|
+
cellId: string | null;
|
|
43
|
+
cardId: string | null;
|
|
44
|
+
gate: 'pass' | 'fail' | 'unknown';
|
|
45
|
+
review: DraftTriageReviewState;
|
|
46
|
+
cellStatus: 'green' | 'yellow' | 'red' | 'done' | 'unknown';
|
|
47
|
+
nextAction: DraftTriageNextAction;
|
|
48
|
+
checks: Readonly<Record<'provenance' | 'gate' | 'review' | 'cell-complete' | 'cell-status-repository-bound' | 'replacement-landed' | 'newer-same-card' | 'idle-48h' | 'protected' | 'recent-commit' | 'running' | 'owner-confirmed', DraftTriageCheck>>;
|
|
49
|
+
evidence: readonly string[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface DraftTriageAssessmentInput {
|
|
53
|
+
draft: DraftTriagePr;
|
|
54
|
+
now: Date;
|
|
55
|
+
runStatus?: string;
|
|
56
|
+
gate?: 'pass' | 'fail';
|
|
57
|
+
review?: DraftTriageReviewState;
|
|
58
|
+
cellStatus?: 'green' | 'yellow' | 'red' | 'done';
|
|
59
|
+
/** Repository identity attached to the cell-status observation, when available. */
|
|
60
|
+
cellStatusRepository?: string;
|
|
61
|
+
/** Repository targeted by this triage request. */
|
|
62
|
+
targetRepository?: string;
|
|
63
|
+
newerSameCellSameCard?: boolean;
|
|
64
|
+
ownerConfirmed?: boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const CLOSE_PROTECTED_LABELS = new Set([
|
|
68
|
+
'elanous:running', 'elanous:keep', 'elanous:release-hold', 'elanous:idea-approval',
|
|
69
|
+
'elanous:harvest-claimed', 'triage:land', 'triage:active',
|
|
70
|
+
]);
|
|
71
|
+
const TRIAGE_TERMINAL_RUN_STATUSES = new Set(['completed', 'failed', 'cancelled', 'abandoned', 'self-implement.result final']);
|
|
72
|
+
|
|
73
|
+
/** Evidence-first recommendation. Unknown evidence always routes to a person. */
|
|
74
|
+
export function assessDraftTriage(input: DraftTriageAssessmentInput): DraftTriageAssessment {
|
|
75
|
+
const { draft, now } = input;
|
|
76
|
+
const originLabels = (draft.labels ?? []).filter((name) => /^elanous:from-[a-z0-9-]+$/.test(name));
|
|
77
|
+
const origin = originLabels.length === 1 ? originLabels[0]! : null;
|
|
78
|
+
const bodyLines = (draft.body ?? '').split(/\r?\n/);
|
|
79
|
+
const cellMarkerLines = bodyLines.filter((line) => /^\s*칸\s*:/.test(line));
|
|
80
|
+
const cellRows = bodyLines.flatMap((line) => {
|
|
81
|
+
const match = /^칸:\s*([^\r\n]*)$/.exec(line);
|
|
82
|
+
return match ? [match[1]!.trim()] : [];
|
|
83
|
+
});
|
|
84
|
+
const cellValues = new Set(cellRows);
|
|
85
|
+
const cellId = cellMarkerLines.length === cellRows.length && cellRows.length > 0 && cellValues.size === 1
|
|
86
|
+
&& /^[A-Z][A-Z0-9-]{2,}$/.test(cellRows[0]!) ? cellRows[0]! : null;
|
|
87
|
+
const cardMarkerLines = bodyLines.filter((line) => /^\s*카드\s*:/.test(line));
|
|
88
|
+
const cardRows = bodyLines.flatMap((line) => {
|
|
89
|
+
const match = /^카드:[ \t]*([^\r\n]+)[ \t]*$/.exec(line);
|
|
90
|
+
return match ? [match[1]!.trim()] : [];
|
|
91
|
+
});
|
|
92
|
+
const cardId = cardMarkerLines.length === cardRows.length && cardRows.length > 0
|
|
93
|
+
&& cardRows.every((value) => value === cardRows[0])
|
|
94
|
+
&& /^[A-Za-z0-9][A-Za-z0-9._:-]{2,}$/.test(cardRows[0]!) ? cardRows[0]! : null;
|
|
95
|
+
const provenance = Boolean(origin && cellId && cardId);
|
|
96
|
+
const latestCommit = Date.parse(draft.latestCommitAt ?? '');
|
|
97
|
+
const clock = now.getTime();
|
|
98
|
+
const ageHours = Number.isFinite(latestCommit) && Number.isFinite(clock) ? (clock - latestCommit) / 3_600_000 : NaN;
|
|
99
|
+
const protectedLabel = (draft.labels ?? []).find((name) => CLOSE_PROTECTED_LABELS.has(name));
|
|
100
|
+
const protectedState = Boolean(protectedLabel);
|
|
101
|
+
const running = input.runStatus === 'running' || input.runStatus === 'probable-running'
|
|
102
|
+
|| (draft.labels ?? []).includes('elanous:running');
|
|
103
|
+
const cellComplete = input.cellStatus === 'green' || input.cellStatus === 'done';
|
|
104
|
+
const hasCellStatusRepositoryIdentity = Boolean(input.cellStatusRepository?.trim() && input.targetRepository?.trim());
|
|
105
|
+
const cellStatusRepositoryBound = hasCellStatusRepositoryIdentity
|
|
106
|
+
&& input.cellStatusRepository!.trim().toLowerCase() === input.targetRepository!.trim().toLowerCase();
|
|
107
|
+
const releaseCutoff = Number.isFinite(clock) ? (() => {
|
|
108
|
+
const date = new Date(clock);
|
|
109
|
+
const cutoff = new Date(date);
|
|
110
|
+
cutoff.setUTCHours(0, 30, 0, 0); // 09:30 KST
|
|
111
|
+
return clock < cutoff.getTime() ? cutoff.getTime() - 86_400_000 : cutoff.getTime();
|
|
112
|
+
})() : NaN;
|
|
113
|
+
const recentCommit = Number.isFinite(latestCommit) && Number.isFinite(releaseCutoff) && latestCommit > releaseCutoff;
|
|
114
|
+
const runNotRunning = input.runStatus !== undefined && TRIAGE_TERMINAL_RUN_STATUSES.has(input.runStatus) && !running;
|
|
115
|
+
// Closing requires positive evidence that the head predates today's release cutoff.
|
|
116
|
+
// Missing timestamps are unknown, so they cannot authorize a close recommendation.
|
|
117
|
+
const closeEligible = provenance && !protectedState && Number.isFinite(latestCommit) && !recentCommit && runNotRunning;
|
|
118
|
+
const idle48h = Number.isFinite(ageHours) && ageHours >= 48;
|
|
119
|
+
let nextAction: DraftTriageNextAction = 'human';
|
|
120
|
+
if (closeEligible && cellComplete && cellStatusRepositoryBound) nextAction = 'close-a';
|
|
121
|
+
else if (closeEligible && idle48h && input.ownerConfirmed === true) nextAction = 'close-c';
|
|
122
|
+
|
|
123
|
+
const checks = {
|
|
124
|
+
provenance: { state: provenance ? 'yes' : 'unknown', evidence: provenance ? `origin=${origin}; cell=${cellId}; card=${cardId}` : '출처·유효 칸·카드 표지가 모두 확인되지 않음' },
|
|
125
|
+
gate: { state: input.gate === undefined ? 'unknown' : input.gate === 'pass' ? 'yes' : 'no', evidence: `gate=${input.gate ?? 'unknown'}` },
|
|
126
|
+
review: { state: input.review === undefined || input.review === 'unknown' ? 'unknown' : input.review === 'approved' ? 'yes' : 'no', evidence: `latest exact-head review=${input.review ?? 'unknown'}` },
|
|
127
|
+
'cell-complete': { state: input.cellStatus && cellStatusRepositoryBound ? (cellComplete ? 'yes' : 'no') : 'unknown', evidence: input.cellStatus ? `cell=${cellId ?? 'unknown'} status=${input.cellStatus}${cellStatusRepositoryBound ? '' : ' (저장소 귀속 미확인)'}` : `칸 상태 미관측${cellId ? ` (${cellId})` : ''}` },
|
|
128
|
+
'cell-status-repository-bound': { state: cellStatusRepositoryBound ? 'yes' : hasCellStatusRepositoryIdentity ? 'no' : 'unknown', evidence: cellStatusRepositoryBound ? `칸 상태 저장소=${input.cellStatusRepository}; 대상 저장소=${input.targetRepository}` : hasCellStatusRepositoryIdentity ? `칸 상태 저장소=${input.cellStatusRepository}; 대상 저장소=${input.targetRepository} (불일치)` : '칸 상태의 대상 저장소 귀속 미확인' },
|
|
129
|
+
'replacement-landed': { state: 'unknown', evidence: '현재 adapter는 같은 칸 병합 PR과 이 초안의 대체 관계를 증명하지 않음; follow-up 필요' },
|
|
130
|
+
'newer-same-card': { state: input.newerSameCellSameCard === undefined ? 'unknown' : input.newerSameCellSameCard ? 'yes' : 'no', evidence: `${input.newerSameCellSameCard === undefined ? '같은 칸·카드 새 draft 관계 미관측' : `same-cell-same-card-newer=${input.newerSameCellSameCard}`}; 관측 표지이며 대체 증거가 아님` },
|
|
131
|
+
'idle-48h': { state: Number.isFinite(ageHours) ? (idle48h ? 'yes' : 'no') : 'unknown', evidence: Number.isFinite(ageHours) ? `head age=${ageHours.toFixed(1)}h` : 'head commit 시각 미관측' },
|
|
132
|
+
protected: { state: protectedState ? 'yes' : 'no', evidence: protectedLabel ? `보호 표지=${protectedLabel}` : '보호 표지 없음' },
|
|
133
|
+
'recent-commit': { state: Number.isFinite(latestCommit) ? (recentCommit ? 'yes' : 'no') : 'unknown', evidence: Number.isFinite(latestCommit) ? `last commit=${draft.latestCommitAt}; cutoff=09:30 KST` : 'head commit 시각 미관측' },
|
|
134
|
+
running: { state: running ? 'yes' : runNotRunning ? 'no' : 'unknown', evidence: running ? `run=${input.runStatus ?? 'elanous:running'}` : runNotRunning ? `종결 run=${input.runStatus}` : `run 상태 미관측${input.runStatus ? ` (${input.runStatus})` : ''}` },
|
|
135
|
+
'owner-confirmed': { state: input.ownerConfirmed === undefined ? 'unknown' : input.ownerConfirmed ? 'yes' : 'no', evidence: input.ownerConfirmed === undefined ? '소유자 출처 미관측' : input.ownerConfirmed ? '고유 카드 또는 활성 claim owner 확인' : '고유 소유자 없음' },
|
|
136
|
+
} satisfies DraftTriageAssessment['checks'];
|
|
137
|
+
const evidence = Object.values(checks).map((check) => check.evidence);
|
|
138
|
+
return { origin, cellId, cardId, gate: input.gate ?? 'unknown', review: input.review ?? 'unknown',
|
|
139
|
+
cellStatus: input.cellStatus ?? 'unknown', nextAction, checks, evidence };
|
|
33
140
|
}
|
|
34
141
|
|
|
35
142
|
export interface DraftTriageInput {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
// 순서: 기준(origin/<base>)에서 임시 워크트리 → 조각 브랜치를 차례로 `merge --no-ff`
|
|
5
5
|
// → 충돌이면 «그 조각 ⊕ 충돌 파일»을 이름으로 대고 병합을 되돌린 뒤 멈춘다(추측으로 풀지 않는다)
|
|
6
|
-
// → 다 합쳐지면 `self gate --base <base>`(새 회귀만 빨강) → 통합 브랜치 푸시 → PR 하나(조각 PR 나열)
|
|
6
|
+
// → 다 합쳐지면 `self gate --local --base <base>`(새 회귀만 빨강) → 통합 브랜치 푸시 → PR 하나(조각 PR 나열)
|
|
7
7
|
// → 조각 PR 에 «통합 PR 로 대체됨» 코멘트(닫지는 않는다 — 사람 몫).
|
|
8
8
|
// ⛔ 조각 PR 을 main 에 따로 병합하지 않는다 — 그건 `--auto-merge` 의 일이고 reduce 는 «하나로»다.
|
|
9
9
|
|
|
@@ -116,7 +116,8 @@ export async function reduceShards(opts: ReduceOptions): Promise<ReduceOutcome>
|
|
|
116
116
|
// 게이트는 저장소 코드로 돈다 — 통합 워크트리에 의존성을 잇는다(설치 없이).
|
|
117
117
|
const nm = join(opts.repoRoot, 'node_modules');
|
|
118
118
|
if (existsSync(nm) && !existsSync(join(wt, 'node_modules'))) symlinkSync(nm, join(wt, 'node_modules'));
|
|
119
|
-
|
|
119
|
+
// This gate measures the local integration worktree; remote SSH availability is unrelated to the merge result.
|
|
120
|
+
const g = run('bun', ['bin/elanous.mjs', 'self', 'gate', '--local', '--changed', '--base', `origin/${base}`], wt); // 📏 `--changed` 가 없으면 rc 2 로 거절한다(첫 실물)
|
|
120
121
|
const tail = `${g.stdout}\n${g.stderr}`.trim().split('\n').slice(-6).join('\n');
|
|
121
122
|
if (g.status !== 0) {
|
|
122
123
|
debug.log('self-dev.reduce', 'gate-failed', { branch, merged: merged.length, rc: g.status });
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { debug } from '../debug/log.js';
|
|
2
|
+
import type { GoalType } from '../self-implement/goal-author.js';
|
|
2
3
|
import { frontObservationTemplate, visitBudgetOfVisits, type VisitBudgetReading } from '../self-implement/graph-authority.js';
|
|
3
4
|
import { GRAPH_TEMPLATES_SOURCE, graphIdentityOf, pipelineNodeEntryPayload, type GraphTemplate } from '../self-implement/graph-templates.js';
|
|
5
|
+
import { appendRunLedgerEntry, runLedgerDir } from '../self-implement/run-ledger.js';
|
|
6
|
+
import { journeyJoinFields } from './graph-journey-nodes.js';
|
|
7
|
+
import { journeySpec, readJourneyEdge, recordJourneyEdge, type JourneyRoute } from './graph-journey-route.js';
|
|
4
8
|
|
|
5
9
|
/** ⭐ RFC §5 «5단계» — 전반부(저작·플랜·분해) 노드를 그래프 관측에 «잇는다».
|
|
6
10
|
*
|
|
@@ -51,6 +55,25 @@ export function resetFrontVisitCountsForTesting(now?: () => number): void {
|
|
|
51
55
|
lastFrontVisitPruneMs = Number.NEGATIVE_INFINITY;
|
|
52
56
|
}
|
|
53
57
|
|
|
58
|
+
/** Record the actual front-half execution boundary, without controlling the stage. */
|
|
59
|
+
export async function observeFrontNodeUnit<T>(node: FrontNodeId, runId: string | undefined, goalType: GoalType | undefined, execute: () => Promise<T>): Promise<T> {
|
|
60
|
+
const emit = (phase: 'enter' | 'exit'): void => {
|
|
61
|
+
if (!runId) return;
|
|
62
|
+
try {
|
|
63
|
+
const template = frontObservationTemplate(goalType);
|
|
64
|
+
const contractId = template.nodes.find((item) => item.nodeId === node)?.recipe ?? null;
|
|
65
|
+
const data = { graphId: template.graphId, nodeId: node, unit: node, contractId, phase };
|
|
66
|
+
try { appendRunLedgerEntry({ timestamp: new Date().toISOString(), runId, event: 'graph.unit', data }, runLedgerDir()); }
|
|
67
|
+
catch { /* ledger failure cannot change execution */ }
|
|
68
|
+
try { debug.log('graph.unit', phase, { ...data, runId }); }
|
|
69
|
+
catch { /* debug failure cannot change execution */ }
|
|
70
|
+
} catch { /* template failure cannot change execution */ }
|
|
71
|
+
};
|
|
72
|
+
emit('enter');
|
|
73
|
+
try { return await execute(); }
|
|
74
|
+
finally { emit('exit'); }
|
|
75
|
+
}
|
|
76
|
+
|
|
54
77
|
function pruneIdleFrontVisitRuns(nowMs: number): void {
|
|
55
78
|
if (nowMs - lastFrontVisitPruneMs < FRONT_VISIT_PRUNE_INTERVAL_MS) return;
|
|
56
79
|
lastFrontVisitPruneMs = nowMs;
|
|
@@ -120,3 +143,92 @@ export function observeFrontNodeEntry(node: FrontNodeId, data: {
|
|
|
120
143
|
});
|
|
121
144
|
} catch { /* 판독 실패는 fail-soft — 예산은 관측이고 저작을 막지 않는다 */ }
|
|
122
145
|
}
|
|
146
|
+
|
|
147
|
+
/** GRAPH-AUTHOR-FAIL-EDGE — author 결과가 고르는 «앞단 결과 노드». ⛔ 런타임 값 — YAML 이 더한 노드를 시험이 센다. */
|
|
148
|
+
export const AUTHOR_OUTCOME_NODE_IDS = ['re-ground', 'needs-human'] as const;
|
|
149
|
+
|
|
150
|
+
/** author 노드의 결과 라벨 — implement-loop.yaml `from: author · on: outcome` 의 map 키와 «같은» 닫힌 집합. */
|
|
151
|
+
export const AUTHOR_EXIT_OUTCOMES = ['ok', 're-authored', 'not-grounded', 'fail'] as const;
|
|
152
|
+
export type AuthorExitOutcome = typeof AUTHOR_EXIT_OUTCOMES[number];
|
|
153
|
+
|
|
154
|
+
export type FrontNodeExit =
|
|
155
|
+
| { readonly node: 'author'; readonly outcome: AuthorExitOutcome }
|
|
156
|
+
| { readonly node: 're-ground'; readonly outcome: 'retry' };
|
|
157
|
+
|
|
158
|
+
export interface FrontNodeExitData {
|
|
159
|
+
/** 1 = 첫 저작 · 2 = 자동 재저작(re-ground 를 한 번 지난 뒤). */
|
|
160
|
+
readonly attempt: number;
|
|
161
|
+
/** 코드가 «실제로» 간 다음 노드 — 그래프 답과 다르면 graph-edge-taken 이 honored:false 로 남긴다. 없으면 그래프 답. */
|
|
162
|
+
readonly taken?: string;
|
|
163
|
+
readonly reason?: string;
|
|
164
|
+
readonly runId?: string;
|
|
165
|
+
readonly goalId?: string;
|
|
166
|
+
readonly goalType?: string;
|
|
167
|
+
readonly goalFile?: string;
|
|
168
|
+
/** 근거 카드 — needs-human 으로 갈 때 사람이 «무엇 때문에»를 다시 캐지 않게 막힘을 그대로 싣는다. */
|
|
169
|
+
readonly blockers?: readonly { readonly kind: string; readonly name: string; readonly detail?: string }[];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const EVIDENCE_DETAIL_CHARS = 400;
|
|
173
|
+
|
|
174
|
+
/** 그래프가 고른 다음 노드에 «방문 예산»을 겹친다 — re-ground(max_visits 1)를 이미 지났으면 같은 결과의
|
|
175
|
+
* 두 번째는 re-ground 가 아니라 author 의 `fail` 출구(needs-human)로 간다. ⛔ 노드 이름·예산은 선언에서 읽는다. */
|
|
176
|
+
function withVisitBudget(route: JourneyRoute, exit: FrontNodeExit, attempt: number): { readonly to: string | null; readonly budgetReason?: string } {
|
|
177
|
+
// ⛔ 예산을 겹치는 대상은 re-ground 뿐이다 — attempt-1 은 «re-ground 를 지난 횟수»이지 다른 노드의 방문 수가 아니다.
|
|
178
|
+
if (exit.node !== 'author' || route.to !== 're-ground') return { to: route.to };
|
|
179
|
+
const target = journeySpec({}).spec?.nodes.find((node) => node.nodeId === route.to);
|
|
180
|
+
const priorVisits = Math.max(0, attempt - 1);
|
|
181
|
+
if (target === undefined || priorVisits < target.maxVisits) return { to: route.to };
|
|
182
|
+
const exhausted = readJourneyEdge('author', 'fail');
|
|
183
|
+
return { to: exhausted.to, budgetReason: `${route.to}-visit-budget-exhausted (max_visits ${target.maxVisits})` };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** ⭐ GRAPH-AUTHOR-FAIL-EDGE ① — 앞 노드의 «나감»을 결과와 함께 남긴다(진입만 있던 자리).
|
|
187
|
+
* 호출부(실행 경로): src/self-dev/ask-launch-flow.ts — 저작 끝(author ok · not-grounded · re-authored) ·
|
|
188
|
+
* 저작기 throw(author fail) · 자동 재저작 시작(re-ground retry).
|
|
189
|
+
* 🔎 관측: `self-implement` / `front-node-exit` ⊕ 같은 자리의 `graph-edge-taken`(from author|re-ground).
|
|
190
|
+
* ⛔ 관측이지 제어가 아니다 — 다음 걸음은 여전히 코드가 정하고, 그래프 답과 다르면 honored:false 로 남는다.
|
|
191
|
+
* ⛔ fail-soft — 관측 실패가 저작을 죽이지 않는다. */
|
|
192
|
+
export function observeFrontNodeExit(exit: FrontNodeExit, data: FrontNodeExitData): JourneyRoute | null {
|
|
193
|
+
let recorded: JourneyRoute | null = null;
|
|
194
|
+
try {
|
|
195
|
+
const route = readJourneyEdge(exit.node, exit.outcome);
|
|
196
|
+
const budget = withVisitBudget(route, exit, data.attempt);
|
|
197
|
+
const graphRoute: JourneyRoute = { ...route, to: budget.to };
|
|
198
|
+
const taken = data.taken ?? budget.to ?? exit.outcome;
|
|
199
|
+
const reason = [budget.budgetReason, data.reason].filter((part): part is string => part !== undefined).join(' · ');
|
|
200
|
+
recordJourneyEdge(graphRoute, taken, reason.length > 0 ? reason : undefined);
|
|
201
|
+
recorded = graphRoute;
|
|
202
|
+
const payload = {
|
|
203
|
+
graphId: 'self-implement',
|
|
204
|
+
node: exit.node,
|
|
205
|
+
outcome: exit.outcome,
|
|
206
|
+
attempt: data.attempt,
|
|
207
|
+
to: budget.to,
|
|
208
|
+
taken,
|
|
209
|
+
honored: budget.to === null || budget.to === taken,
|
|
210
|
+
...(reason.length > 0 ? { reason } : {}),
|
|
211
|
+
...(data.runId === undefined ? {} : { runId: data.runId }),
|
|
212
|
+
...(data.goalId === undefined ? {} : { goalId: data.goalId }),
|
|
213
|
+
...(data.goalType === undefined ? {} : { goalType: data.goalType }),
|
|
214
|
+
...(data.goalFile === undefined ? {} : { goalFile: data.goalFile }),
|
|
215
|
+
...(data.blockers === undefined || data.blockers.length === 0 ? {} : {
|
|
216
|
+
evidenceCard: data.blockers.map((blocker) => ({
|
|
217
|
+
kind: blocker.kind, name: blocker.name,
|
|
218
|
+
...(blocker.detail === undefined ? {} : { detail: blocker.detail.slice(0, EVIDENCE_DETAIL_CHARS) }),
|
|
219
|
+
})),
|
|
220
|
+
}),
|
|
221
|
+
phase: 'front',
|
|
222
|
+
graphTemplatesSource: GRAPH_TEMPLATES_SOURCE,
|
|
223
|
+
...journeyJoinFields(),
|
|
224
|
+
};
|
|
225
|
+
try { debug.log('self-implement', 'front-node-exit', payload); }
|
|
226
|
+
catch { /* debug failure cannot change authoring */ }
|
|
227
|
+
// Pod 의 logs.db 는 Job 과 사라진다 — 원장에도 남겨 호스트가 NOT-GROUNDED 의 길을 사후에 읽게 한다.
|
|
228
|
+
if (data.runId !== undefined) {
|
|
229
|
+
try { appendRunLedgerEntry({ timestamp: new Date().toISOString(), runId: data.runId, event: 'front-node-exit', data: payload }, runLedgerDir()); }
|
|
230
|
+
catch { /* ledger failure cannot change authoring */ }
|
|
231
|
+
}
|
|
232
|
+
} catch { /* 관측은 fail-soft — 저작을 죽이지 않는다 */ }
|
|
233
|
+
return recorded;
|
|
234
|
+
}
|