elanous 0.2.37 → 0.2.40
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/{8kITumG9GAZ1LwT9POrAR → HjeK7zONHfR7op1hKXp4k}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{1746.3563617ea64023a3.js → 1060.014f1f01a17aec26.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9151.a2c51e93f9156dae.js → 1281.d81877e35b9068f4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1350.59f40e39e02d91b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1415.79821ec7ae99acdb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1452.162bb2d9d699e82a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/147.f92f63bbc5e85fa5.js +286 -0
- package/apps/pwa/out/_next/static/chunks/1537-6bb97b5214928ea9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1661.fb425a1d8a065b72.js +149 -0
- package/apps/pwa/out/_next/static/chunks/1671-1c22b40b50b208f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1758.0204d3f48783c49d.js +90 -0
- package/apps/pwa/out/_next/static/chunks/1806.027bf78b6a94d340.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{3578.4e9f9948a9a6f2f4.js → 2047.8f23e210995d4548.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7424.c0fe2a595d4232b5.js → 2066.a77257c8c350770a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2096-a938496bc996dcbd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4931.95cc6dbd230774ca.js → 2177.df8547f9d7215c4e.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6680.6a693c28aae4cd19.js → 2226.2cf61ec781827219.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/2281-b8cede695c6c650e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2499.02fbfd18126c10c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6252.240578f10952e091.js → 2522.f2766b76d22c8bdf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1262.a89bb27a5b2f844e.js → 2566.beaffc3a5e1fcd2e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/261.0d471e8aded799f3.js +226 -0
- package/apps/pwa/out/_next/static/chunks/2615.3c9738153de3ef3f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2727.e703d99ac414916d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2752.7904b8df0254d0ae.js +27 -0
- package/apps/pwa/out/_next/static/chunks/2762-5051a862dfa40e99.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2767-31784bfedf8e245d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2318-450e75d07605b8fe.js → 2774-719820e3f5b2a3eb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4725-34bed25720cc326b.js → 2829-734fe8bf2eee7347.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/311-32dcac79970985e8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3175-f93f7495cd28253c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3184.8da993f5502d2140.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3231-d7c981db0ff8bdcc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3250.151309c5176d6b4b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3330.7443183b7e6fdbdf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3517.a5aa1797a9dbf2ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3567-45f676877ed9e8a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3746-f80a78f220bf37b5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3819.8a1de79b2e8c7298.js +24 -0
- package/apps/pwa/out/_next/static/chunks/39.9b37b0be4c128a83.js +77 -0
- package/apps/pwa/out/_next/static/chunks/{4337e36d.f42c3b391b3d8f20.js → 3b355b3d.6f73c98bf6f9c749.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4023.a19045970a9ce16a.js +36 -0
- package/apps/pwa/out/_next/static/chunks/{58edce7d.f1b0c72acf13b123.js → 409c787b.e48c5bec8ec10456.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/413-24c8284bda08241d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4135.e45d6ebc29e20647.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4283.65502f5d0e6ff6c0.js +287 -0
- package/apps/pwa/out/_next/static/chunks/4305-4e28fa92a7b34a5b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4335-50efa61fd7613142.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4351.0f37a6db2b34d50b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5046.7fd5cbd859299448.js → 470.51a72a2348306455.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/4720.ecbd1693fa151068.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2375.bf364c85dbb6f085.js → 4769.9fd582071301f382.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/483.725e4a61be922788.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{de8446d3.31b73eb239fecd7b.js → 4864a2ca.1c1c280a7772c5e5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4969-4b209d7307410c00.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5068-c7f53862f83c0917.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5315.bc96711c24dfefe2.js +74 -0
- package/apps/pwa/out/_next/static/chunks/{4383.18e5c54db3a22c88.js → 5383.bdfa5d886e39a826.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5436.fdf6fa8ae3e9588d.js +64 -0
- package/apps/pwa/out/_next/static/chunks/5542.efbf14f16baed4dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5622.94893f5aea7185d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5644.8f401a25601d05fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5658.35f70eb9871a54bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5721.7bdc0e904c76ab51.js +8 -0
- package/apps/pwa/out/_next/static/chunks/5790-eef0ca20884a6bdf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5802.ef0d8598ca68fe84.js +62 -0
- package/apps/pwa/out/_next/static/chunks/5890.fb974729788dcb71.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5924.5ef25cddd36d5dbf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5979-e59c099ebf8d1f35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6020.714cfeada2315e2e.js +94 -0
- package/apps/pwa/out/_next/static/chunks/6027-dfe0349d8c50f698.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6745-5a63492933959dd9.js → 6051-0ae955eedb10adb9.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/6178.bc4730c86cf74536.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2283.edd9627b7bdfb546.js → 6257.c0037b8949239f5e.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6273.d808b0dcb3c2b155.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6292.6ef1df64fa6a4c8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/647-af8dd920ba46533c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6541-170dc5c59e135c0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6624.981ef7caeb680560.js +32 -0
- package/apps/pwa/out/_next/static/chunks/6742-a1ad4a94ba7bc37a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6819.be5c9c4d67f22922.js → 6749.0744ce6eb08d40e9.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/6836-493dc55c39187949.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6856-53ac421c06039a18.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6908.06008c67f6380ea9.js +148 -0
- package/apps/pwa/out/_next/static/chunks/6915.096931864206f522.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6925.5e181fb7dcf90193.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6cc1d1d6.9a98dd4622f1afc6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7203-800e11037adc41eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7219-15bdd9a80661af8e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7279.6170f591105936bb.js +93 -0
- package/apps/pwa/out/_next/static/chunks/7349-373165c7fbdcc3df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7514-a533ba0ca1cae4f4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7515.1ad6efe157fa4448.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7521.d919cc1fab80c1d9.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7538.90e97bbdf9178cff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7611.85f045bf232053ac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7825-39203196a12579b2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7869.5e1a9a12fd70d6c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8086.1ab9103c41be884f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8099.1cccf31c1baa7e1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8179-e61fffbdb70f1152.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8265.bdeb991b34db6a06.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2002-a43a3f380df873ec.js → 8272-025653884f9645d2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7867.e8725745ddd1d940.js → 8357.1aaa713b052a78b1.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/8638-e42615f2166165b5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8639-92c11d069792429e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8691.54e22831d5e8ccf8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8d173e38.18a2f7b4e1848bdb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9069.657590a84afb8fac.js +41 -0
- package/apps/pwa/out/_next/static/chunks/9125-ae588d88a0293b93.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4313.76f232c304a15bde.js → 9175.2de5209a5ce6f68a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9184.45afbf44fec87574.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8c58d09b.e8724a299658d86f.js → 9189505a.980427ac048c8c60.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9311.f9f641a46a508611.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9371-a6fee8378ebfa3ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9421-3aa9ff4fa7f63d8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9992.07ce73c10bd5e6a1.js +79 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76394dc618d322c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-1b948637c37b3abd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-c63400f1bcf3e47c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-95d0957267819586.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ba957ff875a026a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-bb6fd0714879cb87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8f9038520d2acbef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-d4b48397e05fce2c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-72d5744245dc0c27.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-37625dc8300fa43a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-fbef9d160272dbc1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-58424168df84928e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-72c12ba430ac57c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-d53f3e9ed806d7e0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-4d2fbd45feee0829.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-76394dc618d322c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-8783dc0ed7590a2c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-3706cb390606e930.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-9b0a86598e0111fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/{page-3337c6a1328c2674.js → page-4edb8df90f4537ce.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-83d27757e2b8060a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-47398b9ba1cc5e1b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-fb86f55cfe2e681d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e22345fc8fd47b1b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-1e5da297557d2354.js → page-fca2e59a81744d9e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-6e96bda63100b31e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-4d17ad8e0db8cea4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-121f92766c33beaa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-43f14212c545f92d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ccec2023e7a974ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-b04f33f548b89a94.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-c8792823c0917021.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-8c0e32782ceef4cb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-94bd3922eb230ce8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-bca565887bafa03c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ac1dffafe649fc6c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-52374edb5e23e455.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ad4ebca120d43ca7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-76394dc618d322c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-718b89ce4b4ae4e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-204eca33eeeaddec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-e58ba9bcdb9ac0f9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-98f6dd50bafd7734.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-ac2c1e6169cfce57.js → page-139d722de1dcd6c1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-5a4bdd72bff27057.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-6f6ab17d44f984ce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-aabb7bd15fb72da9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e4322319164a4436.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-e9efc0c8f32e2371.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/{page-c1c80e345fa9d6f5.js → page-ccde99f07aaf71f7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{d9815f84.4918f682a45a8502.js → b84cad00.594027ebe0531fe2.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/c696986b.5dc8bb1143af16d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{709a918c.4fd3b4e2a32cb4e3.js → ca3702f8.2913182e73889fa2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/d5d3cefc-373c4eb722ed848b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5f6af561-f90b7a67f4f75d13.js → d8de0de2-dd0f4ac8e5ab1832.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-002b472a66935d31.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-49b88d47292c0476.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-fff2549cb10a133f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-32abbbba3f3b76b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-9d9cfef60c60dd7a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-cc7f483fa294034a.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/graphs/demo/persona-marketer/fixtures/marketer-scenario.yaml +10 -0
- package/graphs/demo/persona-marketer/persona-marketer.yaml +25 -0
- package/graphs/demo/persona-marketer/recipes.yaml +19 -0
- package/graphs/release/recipes.yaml +9 -0
- package/graphs/release/release-loop.yaml +26 -18
- package/graphs/video/explainer-line.yaml +4 -1
- package/package.json +1 -1
- package/scripts/ask-op-inbox-once.ts +17 -0
- package/scripts/brand/check.ts +13 -4
- package/scripts/dead-code/report.ts +169 -0
- package/scripts/gate-0226-accepted-remaining-90.txt +91 -0
- package/scripts/gate-0226-failure-census.ts +39 -0
- package/scripts/intake-collect-telegram-saved-stage.ts +48 -0
- package/scripts/lib/morning-report-options.ts +3 -4
- package/scripts/lib/tui-regress-evidence.ts +56 -0
- package/scripts/morning-report.ts +5 -1
- package/scripts/provision-export-redactions.ts +15 -0
- package/scripts/public-copy-lint.ts +122 -0
- package/scripts/public-export.ts +77 -2
- package/scripts/ratchets/next-tui-entry-budget.ts +124 -0
- package/scripts/ratchets/train-side-invariants.sh +7 -1
- package/scripts/release-loop/cut-branch.ts +61 -12
- package/scripts/release-loop/export-check-node.ts +21 -3
- package/scripts/release-loop/gate-node.ts +527 -60
- package/scripts/release-loop/gate-partial.ts +82 -3
- package/scripts/release-loop/gate-prewarm-plan.ts +35 -0
- package/scripts/release-loop/gate-radius-live.ts +4 -2
- package/scripts/release-loop/gate-shard-dispatch.ts +128 -0
- package/scripts/release-loop/gate-shard-receipts.ts +89 -0
- package/scripts/release-loop/gate-wall.ts +5 -5
- package/scripts/release-loop/preflight.ts +6 -2
- package/scripts/release-loop/resume-cap.ts +2 -1
- package/scripts/release-loop/resume-release.ts +317 -13
- package/scripts/release-loop/resume.ts +61 -5
- package/scripts/release-loop/traffic-node.ts +12 -4
- package/scripts/release-loop/traffic-transition.ts +53 -13
- package/scripts/release-loop/version-node.ts +35 -5
- package/scripts/release-story/draft.ts +1 -1
- package/scripts/research-bench/README.md +53 -0
- package/scripts/research-bench/questions.json +66 -0
- package/scripts/research-bench/rubric.md +33 -0
- package/scripts/research-bench/run.ts +523 -0
- package/scripts/tui-regress.ts +85 -10
- package/scripts/ux-sim.ts +1 -1
- package/scripts/video-pipeline.ts +2 -2
- package/src/acp/core-turn-bridge.ts +14 -1
- package/src/agent/autonomous-tools.ts +10 -3
- package/src/agent/monad-agent-turn.ts +4 -1
- package/src/agent/registry.ts +26 -2
- package/src/agent/run-context.ts +1 -1
- package/src/agent/shared-app-tools.ts +1 -1
- package/src/agent/surface-ux/build.ts +12 -3
- package/src/agent/surface-ux/types.ts +1 -1
- package/src/agent/task-notification.ts +78 -7
- package/src/agent/types.ts +3 -0
- package/src/agent-mission/driver.ts +29 -3
- package/src/agent-mission/mission-cli.ts +2 -1
- package/src/agent-substrate/review-context-pack.ts +365 -0
- package/src/agent-substrate/review-observation.ts +10 -0
- package/src/agent-substrate/self-review-cli.ts +419 -42
- package/src/ask-user-question/index.ts +6 -0
- package/src/ask-user-question/inline-resolver.ts +49 -0
- package/src/auto-research/question-ladder-contract.ts +156 -0
- package/src/auto-research/research-turn.ts +467 -0
- package/src/autopilot/agent-loop.ts +1 -1
- package/src/autopilot/discovery/doc-lint.ts +1 -1
- package/src/autopilot/pty-control-loop.ts +8 -1
- package/src/boot/daemon-tools/index.ts +4 -3
- package/src/boot/daemon-tools/self-implement.ts +270 -2
- package/src/boot/daemon-tools/types.ts +2 -0
- package/src/bots/screen-probe.ts +1 -1
- package/src/budget/llm-cost.ts +44 -5
- package/src/budget/unified-usage.ts +17 -1
- package/src/capture/tui-self-report.ts +24 -2
- package/src/chat/index.ts +34 -7
- package/src/chat/tool-render/dispatch.ts +8 -1
- package/src/cli/agent-cli.ts +43 -8
- package/src/cli/guardian-cli.ts +3 -1
- package/src/cli/intake-cli.ts +70 -13
- package/src/cli/lesson-cli.ts +86 -10
- package/src/cli/log-event-names.ts +1 -0
- package/src/cli/pod-cli.ts +17 -2
- package/src/cli/pr-land-overlap-evidence.ts +38 -5
- package/src/cli/pr-land-refusal.ts +1 -1
- package/src/cli/pty-takeover-cli.ts +125 -12
- package/src/cli/release-checklist-read-cli.ts +5 -2
- package/src/cli/release-cli.ts +99 -15
- package/src/cli/repo-cli.ts +2 -1
- package/src/cli/review-carry.ts +77 -0
- package/src/cli/self-update.ts +1 -1
- package/src/cli/tasks-card-show.ts +31 -1
- package/src/cli/tasks-cli.ts +98 -32
- package/src/cli/tasks-read-cli.ts +13 -5
- package/src/context-bus/context-now.ts +86 -2
- package/src/control-plane/ledger.ts +21 -4
- package/src/core-turn/run-core-turn.ts +51 -3
- package/src/core-turn/run-goal-loop.ts +152 -8
- package/src/core-turn/types.ts +12 -0
- package/src/dashboard/chat/acp-chat.ts +2 -2
- package/src/dashboard/classic-sigquit.ts +16 -0
- package/src/dashboard/index.ts +339 -44
- package/src/dashboard/input/chat-main-interaction-opts.ts +3 -0
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +7 -2
- package/src/dashboard/input/chat-main-slash-command.ts +7 -0
- package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
- package/src/dashboard/input/dashboard-priority-key-route.ts +21 -5
- package/src/dashboard/input/external-input-host.ts +2 -0
- package/src/dashboard/input/terminal-modal-router.ts +8 -159
- package/src/dashboard/side-basic-runtime.ts +61 -0
- package/src/dashboard/sidetab-runtime.ts +228 -0
- package/src/dashboard/slash-runtime/ask-clarification.ts +7 -1
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +22 -8
- package/src/dashboard/slash-runtime/help-from-registry.ts +2 -2
- package/src/dashboard/term-slash-runtime.ts +18 -18
- package/src/dashboard/turn-preamble.ts +30 -4
- package/src/domains/guardian-tick.ts +9 -0
- package/src/domains/knowledge.ts +1 -1
- package/src/esc-abort-gate.ts +33 -1
- package/src/execution-loop/launch-gate.ts +206 -1
- package/src/git-fs/watcher.ts +27 -22
- package/src/git-fs/worktree.ts +19 -3
- package/src/graph-runner/graph-cli.ts +6 -4
- package/src/graph-runner/graph-grow.ts +37 -9
- package/src/graph-runner/runner.ts +48 -11
- package/src/graph-wizard/generate.ts +16 -7
- package/src/graph-wizard/mission-compose.ts +201 -0
- package/src/grok/agent-search.ts +8 -2
- package/src/grok/credential.ts +112 -36
- package/src/grounding/ref-index.ts +11 -0
- package/src/grounding/ref-vector.ts +61 -0
- package/src/grounding/sources-cli.ts +2 -2
- package/src/grounding/sources.ts +15 -1
- package/src/harness/harness-cli-command.ts +38 -9
- package/src/harness/harness-pod-dispatch.ts +7 -1
- package/src/hq/fence-wrapper.ts +1 -1
- package/src/hq/transfer.ts +1 -1
- package/src/index.ts +60 -16
- package/src/input/external-input-queue.ts +10 -0
- package/src/intake-plane/collect-telegram-saved.ts +90 -6
- package/src/intake-plane/intake-to-tasks.ts +246 -3
- package/src/interactive-terminal-modal.ts +3 -0
- package/src/keybindings.ts +17 -22
- package/src/lessons/friction-ledger.ts +154 -0
- package/src/live-supply/collector.ts +149 -0
- package/src/live-supply/probes.ts +52 -0
- package/src/live-supply/snapshot.ts +40 -0
- package/src/llm/provider-credentials.ts +1 -1
- package/src/llm-tool-schema.ts +20 -0
- package/src/llm.ts +486 -61
- package/src/loops/orchestrator/inbox-once.ts +28 -0
- package/src/loops/orchestrator/inbox.ts +130 -1
- package/src/loops/orchestrator/tick.ts +14 -3
- package/src/maturity/feature-maturity.ts +1 -0
- package/src/nexus/api/channel-ask-op.ts +96 -0
- package/src/nexus/api/discord-trigger-bot.ts +28 -1
- package/src/nexus/api/harness-api.ts +2 -1
- package/src/nexus/api/telegram-trigger-bot.ts +24 -0
- package/src/nexus/api/terminals.ts +28 -6
- package/src/patents/ledger.ts +18 -1
- package/src/preview/terminal.ts +4 -2
- package/src/prompt-cache/anthropic.ts +2 -0
- package/src/prompt-enhance/enhance.ts +5 -0
- package/src/pty/snapshot.py +132 -0
- package/src/pty-shell/pty-control-ipc.ts +29 -2
- package/src/pty-shell/pty-manifest.ts +75 -5
- package/src/pty-shell/registry.ts +2 -0
- package/src/pty-shell/tui-run-state.ts +80 -3
- package/src/release-loop/gate-host-reservation.ts +13 -4
- package/src/release-loop/gate-shard-ledger.ts +68 -0
- package/src/release-loop/gate-shards.ts +61 -0
- package/src/release-loop/light-rc.ts +7 -4
- package/src/release-loop/merged-pr-checklist.ts +25 -2
- package/src/release-loop/rehearsal-shard-plan.ts +6 -1
- package/src/release-loop/rehearsal.ts +28 -1
- package/src/repl/index.ts +10 -0
- package/src/research/axis-fanout.ts +133 -0
- package/src/research/edge-decision.ts +197 -0
- package/src/research/gap-followup.ts +249 -0
- package/src/research/lenses/counter-evidence.ts +100 -0
- package/src/research/lenses/working-backwards.ts +89 -0
- package/src/research/output-router.ts +127 -0
- package/src/research/plugin-discovery.ts +242 -0
- package/src/research-bridge/format.ts +16 -1
- package/src/research-bridge/index.ts +1 -0
- package/src/research-bridge/invoke.ts +45 -7
- package/src/research-bridge/types.ts +2 -0
- package/src/self-dev/ask-launch-flow.ts +34 -106
- package/src/self-dev/decompose.ts +45 -9
- package/src/self-dev/dev-cli.ts +2 -0
- package/src/self-dev/dev-pipeline.ts +8 -4
- package/src/self-dev/draft-residue.ts +221 -2
- package/src/self-dev/draft-sweep.ts +29 -16
- package/src/self-dev/graph-journey-route.ts +10 -2
- package/src/self-dev/launch-preflight-text.ts +2 -2
- package/src/self-dev/launch-preflight.ts +38 -7
- package/src/self-dev/orchestrate-cli.ts +1 -0
- package/src/self-dev/orchestrate.ts +1 -0
- package/src/self-dev/run-supervisor.ts +41 -7
- package/src/self-dev/shard-run.ts +260 -3
- package/src/self-implement/comment-only-source.ts +54 -0
- package/src/self-implement/device-first.ts +8 -2
- package/src/self-implement/doctor-visit.ts +100 -57
- package/src/self-implement/gate-artifacts.ts +5 -2
- package/src/self-implement/gate-baseline.ts +119 -13
- package/src/self-implement/gate-cli.ts +466 -93
- package/src/self-implement/gate-failure-signature.ts +44 -0
- package/src/self-implement/gate-receipt-registry.ts +180 -0
- package/src/self-implement/gate-remote.ts +147 -22
- package/src/self-implement/goal-author-clarification.ts +178 -24
- package/src/self-implement/goal-author-decompose.ts +24 -15
- package/src/self-implement/goal-author.ts +82 -7
- package/src/self-implement/goal-doc/section.ts +22 -0
- package/src/self-implement/goal-supervisor-fill.ts +38 -4
- package/src/self-implement/host-regate.ts +120 -45
- package/src/self-implement/impl-findings-feedback.ts +188 -0
- package/src/self-implement/knowhow-pack.ts +301 -9
- package/src/self-implement/l8-merge-queue.ts +198 -32
- package/src/self-implement/off-diff-evidence.ts +147 -0
- package/src/self-implement/orchestrator.ts +137 -16
- package/src/self-implement/pod-inplace-worktree.ts +82 -0
- package/src/self-implement/pod-warm-pool-profile.ts +2 -2
- package/src/self-implement/premise-review.ts +7 -5
- package/src/self-implement/run-ledger.ts +304 -8
- package/src/self-implement/run-stop.ts +12 -0
- package/src/self-implement/seams.ts +39 -13
- package/src/self-implement/self-implement-cli.ts +30 -4
- package/src/session/channel-ask-op-envelope.ts +36 -0
- package/src/session/channel-op-reply-route.ts +200 -0
- package/src/session/chat.ts +92 -15
- package/src/session/index.ts +2 -0
- package/src/session-runtime/index.ts +9 -22
- package/src/session-runtime/provider-circuit.ts +140 -0
- package/src/shell-runner/file-engine.ts +1 -0
- package/src/shell-runner/types.ts +4 -0
- package/src/sidetab-core/model.ts +176 -0
- package/src/skills/runner.ts +7 -3
- package/src/skills/tools/dev-harness.ts +2 -2
- package/src/skills/tools/schedule-wakeup.ts +24 -7
- package/src/skills/tools/shell.ts +51 -5
- package/src/status/bar.ts +3 -3
- package/src/steward/directive-audit.ts +354 -0
- package/src/storage/file-lock.ts +17 -4
- package/src/surface/child-process.ts +31 -0
- package/src/surface/tui-stderr-owner.ts +48 -0
- package/src/task-agent/adopt-pr.ts +63 -2
- package/src/task-agent/cover.ts +30 -12
- package/src/task-agent/evidence-command-normalize.ts +42 -0
- package/src/task-agent/export-redactions-provision.ts +43 -0
- package/src/task-agent/judge.ts +56 -0
- package/src/task-agent/parent-host.ts +59 -12
- package/src/task-agent/postland-card.ts +35 -2
- package/src/task-agent/rejudge-on-head.ts +46 -2
- package/src/task-agent/repair-cycle.ts +68 -9
- package/src/task-agent/repair-worker.ts +37 -1
- package/src/task-agent/task-hand.ts +226 -33
- package/src/task-agent/tier-split.ts +142 -24
- package/src/task-orchestrator/surfaces/pod-command-job.ts +330 -2
- package/src/task-orchestrator/surfaces/pod-config-snapshot.ts +123 -0
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +57 -5
- package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +11 -8
- package/src/task-orchestrator/surfaces/pod-pool.ts +27 -4
- package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +74 -6
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +2 -1
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +56 -15
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +310 -79
- package/src/task-orchestrator/surfaces/self-implement.ts +33 -2
- package/src/terminal/session-registry.ts +1 -0
- package/src/terminal/terminal-modal-router.ts +156 -0
- package/src/tool-hints/gate.ts +6 -4
- package/src/tool-hints/signals.ts +33 -1
- package/src/tool-runtime/skill-exec-runtime.ts +95 -5
- package/src/tui/chat/background-job-status.ts +8 -2
- package/src/tui/entry.ts +483 -32
- package/src/tui/inline-choice.ts +188 -0
- package/src/tui/sidetab/attach.ts +304 -0
- package/src/tui/sidetab/list.ts +2 -0
- package/src/tui/sidetab/nl-tool.ts +136 -0
- package/src/tui/slash/resume-command.ts +23 -0
- package/src/tui/slash/resume.ts +3 -23
- package/src/tui/slash/term-next.ts +2 -1
- package/src/tui/slash/term.ts +12 -1
- package/src/tui-client/dashboard-session.ts +7 -1
- package/src/tui-client/local-chat-turn.ts +29 -8
- package/src/user-config.ts +42 -3
- package/src/ux-sim/classic-tui-seat-scenarios.ts +1 -7
- package/src/ux-sim/fake-land-queue.ts +88 -0
- package/src/ux-sim/fake-llm.ts +11 -5
- package/src/ux-sim/gate-shard-host-reroute.ts +82 -0
- package/src/ux-sim/goal-interim-trace.ts +24 -0
- package/src/ux-sim/next-tui-seat-scenarios.ts +61 -14
- package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +4 -1
- package/src/version/packed-revision.json +1 -1
- package/src/video-pipeline/recipes/explainer.ts +54 -2
- package/src/web-search/grok.ts +32 -6
- package/src/web-search/index.ts +8 -7
- package/src/workflow-runtime/node-catalog.ts +53 -4
- package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1224.2ceca6c180d5130b.js +0 -62
- package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1ed5e8af.cf424815c7c0efad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/210.90b2cbd64926cf34.js +0 -32
- package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2479-fe7e188bd9402d14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +0 -148
- package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +0 -27
- package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3199.6a1a9b0e6cd01dc6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +0 -36
- package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4036.d54e55e1ebf5acdc.js +0 -90
- package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +0 -226
- package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +0 -287
- package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4324.c99ba3e83eb1b691.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4833-7934c592c5569f00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +0 -24
- package/apps/pwa/out/_next/static/chunks/4937-28d437999b77c9dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +0 -104
- package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +0 -1
- package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +0 -93
- package/apps/pwa/out/_next/static/chunks/5952.294fc574a8625184.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +0 -74
- package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +0 -149
- package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6971-fb5f9dc0a2cb5d2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +0 -41
- package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +0 -1
- package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +0 -1
- package/apps/pwa/out/_next/static/chunks/757-4fbaf50942b8c424.js +0 -1
- package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7893-e444a1b0809cd1e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7c5ed21f-f286708e57cf88f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +0 -8
- package/apps/pwa/out/_next/static/chunks/8080-40d781e7704d3671.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +0 -77
- package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +0 -1
- package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +0 -286
- package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +0 -79
- package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9175-7d383df15a82e2be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +0 -1
- package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +0 -94
- package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +0 -1
- package/apps/pwa/out/_next/static/chunks/958.53a8dcf4729e6997.js +0 -64
- package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-5c112c6d7c33656e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-89acd5d68c0bc560.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-fe986fe79b107546.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-88a1edbff62eaf1d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-443364c9e4a23b31.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-b9af2ac1c4737ce8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-fb9e639c107f5f72.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +0 -1
- package/scripts/migrate-monad-to-elanous.ts +0 -195
- package/scripts/rebrand-elanous.ts +0 -242
- /package/apps/pwa/out/_next/static/{8kITumG9GAZ1LwT9POrAR → HjeK7zONHfR7op1hKXp4k}/_ssgManifest.js +0 -0
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// GATE-REUSE-BY-DIFF (0.2.25): a code change no longer forces the full sweep — with the tip's import closure
|
|
6
6
|
// (gate-closure.ts) the plan adds every test that can reach a changed file, and every test whose closure is opaque.
|
|
7
7
|
// `release resume --from gate` now plans this by default when the tip moved (`--no-partial` = full gate).
|
|
8
|
-
import { existsSync, linkSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { existsSync, linkSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
9
9
|
import { randomUUID } from 'node:crypto';
|
|
10
10
|
import { spawnSync } from 'node:child_process';
|
|
11
11
|
import { dirname, join } from 'node:path';
|
|
@@ -23,6 +23,64 @@ export interface PartialPlan {
|
|
|
23
23
|
files: string[];
|
|
24
24
|
priorFailures: string[];
|
|
25
25
|
priorErrors: string[];
|
|
26
|
+
/** Per-shard executed container imageID digest (never a Job image ref/tag). Present only when every shard recorded one. */
|
|
27
|
+
shardImageDigests?: string[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** A Pod shard result's executed image ID digest. Job image refs/tags are not this field. */
|
|
31
|
+
export interface PartialPlanShardImage {
|
|
32
|
+
imageDigest?: string | null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type PartialPlanImageDigestDecision =
|
|
36
|
+
{ reuse: 1; reason: 'executed-pod-image-digest-match' }
|
|
37
|
+
| { reuse: 0; reason: 'executed-pod-image-digest-missing' | 'executed-pod-image-digest-mismatch' };
|
|
38
|
+
|
|
39
|
+
const IMAGE_DIGEST = /^sha256:[0-9a-f]{64}$/i;
|
|
40
|
+
|
|
41
|
+
function executedImageDigest(value: unknown): string | null {
|
|
42
|
+
return typeof value === 'string' && IMAGE_DIGEST.test(value) ? value.toLowerCase() : null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function shardExecutedDigests(shards: readonly PartialPlanShardImage[]): Array<string | null> {
|
|
46
|
+
return shards.map((shard) => executedImageDigest(shard.imageDigest));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Reuse is allowed only when every shard digest is present and equal. Missing vs mismatch are distinct reasons. */
|
|
50
|
+
export function partialPlanImageDigestsMatch(
|
|
51
|
+
prior: readonly PartialPlanShardImage[],
|
|
52
|
+
current?: readonly PartialPlanShardImage[],
|
|
53
|
+
): PartialPlanImageDigestDecision {
|
|
54
|
+
const left = shardExecutedDigests(prior);
|
|
55
|
+
if (!left.length || left.some((digest) => !digest)) return { reuse: 0, reason: 'executed-pod-image-digest-missing' };
|
|
56
|
+
const first = left[0]!;
|
|
57
|
+
if (left.some((digest) => digest !== first)) return { reuse: 0, reason: 'executed-pod-image-digest-mismatch' };
|
|
58
|
+
if (current !== undefined) {
|
|
59
|
+
const right = shardExecutedDigests(current);
|
|
60
|
+
if (!right.length || right.some((digest) => !digest)) return { reuse: 0, reason: 'executed-pod-image-digest-missing' };
|
|
61
|
+
if (right.some((digest) => digest !== first)) return { reuse: 0, reason: 'executed-pod-image-digest-mismatch' };
|
|
62
|
+
}
|
|
63
|
+
return { reuse: 1, reason: 'executed-pod-image-digest-match' };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function planImageDigestDecision(digests: readonly unknown[]): PartialPlanImageDigestDecision {
|
|
67
|
+
return partialPlanImageDigestsMatch(digests.map((imageDigest) => ({ imageDigest: typeof imageDigest === 'string' ? imageDigest : null })));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Every executed root/retry Pod row. Reads `imageDigest` (container imageID); Job `image` ref/tag is ignored. */
|
|
71
|
+
export function collectExecutedPodShardImages(dir: string, commit?: string): PartialPlanShardImage[] {
|
|
72
|
+
if (!existsSync(dir)) return [];
|
|
73
|
+
try {
|
|
74
|
+
return readdirSync(dir).filter((name) => /^pod-\d+(?:-[\w-]+)?\.json$/.test(name))
|
|
75
|
+
.sort((a, b) => Number(/^pod-(\d+)/.exec(a)![1]) - Number(/^pod-(\d+)/.exec(b)![1]) || a.localeCompare(b))
|
|
76
|
+
.map((name) => {
|
|
77
|
+
try {
|
|
78
|
+
const row = JSON.parse(readFileSync(join(dir, name), 'utf8')) as { commit?: string; imageDigest?: string };
|
|
79
|
+
if (commit && row.commit !== commit) return { imageDigest: null };
|
|
80
|
+
return { imageDigest: row.imageDigest ?? null };
|
|
81
|
+
} catch { return { imageDigest: null }; }
|
|
82
|
+
});
|
|
83
|
+
} catch { return []; }
|
|
26
84
|
}
|
|
27
85
|
|
|
28
86
|
/** G1: a second measurement of only the failed files on the very same release commit.
|
|
@@ -172,10 +230,22 @@ export function planPartialRegate(input: { version: string; priorCommit: string;
|
|
|
172
230
|
closure?: (changedCode: string[]) => ClosureVerdict;
|
|
173
231
|
/** Tracked at the tip — a deleted changed test is not re-run (nothing to run); a deleted prior-failure file is a full
|
|
174
232
|
* gate (its failure can be neither re-measured nor carried). Without it every changed test is planned. */
|
|
175
|
-
existsAtTip?: (file: string) => boolean
|
|
233
|
+
existsAtTip?: (file: string) => boolean;
|
|
234
|
+
/** Executed Pod shard imageID digests from the prior full gate. A Job image ref/tag is not this field. */
|
|
235
|
+
priorShards?: readonly PartialPlanShardImage[];
|
|
236
|
+
/** Executed Pod shard imageID digests of the current sweep, when already measured. */
|
|
237
|
+
currentShards?: readonly PartialPlanShardImage[];
|
|
238
|
+
/** Directory of prior full-gate `pod-N.json` rows; collected when `priorShards` is omitted. */
|
|
239
|
+
priorCutLogs?: string;
|
|
240
|
+
/** Directory of current-sweep `pod-N.json` rows; collected when `currentShards` is omitted. */
|
|
241
|
+
currentCutLogs?: string }):
|
|
176
242
|
{ ok: true; plan: PartialPlan; closure?: { reached: number; opaque: number } } | { ok: false; reason: string } {
|
|
177
243
|
if (!/^[0-9a-f]{40}$/i.test(input.priorCommit) || !/^[0-9a-f]{40}$/i.test(input.forCommit)) return { ok: false, reason: 'commit is not a full sha' };
|
|
178
244
|
if (input.priorCommit === input.forCommit) return { ok: false, reason: 'no new commit since the prior gate' };
|
|
245
|
+
const priorShards = input.priorShards ?? (input.priorCutLogs ? collectExecutedPodShardImages(input.priorCutLogs, input.priorCommit) : undefined);
|
|
246
|
+
const currentShards = input.currentShards ?? (input.currentCutLogs ? collectExecutedPodShardImages(input.currentCutLogs, input.forCommit) : undefined);
|
|
247
|
+
const imageIdentity = priorShards ? partialPlanImageDigestsMatch(priorShards, currentShards) : undefined;
|
|
248
|
+
if (imageIdentity && imageIdentity.reuse === 0) return { ok: false, reason: imageIdentity.reason };
|
|
179
249
|
const source = input.changedFiles.filter((file) => !TEST_FILE.test(file) && !isInert(file));
|
|
180
250
|
const list = (files: string[]) => `${files.slice(0, 5).join(', ')}${files.length > 5 ? ` (+${files.length - 5})` : ''}`;
|
|
181
251
|
// Only code is followed through the closure: a changed fixture, JSON, lockfile, config or script is a full gate.
|
|
@@ -204,8 +274,12 @@ export function planPartialRegate(input: { version: string; priorCommit: string;
|
|
|
204
274
|
// but it changes the measured suite and must not masquerade as a carry.
|
|
205
275
|
if (!files.length && (!input.changedFiles.length || input.changedFiles.some((file) => !isInert(file))))
|
|
206
276
|
return { ok: false, reason: 'nothing to re-run (not a docs-only append)' };
|
|
277
|
+
const shardImageDigests = imageIdentity?.reuse === 1
|
|
278
|
+
? shardExecutedDigests(priorShards!).filter((digest): digest is string => !!digest)
|
|
279
|
+
: undefined;
|
|
207
280
|
return { ok: true, plan: { ...(!files.length ? { kind: 'carry' as const } : {}), version: input.version, priorCommit: input.priorCommit, forCommit: input.forCommit, files,
|
|
208
|
-
priorFailures: [...input.priorFailures], priorErrors: [...input.priorErrors]
|
|
281
|
+
priorFailures: [...input.priorFailures], priorErrors: [...input.priorErrors],
|
|
282
|
+
...(shardImageDigests ? { shardImageDigests } : {}) }, ...(closure ? { closure } : {}) };
|
|
209
283
|
}
|
|
210
284
|
|
|
211
285
|
export function writePartialPlan(root: string, plan: PartialPlan): string {
|
|
@@ -259,6 +333,11 @@ export function readPartialPlanResult(roots: readonly string[], version: string,
|
|
|
259
333
|
catch { throw new Error(`invalid gate partial plan: ${path}`); }
|
|
260
334
|
if (failureFiles.some((file) => !rerun.has(file))) throw new Error(`invalid gate partial plan (prior failure not re-run): ${path}`);
|
|
261
335
|
if (raw.forCommit !== commit) { fallbackReason = 'plan-commit-mismatch'; continue; }
|
|
336
|
+
if (raw.shardImageDigests !== undefined) {
|
|
337
|
+
if (!Array.isArray(raw.shardImageDigests)) throw new Error(`invalid gate partial plan: ${path}`);
|
|
338
|
+
const identity = planImageDigestDecision(raw.shardImageDigests);
|
|
339
|
+
if (identity.reuse === 0) { fallbackReason = identity.reason; continue; }
|
|
340
|
+
}
|
|
262
341
|
return { plan: raw as PartialPlan, fallbackReason: null };
|
|
263
342
|
}
|
|
264
343
|
return { plan: null, fallbackReason };
|
|
@@ -32,6 +32,41 @@ export type GatePrewarmPlan =
|
|
|
32
32
|
| { action: 'prepare-mirror'; cutSha: string; lockHash: string }
|
|
33
33
|
| { action: 'start-worker'; cutSha: string; lockHash: string; slotAfter: number };
|
|
34
34
|
|
|
35
|
+
/** A cut observation names the intended gate profile without granting a Pod slot. */
|
|
36
|
+
export function planGatePrewarmCutShadow(input: GatePrewarmInput | { cutSha: string }, warmMemberCount: number | null):
|
|
37
|
+
{ profile: 'gate'; transition: 'shadow'; plan: GatePrewarmPlan; reason?: 'warm-members-exceed-occupied' } {
|
|
38
|
+
const shadow = { profile: 'gate' as const, transition: 'shadow' as const };
|
|
39
|
+
if (!('nowMs' in input) || warmMemberCount === null) {
|
|
40
|
+
return { ...shadow, plan: { action: 'defer', reason: 'unmeasured' } };
|
|
41
|
+
}
|
|
42
|
+
if (input.occupiedPods !== null && warmMemberCount > input.occupiedPods) {
|
|
43
|
+
return { ...shadow, plan: { action: 'defer', reason: 'unmeasured' }, reason: 'warm-members-exceed-occupied' };
|
|
44
|
+
}
|
|
45
|
+
return { ...shadow, plan: planGatePrewarm(input) };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
type WarmMemberSnapshot = Record<string, readonly unknown[]>;
|
|
49
|
+
|
|
50
|
+
/** Compare the same observed cut on both sides of a read-only profile decision. */
|
|
51
|
+
export function observeGatePrewarmCutShadow(input: GatePrewarmInput | { cutSha: string },
|
|
52
|
+
readWarmMembers: () => WarmMemberSnapshot | null, readPlacement: () => Record<string, number>) {
|
|
53
|
+
const placementBefore = readPlacement();
|
|
54
|
+
const membersBefore = readWarmMembers();
|
|
55
|
+
const memberCountBefore = membersBefore ? Object.values(membersBefore).reduce((n, rows) => n + rows.length, 0) : null;
|
|
56
|
+
const shadow = planGatePrewarmCutShadow(input, memberCountBefore);
|
|
57
|
+
const membersAfter = readWarmMembers();
|
|
58
|
+
const placementAfter = readPlacement();
|
|
59
|
+
const memberCountAfter = membersAfter ? Object.values(membersAfter).reduce((n, rows) => n + rows.length, 0) : null;
|
|
60
|
+
const stable = membersBefore !== null && membersAfter !== null
|
|
61
|
+
&& JSON.stringify(membersBefore) === JSON.stringify(membersAfter)
|
|
62
|
+
&& JSON.stringify(placementBefore) === JSON.stringify(placementAfter);
|
|
63
|
+
if (!stable) return { profile: 'gate' as const, transition: 'shadow' as const, status: 'unmeasured' as const,
|
|
64
|
+
plan: { action: 'defer' as const, reason: 'unmeasured' as const }, reason: 'warm-members-unmeasured-or-changed' as const,
|
|
65
|
+
memberCountBefore, memberCountAfter, membersBefore, membersAfter, placementBefore, placementAfter };
|
|
66
|
+
return { ...shadow, status: shadow.plan.action === 'defer' && shadow.plan.reason === 'unmeasured' ? 'unmeasured' as const : 'observed' as const,
|
|
67
|
+
memberCountBefore, memberCountAfter, membersBefore, membersAfter, placementBefore, placementAfter };
|
|
68
|
+
}
|
|
69
|
+
|
|
35
70
|
const count = (value: number | null): value is number =>
|
|
36
71
|
value !== null && Number.isSafeInteger(value) && value >= 0;
|
|
37
72
|
|
|
@@ -152,8 +152,10 @@ export function planHardRehearsalRadius(input: { root: string; repo: string; ver
|
|
|
152
152
|
const planned = planPartialRegate({ version: input.version, priorCommit: stamp.sha, forCommit: input.forCommit,
|
|
153
153
|
changedFiles: effective, priorFailures: failures.failures, priorErrors: failures.errors ?? [],
|
|
154
154
|
existsAtTip: (file) => tree.files.includes(file),
|
|
155
|
-
closure: (code) => testsReachingChanged(tree, code, tests)
|
|
156
|
-
|
|
155
|
+
closure: (code) => testsReachingChanged(tree, code, tests),
|
|
156
|
+
priorCutLogs: join(dir, 'gate-logs', 'cut') });
|
|
157
|
+
if (!planned.ok && (effective.length || planned.reason.startsWith('executed-pod-image-digest-')))
|
|
158
|
+
return full(planned.reason);
|
|
157
159
|
let fileSet: string[];
|
|
158
160
|
let base: PartialPlan;
|
|
159
161
|
if (planned.ok) {
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/** Pure, fail-closed planning for a release gate measured across hosts. No host command runs here. */
|
|
2
|
+
export interface GateShardIdentity {
|
|
3
|
+
id: string;
|
|
4
|
+
files: string[];
|
|
5
|
+
/** Execution requirement, never a concrete host identity. */
|
|
6
|
+
requiredOs?: 'darwin' | 'linux';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface GateShardReceipt extends GateShardIdentity {
|
|
10
|
+
head40: string;
|
|
11
|
+
base40: string;
|
|
12
|
+
host: string;
|
|
13
|
+
envKey: string;
|
|
14
|
+
status: 'complete' | 'unmeasured';
|
|
15
|
+
/** A complete measurement can contain existing or introduced failures. */
|
|
16
|
+
failureIds: string[];
|
|
17
|
+
errorIds: string[];
|
|
18
|
+
/** Relative path to the measurement artifact, checked by the caller before reuse. */
|
|
19
|
+
evidencePath: string;
|
|
20
|
+
evidenceSha256: string;
|
|
21
|
+
measuredAt: string;
|
|
22
|
+
attempt: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface GateShardHost {
|
|
26
|
+
id: string;
|
|
27
|
+
platform: 'darwin' | 'linux' | 'other';
|
|
28
|
+
available: boolean;
|
|
29
|
+
reserved: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface GateShardDispatchInput {
|
|
33
|
+
head40: string;
|
|
34
|
+
base40: string;
|
|
35
|
+
shards: readonly GateShardIdentity[];
|
|
36
|
+
receipts: readonly GateShardReceipt[];
|
|
37
|
+
hosts: readonly GateShardHost[];
|
|
38
|
+
rerouteShard?: string | 'auto';
|
|
39
|
+
shardHost?: string;
|
|
40
|
+
/** IDs known to pass on macOS, supplied by the caller's env-known policy. */
|
|
41
|
+
macPassShardIds?: readonly string[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type GateShardAction =
|
|
45
|
+
| { shardId: string; files: string[]; kind: 'reuse'; receipt: GateShardReceipt }
|
|
46
|
+
| { shardId: string; files: string[]; kind: 'run'; host: string; replacing?: GateShardReceipt }
|
|
47
|
+
| { shardId: string; files: string[]; kind: 'unmeasured'; reason: string };
|
|
48
|
+
|
|
49
|
+
const SHA40 = /^[a-f0-9]{40}$/i;
|
|
50
|
+
const safeId = (id: string) => /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(id);
|
|
51
|
+
const sameFiles = (a: readonly string[], b: readonly string[]) => a.length === b.length && a.every((file, i) => file === b[i]);
|
|
52
|
+
|
|
53
|
+
export function validGateShardIdentity(head40: string, base40: string, shards: readonly GateShardIdentity[]): boolean {
|
|
54
|
+
if (!SHA40.test(head40) || !SHA40.test(base40) || shards.length === 0) return false;
|
|
55
|
+
const ids = new Set<string>();
|
|
56
|
+
const files = new Set<string>();
|
|
57
|
+
for (const shard of shards) {
|
|
58
|
+
if (!safeId(shard.id) || ids.has(shard.id) || shard.files.length === 0
|
|
59
|
+
|| (shard.requiredOs !== undefined && shard.requiredOs !== 'darwin' && shard.requiredOs !== 'linux')) return false;
|
|
60
|
+
ids.add(shard.id);
|
|
61
|
+
for (const file of shard.files) {
|
|
62
|
+
if (!/^(?:[\w.-]+\/)*[\w.-]+\.test\.(?:tsx?|jsx?|mts|cts)$/.test(file) || file.split('/').includes('..') || files.has(file)) return false;
|
|
63
|
+
files.add(file);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function eligibleGateShardReceipt(
|
|
70
|
+
receipt: GateShardReceipt,
|
|
71
|
+
shard: GateShardIdentity,
|
|
72
|
+
head40: string,
|
|
73
|
+
base40: string,
|
|
74
|
+
): boolean {
|
|
75
|
+
return receipt.status === 'complete' && receipt.id === shard.id
|
|
76
|
+
&& receipt.head40 === head40 && receipt.base40 === base40 && sameFiles(receipt.files, shard.files)
|
|
77
|
+
&& receipt.envKey.trim().length > 0 && receipt.host.trim().length > 0
|
|
78
|
+
&& receipt.evidencePath.trim().length > 0 && /^[a-f0-9]{64}$/i.test(receipt.evidenceSha256)
|
|
79
|
+
&& Number.isSafeInteger(receipt.attempt) && receipt.attempt > 0
|
|
80
|
+
&& Array.isArray(receipt.failureIds) && receipt.failureIds.every((id) => typeof id === 'string')
|
|
81
|
+
&& Array.isArray(receipt.errorIds) && receipt.errorIds.every((id) => typeof id === 'string');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Reuse only exact complete measurements. A requested remeasure replaces one shard, not the whole sweep. */
|
|
85
|
+
export function planGateShardDispatch(input: GateShardDispatchInput): GateShardAction[] {
|
|
86
|
+
if (!validGateShardIdentity(input.head40, input.base40, input.shards)) throw new Error('invalid gate shard identity');
|
|
87
|
+
if (input.rerouteShard && input.rerouteShard !== 'auto' && !input.shards.some((s) => s.id === input.rerouteShard))
|
|
88
|
+
throw new Error(`unknown reroute shard: ${input.rerouteShard}`);
|
|
89
|
+
if (input.shardHost && !input.hosts.some((host) => host.id === input.shardHost)) throw new Error(`unknown shard host: ${input.shardHost}`);
|
|
90
|
+
const hosts = input.hosts.filter((host) => host.available && !host.reserved);
|
|
91
|
+
const macPass = new Set(input.macPassShardIds ?? []);
|
|
92
|
+
let nextHost = 0;
|
|
93
|
+
return input.shards.map((shard) => {
|
|
94
|
+
const receipt = [...input.receipts].reverse().find((r) => eligibleGateShardReceipt(r, shard, input.head40, input.base40));
|
|
95
|
+
const prior = [...input.receipts].reverse().find((r) => r.id === shard.id && r.head40 === input.head40 && r.base40 === input.base40 && sameFiles(r.files, shard.files));
|
|
96
|
+
const forced = input.rerouteShard === shard.id;
|
|
97
|
+
const auto = input.rerouteShard === 'auto' && (prior?.status === 'unmeasured'
|
|
98
|
+
|| (macPass.has(shard.id) && !!prior && (prior.failureIds.length > 0 || prior.errorIds.length > 0)));
|
|
99
|
+
const receiptHost = hosts.find((host) => host.id === receipt?.host);
|
|
100
|
+
if (receipt && !forced && !auto && (!shard.requiredOs || receiptHost?.platform === shard.requiredOs))
|
|
101
|
+
return { shardId: shard.id, files: [...shard.files], kind: 'reuse', receipt };
|
|
102
|
+
let candidates = hosts.filter((host) => !shard.requiredOs || host.platform === shard.requiredOs);
|
|
103
|
+
if (input.shardHost && (forced || auto)) candidates = candidates.filter((host) => host.id === input.shardHost);
|
|
104
|
+
else if (auto && macPass.has(shard.id)) candidates = candidates.filter((host) => host.platform === 'darwin');
|
|
105
|
+
if ((forced || auto) && prior && candidates.some((host) => host.id !== prior.host)) candidates = candidates.filter((host) => host.id !== prior.host);
|
|
106
|
+
if (!candidates.length) return { shardId: shard.id, files: [...shard.files], kind: 'unmeasured', reason: 'no eligible host' };
|
|
107
|
+
const host = candidates[nextHost++ % candidates.length]!;
|
|
108
|
+
return { shardId: shard.id, files: [...shard.files], kind: 'run', host: host.id, ...(prior ? { replacing: prior } : {}) };
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export type GateShardReduction =
|
|
113
|
+
| { status: 'complete'; failureIds: string[]; errorIds: string[]; receipts: GateShardReceipt[] }
|
|
114
|
+
| { status: 'unmeasured'; reason: string };
|
|
115
|
+
|
|
116
|
+
/** Require exactly one exact, complete receipt per expected shard; classification remains with judgeGate. */
|
|
117
|
+
export function reduceGateShardReceipts(input: { head40: string; base40: string; shards: readonly GateShardIdentity[]; receipts: readonly GateShardReceipt[] }): GateShardReduction {
|
|
118
|
+
if (!validGateShardIdentity(input.head40, input.base40, input.shards)) return { status: 'unmeasured', reason: 'invalid gate shard identity' };
|
|
119
|
+
const selected: GateShardReceipt[] = [];
|
|
120
|
+
for (const shard of input.shards) {
|
|
121
|
+
const matched = input.receipts.filter((r) => eligibleGateShardReceipt(r, shard, input.head40, input.base40));
|
|
122
|
+
if (matched.length !== 1) return { status: 'unmeasured', reason: `${shard.id}: expected one complete receipt, found ${matched.length}` };
|
|
123
|
+
selected.push(matched[0]!);
|
|
124
|
+
}
|
|
125
|
+
return { status: 'complete', receipts: selected,
|
|
126
|
+
failureIds: [...new Set(selected.flatMap((r) => r.failureIds))].sort(),
|
|
127
|
+
errorIds: [...new Set(selected.flatMap((r) => r.errorIds))].sort() };
|
|
128
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { basename, dirname, join } from 'node:path';
|
|
4
|
+
import { eligibleGateShardReceipt, type GateShardIdentity, type GateShardReceipt } from './gate-shard-dispatch.js';
|
|
5
|
+
|
|
6
|
+
export interface GateShardSavedRun {
|
|
7
|
+
output: string;
|
|
8
|
+
rc: number;
|
|
9
|
+
pass: number;
|
|
10
|
+
fail: number;
|
|
11
|
+
errors: number;
|
|
12
|
+
ran: number;
|
|
13
|
+
files: number;
|
|
14
|
+
passedIds: string[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface GateShardSavedResult {
|
|
18
|
+
receipt: GateShardReceipt;
|
|
19
|
+
runs: GateShardSavedRun[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function gateShardReceiptPath(root: string, shardId: string): string {
|
|
23
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(shardId)) throw new Error('invalid shard id');
|
|
24
|
+
return join(root, `${shardId}.receipt.json`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function nextGateShardAttempt(root: string, shardId: string): number {
|
|
28
|
+
try {
|
|
29
|
+
const previous = JSON.parse(readFileSync(gateShardReceiptPath(root, shardId), 'utf8')) as { attempt?: unknown };
|
|
30
|
+
return Number.isSafeInteger(previous.attempt) && (previous.attempt as number) > 0 ? (previous.attempt as number) + 1 : 1;
|
|
31
|
+
} catch { return 1; }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Planning may inspect an unmeasured predecessor; only readGateShardResult authorizes reuse. */
|
|
35
|
+
export function readGateShardManifest(root: string, shardId: string): GateShardReceipt | null {
|
|
36
|
+
try {
|
|
37
|
+
const value = JSON.parse(readFileSync(gateShardReceiptPath(root, shardId), 'utf8')) as GateShardReceipt;
|
|
38
|
+
return value && value.id === shardId && Array.isArray(value.files)
|
|
39
|
+
&& Array.isArray(value.failureIds) && value.failureIds.every((id) => typeof id === 'string')
|
|
40
|
+
&& Array.isArray(value.errorIds) && value.errorIds.every((id) => typeof id === 'string')
|
|
41
|
+
&& (value.status === 'complete' || value.status === 'unmeasured') ? value : null;
|
|
42
|
+
} catch { return null; }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function atomicJson(path: string, value: unknown): void {
|
|
46
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
47
|
+
const temp = join(dirname(path), `.${basename(path)}-${process.pid}-${randomUUID()}.tmp`);
|
|
48
|
+
try { writeFileSync(temp, JSON.stringify(value) + '\n', { mode: 0o600 }); renameSync(temp, path); }
|
|
49
|
+
finally { if (existsSync(temp)) rmSync(temp); }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** A new attempt invalidates an old success before host execution starts. */
|
|
53
|
+
export function markGateShardUnmeasured(root: string, receipt: GateShardReceipt): void {
|
|
54
|
+
atomicJson(gateShardReceiptPath(root, receipt.id), { ...receipt, status: 'unmeasured' });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Save the actual measured bytes and bind their digest to the manifest. */
|
|
58
|
+
export function saveGateShardResult(root: string, result: GateShardSavedResult): GateShardReceipt {
|
|
59
|
+
const { receipt, runs } = result;
|
|
60
|
+
if (!eligibleGateShardReceipt(receipt, receipt, receipt.head40, receipt.base40) || !runs.length
|
|
61
|
+
|| runs.some((run) => !Number.isSafeInteger(run.ran) || run.ran < 0 || !Number.isSafeInteger(run.files) || run.files < 1))
|
|
62
|
+
throw new Error('incomplete gate shard result');
|
|
63
|
+
const payloadName = `${receipt.id}.attempt-${receipt.attempt}-${randomUUID()}.result.json`;
|
|
64
|
+
const payloadBody = { runs, failureIds: receipt.failureIds, errorIds: receipt.errorIds };
|
|
65
|
+
const payload = JSON.stringify(payloadBody) + '\n';
|
|
66
|
+
const digest = createHash('sha256').update(payload).digest('hex');
|
|
67
|
+
atomicJson(join(root, payloadName), payloadBody);
|
|
68
|
+
const saved = { ...receipt, evidencePath: payloadName, evidenceSha256: digest };
|
|
69
|
+
atomicJson(gateShardReceiptPath(root, receipt.id), saved);
|
|
70
|
+
return saved;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** No manifest, stale identity, missing bytes or digest mismatch can become a reused pass. */
|
|
74
|
+
export function readGateShardResult(root: string, expected: { shard: GateShardIdentity; head40: string; base40: string; envKey: string }): GateShardSavedResult | null {
|
|
75
|
+
try {
|
|
76
|
+
const receipt = JSON.parse(readFileSync(gateShardReceiptPath(root, expected.shard.id), 'utf8')) as GateShardReceipt;
|
|
77
|
+
if (!eligibleGateShardReceipt(receipt, expected.shard, expected.head40, expected.base40) || receipt.envKey !== expected.envKey
|
|
78
|
+
|| !/^[A-Za-z0-9][A-Za-z0-9._-]*\.result\.json$/.test(receipt.evidencePath)) return null;
|
|
79
|
+
const payload = readFileSync(join(root, receipt.evidencePath), 'utf8');
|
|
80
|
+
if (createHash('sha256').update(payload).digest('hex') !== receipt.evidenceSha256) return null;
|
|
81
|
+
const parsed = JSON.parse(payload) as { runs?: GateShardSavedRun[]; failureIds?: string[]; errorIds?: string[] };
|
|
82
|
+
if (!Array.isArray(parsed.runs) || parsed.runs.length === 0 || parsed.runs.some((run) =>
|
|
83
|
+
typeof run.output !== 'string' || !Number.isSafeInteger(run.rc) || !Number.isSafeInteger(run.ran)
|
|
84
|
+
|| !Number.isSafeInteger(run.files) || !Array.isArray(run.passedIds))
|
|
85
|
+
|| JSON.stringify(parsed.failureIds) !== JSON.stringify(receipt.failureIds)
|
|
86
|
+
|| JSON.stringify(parsed.errorIds) !== JSON.stringify(receipt.errorIds)) return null;
|
|
87
|
+
return { receipt, runs: parsed.runs };
|
|
88
|
+
} catch { return null; }
|
|
89
|
+
}
|
|
@@ -79,12 +79,12 @@ function attempt(dir: string, commit: string, pods: TimedPod[]): GateWallAttempt
|
|
|
79
79
|
const SHARDS_WINDOW_SLACK_MS = 5 * 60_000;
|
|
80
80
|
/**
|
|
81
81
|
* shards.json is a snapshot of the latest attempt, not an archive of every commit, and has no attempt identity.
|
|
82
|
-
* A row is attributed to the attempt only when its
|
|
82
|
+
* A row is attributed to the attempt only when its id is one of the attempt's pod records AND
|
|
83
83
|
* a row starts inside the attempt's pod-record window (from 5 min before its first start to its last end) — a
|
|
84
84
|
* previous attempt's snapshot reusing `pod-0` started earlier and is rejected. The end is free: a longer
|
|
85
85
|
* snapshot is exactly the disagreement this report keeps.
|
|
86
86
|
*/
|
|
87
|
-
function shardsSpan(dir: string,
|
|
87
|
+
function shardsSpan(dir: string, podNames: Set<string>, window: { start: number; end: number }): number | 'outside-attempt-window' | null {
|
|
88
88
|
try {
|
|
89
89
|
const file: unknown = JSON.parse(readFileSync(join(dir, 'shards.json'), 'utf8'));
|
|
90
90
|
if (!file || typeof file !== 'object' || !('shards' in file) || !Array.isArray(file.shards)) return null;
|
|
@@ -94,7 +94,7 @@ function shardsSpan(dir: string, rootNames: Set<string>, window: { start: number
|
|
|
94
94
|
const ends: number[] = [];
|
|
95
95
|
for (const row of rows) {
|
|
96
96
|
if (!row || typeof row !== 'object' || !('id' in row) || typeof row.id !== 'string'
|
|
97
|
-
|| !
|
|
97
|
+
|| !podNames.has(`${row.id}.json`)) return null;
|
|
98
98
|
const start = 'startedAt' in row && typeof row.startedAt === 'string' ? Date.parse(row.startedAt) : NaN;
|
|
99
99
|
const end = 'endedAt' in row && typeof row.endedAt === 'string' ? Date.parse(row.endedAt) : NaN;
|
|
100
100
|
if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return null;
|
|
@@ -134,10 +134,10 @@ export function gateWall(dir: string, opts: { commit?: string; targetMin?: numbe
|
|
|
134
134
|
const chosen = matching.find(([, pods]) => pods.some((p) => p.root));
|
|
135
135
|
const attempts = ordered.map(([commit, pods]) => attempt(dir, commit, pods));
|
|
136
136
|
const selected = chosen && attempts.find((a) => a.commit === chosen[0]);
|
|
137
|
-
// The snapshot has no commit field. Only the latest recorded attempt can own it; require
|
|
137
|
+
// The snapshot has no commit field. Only the latest recorded attempt can own it; require every row's pod record.
|
|
138
138
|
const latest = chosen !== undefined && ordered[0]?.[0] === chosen[0];
|
|
139
139
|
const span = chosen && latest
|
|
140
|
-
? shardsSpan(dir, new Set(chosen[1].
|
|
140
|
+
? shardsSpan(dir, new Set(chosen[1].map((p) => p.name)),
|
|
141
141
|
{ start: Math.min(...chosen[1].map((p) => p.start)), end: Math.max(...chosen[1].map((p) => p.end)) }) : null;
|
|
142
142
|
const snapshot = typeof span === 'number' ? span : null;
|
|
143
143
|
const shardsWallMin = snapshot;
|
|
@@ -106,10 +106,14 @@ export async function scanOriginMainExport(): Promise<{ mainSha: string; files:
|
|
|
106
106
|
try { code = runPublicExport(['--leak-check', '--json'], snapshot); }
|
|
107
107
|
finally { console.log = originalLog; console.error = originalError; }
|
|
108
108
|
const report = JSON.parse(output.trim()) as {
|
|
109
|
-
files?: number; leaks?: number; hits?: Array<{ marker: string }>; codeLiterals?: { hits?: number };
|
|
109
|
+
files?: number; leaks?: number; hits?: Array<{ marker: string; file?: string; line?: number }>; codeLiterals?: { hits?: number };
|
|
110
110
|
privateRedactions?: { loaded?: boolean };
|
|
111
111
|
};
|
|
112
|
-
if (report.privateRedactions?.loaded !== true)
|
|
112
|
+
if (report.privateRedactions?.loaded !== true) {
|
|
113
|
+
const failure = report.hits?.find((hit) => hit.marker.startsWith('private-redaction-'));
|
|
114
|
+
if (failure) throw new Error(`공개 export 개인 치환 실패: ${failure.marker} ${failure.file ?? ''}:${failure.line ?? 0}`);
|
|
115
|
+
throw new Error('개인 치환표를 읽지 못해 export 누수 검사를 완결할 수 없다');
|
|
116
|
+
}
|
|
113
117
|
if (typeof report.files !== 'number' || typeof report.leaks !== 'number') throw new Error('public-export 검사 결과가 완전하지 않다');
|
|
114
118
|
if (code !== (report.leaks > 0 ? 1 : 0)) throw new Error(`public-export 종료 코드와 누수 결과 불일치: rc=${code} leaks=${report.leaks}`);
|
|
115
119
|
return { mainSha, files: report.files, leaks: report.leaks, codeLiterals: report.codeLiterals?.hits ?? 0 };
|
|
@@ -27,7 +27,8 @@ export function reserveReleaseResumeAttempt(state: GraphRunState, root: string,
|
|
|
27
27
|
const priorCountKnown = hadLedger ? saved.priorCountKnown !== false : !state.resume;
|
|
28
28
|
if (options.checkOnly) return { attempt: saved.attempts.length + 1, path, priorCountKnown };
|
|
29
29
|
const at = (options.now ?? (() => new Date()))().toISOString();
|
|
30
|
-
|
|
30
|
+
// `...saved` keeps fields this function does not own (RELEASE-RECOVER-ONE-CMD stage results) across a resume.
|
|
31
|
+
const next = { ...saved, version, runId: state.runId, priorCountKnown, attempts: [...saved.attempts, at] };
|
|
31
32
|
mkdirSync(dirname(path), { recursive: true });
|
|
32
33
|
const temp = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
33
34
|
try { writeFileSync(temp, `${JSON.stringify(next)}\n`, { mode: 0o600 }); renameSync(temp, path); }
|