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
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
|
|
3
|
+
type JsonMap = Record<string, unknown>;
|
|
4
|
+
interface GraphContext { readonly nodeId?: string; readonly input: unknown; readonly outputs: Record<string, unknown> }
|
|
5
|
+
|
|
6
|
+
function record(value: unknown): JsonMap {
|
|
7
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value as JsonMap : {};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function firstValue(context: GraphContext, key: string): unknown {
|
|
11
|
+
const input = record(context.input);
|
|
12
|
+
if (Object.hasOwn(input, key) && input[key] !== undefined && input[key] !== null) return input[key];
|
|
13
|
+
for (const output of Object.values(context.outputs ?? {})) {
|
|
14
|
+
const value = record(output)[key];
|
|
15
|
+
if (value !== undefined && value !== null) return value;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const VERIFY_INPUTS = ['worktree', 'changed-files', 'diff', 'review-intent', 'must-fix', 'gate-log'] as const;
|
|
21
|
+
const VERIFY_STARTS = new Set(['gate', 'review', 'rework']);
|
|
22
|
+
|
|
23
|
+
export interface MakeDocInputs {
|
|
24
|
+
readonly goal: string;
|
|
25
|
+
readonly worktree: unknown;
|
|
26
|
+
readonly branch: unknown;
|
|
27
|
+
readonly 'review-intent': unknown;
|
|
28
|
+
readonly 'head-sha': unknown;
|
|
29
|
+
readonly 'base-branch': unknown;
|
|
30
|
+
readonly prior: unknown;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Converts the public make-doc envelope into the existing document-loop recipe contract. */
|
|
34
|
+
export function unpackMakeDocEnvelope(envelope: { readonly ask?: unknown; readonly context?: unknown; readonly prior?: unknown }): MakeDocInputs {
|
|
35
|
+
const context = record(envelope.context);
|
|
36
|
+
const contextGoal = context.goal;
|
|
37
|
+
const ask = typeof envelope.ask === 'string' ? envelope.ask : '';
|
|
38
|
+
const reviewIntent = context['review-intent'] ?? (ask.trim() ? ask : null);
|
|
39
|
+
const goal = typeof contextGoal === 'string' && contextGoal.trim() ? contextGoal : ask;
|
|
40
|
+
return {
|
|
41
|
+
goal,
|
|
42
|
+
worktree: context.worktree ?? null,
|
|
43
|
+
branch: context.branch ?? null,
|
|
44
|
+
'review-intent': reviewIntent,
|
|
45
|
+
'head-sha': context['head-sha'] ?? null,
|
|
46
|
+
'base-branch': context['base-branch'] ?? null,
|
|
47
|
+
prior: envelope.prior ?? null,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Keeps the make-doc outputs present on every declared exit. */
|
|
52
|
+
export function buildMakeDocOutput(context: GraphContext): JsonMap {
|
|
53
|
+
const draft = record(context.outputs?.['document-draft']);
|
|
54
|
+
const input = record(context.input);
|
|
55
|
+
const prior = record(input.prior);
|
|
56
|
+
const priorEvidence = record(prior.evidence);
|
|
57
|
+
const inputEvidence = record(input.evidence);
|
|
58
|
+
const draftEvidence = record(draft.evidence);
|
|
59
|
+
const evidence = { ...priorEvidence, ...inputEvidence, ...draftEvidence };
|
|
60
|
+
if (prior.result !== undefined) evidence['prior-result'] = prior.result;
|
|
61
|
+
return {
|
|
62
|
+
result: draft.result ?? draft.summary ?? input.result ?? null,
|
|
63
|
+
evidence,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Selects a verify entry while keeping every unit input explicit at the call boundary. */
|
|
68
|
+
export function buildVerifyEnvelope(context: GraphContext): JsonMap {
|
|
69
|
+
const input = record(context.input);
|
|
70
|
+
const detail = record(input.context);
|
|
71
|
+
const prior = record(input.prior);
|
|
72
|
+
const priorResult = record(prior.result);
|
|
73
|
+
const priorEvidence = record(prior.evidence);
|
|
74
|
+
const start = detail.start_at ?? detail.startAt;
|
|
75
|
+
const startAt = typeof start === 'string' && VERIFY_STARTS.has(start) ? start : 'gate';
|
|
76
|
+
const envelope: JsonMap = {
|
|
77
|
+
outcome: startAt,
|
|
78
|
+
...Object.fromEntries(VERIFY_INPUTS.map(key => [key, detail[key] ?? prior[key] ?? priorEvidence[key] ?? priorResult[key] ?? firstValue(context, key)])),
|
|
79
|
+
};
|
|
80
|
+
if (detail['review-intent'] == null && typeof input.ask === 'string' && input.ask.trim()) envelope['review-intent'] = input.ask;
|
|
81
|
+
return envelope;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Emits the complete verify output contract from whichever routes ran. */
|
|
85
|
+
export function buildVerifyOutput(context: GraphContext, outcome: 'done' | 'rework' | 'needs-human' | 'failed'): JsonMap {
|
|
86
|
+
const input = record(context.input);
|
|
87
|
+
const prior = record(input.prior);
|
|
88
|
+
const priorEvidence = record(prior.evidence);
|
|
89
|
+
const outputsByNode = record(context.outputs);
|
|
90
|
+
const stageOrder = outcome === 'done'
|
|
91
|
+
? ['prepare', 'rework-loop', 'gate', 'review']
|
|
92
|
+
: outcome === 'rework'
|
|
93
|
+
? ['prepare', 'gate', 'review', 'rework-loop']
|
|
94
|
+
: (() => {
|
|
95
|
+
const source = ['prepare', 'gate', 'review', 'rework-loop']
|
|
96
|
+
.find(node => record(outputsByNode[node]).outcome === outcome);
|
|
97
|
+
if (source === 'gate') return ['prepare', 'review', 'rework-loop', 'gate'];
|
|
98
|
+
if (source === 'review') return ['prepare', 'rework-loop', 'gate', 'review'];
|
|
99
|
+
if (source === 'rework-loop') return ['prepare', 'gate', 'review', 'rework-loop'];
|
|
100
|
+
return ['prepare'];
|
|
101
|
+
})();
|
|
102
|
+
const outputs = stageOrder.map(node => record(outputsByNode[node]));
|
|
103
|
+
const evidence = { ...priorEvidence };
|
|
104
|
+
for (const output of outputs) Object.assign(evidence, record(output.evidence));
|
|
105
|
+
const latest = (key: string, aliases: readonly string[] = []): unknown => {
|
|
106
|
+
let value: unknown = priorEvidence[key] ?? null;
|
|
107
|
+
for (const output of outputs) {
|
|
108
|
+
const nodeValue = [key, ...aliases].map(name => output[name]).find(candidate => candidate !== undefined && candidate !== null);
|
|
109
|
+
const evidenceValue = record(output.evidence)[key];
|
|
110
|
+
if (nodeValue !== undefined) value = nodeValue;
|
|
111
|
+
else if (evidenceValue !== undefined && evidenceValue !== null) value = evidenceValue;
|
|
112
|
+
}
|
|
113
|
+
return value;
|
|
114
|
+
};
|
|
115
|
+
return {
|
|
116
|
+
result: outcome,
|
|
117
|
+
evidence: {
|
|
118
|
+
...evidence,
|
|
119
|
+
...(prior.result === undefined ? {} : { 'prior-result': prior.result }),
|
|
120
|
+
'review-summary': latest('review-summary', ['review_summary']),
|
|
121
|
+
'must-fix': outcome === 'done' ? [] : latest('must-fix', ['must_fix']),
|
|
122
|
+
'gate-log': latest('gate-log', ['gate_log']),
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (import.meta.main) {
|
|
128
|
+
const contextPath = process.env.ELANOUS_GRAPH_CONTEXT;
|
|
129
|
+
if (!contextPath) throw new Error('ELANOUS_GRAPH_CONTEXT is required');
|
|
130
|
+
const context = JSON.parse(readFileSync(contextPath, 'utf8')) as GraphContext;
|
|
131
|
+
const mode = process.argv[2];
|
|
132
|
+
const output = mode === 'make-doc-input'
|
|
133
|
+
? unpackMakeDocEnvelope(record(context.input) as { ask?: unknown; context?: unknown; prior?: unknown })
|
|
134
|
+
: mode === 'make-doc-output' ? buildMakeDocOutput(context)
|
|
135
|
+
: mode === 'verify-envelope' ? buildVerifyEnvelope(context)
|
|
136
|
+
: mode === 'verify-output' ? buildVerifyOutput(context, process.argv[3] as 'done' | 'rework' | 'needs-human' | 'failed') : undefined;
|
|
137
|
+
if (!output) throw new Error(`unknown verbs-envelope mode: ${mode ?? '<missing>'}`);
|
|
138
|
+
process.stdout.write(`${JSON.stringify(output)}\n`);
|
|
139
|
+
}
|
|
@@ -193,8 +193,38 @@ function pushSurvival(target: string, local: string, manifest: Manifest, root: s
|
|
|
193
193
|
rmSync(staging, { recursive: true, force: true });
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
+
/** Flags that need a value before any snapshot work (STANDBY-SURVIVAL-KEEP-ARGS · mirror parseVerifyArgs / parsePromoteArgs). */
|
|
197
|
+
export const SURVIVAL_VALUE_FLAGS = ['--survival-keep', '--survival-keep-daily', '--prune-survival'] as const;
|
|
198
|
+
|
|
199
|
+
/** Throw when a survival-keep / prune-survival flag is present without its value/target — same rule as `${flag} requires a value`. */
|
|
200
|
+
export function assertSurvivalKeepArgs(argv: string[]): void {
|
|
201
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
202
|
+
const token = argv[i];
|
|
203
|
+
const equalsAt = token.indexOf('=');
|
|
204
|
+
const flag = equalsAt < 0 ? token : token.slice(0, equalsAt);
|
|
205
|
+
if (!SURVIVAL_VALUE_FLAGS.some(candidate => candidate === flag)) continue;
|
|
206
|
+
if (equalsAt >= 0) {
|
|
207
|
+
if (token.slice(equalsAt + 1).length === 0) throw new Error(`${flag} requires a value`);
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
const value = argv[i + 1];
|
|
211
|
+
if (!value || value.startsWith('--')) throw new Error(`${flag} requires a value`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function preflightStandbySnapshotArgs(argv: string[]): void {
|
|
216
|
+
// Preflight survival argument values before tier selection, staging, or snapshot work.
|
|
217
|
+
try {
|
|
218
|
+
assertSurvivalKeepArgs(argv);
|
|
219
|
+
} catch (error) {
|
|
220
|
+
console.error(`standby-snapshot: ${String(error)}`);
|
|
221
|
+
process.exit(2);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
196
225
|
if (import.meta.main) {
|
|
197
226
|
const argv = process.argv.slice(2);
|
|
227
|
+
preflightStandbySnapshotArgs(argv);
|
|
198
228
|
const val = (k: string) => { const i = argv.indexOf(k); return i >= 0 ? argv[i + 1] : undefined; };
|
|
199
229
|
const tier = (val('--tier') ?? 'core') as Tier;
|
|
200
230
|
if (tier !== 'core' && tier !== 'big' && tier !== 'obs') { console.error('--tier core|big|obs'); process.exit(2); }
|
package/scripts/public-export.ts
CHANGED
|
@@ -283,6 +283,45 @@ export function scanLeaks(root: string, files: readonly string[], markers = LEAK
|
|
|
283
283
|
return hits;
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
+
/** Code literals are reported separately for the crown marker: they are not document/comment leakage. */
|
|
287
|
+
function codeLiteralRanges(file: string, text: string): Array<[number, number]> {
|
|
288
|
+
if (!/\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/iu.test(file)) return [];
|
|
289
|
+
const scanner = ts.createScanner(ts.ScriptTarget.Latest, false, /\.(?:tsx|jsx)$/iu.test(file) ? ts.LanguageVariant.JSX : ts.LanguageVariant.Standard, text);
|
|
290
|
+
const ranges: Array<[number, number]> = [];
|
|
291
|
+
for (let token = scanner.scan(); token !== ts.SyntaxKind.EndOfFileToken; token = scanner.scan()) {
|
|
292
|
+
if (token === ts.SyntaxKind.StringLiteral || token === ts.SyntaxKind.NoSubstitutionTemplateLiteral ||
|
|
293
|
+
token === ts.SyntaxKind.TemplateHead || token === ts.SyntaxKind.TemplateMiddle || token === ts.SyntaxKind.TemplateTail) {
|
|
294
|
+
ranges.push([scanner.getTokenPos(), scanner.getTextPos()]);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return ranges;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export function splitCodeLiteralCeoMarks(files: readonly string[], contents: ReadonlyMap<string, string>, hits: readonly LeakHit[]): { leaks: LeakHit[]; codeLiterals: LeakHit[] } {
|
|
301
|
+
const leaks: LeakHit[] = [];
|
|
302
|
+
const codeLiterals: LeakHit[] = [];
|
|
303
|
+
const fileSet = new Set(files);
|
|
304
|
+
const classification = new Map<string, Set<number>>();
|
|
305
|
+
for (const file of new Set(hits.filter((hit) => hit.marker === 'ceo-mark' && !/\.(?:test|spec)\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/iu.test(hit.file)).map((hit) => hit.file))) {
|
|
306
|
+
const text = contents.get(file);
|
|
307
|
+
if (text === undefined || !fileSet.has(file)) continue;
|
|
308
|
+
const ranges = codeLiteralRanges(file, text);
|
|
309
|
+
const lines = new Set<number>();
|
|
310
|
+
let offset = 0;
|
|
311
|
+
text.split('\n').forEach((line, index) => {
|
|
312
|
+
const marks = [...line.matchAll(/\u{1F451}/gu)];
|
|
313
|
+
if (marks.length && marks.every((mark) => ranges.some(([from, to]) => offset + mark.index! >= from && offset + mark.index! + mark[0].length <= to))) lines.add(index + 1);
|
|
314
|
+
offset += line.length + 1;
|
|
315
|
+
});
|
|
316
|
+
classification.set(file, lines);
|
|
317
|
+
}
|
|
318
|
+
for (const hit of hits) {
|
|
319
|
+
if (hit.marker !== 'ceo-mark' || /\.(?:test|spec)\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/iu.test(hit.file)) { leaks.push(hit); continue; }
|
|
320
|
+
(classification.get(hit.file)?.has(hit.line) ? codeLiterals : leaks).push(hit);
|
|
321
|
+
}
|
|
322
|
+
return { leaks, codeLiterals };
|
|
323
|
+
}
|
|
324
|
+
|
|
286
325
|
/**
|
|
287
326
|
* 🆕 `runtime-path-outside-export` — 공개되는 «코드»가 공개본에 «없는» 저장소 경로를 문자열로 쥐고 있다.
|
|
288
327
|
* 계기: `docs/graph-templates/**` 가 허용 목록에서 빠져 공개본 영상 라인이 실행 중에 죽을 뻔했다(🅣 · `#20098`).
|
|
@@ -448,12 +487,13 @@ export function run(argv: readonly string[], root = resolve(import.meta.dir, '..
|
|
|
448
487
|
}
|
|
449
488
|
console.error(`exported ${files.length} files (+${Object.keys(config.replace).length} replaced) → ${target}`);
|
|
450
489
|
}
|
|
451
|
-
const
|
|
490
|
+
const rawHits = [
|
|
452
491
|
...gitIgnoredExportFiles(root, files).filter(inScope).map((file) => ({ marker: 'export-gitignored', file, line: 0, text: '공개본 .gitignore 에 걸린다 — 커밋하면 사라진다' })),
|
|
453
492
|
...scanLeaks(root, scanned, LEAK_MARKERS, transformed.contents, realDocs),
|
|
454
493
|
...(redactions ? scanLeaks(root, scanned, privateIdentifierMarkers(redactions), transformed.contents, realDocs) : []),
|
|
455
494
|
...(!redactions && !noPrivateList ? [{ marker: 'private-identifiers-unchecked', file: privateRedactionsPath(), line: 0, text: 'private redaction list missing' }] : []),
|
|
456
495
|
];
|
|
496
|
+
const { leaks: hits, codeLiterals } = splitCodeLiteralCeoMarks(scanned, transformed.contents, rawHits);
|
|
457
497
|
const advisory = scanRuntimePaths(root, files, tracked, transformed.contents).filter((h) => inScope(h.file));
|
|
458
498
|
const summary = summarizeLeaks(hits);
|
|
459
499
|
const advisorySummary = summarizeLeaks(advisory);
|
|
@@ -464,6 +504,7 @@ export function run(argv: readonly string[], root = resolve(import.meta.dir, '..
|
|
|
464
504
|
if (json) {
|
|
465
505
|
console.log(JSON.stringify({
|
|
466
506
|
files: scanned.length, leaks: hits.length, summary, before: { leaks: before.length, summary: beforeSummary }, transforms: transformed.counts, privateRedactions,
|
|
507
|
+
codeLiterals: { hits: codeLiterals.length, summary: summarizeLeaks(codeLiterals), items: all ? codeLiterals : codeLiterals.slice(0, limit) },
|
|
467
508
|
shownHits: shown.length, truncated, omittedHits: hits.length - shown.length,
|
|
468
509
|
...(pathPrefix ? { pathPrefix } : {}), hits: shown,
|
|
469
510
|
advisory: { hits: advisory.length, summary: advisorySummary, judge: RUNTIME_PATH_JUDGE, items: all ? advisory : advisory.slice(0, limit) },
|
|
@@ -473,6 +514,7 @@ export function run(argv: readonly string[], root = resolve(import.meta.dir, '..
|
|
|
473
514
|
console.log(`leak check — ${scanned.length} files${pathPrefix ? ` under ${pathPrefix}` : ''} · ${hits.length} hits`);
|
|
474
515
|
for (const [marker, s] of Object.entries(summary)) console.log(` ${marker.padEnd(20)} ${String(s.files).padStart(5)} files ${String(s.hits).padStart(6)} lines`);
|
|
475
516
|
for (const hit of shown) console.log(` ${hit.marker} ${hit.file}:${hit.line} ${hit.text}`);
|
|
517
|
+
if (codeLiterals.length) console.log(`code literals (not document/comment leakage) — ceo-mark ${codeLiterals.length} lines`);
|
|
476
518
|
if (truncated) console.log(` … ${hits.length - shown.length} more hits not shown — use --all, or narrow with --path <prefix> (⛔ «not in this list» ≠ «no leak»)`);
|
|
477
519
|
if (advisory.length) console.log(`advisory (not counted) — runtime-path-outside-export ${advisory.length} lines · ${advisorySummary['runtime-path-outside-export']?.files ?? 0} files · judge = ${RUNTIME_PATH_JUDGE}`);
|
|
478
520
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Train-side sentinel for the eight real HARD 0.2.32 regressions. Run on the
|
|
3
|
+
# merged side tree before the changed-file gate; never interpret a missing test
|
|
4
|
+
# or an incomplete run as a pass.
|
|
5
|
+
set -u
|
|
6
|
+
|
|
7
|
+
files=(
|
|
8
|
+
scripts/ratchets/test-interference-patterns.test.ts
|
|
9
|
+
src/domains/finance-cli.test.ts
|
|
10
|
+
src/instance/state-dir-provenance-ratchet.test.ts
|
|
11
|
+
src/self-implement/graph-yaml.test.ts
|
|
12
|
+
src/self-implement/self-cli-sink-surface.test.ts
|
|
13
|
+
test/identity-env.test.ts
|
|
14
|
+
test/no-absolute-path-imports.test.ts
|
|
15
|
+
test/scenarios/integration.test.ts
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
if [[ ${1:-} == --list ]]; then
|
|
19
|
+
printf '%s\n' "${files[@]}"
|
|
20
|
+
exit 0
|
|
21
|
+
fi
|
|
22
|
+
if [[ $# -gt 1 ]]; then
|
|
23
|
+
echo 'TRAIN_INVARIANTS_UNMEASURED invalid-arguments'
|
|
24
|
+
exit 2
|
|
25
|
+
fi
|
|
26
|
+
cd "${1:-.}" || { echo 'TRAIN_INVARIANTS_UNMEASURED repo-unreadable'; exit 2; }
|
|
27
|
+
command -v bun >/dev/null 2>&1 || { echo 'TRAIN_INVARIANTS_UNMEASURED bun-missing'; exit 2; }
|
|
28
|
+
|
|
29
|
+
for file in "${files[@]}"; do
|
|
30
|
+
if [[ ! -f $file ]]; then
|
|
31
|
+
echo "TRAIN_INVARIANTS_UNMEASURED missing-file=$file"
|
|
32
|
+
exit 2
|
|
33
|
+
fi
|
|
34
|
+
done
|
|
35
|
+
|
|
36
|
+
for file in "${files[@]}"; do
|
|
37
|
+
echo "TRAIN_INVARIANTS_START $file"
|
|
38
|
+
bun test "$file"
|
|
39
|
+
rc=$?
|
|
40
|
+
if [[ $rc -ne 0 ]]; then
|
|
41
|
+
echo "TRAIN_INVARIANTS_FAIL file=$file rc=$rc"
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
done
|
|
45
|
+
echo "TRAIN_INVARIANTS_PASS files=${#files[@]}"
|
|
@@ -15,8 +15,12 @@ const outcomeMetric = (name: string, node: Record<string, unknown> | undefined):
|
|
|
15
15
|
verdict: node?.outcome === undefined ? 'unmeasured' : node.outcome === 'ok' ? 'pass' : 'fail',
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
/** Rows
|
|
18
|
+
/** Rows outside the original eight fixed metrics. TUI regressions have their own HITL gate below. */
|
|
19
19
|
export const WARNING_ONLY = new Set(['tui-regress', 'mac-smoke']);
|
|
20
|
+
export const BLOCKING_METRIC_NAMES = [
|
|
21
|
+
'gate regressions and measurement', 'bun version', 'upgrade', 'tui', 'notes-check',
|
|
22
|
+
'public leak and prepare completeness', 'docs notes page', 'installation files',
|
|
23
|
+
] as const;
|
|
20
24
|
|
|
21
25
|
/** `ok` · `warn` (a failure) · `unmeasured` (error or no output) — the macOS smoke never blocks publishing. */
|
|
22
26
|
function macSmokeLevel(node: Record<string, unknown> | undefined): 'ok' | 'warn' | 'unmeasured' {
|
|
@@ -42,40 +46,50 @@ export function runAutoApprove(context: GraphContext = readGraphContext(), deps:
|
|
|
42
46
|
catch { distCount = undefined; }
|
|
43
47
|
}
|
|
44
48
|
const gateErrorAbsent = gate && !Object.hasOwn(gate, 'error');
|
|
45
|
-
const
|
|
49
|
+
const regress = validatedTuiRegress(context.outputs.tui?.regress);
|
|
50
|
+
const regressStatus = regressWarning(regress);
|
|
51
|
+
const failedCheckIds = 'unmeasured' in regress ? null : regress.results.filter((result) => !result.ok).map((result) => result.id);
|
|
52
|
+
const failedLabel = failedCheckIds === null ? 'unmeasured' : `${failedCheckIds.length} [${failedCheckIds.join(', ') || '-'}]`;
|
|
53
|
+
const regressNeedsApproval = regressStatus.level !== 'ok';
|
|
46
54
|
const macSmoke = context.outputs['mac-smoke'];
|
|
47
55
|
const metrics: ApprovalMetric[] = [
|
|
48
|
-
{ name:
|
|
56
|
+
{ name: BLOCKING_METRIC_NAMES[0], value: JSON.stringify({ outcome: gate?.outcome ?? null, introduced: gate?.introduced ?? null, error: gate?.error ?? null }),
|
|
49
57
|
verdict: !gate || gate.outcome === undefined || !Array.isArray(gate.introduced) ? 'unmeasured'
|
|
50
58
|
: gate.outcome === 'ok' && gate.introduced.length === 0 && gateErrorAbsent ? 'pass' : 'fail' },
|
|
51
|
-
{ name:
|
|
59
|
+
{ name: BLOCKING_METRIC_NAMES[1], value: `running=${bunVersion}; pinned=${pinned ?? 'missing'}`,
|
|
52
60
|
verdict: !pinned ? 'unmeasured' : bunVersion === pinned ? 'pass' : 'fail' },
|
|
53
|
-
outcomeMetric(
|
|
54
|
-
outcomeMetric(
|
|
55
|
-
outcomeMetric(
|
|
56
|
-
{ name:
|
|
61
|
+
outcomeMetric(BLOCKING_METRIC_NAMES[2], context.outputs.upgrade),
|
|
62
|
+
outcomeMetric(BLOCKING_METRIC_NAMES[3], context.outputs.tui),
|
|
63
|
+
outcomeMetric(BLOCKING_METRIC_NAMES[4], context.outputs['notes-check']),
|
|
64
|
+
{ name: BLOCKING_METRIC_NAMES[5], value: `prepare=${prepare?.outcome ?? 'missing'}`,
|
|
57
65
|
verdict: prepare?.outcome === undefined ? 'unmeasured' : prepare.outcome === 'ok' ? 'pass' : 'fail' },
|
|
58
|
-
{ name:
|
|
66
|
+
{ name: BLOCKING_METRIC_NAMES[6], value: `docs=${context.outputs.docs?.outcome ?? 'missing'}; notes=${String(context.outputs.docs?.notes ?? 'missing')}`,
|
|
59
67
|
verdict: context.outputs.docs?.outcome === undefined || context.outputs.docs.notes === undefined ? 'unmeasured'
|
|
60
68
|
: context.outputs.docs.outcome === 'ok' && typeof context.outputs.docs.notes === 'string' && context.outputs.docs.notes.trim() ? 'pass' : 'fail' },
|
|
61
|
-
{ name:
|
|
69
|
+
{ name: BLOCKING_METRIC_NAMES[7], value: `dist files=${distCount ?? 'missing'}; prepare.out=${String(out ?? 'missing')}`,
|
|
62
70
|
verdict: prepare?.outcome !== 'ok' ? prepare?.outcome === undefined ? 'unmeasured' : 'fail'
|
|
63
71
|
: distCount === undefined ? 'unmeasured' : distCount === 5 ? 'pass' : 'fail' },
|
|
64
|
-
//
|
|
65
|
-
{ name: 'tui-regress', value: regressStatus.level, reason: regressStatus.line,
|
|
72
|
+
// Kept after the eight fixed metrics; a failed or unmeasured subcheck requires the existing approve-publish HITL node.
|
|
73
|
+
{ name: 'tui-regress', value: regressStatus.level, reason: regressStatus.line,
|
|
74
|
+
verdict: regressStatus.level === 'ok' ? 'pass' : regressStatus.level === 'warn' ? 'fail' : 'unmeasured' },
|
|
66
75
|
// MAC1: the macOS smoke is warning-only too (ship with known issues) — shown, never counted.
|
|
67
76
|
{ name: 'mac-smoke', value: macSmokeLevel(macSmoke), reason: typeof macSmoke?.summary === 'string' ? macSmoke.summary : undefined, verdict: 'pass' },
|
|
68
77
|
];
|
|
69
|
-
const outcome = metrics.filter((metric) => !WARNING_ONLY.has(metric.name)).every((metric) => metric.verdict === 'pass')
|
|
78
|
+
const outcome = metrics.filter((metric) => !WARNING_ONLY.has(metric.name)).every((metric) => metric.verdict === 'pass')
|
|
79
|
+
&& !regressNeedsApproval ? 'ok' as const : 'fail' as const;
|
|
70
80
|
const report = join(root, 'release', version, 'auto-approval.md');
|
|
71
81
|
const lines = [`# v${version} auto-approval`, '', `Outcome: ${outcome}`, '', '| # | Metric | Value | Verdict |', '|---|---|---|---|',
|
|
72
82
|
...metrics.map((metric, i) => `| ${i + 1} | ${metric.name} | ${[metric.value, metric.reason].filter(Boolean).join(' — ').replaceAll('|', '\\|').replace(/[\r\n]/g, ' ')} | ${metric.verdict} |`),
|
|
83
|
+
'', `TUI subcheck: ${regressStatus.level} · failed ${failedLabel} · ${regressNeedsApproval ? 'HITL 수용/정지 필요' : '자동 판정 가능'}`,
|
|
73
84
|
'', '## 되돌리는 법', `gh release edit v${version} --draft`, `git tag -d v${version} && git push origin :refs/tags/v${version}`, '해당 docs PR revert', ''];
|
|
74
85
|
mkdirSync(dirname(report), { recursive: true });
|
|
75
86
|
writeFileSync(report, lines.join('\n'));
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
87
|
+
const tuiSubcheck = { runId: context.runId ?? null, level: regressStatus.level,
|
|
88
|
+
fail: failedCheckIds?.length ?? null, failedCheckIds, approvalRequired: regressNeedsApproval };
|
|
89
|
+
debug.log('release-loop.approve', 'auto-decision', { version, outcome, metrics, tuiSubcheck });
|
|
90
|
+
return { outcome, verdict: outcome === 'ok' ? 'pass' as const : 'fail' as const,
|
|
91
|
+
summary: `auto approval ${outcome}: ${metrics.filter((metric) => !WARNING_ONLY.has(metric.name) && metric.verdict === 'pass').length}/8${regressNeedsApproval ? ` · tui-regress ${regressStatus.level} failed ${failedLabel} → HITL` : ''}`,
|
|
92
|
+
runId: context.runId ?? null, tuiSubcheck, ...(outcome === 'ok' ? { decidedBy: 'release-loop metrics' as const } : {}), metrics, report };
|
|
79
93
|
}
|
|
80
94
|
|
|
81
95
|
if (import.meta.main) {
|
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
2
|
+
import { existsSync, mkdtempSync, readFileSync, realpathSync, rmSync } from 'node:fs';
|
|
3
3
|
import { effectiveInstanceRoot, releaseLedgerRoot } from '../../src/instance/resolve.js';
|
|
4
4
|
import { listChecklist } from '../../src/release-loop/checklist.js';
|
|
5
5
|
import type { ReleaseManifest } from '../../src/release-loop/manifest.js';
|
|
6
6
|
import { recordDocsFollow, type DocsFollowItem } from './release-docs.js';
|
|
7
|
-
import { dirname, join } from 'node:path';
|
|
7
|
+
import { basename, dirname, join } from 'node:path';
|
|
8
8
|
import { tmpdir } from 'node:os';
|
|
9
|
-
import { errorResult, finishNode, nodeOutput, readGraphContext, runCommand, type CommandRunner } from './node-verdict.js';
|
|
9
|
+
import { errorResult, finishNode, nodeOutput, readGraphContext, runCommand, type CommandRunner, type GraphContext } from './node-verdict.js';
|
|
10
10
|
import { prereleaseKind } from './release-version.js';
|
|
11
11
|
|
|
12
|
+
function isRunOwnedDocsPrefetchTree(worktree: string, context: GraphContext, ledgerRoot: string): boolean {
|
|
13
|
+
const runId = context.runId;
|
|
14
|
+
if (!runId || !/^[A-Za-z0-9._-]+$/.test(runId)) return false;
|
|
15
|
+
const prefetchRoot = join(ledgerRoot, 'graph-runs', 'release-loop', `${runId}.json.contexts`, 'docs-prefetch');
|
|
16
|
+
try {
|
|
17
|
+
// Resolve symlinks too: an in-run path that points outside this run does not establish ownership.
|
|
18
|
+
const owner = realpathSync(prefetchRoot);
|
|
19
|
+
const tree = realpathSync(worktree);
|
|
20
|
+
return dirname(tree) === owner && /^tree(?:-[0-9a-f-]{36})?$/.test(basename(tree));
|
|
21
|
+
} catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
12
26
|
export function runDocsLand(run: CommandRunner = runCommand, stateRoot = effectiveInstanceRoot(), ledgerRoot = releaseLedgerRoot()) {
|
|
13
27
|
const context = readGraphContext();
|
|
14
28
|
const version = context.input.version;
|
|
@@ -18,7 +32,9 @@ export function runDocsLand(run: CommandRunner = runCommand, stateRoot = effecti
|
|
|
18
32
|
if (branch !== `release-docs/${version}`) throw new Error('docs branch/version mismatch');
|
|
19
33
|
const worktree = nodeOutput(context, 'docs', 'worktree');
|
|
20
34
|
const scratch = dirname(worktree);
|
|
21
|
-
|
|
35
|
+
const tmpWorktree = dirname(scratch) === tmpdir() && /^release-docs-[A-Za-z0-9]+$/.test(basename(scratch))
|
|
36
|
+
&& worktree === join(scratch, 'tree');
|
|
37
|
+
if (!tmpWorktree && !isRunOwnedDocsPrefetchTree(worktree, context, ledgerRoot)) throw new Error('invalid docs worktree');
|
|
22
38
|
const recordFollow = (deployed: boolean) => {
|
|
23
39
|
const releaseDir = join(stateRoot, 'release', version);
|
|
24
40
|
const manifest: ReleaseManifest = JSON.parse(readFileSync(join(releaseDir, 'manifest.json'), 'utf8'));
|
|
@@ -88,7 +104,7 @@ export function runDocsLand(run: CommandRunner = runCommand, stateRoot = effecti
|
|
|
88
104
|
const remove = run('git', ['worktree', 'remove', '--force', worktree]);
|
|
89
105
|
if (remove.status !== 0) throw new Error(`docs worktree cleanup failed: ${remove.stderr}`);
|
|
90
106
|
}
|
|
91
|
-
rmSync(scratch, { recursive: true, force: true });
|
|
107
|
+
if (tmpWorktree) rmSync(scratch, { recursive: true, force: true });
|
|
92
108
|
// 배포 성공 — 후속 기록 실패(manifest 없음 등)는 결과를 «실패»로 바꾸지 않는다. 알리고 넘어간다.
|
|
93
109
|
let follow: ReturnType<typeof recordFollow> | undefined;
|
|
94
110
|
try { follow = recordFollow(true); }
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/** A full gate's reusable identity. Missing evidence is recorded, never promoted to a clean baseline. */
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { gateTestBaseline } from '../lib/gate-test-env.js';
|
|
7
|
+
|
|
8
|
+
const SHA256 = /^[0-9a-f]{64}$/i;
|
|
9
|
+
const IMAGE_DIGEST = /^sha256:[0-9a-f]{64}$/i;
|
|
10
|
+
export const POD_SWEEP_INTEGRATION_ONLY: readonly string[] = ['scripts/install.test.ts', 'scripts/review-model-ab.test.ts'];
|
|
11
|
+
|
|
12
|
+
/** Reconstruct the producer's tracked test selection at its pinned commit. Missing Git evidence is not a smaller set. */
|
|
13
|
+
export function gateAssignableTestsAtCommit(repo: string, commit: string): string[] | null {
|
|
14
|
+
if (!/^[0-9a-f]{40}$/i.test(commit)) return null;
|
|
15
|
+
const tree = spawnSync('git', ['ls-tree', '-r', '--name-only', commit], { cwd: repo, encoding: 'utf8', maxBuffer: 32 * 1024 * 1024 });
|
|
16
|
+
const cdp = spawnSync('git', ['grep', '-l', '-e', 'requireCdpBase', '-e', '9333', commit, '--', 'test', 'scripts'],
|
|
17
|
+
{ cwd: repo, encoding: 'utf8', maxBuffer: 32 * 1024 * 1024 });
|
|
18
|
+
if (tree.status !== 0 || tree.error || (cdp.status !== 0 && cdp.status !== 1) || cdp.error) return null;
|
|
19
|
+
const cdpFiles = new Set(cdp.stdout.split(/\r?\n/).filter(Boolean).map((line) => line.slice(commit.length + 1))
|
|
20
|
+
.filter((file) => file.endsWith('.test.ts')));
|
|
21
|
+
return tree.stdout.split(/\r?\n/).filter((file) => /\.test\.(?:tsx?|jsx?|mts|cts)$/.test(file)
|
|
22
|
+
&& !cdpFiles.has(file) && !POD_SWEEP_INTEGRATION_ONLY.includes(file)
|
|
23
|
+
&& !file.split('/').some((part) => part.startsWith('.'))).sort();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface GateBaselineReceipt {
|
|
27
|
+
schema: 1;
|
|
28
|
+
valid: boolean;
|
|
29
|
+
reason: string;
|
|
30
|
+
version: string;
|
|
31
|
+
commit: string;
|
|
32
|
+
graphSha: string | null;
|
|
33
|
+
recipeSha: string | null;
|
|
34
|
+
envFingerprint: string;
|
|
35
|
+
imageDigest: string | null;
|
|
36
|
+
files: number;
|
|
37
|
+
shards: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** A direct hard rehearsal has no graph run state. Pin the graph and recipe bytes at its Git SHA. */
|
|
41
|
+
export function gateSourcePins(repo: string, commit: string): { graphSha: string; recipeSha: string } | null {
|
|
42
|
+
if (!/^[0-9a-f]{40}$/i.test(commit)) return null;
|
|
43
|
+
const read = (file: string): string | null => {
|
|
44
|
+
const result = spawnSync('git', ['show', `${commit}:${file}`], { cwd: repo, encoding: 'utf8', maxBuffer: 8 * 1024 * 1024 });
|
|
45
|
+
return result.status === 0 && !result.error ? result.stdout : null;
|
|
46
|
+
};
|
|
47
|
+
const graph = read('graphs/release/release-loop.yaml');
|
|
48
|
+
const recipe = read('graphs/release/recipes.yaml');
|
|
49
|
+
return graph === null || recipe === null ? null : {
|
|
50
|
+
graphSha: createHash('sha256').update(graph).digest('hex'),
|
|
51
|
+
recipeSha: createHash('sha256').update(recipe).digest('hex'),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Only Kubernetes' observed child container imageID is evidence; the requested image tag is not. */
|
|
56
|
+
export function actualGatePodImageDigest(podJson: string): string | null {
|
|
57
|
+
try {
|
|
58
|
+
const pods = JSON.parse(podJson) as { items?: Array<{ status?: { containerStatuses?: Array<{ name?: string; imageID?: string }> } }> };
|
|
59
|
+
// A retry can create more than one Pod; collected test bytes are not bound to one of their UIDs.
|
|
60
|
+
if (pods.items?.length !== 1) return null;
|
|
61
|
+
const id = pods.items[0]?.status?.containerStatuses?.find((row) => row.name === 'child')?.imageID;
|
|
62
|
+
const digest = typeof id === 'string' ? /(?:^|@|:\/\/)(sha256:[0-9a-f]{64})$/i.exec(id)?.[1] : undefined;
|
|
63
|
+
return digest && IMAGE_DIGEST.test(digest) ? digest.toLowerCase() : null;
|
|
64
|
+
} catch { return null; }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function gateEnvFingerprint(env: NodeJS.ProcessEnv): string {
|
|
68
|
+
const baseline = gateTestBaseline(env);
|
|
69
|
+
return createHash('sha256').update(JSON.stringify(Object.fromEntries(Object.entries(baseline).sort(([a], [b]) => a.localeCompare(b))))).digest('hex');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Graph runner pins these bytes in its run state. A direct gate without that state cannot mint a reusable receipt. */
|
|
73
|
+
export function gateGraphPins(root: string, runId: string | undefined): { graphSha: string; recipeSha: string } | null {
|
|
74
|
+
if (!runId || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(runId)) return null;
|
|
75
|
+
try {
|
|
76
|
+
const state = JSON.parse(readFileSync(join(root, 'graph-runs', 'release-loop', `${runId}.json`), 'utf8')) as
|
|
77
|
+
{ graphId?: string; runId?: string; graphSnapshot?: { graphSha?: string; recipesSha?: string } };
|
|
78
|
+
const graphSha = state.graphSnapshot?.graphSha;
|
|
79
|
+
const recipeSha = state.graphSnapshot?.recipesSha;
|
|
80
|
+
return state.graphId === 'release-loop' && state.runId === runId && graphSha && recipeSha
|
|
81
|
+
&& SHA256.test(graphSha) && SHA256.test(recipeSha) ? { graphSha, recipeSha } : null;
|
|
82
|
+
} catch { return null; }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function gateBaselineReceipt(input: { root: string; version: string; commit: string; fullSweep: boolean;
|
|
86
|
+
graphPins: { graphSha: string; recipeSha: string } | null; envFingerprint: string }): GateBaselineReceipt {
|
|
87
|
+
const { root, version, commit, graphPins, envFingerprint } = input;
|
|
88
|
+
const base = { schema: 1 as const, version, commit, graphSha: graphPins?.graphSha ?? null,
|
|
89
|
+
recipeSha: graphPins?.recipeSha ?? null, envFingerprint, imageDigest: null as string | null, files: 0, shards: 0 };
|
|
90
|
+
const invalid = (reason: string): GateBaselineReceipt => ({ ...base, valid: false, reason });
|
|
91
|
+
if (!input.fullSweep) return invalid('gate was not a complete clean full sweep');
|
|
92
|
+
if (!graphPins) return invalid('pinned graph or recipe SHA absent');
|
|
93
|
+
if (!SHA256.test(envFingerprint)) return invalid('gate environment fingerprint absent');
|
|
94
|
+
try {
|
|
95
|
+
const dir = join(root, 'release', version, 'gate-logs', 'cut');
|
|
96
|
+
if (!existsSync(dir)) return invalid('cut Pod logs absent');
|
|
97
|
+
const names = readdirSync(dir).filter((name) => /^pod-\d+(?:-[\w-]+)?\.json$/.test(name));
|
|
98
|
+
const roots = new Map<number, { files: string[]; shardCount: number; sweepId: string; attemptId: string }>();
|
|
99
|
+
const descendants: Array<{ name: string; commit?: string; imageDigest?: string; sweepId?: string; parentAttempt?: string; attemptId?: string }> = [];
|
|
100
|
+
const images = new Set<string>();
|
|
101
|
+
for (const name of names) {
|
|
102
|
+
const row = JSON.parse(readFileSync(join(dir, name), 'utf8')) as
|
|
103
|
+
{ commit?: string; files?: unknown; shardCount?: number; sweepId?: string; imageDigest?: string; parentAttempt?: string; attemptId?: string };
|
|
104
|
+
const match = /^pod-(\d+)\.json$/.exec(name);
|
|
105
|
+
if (match) {
|
|
106
|
+
if (row.commit !== commit) return invalid(`root cut Pod ${name} belongs to another commit`);
|
|
107
|
+
if (!Array.isArray(row.files) || !row.files.length || !row.files.every((file) => typeof file === 'string'))
|
|
108
|
+
return invalid(`root cut Pod ${name} has no file list`);
|
|
109
|
+
if (!row.attemptId) return invalid(`root cut Pod ${name} has no attempt`);
|
|
110
|
+
if (!row.sweepId) return invalid(`root cut Pod ${name} has no sweep identity`);
|
|
111
|
+
roots.set(Number(match[1]), { files: row.files as string[], shardCount: row.shardCount ?? 0, sweepId: row.sweepId, attemptId: row.attemptId });
|
|
112
|
+
} else descendants.push({ name, commit: row.commit, imageDigest: row.imageDigest, sweepId: row.sweepId,
|
|
113
|
+
parentAttempt: row.parentAttempt, attemptId: row.attemptId });
|
|
114
|
+
if (match) {
|
|
115
|
+
if (!row.imageDigest || !IMAGE_DIGEST.test(row.imageDigest)) return invalid(`actual Pod image digest absent: ${name}`);
|
|
116
|
+
images.add(row.imageDigest.toLowerCase());
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (!roots.size) return invalid('root cut shards absent');
|
|
120
|
+
const count = roots.get(0)?.shardCount;
|
|
121
|
+
if (!count || !Number.isSafeInteger(count) || count !== roots.size
|
|
122
|
+
|| [...roots.keys()].some((index) => index < 0 || index >= count)) return invalid('root cut shard set incomplete');
|
|
123
|
+
const sweepId = roots.get(0)!.sweepId;
|
|
124
|
+
if ([...roots.values()].some((row) => row.shardCount !== count || row.sweepId !== sweepId))
|
|
125
|
+
return invalid('root cut shards belong to different sweeps');
|
|
126
|
+
const files = [...roots.values()].flatMap((row) => row.files);
|
|
127
|
+
if (new Set(files).size !== files.length) return invalid('root cut file lists overlap');
|
|
128
|
+
// A new cut can leave older split descendants in the same directory. Bind only the current roots' attempt tree.
|
|
129
|
+
const attempts = new Set([...roots.values()].map((row) => row.attemptId));
|
|
130
|
+
let pending = descendants;
|
|
131
|
+
for (; pending.length;) {
|
|
132
|
+
const next = pending.filter((row) => !row.parentAttempt || !attempts.has(row.parentAttempt));
|
|
133
|
+
if (next.length === pending.length) break;
|
|
134
|
+
for (const row of pending) {
|
|
135
|
+
if (!row.parentAttempt || !attempts.has(row.parentAttempt)) continue;
|
|
136
|
+
if (row.commit !== commit) return invalid(`cut Pod ${row.name} belongs to another commit`);
|
|
137
|
+
if (row.sweepId !== sweepId) return invalid(`cut Pod ${row.name} belongs to another sweep`);
|
|
138
|
+
if (!row.imageDigest || !IMAGE_DIGEST.test(row.imageDigest)) return invalid(`actual Pod image digest absent: ${row.name}`);
|
|
139
|
+
if (!row.attemptId) return invalid(`cut Pod ${row.name} has no attempt`);
|
|
140
|
+
images.add(row.imageDigest.toLowerCase());
|
|
141
|
+
attempts.add(row.attemptId);
|
|
142
|
+
}
|
|
143
|
+
pending = next;
|
|
144
|
+
}
|
|
145
|
+
// A child carrying this sweep's identity must be connected to a root,
|
|
146
|
+
// even when its parentAttempt is missing or corrupt. Otherwise its image
|
|
147
|
+
// evidence is silently omitted and a mixed-image receipt can look valid.
|
|
148
|
+
for (const row of pending) {
|
|
149
|
+
if (row.sweepId === sweepId) return invalid(`cut Pod ${row.name} has no connected parent attempt`);
|
|
150
|
+
if (row.commit === commit && !row.sweepId) return invalid(`cut Pod ${row.name} has no sweep identity`);
|
|
151
|
+
}
|
|
152
|
+
if (images.size !== 1) return invalid('cut Pods used different image digests');
|
|
153
|
+
return { ...base, valid: true, reason: 'complete clean full sweep', imageDigest: [...images][0]!, files: files.length, shards: count };
|
|
154
|
+
} catch (error) { return invalid(`cut Pod evidence unreadable: ${String(error)}`); }
|
|
155
|
+
}
|
|
@@ -11,6 +11,9 @@ import { sourceCandidates } from '../../src/self-implement/importer-test-index.j
|
|
|
11
11
|
|
|
12
12
|
/** Files the closure follows (code). Changing anything else that is not a test or inert Markdown is a full gate. */
|
|
13
13
|
export const CODE_FILE = /\.(?:[cm]?[jt]sx?)$/;
|
|
14
|
+
/** One release input whose readers use a literal basename in readFileSync(join(import.meta.dir, ...)).
|
|
15
|
+
* Other JSON stays a full gate until its dependency edge is proved. */
|
|
16
|
+
export const TRACEABLE_RELEASE_JSON = 'scripts/release-loop/known-issues-0.2.33-approved.json';
|
|
14
17
|
const TEST_FILE = /^(?:[\w.-]+\/)*[\w.-]+\.test\.(?:tsx?|jsx?|mts|cts)$/;
|
|
15
18
|
/** Test-side helpers: their filesystem scans and unresolved code paths make a test opaque (production code is trusted to
|
|
16
19
|
* reach code only through imports and the literal paths below). */
|
|
@@ -159,7 +162,8 @@ export function buildClosureGraph(tree: ClosureTree, options: ClosureOptions = {
|
|
|
159
162
|
for (const match of code.matchAll(LITERAL)) {
|
|
160
163
|
const value = match[2]!;
|
|
161
164
|
if (!value || value.length > 300 || value.includes('${') || /\s/.test(value) || /^[a-z]+:/i.test(value)) continue;
|
|
162
|
-
const pathLike = value.startsWith('./') || value.startsWith('../') || (value.includes('/') && /^[\w@.-]+(?:\/[\w@.-]+)+\/?$/.test(value)) || CODE_FILE.test(value)
|
|
165
|
+
const pathLike = value.startsWith('./') || value.startsWith('../') || (value.includes('/') && /^[\w@.-]+(?:\/[\w@.-]+)+\/?$/.test(value)) || CODE_FILE.test(value)
|
|
166
|
+
|| value === TRACEABLE_RELEASE_JSON.split('/').at(-1);
|
|
163
167
|
if (!pathLike) continue;
|
|
164
168
|
const plain = value.replace(/\/$/, '');
|
|
165
169
|
const hit = resolveLiteral(file, plain);
|
|
@@ -12,7 +12,7 @@ export function parseFailures(output: string): string[] {
|
|
|
12
12
|
const line = raw.trim();
|
|
13
13
|
const header = /^(?:\.\/)?((?:[\w.-]+\/)+[\w.-]+\.test\.tsx?):(?:\s|$)/.exec(line);
|
|
14
14
|
if (header) { file = header[1]; continue; }
|
|
15
|
-
const failed = /^\(fail\)[ \t]+(.+?)(?:[ \t]+\[[\d.]+(?:ms|s)\])
|
|
15
|
+
const failed = /^\(fail\)[ \t]+(.+?)(?:[ \t]+\[[\d.]+(?:ms|s)\])?[ \t]*$/.exec(raw);
|
|
16
16
|
if (failed && file) failures.add(`${file} > ${failed[1]!.trim()}`);
|
|
17
17
|
}
|
|
18
18
|
return [...failures].sort();
|