elanous 0.2.38 → 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/{RrjXTwz-urRAbChP1bX02 → HjeK7zONHfR7op1hKXp4k}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{7954.4f7a8832663ee979.js → 1060.014f1f01a17aec26.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{8911.bf5e712acb25fb6c.js → 1281.d81877e35b9068f4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2104.70e086d5174a4736.js → 1350.59f40e39e02d91b1.js} +1 -1
- 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/2047.8f23e210995d4548.js +2 -0
- package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1632.7d87f998e714bede.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/{8019.21ca554a821dad01.js → 2177.df8547f9d7215c4e.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3528.e4b8ab70d339f965.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/{6493.27ad77de7aac7966.js → 2499.02fbfd18126c10c0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7628.6b16863ac3972333.js → 2522.f2766b76d22c8bdf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3086.fb14b60ce98b53d3.js → 2566.beaffc3a5e1fcd2e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9299.24e2a7d9b6d1f91b.js → 261.0d471e8aded799f3.js} +3 -3
- 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/2774-719820e3f5b2a3eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2829-734fe8bf2eee7347.js +1 -0
- 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/{7524.ce973525d30b3d52.js → 3330.7443183b7e6fdbdf.js} +1 -1
- 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/{3124-561f7f037943cde2.js → 3746-f80a78f220bf37b5.js} +1 -1
- 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/{bb6987f9.3647e1a23b0e3217.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/{8994d93e.33ba491f95345fc2.js → 409c787b.e48c5bec8ec10456.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5041-5aada92ca215ffdd.js → 413-24c8284bda08241d.js} +1 -1
- 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/{5638.107314dc479e2f37.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/{8487.291666583bebe640.js → 4769.9fd582071301f382.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{8509.3a54d4e61893d7cb.js → 483.725e4a61be922788.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9fe1b809.738da85c8b17e3fb.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/{8879.ac06755bcf3e44a1.js → 5383.bdfa5d886e39a826.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6142.913b44e260a3f925.js → 5436.fdf6fa8ae3e9588d.js} +1 -1
- 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/{7161-8f22db3ec5ed005e.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/{3291.f6c1005387d514bd.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/{5203.51e5d8b5f1dcfe53.js → 6749.0744ce6eb08d40e9.js} +3 -3
- 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/{1938.0e6c60ee91c4d7f5.js → 6908.06008c67f6380ea9.js} +2 -2
- 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/{de8b930d.d94c0f42acf807fc.js → 6cc1d1d6.9a98dd4622f1afc6.js} +1 -1
- 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/{1026-44010f405704050c.js → 8272-025653884f9645d2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5307.d7328020227880c2.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/{4199-f7c6eb40cd0322f8.js → 8639-92c11d069792429e.js} +1 -1
- 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/9175.2de5209a5ce6f68a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9184.45afbf44fec87574.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{eaad0cba.771200940c529df7.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-866aac5ff226a7f3.js → page-ba957ff875a026a0.js} +1 -1
- 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-4edb8df90f4537ce.js +1 -0
- 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-fca2e59a81744d9e.js +1 -0
- 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-139d722de1dcd6c1.js +1 -0
- 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-ccde99f07aaf71f7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b7478fef.5917716286213fcc.js → b84cad00.594027ebe0531fe2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/c696986b.5dc8bb1143af16d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b7459770.6539b11860eb8a9c.js → ca3702f8.2913182e73889fa2.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/{3f0de3de-2340c532c00395db.js → d5d3cefc-373c4eb722ed848b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{89d6c04f-6b8ab341748e468a.js → d8de0de2-dd0f4ac8e5ab1832.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{framework-4b12a946f352cee2.js → framework-002b472a66935d31.js} +1 -1
- 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/video/explainer-line.yaml +4 -1
- package/package.json +1 -1
- package/scripts/dead-code/report.ts +169 -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/public-export.ts +15 -7
- package/scripts/release-loop/export-check-node.ts +21 -3
- package/scripts/release-loop/gate-node.ts +379 -48
- 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-release.ts +20 -5
- package/scripts/release-loop/resume.ts +48 -0
- package/scripts/release-loop/version-node.ts +7 -2
- 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/src/acp/core-turn-bridge.ts +8 -0
- 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/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 +75 -6
- 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/self-review-cli.ts +226 -17
- 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 +22 -3
- package/src/auto-research/research-turn.ts +350 -17
- package/src/autopilot/agent-loop.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/budget/llm-cost.ts +44 -5
- package/src/budget/unified-usage.ts +17 -1
- package/src/capture/tui-self-report.ts +14 -0
- package/src/chat/index.ts +33 -7
- package/src/cli/agent-cli.ts +43 -8
- package/src/cli/intake-cli.ts +22 -1
- package/src/cli/lesson-cli.ts +19 -3
- package/src/cli/log-event-names.ts +1 -0
- package/src/cli/pod-cli.ts +17 -2
- package/src/cli/pty-takeover-cli.ts +67 -7
- package/src/cli/release-cli.ts +52 -6
- package/src/cli/repo-cli.ts +2 -1
- package/src/cli/tasks-cli.ts +36 -9
- package/src/control-plane/ledger.ts +21 -4
- package/src/core-turn/run-core-turn.ts +44 -3
- package/src/core-turn/run-goal-loop.ts +152 -8
- package/src/core-turn/types.ts +9 -0
- package/src/dashboard/chat/acp-chat.ts +2 -2
- package/src/dashboard/classic-sigquit.ts +16 -0
- package/src/dashboard/index.ts +321 -27
- 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/sidetab-runtime.ts +228 -0
- package/src/dashboard/slash-runtime/ask-clarification.ts +7 -1
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +20 -8
- package/src/dashboard/slash-runtime/help-from-registry.ts +2 -2
- package/src/dashboard/term-slash-runtime.ts +16 -18
- package/src/dashboard/turn-preamble.ts +2 -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/graph-runner/graph-cli.ts +6 -4
- package/src/graph-runner/runner.ts +31 -9
- 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 +5 -0
- 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/index.ts +18 -4
- package/src/input/external-input-queue.ts +10 -0
- package/src/intake-plane/collect-telegram-saved.ts +36 -1
- package/src/intake-plane/intake-to-tasks.ts +246 -3
- 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.ts +431 -76
- package/src/loops/orchestrator/tick.ts +8 -0
- package/src/nexus/api/harness-api.ts +2 -1
- package/src/pty/snapshot.py +132 -0
- package/src/pty-shell/pty-control-ipc.ts +29 -2
- package/src/pty-shell/pty-manifest.ts +59 -3
- 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/merged-pr-checklist.ts +25 -2
- package/src/release-loop/rehearsal-shard-plan.ts +6 -1
- package/src/release-loop/rehearsal.ts +27 -0
- package/src/research/edge-decision.ts +124 -15
- 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/plugin-discovery.ts +242 -0
- package/src/research-bridge/invoke.ts +4 -2
- package/src/research-bridge/types.ts +2 -0
- package/src/self-dev/ask-launch-flow.ts +34 -106
- package/src/self-dev/dev-cli.ts +2 -0
- package/src/self-dev/dev-pipeline.ts +8 -4
- 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/run-supervisor.ts +19 -0
- package/src/self-implement/device-first.ts +8 -2
- package/src/self-implement/doctor-visit.ts +76 -58
- package/src/self-implement/gate-artifacts.ts +3 -0
- package/src/self-implement/gate-baseline.ts +75 -4
- package/src/self-implement/gate-cli.ts +317 -9
- package/src/self-implement/gate-receipt-registry.ts +180 -0
- package/src/self-implement/gate-remote.ts +145 -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 +9 -5
- 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 +189 -10
- package/src/self-implement/off-diff-evidence.ts +124 -0
- package/src/self-implement/orchestrator.ts +85 -7
- package/src/self-implement/run-ledger.ts +46 -8
- package/src/self-implement/run-stop.ts +12 -0
- package/src/self-implement/seams.ts +6 -3
- package/src/self-implement/self-implement-cli.ts +4 -2
- package/src/session/chat.ts +89 -15
- 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/tools/schedule-wakeup.ts +23 -1
- package/src/skills/tools/shell.ts +51 -5
- package/src/steward/directive-audit.ts +354 -0
- package/src/surface/child-process.ts +31 -0
- package/src/surface/tui-stderr-owner.ts +48 -0
- package/src/task-agent/cover.ts +30 -12
- package/src/task-agent/judge.ts +56 -0
- 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 +1 -1
- package/src/task-agent/task-hand.ts +129 -24
- package/src/task-agent/tier-split.ts +105 -21
- 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 +27 -2
- package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +11 -8
- 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 +186 -33
- package/src/tool-runtime/skill-exec-runtime.ts +95 -5
- package/src/tui/entry.ts +15 -2
- package/src/tui/inline-choice.ts +188 -0
- package/src/tui/sidetab/list.ts +2 -176
- package/src/tui/slash/term.ts +12 -1
- package/src/tui-client/dashboard-session.ts +7 -1
- package/src/user-config.ts +34 -4
- 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/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 +8 -13
- 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/1118.a8a74ea29aac3e46.js +0 -27
- package/apps/pwa/out/_next/static/chunks/1204-2aa830479adf80f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1341-43b7d2dc77d45c9d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1440-c3ea8882badfd9bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1698-9c11cbf97f13717e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1770-3b1fc92253ef9f2f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1923-5c1695332240246a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/213-20675f20673ba22a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/214.186a430da28338f1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2277.3bd4c0ac7f1b5996.js +0 -93
- package/apps/pwa/out/_next/static/chunks/240.e09f433f71c78ff4.js +0 -104
- package/apps/pwa/out/_next/static/chunks/2415.738b777642a02233.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2417.02151393605a7cd0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2463.cd2641a76daaa9ff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2576.b9e9c629c4b84c52.js +0 -1
- package/apps/pwa/out/_next/static/chunks/265-c021de53f0865bd9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2998-b1cc13956cd6a6e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2e4782d3.ba2f0ab2b63a53e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3130.626b54382b4dc379.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3221-1bb3f99a55088613.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3280.24edb1ffd03a7f3f.js +0 -24
- package/apps/pwa/out/_next/static/chunks/3288-eb3c22a1cbf2ae68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/33.ef99e8374f96c6c4.js +0 -36
- package/apps/pwa/out/_next/static/chunks/3341-f09b9efbd7a82f70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3389.012c70767a872f9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3410-d7c0f14b329d6fda.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3421.c87d6313a7d670f7.js +0 -287
- package/apps/pwa/out/_next/static/chunks/3422-83a3953f9bd67e26.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3587-002e24e368c515a9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3644.f12a7d821ab940af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3660.d7516588e2d875c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3695.b82e2610f4cd4ea9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3858.ca1f5bc0f577eac9.js +0 -94
- package/apps/pwa/out/_next/static/chunks/3959-e6ac4a139d9d4bcc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4032.53f62176514ec0ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4204-ef8484cbecd5d62f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4259-163129ca79913c4b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/428-eaa77df3d0c85969.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4432-97e400ffa1e161f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/449-aa427cf2cbb75f50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4491-39a0fd32bbaf3840.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4588.b7cf06d382953979.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4690.70ec8060825366ab.js +0 -32
- package/apps/pwa/out/_next/static/chunks/4804.6012b5cd33c22792.js +0 -90
- package/apps/pwa/out/_next/static/chunks/4881.e4d22d730e3b9df5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4937.ce2e340dc29cad3e.js +0 -79
- package/apps/pwa/out/_next/static/chunks/5-bb1c08d84bd71df3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5005.de98df23b37cdf3c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5035.dc64a89cad5573cc.js +0 -74
- package/apps/pwa/out/_next/static/chunks/5207.1a224035455790fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5255-1b60d50eabe9f057.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5269.d0436ee6d773382a.js +0 -286
- package/apps/pwa/out/_next/static/chunks/5300.677c97e0393742e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5309.3367c4d50f52b489.js +0 -1
- package/apps/pwa/out/_next/static/chunks/552-689827d49780fa00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5539.34cc9d60622cb69b.js +0 -8
- package/apps/pwa/out/_next/static/chunks/5568.218dea0c00ca2ec7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5645.b7e3b055455a04ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5662.18cc0f30353cbd96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5671.da24fc9dc5e98325.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5b141171.324c40fd49cb6821.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6175-d4621f6a10b0cfab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6290.3eb53a20746b72ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6415-9307f3eafa90837f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6579-3de35d00aacd71b5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/680-2f324c4e039a5b67.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6845-331b3c7481da3ba3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7000.28157393caaf5343.js +0 -62
- package/apps/pwa/out/_next/static/chunks/7311-60a7ea80d23c7521.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7401.525d0a12f7d02c06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7438.c2cf72b66dca6aa4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7488.966b116789f3d41a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7573.2376e13c9c21f1f8.js +0 -77
- package/apps/pwa/out/_next/static/chunks/7577.ea6e9ac72e035520.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7657.8d1fb3d2f7ebe273.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7903-1435d5d2f0dd7807.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7978-30a91192c5dbe3c2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8025-8795821525cf1a07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8191.3674a00f0b565c23.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8217-604955d8885c5ef2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8298-eed6f5f2585a63f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8758.ac421f726a189125.js +0 -1
- package/apps/pwa/out/_next/static/chunks/891.d6c723a51a067b36.js +0 -149
- package/apps/pwa/out/_next/static/chunks/9223.cbcc88e0e9950426.js +0 -41
- package/apps/pwa/out/_next/static/chunks/9317.6a9869039c231bb3.js +0 -24
- package/apps/pwa/out/_next/static/chunks/9383.e4755f275b3c11ff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9581.da63ddf41acfad46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9715.8c5529a0a5c41a36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9817.3009d65f0889ef1f.js +0 -2
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76873dd80da4f715.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed32b6ec5dea8f23.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-fdd40e15babf3d25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-384efc78e85e400b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-d91809c5aeed319a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-128f3522f89a81ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-595961abf3b43ad1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-f41dccb76d8c0263.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-a3205c2e28b7d0d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-c39a80277814a3f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-1ab3f98194513195.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-a5246f7e254d77d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-0f92287bdb81217d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-5a37131ff63793ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-76873dd80da4f715.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-ac4bd14bb2348bfd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c348a3959c5b5fc6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-2addd81c0d3e2906.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-da6b765f58a3eefb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-0661e40f8780c32c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-b89af1b1c8e4875b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-da8aeb82ba751cdb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-cc71317b239439db.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-bde7fc1d64ffe369.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-e2797214f713fa58.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-2a35bcda70defaf6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3af03deedde45032.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d1d1210f99f620ae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-46d1b5500885861d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-291ab19fe2acb173.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-7f569e533ddeecba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-990129c9fee46d8f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-7737f785ebb1cdaf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f3c73a4f7ffd2f8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-03be7fb347f01058.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-96b0280625e4df2b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-56855545049eb56d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-76873dd80da4f715.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-79a909c9981f0338.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-a9d9a3e66459c1e0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-c383cbf2013f7069.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f57c6a2e54dbdca4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-6b140f77593576eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-6b767ae2d9d0adfc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-116d6198d5da0e3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-b9c9b778c7501370.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-a6c78392ab8f6335.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-455183deb4ed0cfe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-6a63e99526bd63d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-31c22caafe788c08.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-941155250ed2644b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-f8b6765abed6d149.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-78432194c85388f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-cdf7390829512b1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-d5f0964a9c2e92d2.js +0 -1
- /package/apps/pwa/out/_next/static/{RrjXTwz-urRAbChP1bX02 → HjeK7zONHfR7op1hKXp4k}/_ssgManifest.js +0 -0
|
@@ -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 };
|
|
@@ -14,7 +14,7 @@ import { releaseRunUniverse } from './release-universe.js';
|
|
|
14
14
|
import { isReleaseVersion } from './release-version.js';
|
|
15
15
|
import { changedFilesBetween, clearPartialPlan, collectExecutedPodShardImages, planPartialRegate, planStalledShardRecheck, writePartialPlan, writeRecheckPlan } from './gate-partial.js';
|
|
16
16
|
import { gitClosureTree, testsReachingChanged, TRACEABLE_RELEASE_JSON, type ClosureTree } from './gate-closure.js';
|
|
17
|
-
import { releaseResumeAcceptedRegressions, releaseResumeGateExecutor, releaseResumeGatePodPool, releaseResumeWaiver, type AcceptedRegression } from './resume.js';
|
|
17
|
+
import { assertReleaseResumeApprovalBoundary, releaseResumeAcceptedRegressions, releaseResumeGateExecutor, releaseResumeGatePodPool, releaseResumeGateShardReroute, releaseResumeWaiver, type AcceptedRegression } from './resume.js';
|
|
18
18
|
import { reserveReleaseResumeAttempt } from './resume-cap.js';
|
|
19
19
|
import { cutReleaseBranch } from './cut-branch.js';
|
|
20
20
|
import { releaseLoopConfig } from './unattended-release.js';
|
|
@@ -55,6 +55,7 @@ export interface ResumeReleaseDeps {
|
|
|
55
55
|
export interface ResumeReleaseOptions {
|
|
56
56
|
runId: string; from: string; partial?: boolean; waive?: string; reason?: string;
|
|
57
57
|
acceptedRegressions?: AcceptedRegression[]; gateExecutor?: string; gateHost?: string; gatePodPool?: string;
|
|
58
|
+
rerouteShard?: string; shardHost?: string; shardOs?: 'darwin' | 'linux';
|
|
58
59
|
commandRoot?: string;
|
|
59
60
|
}
|
|
60
61
|
|
|
@@ -456,12 +457,16 @@ async function planResumeReleaseRunLocked(opts: ResumeReleaseOptions, deps: Resu
|
|
|
456
457
|
const statePath = join(deps.root!, 'graph-runs', 'release-loop', `${safeRunId(opts.runId)}.json`);
|
|
457
458
|
const savedRun = JSON.parse(readFileSync(statePath, 'utf8')) as GraphRunState;
|
|
458
459
|
if (savedRun.graphId !== 'release-loop' || savedRun.runId !== opts.runId) throw new Error(`run identity mismatch: ${statePath}`);
|
|
460
|
+
assertReleaseResumeApprovalBoundary({ ...savedRun, statePath }, opts.from);
|
|
459
461
|
if (opts.gateHost !== undefined && opts.gateExecutor === undefined) throw new Error('--gate-host requires --gate-executor host');
|
|
462
|
+
if ((opts.shardHost !== undefined || opts.shardOs !== undefined) && opts.rerouteShard === undefined)
|
|
463
|
+
throw new Error('--shard-host/--shard-os require --reroute-shard');
|
|
460
464
|
const hasOverrides = opts.waive !== undefined || opts.reason !== undefined || opts.acceptedRegressions !== undefined
|
|
461
|
-
|| opts.gateExecutor !== undefined || opts.gatePodPool !== undefined;
|
|
465
|
+
|| opts.gateExecutor !== undefined || opts.gatePodPool !== undefined || opts.rerouteShard !== undefined;
|
|
462
466
|
const original = hasOverrides ? savedRun : undefined;
|
|
463
467
|
if (original && opts.gateExecutor !== undefined) releaseResumeGateExecutor(original, { from: opts.from, executor: opts.gateExecutor, host: opts.gateHost });
|
|
464
468
|
if (original && opts.gatePodPool !== undefined) releaseResumeGatePodPool(original, { from: opts.from, pool: opts.gatePodPool });
|
|
469
|
+
if (original && opts.rerouteShard !== undefined) releaseResumeGateShardReroute(original, { from: opts.from, shard: opts.rerouteShard, host: opts.shardHost, os: opts.shardOs });
|
|
465
470
|
const waiver = original && (opts.waive !== undefined || opts.reason !== undefined) ? releaseResumeWaiver(original, opts) : undefined;
|
|
466
471
|
if (original && opts.acceptedRegressions !== undefined && !waiver)
|
|
467
472
|
releaseResumeAcceptedRegressions(original, opts.acceptedRegressions, opts.from);
|
|
@@ -478,10 +483,11 @@ async function planResumeReleaseRunLocked(opts: ResumeReleaseOptions, deps: Resu
|
|
|
478
483
|
waiverCommit = recorded;
|
|
479
484
|
}
|
|
480
485
|
const tip = refreshReleaseBranchTipInternal(opts.runId, deps, opts.from, waiverCommit, true);
|
|
486
|
+
if (opts.rerouteShard !== undefined && tip.changed) throw new Error('shard reroute requires the original cut head; moved tip needs a full re-gate');
|
|
481
487
|
verifyResumeRecipePin(opts.commandRoot ?? process.cwd(), savedRun.graphSnapshot, tip.version);
|
|
482
488
|
const commandRoot = verifyReleaseCommandRoot(opts.commandRoot ?? process.cwd(), tip.to, deps.git);
|
|
483
489
|
verifyResumePreflight(savedRun, opts, deps, tip.version, tip.from, tip.to, commandRoot);
|
|
484
|
-
const partial = preparePartial(tip, opts, deps, true);
|
|
490
|
+
const partial = preparePartial(tip, opts.rerouteShard !== undefined ? { ...opts, partial: false } : opts, deps, true);
|
|
485
491
|
const fromIndex = savedRun.path.indexOf(opts.from);
|
|
486
492
|
const gateIndex = savedRun.path.indexOf('gate');
|
|
487
493
|
const gateWillRun = fromIndex >= 0 && gateIndex >= fromIndex;
|
|
@@ -498,15 +504,20 @@ async function resumeReleaseRunLocked(opts: ResumeReleaseOptions, deps: ResumeRe
|
|
|
498
504
|
deps = { ...deps, root: releaseRunUniverse({ root: deps.root }) };
|
|
499
505
|
const statePath = join(deps.root!, 'graph-runs', 'release-loop', `${safeRunId(opts.runId)}.json`);
|
|
500
506
|
const savedRun = JSON.parse(readFileSync(statePath, 'utf8')) as GraphRunState;
|
|
507
|
+
assertReleaseResumeApprovalBoundary({ ...savedRun, statePath }, opts.from);
|
|
501
508
|
let waiverCommit: string | undefined;
|
|
502
509
|
if (opts.gateHost !== undefined && opts.gateExecutor === undefined) throw new Error('--gate-host requires --gate-executor host');
|
|
503
|
-
|
|
510
|
+
if ((opts.shardHost !== undefined || opts.shardOs !== undefined) && opts.rerouteShard === undefined)
|
|
511
|
+
throw new Error('--shard-host/--shard-os require --reroute-shard');
|
|
512
|
+
const original = opts.waive !== undefined || opts.reason !== undefined || opts.acceptedRegressions !== undefined || opts.gateExecutor !== undefined || opts.gatePodPool !== undefined || opts.rerouteShard !== undefined
|
|
504
513
|
? savedRun : undefined;
|
|
505
514
|
// GATE-HOST-EXECUTOR: checked before the tip refresh writes anything; the runner checks it again under the resume lock.
|
|
506
515
|
const gateExecutor = original && opts.gateExecutor !== undefined
|
|
507
516
|
? releaseResumeGateExecutor(original, { from: opts.from, executor: opts.gateExecutor, host: opts.gateHost }) : undefined;
|
|
508
517
|
const gatePodPool = original && opts.gatePodPool !== undefined
|
|
509
518
|
? releaseResumeGatePodPool(original, { from: opts.from, pool: opts.gatePodPool }) : undefined;
|
|
519
|
+
const shardReroute = original && opts.rerouteShard !== undefined
|
|
520
|
+
? releaseResumeGateShardReroute(original, { from: opts.from, shard: opts.rerouteShard, host: opts.shardHost, os: opts.shardOs }) : undefined;
|
|
510
521
|
if (gateExecutor) debug.log('release-loop.resume', 'gate-executor', { runId: opts.runId, from: opts.from, executor: gateExecutor.set.gateExecutor, host: gateExecutor.set.gateRemote ?? null, previous: gateExecutor.previous });
|
|
511
522
|
if (gatePodPool) debug.log('release-loop.resume', 'gate-pod-pool', {
|
|
512
523
|
runId: opts.runId, from: opts.from, pool: gatePodPool.set.gatePodPool, previous: gatePodPool.previous,
|
|
@@ -534,11 +545,12 @@ async function resumeReleaseRunLocked(opts: ResumeReleaseOptions, deps: ResumeRe
|
|
|
534
545
|
}
|
|
535
546
|
// The read-only tip and recipe pin preflight must pass before fetch or a saved-run rewrite.
|
|
536
547
|
const previewTip = refreshReleaseBranchTipInternal(opts.runId, deps, opts.from, waiverCommit, true);
|
|
548
|
+
if (shardReroute && previewTip.changed) throw new Error('shard reroute requires the original cut head; moved tip needs a full re-gate');
|
|
537
549
|
verifyResumeRecipePin(opts.commandRoot ?? process.cwd(), savedRun.graphSnapshot, previewTip.version);
|
|
538
550
|
const commandRoot = verifyReleaseCommandRoot(opts.commandRoot ?? process.cwd(), previewTip.to, deps.git);
|
|
539
551
|
verifyResumePreflight(savedRun, opts, deps, previewTip.version, previewTip.from, previewTip.to, commandRoot);
|
|
540
552
|
const tip = refreshReleaseBranchTipInternal(opts.runId, deps, opts.from, waiverCommit, false, previewTip.to);
|
|
541
|
-
const partial = preparePartial(tip, opts, deps);
|
|
553
|
+
const partial = preparePartial(tip, shardReroute ? { ...opts, partial: false } : opts, deps);
|
|
542
554
|
// A failed preflight does not consume an observed release resume attempt.
|
|
543
555
|
const attempt = reserveReleaseResumeAttempt(savedRun, deps.root!, { now: deps.now });
|
|
544
556
|
debug.log('release-loop.resume', 'attempt', { runId: opts.runId, attempt: attempt.attempt,
|
|
@@ -553,6 +565,9 @@ async function resumeReleaseRunLocked(opts: ResumeReleaseOptions, deps: ResumeRe
|
|
|
553
565
|
...(acceptedRegressions ? { releaseAcceptedRegressions: { requested: opts.acceptedRegressions!, acceptedRegressions } } : {}),
|
|
554
566
|
...(gateExecutor ? { releaseGateExecutor: { executor: gateExecutor.set.gateExecutor, ...(opts.gateHost !== undefined ? { host: opts.gateHost } : {}) } } : {}),
|
|
555
567
|
...(gatePodPool ? { releaseGatePodPool: gatePodPool.set.gatePodPool } : {}),
|
|
568
|
+
...(shardReroute ? { releaseGateShardReroute: { shard: shardReroute.set.gateRerouteShard,
|
|
569
|
+
...(shardReroute.set.gateShardHost ? { host: shardReroute.set.gateShardHost } : {}),
|
|
570
|
+
...(opts.shardOs ? { os: opts.shardOs } : {}) } } : {}),
|
|
556
571
|
deps: { root: deps.root, ...(deps.runBash ? { runBash: deps.runBash } : {}) } });
|
|
557
572
|
return { tip, partial, state };
|
|
558
573
|
}
|
|
@@ -1,9 +1,31 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
1
2
|
import { lastJsonObject, STOPPED_NODE_ERROR, type GraphRunState } from '../../src/graph-runner/runner.js';
|
|
2
3
|
import { publicWaiverReason } from './known-issues-node.js';
|
|
3
4
|
import { checkGateExecutorChoice, type GateExecutor } from './gate-executor.js';
|
|
4
5
|
|
|
5
6
|
export interface AcceptedRegression { id: string; note: string }
|
|
6
7
|
|
|
8
|
+
/** Match the graph runner's approval boundary before release resume performs tip refresh or writes an attempt. */
|
|
9
|
+
export function assertReleaseResumeApprovalBoundary(state: GraphRunState, from: string): void {
|
|
10
|
+
if (!Array.isArray(state.path)) return;
|
|
11
|
+
const start = state.path.indexOf(from);
|
|
12
|
+
if (start < 0 || state.path.lastIndexOf(from) !== start) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
for (let index = 0; index < state.nodes.length; index++) {
|
|
16
|
+
const record = state.nodes[index]!;
|
|
17
|
+
if (typeof record.decidedAt !== 'string') continue;
|
|
18
|
+
if (index >= start) throw new Error('cannot restart across an approval decision — start a new release run with the full gate');
|
|
19
|
+
if (!record.ok) throw new Error('cannot preserve a failed predecessor when resuming');
|
|
20
|
+
let decision: { nodeId?: unknown; decision?: unknown; decidedAt?: unknown };
|
|
21
|
+
try { decision = JSON.parse(readFileSync(`${state.statePath}.${index + 1}.decision.json`, 'utf8')); }
|
|
22
|
+
catch { throw new Error(`missing approval decision for ${record.nodeId}`); }
|
|
23
|
+
if (decision.nodeId !== record.nodeId || decision.decision !== 'approved' || decision.decidedAt !== record.decidedAt) {
|
|
24
|
+
throw new Error(`invalid approval decision for ${record.nodeId}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
7
29
|
/** Merge explicit public issues with the saved release input without changing the ledger shape. */
|
|
8
30
|
export function releaseResumeAcceptedRegressions(state: GraphRunState, additions: AcceptedRegression[], from?: string): AcceptedRegression[] {
|
|
9
31
|
if (!Array.isArray(additions) || additions.some((issue) => !issue || typeof issue.id !== 'string' || !issue.id.trim() || typeof issue.note !== 'string' || !issue.note.trim())) {
|
|
@@ -154,6 +176,32 @@ export interface GatePodPoolOverride {
|
|
|
154
176
|
previous: { gatePodPool: unknown };
|
|
155
177
|
}
|
|
156
178
|
|
|
179
|
+
/** One shard keeps its component identity while the run-time scheduler chooses a compatible member. */
|
|
180
|
+
export interface GateShardRerouteOverride {
|
|
181
|
+
kind: 'gate-shard-reroute'; at: string; from: string;
|
|
182
|
+
set: { gateRerouteShard: string; gateShardHost?: string; gateShardCapabilities?: Record<string, { os: 'darwin' | 'linux' }> };
|
|
183
|
+
previous: { gateRerouteShard: unknown; gateShardHost: unknown; gateShardCapabilities: unknown };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function releaseResumeGateShardReroute(state: GraphRunState, opts: {
|
|
187
|
+
from: string; shard: unknown; host?: unknown; os?: unknown; at?: string;
|
|
188
|
+
}): GateShardRerouteOverride {
|
|
189
|
+
const input = state.input as Record<string, unknown> | undefined;
|
|
190
|
+
if (!input || typeof input.gatePodPool !== 'string' || !input.gatePodPool.trim())
|
|
191
|
+
throw new Error('shard reroute requires the saved Pod gate pool');
|
|
192
|
+
if (opts.from !== 'gate' || !state.path.includes('gate')) throw new Error('shard reroute requires --from gate');
|
|
193
|
+
if (typeof opts.shard !== 'string' || !/^(?:auto|pod-\d+)$/.test(opts.shard))
|
|
194
|
+
throw new Error('--reroute-shard requires auto or pod-N');
|
|
195
|
+
if (opts.host !== undefined && (typeof opts.host !== 'string' || !opts.host.trim())) throw new Error('--shard-host requires a pool context');
|
|
196
|
+
if (opts.os !== undefined && (opts.shard === 'auto' || opts.os !== 'darwin' && opts.os !== 'linux'))
|
|
197
|
+
throw new Error('--shard-os requires pod-N and darwin or linux');
|
|
198
|
+
return { kind: 'gate-shard-reroute', at: opts.at ?? new Date().toISOString(), from: opts.from,
|
|
199
|
+
set: { gateRerouteShard: opts.shard, ...(opts.host ? { gateShardHost: opts.host.trim() } : {}),
|
|
200
|
+
...(opts.os ? { gateShardCapabilities: { [opts.shard]: { os: opts.os } } } : {}) },
|
|
201
|
+
previous: { gateRerouteShard: input.gateRerouteShard ?? null, gateShardHost: input.gateShardHost ?? null,
|
|
202
|
+
gateShardCapabilities: input.gateShardCapabilities ?? null } };
|
|
203
|
+
}
|
|
204
|
+
|
|
157
205
|
export function releaseResumeGatePodPool(state: GraphRunState, opts: { from: string; pool: unknown; at?: string }): GatePodPoolOverride {
|
|
158
206
|
const input = state.input;
|
|
159
207
|
if (!input || typeof input !== 'object' || Array.isArray(input) || typeof (input as { version?: unknown }).version !== 'string') throw new Error('release run has no input');
|
|
@@ -465,14 +465,19 @@ export function main(args: string[] = process.argv.slice(2), repo = process.cwd(
|
|
|
465
465
|
const location = process.env.ELANOUS_GRAPH_CONTEXT;
|
|
466
466
|
const context = JSON.parse(location.trimStart().startsWith('{') ? location : readFileSync(location, 'utf8')) as {
|
|
467
467
|
runId?: unknown; input?: { version?: unknown; cutCommit?: unknown; forceFreeze?: unknown; branchCut?: unknown };
|
|
468
|
-
outputs?: Record<string, { commit?: unknown; base?: unknown; branch?: unknown } | undefined> };
|
|
468
|
+
outputs?: Record<string, { outcome?: unknown; commit?: unknown; base?: unknown; branch?: unknown } | undefined> };
|
|
469
469
|
if (context.runId !== undefined) {
|
|
470
470
|
if (typeof context.runId !== 'string') throw new Error('runId must be a string');
|
|
471
471
|
runId = context.runId;
|
|
472
472
|
}
|
|
473
473
|
if (!version && typeof context.input?.version === 'string') version = context.input.version;
|
|
474
474
|
forceFreeze = context.input?.forceFreeze === true;
|
|
475
|
-
|
|
475
|
+
const releasedBranch = context.outputs?.['version-release']?.branch;
|
|
476
|
+
branchCut = context.input?.branchCut === true
|
|
477
|
+
|| (kind === 'dev-bump'
|
|
478
|
+
&& context.outputs?.['version-release']?.outcome === 'ok'
|
|
479
|
+
&& typeof version === 'string'
|
|
480
|
+
&& releasedBranch === `release/${version}`);
|
|
476
481
|
if (kind === 'release' && cutCommit === undefined && context.input?.cutCommit !== undefined) {
|
|
477
482
|
if (typeof context.input.cutCommit !== 'string') throw new Error('cutCommit must be a commit SHA');
|
|
478
483
|
cutCommit = context.input.cutCommit;
|
|
@@ -46,7 +46,7 @@ function userFacingLines(markdown: string): { lines: string[]; internalDropped:
|
|
|
46
46
|
if (text) internalDropped++;
|
|
47
47
|
return [];
|
|
48
48
|
}
|
|
49
|
-
const publicText = text.replace(/\s+["'“]?Target:\s*next\.["'”]?\s
|
|
49
|
+
const publicText = text.replace(/\s+["'“]?Target:\s*next\.["'”]?(?=\s*(?:\([^)]*\))?\s*$)/i, '')
|
|
50
50
|
.replace(/\s+["'“]?Documentation:\s*.*\.["'”]?\s*$/i, '').trim()
|
|
51
51
|
.replace(/^(?:feat|fix)\s*—\s*/i, '');
|
|
52
52
|
return publicText ? [publicText] : [];
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
신설: scripts/research-bench/README.md
|
|
2
|
+
# Research harness benchmark
|
|
3
|
+
|
|
4
|
+
## SCQA
|
|
5
|
+
|
|
6
|
+
**S** — The 10/31 positioning decision needs evidence about Elanous research quality and its Bloom-native research design.
|
|
7
|
+
|
|
8
|
+
**C** — A product-default comparison mixes harness and model effects. Bloom stages and graph layouts also need isolated comparisons under one model and fixed questions.
|
|
9
|
+
|
|
10
|
+
**Q** — How do we compare the products, measure Bloom's contribution, and test the recommended stage layout under either the default API cap or an explicitly approved uncapped run?
|
|
11
|
+
|
|
12
|
+
**A** — Run the same ten questions across a controlled pair, Bloom ablation, product-default pair, and Elanous layout ablation. Start with three questions, review the measurement, then run all ten. Keep manifests, raw answers, scores, latency, and spend in private evidence.
|
|
13
|
+
|
|
14
|
+
## Experiment matrix
|
|
15
|
+
|
|
16
|
+
| Cell | Comparison | Bloom instruction | Layout | Harnesses |
|
|
17
|
+
|---|---|---|---|---|
|
|
18
|
+
| A0 | Controlled baseline and no-Bloom ablation | None | Baseline | Elanous + Claude Code, both Opus 5.5 |
|
|
19
|
+
| A1 | Bloom ablation | Stages 1–3 | Baseline | Elanous + Claude Code, both Opus 5.5 |
|
|
20
|
+
| A2 | Bloom ablation | Stages 1–5 | Baseline | Elanous + Claude Code, both Opus 5.5 |
|
|
21
|
+
| A3 | Bloom ablation | Stages 1–6 | Baseline | Elanous + Claude Code, both Opus 5.5 |
|
|
22
|
+
| B | Product comparison | None | Product defaults | Elanous installed default + Claude Code defaults |
|
|
23
|
+
| P1 | Layout ablation | Stages 1–6 | Linear 1→6 | Elanous, Opus 5.5 |
|
|
24
|
+
| P5 | Layout ablation | Stages 1–6 | Front 6 reverse design; parallel 1/3; 4/5 loop; final 6 | Elanous, Opus 5.5 |
|
|
25
|
+
| P5-no-front6 | Layout ablation | Stages 1–6 | P5 without front 6 | Elanous, Opus 5.5 |
|
|
26
|
+
|
|
27
|
+
A0 is also the no-Bloom ablation baseline. A1–A3 add cumulative Bloom scaffolding to the same question; the question text stays unchanged. The product cell uses Elanous's installed default configuration (gpt-6-luna) against Claude Code defaults; it is not a controlled model comparison. OP deferred role-routed Elanous best-config measurement to B2 after 0.2.40. Layout cells measure Elanous architecture only. The 10 questions cover finance, technology, and market; at least four require analysis/evaluation.
|
|
28
|
+
|
|
29
|
+
## Run order and budget
|
|
30
|
+
|
|
31
|
+
- Pilot: the first-listed question in each of the finance, technology, and market domains across all eight cells, 39 total invocations (24 Elanous API calls, 15 Claude subscription calls).
|
|
32
|
+
- Execution-validation smoke: a configurable number of first-listed questions in A0 only, each as one matched Claude/Elanous pair. This checks runtime, timeout recovery, and cost collection; do not score it.
|
|
33
|
+
- Full: 10 questions in all eight cells, 130 total invocations (80 Elanous API calls, 50 Claude subscription calls).
|
|
34
|
+
- Default runs use the approved Elanous API cap of $200. After each Elanous call, read its `llm-usage` event, calculate token cost at official rates, and append to the private ledger. Do not start the next pair once cumulative Elanous API spend reaches $160 (80%). Finish the current matched pair. Claude Code subscription calls are recorded at $0 API spend and do not consume that cap. Use `--no-cost-cap` only when OP explicitly authorizes an uncapped run; manifests and ledgers mark both cap fields `null`.
|
|
35
|
+
- Opus 5.5 rates are $4/MTok input, $20/MTok output, $5/MTok 5-minute cache writes, and $0.20/MTok cache reads. The official price table is [Anthropic prompt-cache pricing](https://platform.claude.com/docs/en/build-with-claude/prompt-caching) and [Claude Opus pricing](https://www.anthropic.com/claude/opus). Other Elanous models use the price estimate in their `llm-usage` event; an unknown API price stops the run.
|
|
36
|
+
- Pair order alternates for the controlled cells by question and cell. Every invocation starts a fresh session. Never pass one answer to another run.
|
|
37
|
+
- Collect per-cell rubric scores, actual provider spend, elapsed time, source count/quality, resolution level, tool traces, and failure/unknown notes. Report paired deltas and uncertainty; ten questions do not support broad population claims.
|
|
38
|
+
|
|
39
|
+
## Commands
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
bun scripts/research-bench/run.ts --dry-run
|
|
43
|
+
bun scripts/research-bench/run.ts --live --smoke-pairs 3 --baseline-sha <main-commit-sha> --config <private-config.json> --no-cost-cap --approval-ref OP#42096 --out ~/elanous-hq/seat-state/OP/evidence/20261026/askop-model-vs-harness
|
|
44
|
+
bun scripts/research-bench/run.ts --live --pilot --baseline-sha <main-commit-sha> --config <private-config.json> --max-total-cost-usd 200 --out ~/elanous-hq/seat-state/OP/evidence/20261026/askop-model-vs-harness
|
|
45
|
+
bun scripts/research-bench/run.ts --live --pilot --baseline-sha <main-commit-sha> --config <private-config.json> --no-cost-cap --approval-ref OP#42096 --out ~/elanous-hq/seat-state/OP/evidence/20261026/askop-model-vs-harness
|
|
46
|
+
bun scripts/research-bench/run.ts --live --full --baseline-sha <main-commit-sha> --config <private-config.json> --max-total-cost-usd 200 --out ~/elanous-hq/seat-state/OP/evidence/20261026/askop-model-vs-harness
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The private config is version 2 and has adapters for A0, A1, A2, A3, B, P1, P5, and P5-no-front6, plus a baseline version probe. The probe must report the exact `--baseline-sha` requested before any live invocation starts. Smoke validation selects one question each from finance, technology, and market (one to three pairs), and its results are not scored. Adapter arguments are arrays, never shell strings; `{prompt}` is required and the other values may be interpolated when the adapter supports them. Each adapter declares model, tool-policy ID, turn limit, timeout, and a usage source. A0–A3 use Opus 5.5, eight tool turns, a 10-minute timeout, and a common research tool-policy ID; the Elanous config sets the Anthropic turn cap to eight, while Claude Code uses `--max-turns 8`. Elanous adapters query `eln logs --category llm.usage --event llm-usage --json --json-data --session {sessionId}` after each invocation; Claude Code adapters emit `stream-json` usage. Tool names differ slightly between CLI surfaces (Elanous `ListDir`, Claude Code `LS`); each call records the model reported by its usage source and token usage, using `unknown` when the source omits the model. Product defaults may differ by design.
|
|
50
|
+
|
|
51
|
+
## Scoring and evidence
|
|
52
|
+
|
|
53
|
+
Use `rubric.md` with blinded harness/model labels. Two raters score independently; a third resolves any two-point disagreement. Report per-question and per-dimension results, latency, and actual API spend. Outputs go only to private `seat-state/OP/evidence/`; never commit provider answers. Keep question and rubric versions fixed for regression comparisons.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "finance-01-kgb-10y",
|
|
4
|
+
"domain": "finance",
|
|
5
|
+
"bloom": ["remember", "understand", "analyze", "evaluate", "create"],
|
|
6
|
+
"requiresHigherOrder": true,
|
|
7
|
+
"prompt": "현재 기준으로 한국 국고채 10년물 금리의 최근 30일 변화를 조사하라. 공신력 있는 시계열 값과 날짜를 먼저 제시하고, 움직임을 설명하는 요인을 데이터로 분해하라. 가장 강한 대안 설명과 반대 근거를 포함하고, 향후 3개월의 조건부 시나리오를 제시하되 투자 권유는 하지 마라. 핵심 주장마다 원문 출처 URL과 기준 시각을 붙여라."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "finance-02-usdkrw",
|
|
11
|
+
"domain": "finance",
|
|
12
|
+
"bloom": ["remember", "understand", "apply", "analyze", "evaluate"],
|
|
13
|
+
"requiresHigherOrder": true,
|
|
14
|
+
"prompt": "현재 기준 최근 90일 원/달러 환율 변화를 조사하고, 달러지수·미 국채금리·한국 수출 및 자금 흐름이 각각 설명하는 부분을 구분하라. 인과관계와 동시 움직임을 혼동하지 말고, 각 설명을 지지하는 자료와 반대 사례를 대조하라. 근거가 부족한 요인은 미확인으로 남기고, 출처 URL·값·날짜를 제시하라."
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "finance-03-korean-memory-producers",
|
|
18
|
+
"domain": "finance",
|
|
19
|
+
"bloom": ["remember", "understand", "apply", "analyze", "evaluate", "create"],
|
|
20
|
+
"requiresHigherOrder": true,
|
|
21
|
+
"prompt": "현재 공개된 최신 실적 기준으로 삼성전자와 SK하이닉스의 메모리 사업을 비교하라. 매출·수익성·제품 믹스·CAPEX 등 비교 가능한 수치를 같은 기간으로 정렬하고, 차이의 원인을 분해하라. 두 회사 각각에 유리한 반대 근거와 데이터 공백을 포함하고, 다음 두 분기에 관찰할 지표와 조건부 시나리오를 제안하라. 투자 권유는 하지 말고 원문 출처·기간·단위를 표시하라."
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "technology-01-hbm4",
|
|
25
|
+
"domain": "technology",
|
|
26
|
+
"bloom": ["remember", "understand", "apply", "analyze", "evaluate", "create"],
|
|
27
|
+
"requiresHigherOrder": true,
|
|
28
|
+
"prompt": "HBM4의 현재 개발·양산·고객 인증 상태와 공급망 병목을 1차 자료 중심으로 조사하라. 발표·샘플·인증·양산을 서로 다른 상태로 구분하고, 메모리 업체·패키징·가속기 공급망의 인과 관계를 설명하라. 일정 지연 또는 채택 축소를 뒷받침하는 반대 근거도 찾고, 2027년까지 확인 가능한 관측 지표와 시나리오를 제시하라."
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "technology-02-coding-agent-adoption",
|
|
32
|
+
"domain": "technology",
|
|
33
|
+
"bloom": ["remember", "understand", "apply", "analyze", "evaluate"],
|
|
34
|
+
"prompt": "2025년 이후 코딩 에이전트의 실제 조직 도입과 생산성 효과를 조사하라. 벤더 발표·설문·독립 실험을 출처 유형별로 분리하고, 표본·측정 정의·선택 편향을 비교하라. 생산성 향상 주장에 대한 반대 결과와 보안·검토 비용도 포함하고, 근거가 말할 수 있는 범위를 제안하라. 핵심 수치에는 모집단·기간·원문 URL을 붙여라."
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "technology-03-inference-economics",
|
|
38
|
+
"domain": "technology",
|
|
39
|
+
"bloom": ["remember", "understand", "apply", "analyze", "evaluate", "create"],
|
|
40
|
+
"prompt": "최근 12개월의 frontier 및 open-weight 모델 추론 비용·성능 변화를 비교하라. 공개 가격표와 재현 가능한 독립 평가를 분리하고, 토큰 가격·지연·품질·하드웨어 이용률이 실제 총비용에 미치는 영향을 계산 가능한 단위로 제시하라. '더 싸다'는 주장에 대한 반례와 작업별 차이를 분석하고, 12개월의 조건부 시나리오를 제시하라."
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "market-01-enterprise-research-agents",
|
|
44
|
+
"domain": "market",
|
|
45
|
+
"bloom": ["remember", "understand", "analyze", "evaluate", "create"],
|
|
46
|
+
"prompt": "기업용 조사·리서치 에이전트 시장의 규모와 성장률 주장을 비교하라. 최소 세 출처의 정의·포함 제품·기준 연도·예측 기간을 대조하고, 같은 시장을 측정하는지 판단하라. 도입 사례와 실사용 효과의 독립 근거를 벤더 전망과 분리하고, 가장 큰 불확실성 및 반대 근거를 제시하라."
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "market-02-korean-enterprise-automation",
|
|
50
|
+
"domain": "market",
|
|
51
|
+
"bloom": ["remember", "understand", "apply", "analyze", "evaluate", "create"],
|
|
52
|
+
"prompt": "한국 기업의 에이전트형 AI 업무 자동화에서 현재 가치가 검증된 부문을 조사하라. 금융·제조·고객지원 등 최소 세 부문에서 실제 배포, 실험, 계획 발표를 구분하고, 도입 전후의 비용·시간·오류 지표를 찾아라. 규제·데이터·통합 비용과 효과가 없었던 사례도 포함하고, 다음 12개월에 검증할 측정 설계를 제안하라."
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"id": "market-03-ai-research-assistants",
|
|
56
|
+
"domain": "market",
|
|
57
|
+
"bloom": ["remember", "understand", "apply", "analyze", "evaluate"],
|
|
58
|
+
"prompt": "AI 조사 보조 제품군의 최근 경쟁 구도를 조사하라. 제품 기능 나열 대신 출처 발견·교차검증·기억·도구 실행·인용 정확도·가격을 축으로 비교하라. 독립 평가와 공식 문서를 구분하고, 강점 주장을 뒤집을 수 있는 반례 및 기능 미지원 증거를 찾으라. 사용 사례별로 승자를 달리 제시하고 근거 수준을 표시하라."
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "market-04-agentic-knowledge-work",
|
|
62
|
+
"domain": "market",
|
|
63
|
+
"bloom": ["understand", "apply", "analyze", "evaluate", "create"],
|
|
64
|
+
"prompt": "지식 노동에서 조사 에이전트가 검색·분석·보고 과정을 바꾸는 방식을 조사하라. 현장 도입 사례와 통제된 연구를 분리하고, 어떤 작업은 자동화되고 어떤 판단은 사람에게 남는지 사례로 분석하라. 생산성 이익과 함께 오류·근거 누락·데이터 유출·검토 비용의 반대 근거를 다루고, 측정 가능한 성공 기준과 실패 시 대안을 설계하라."
|
|
65
|
+
}
|
|
66
|
+
]
|