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
|
@@ -12,6 +12,12 @@ export type ShardState = typeof SHARD_STATES[number];
|
|
|
12
12
|
export interface GateShard {
|
|
13
13
|
id: string;
|
|
14
14
|
state: ShardState;
|
|
15
|
+
/** Kubernetes Job for the current attempt; lets the gate watchdog reconcile a lost completion callback. */
|
|
16
|
+
job?: string;
|
|
17
|
+
/** Attempt identity associated with the currently recorded Job/result marker. */
|
|
18
|
+
attemptId?: string;
|
|
19
|
+
/** Result JSON for the current attempt; retries replace this so an older marker cannot close a new Job. */
|
|
20
|
+
resultFile?: string;
|
|
15
21
|
startedAt?: string;
|
|
16
22
|
endedAt?: string;
|
|
17
23
|
/** 설치(install) 단계에 쓴 초. */
|
|
@@ -61,8 +67,14 @@ function shardOf(value: unknown): GateShard | null {
|
|
|
61
67
|
const waitReason = str(raw.waitReason);
|
|
62
68
|
const plannedMin = num(raw.plannedMin);
|
|
63
69
|
const host = str(raw.host, 120);
|
|
70
|
+
const job = str(raw.job, 120);
|
|
71
|
+
const attemptId = str(raw.attemptId, 120);
|
|
72
|
+
const resultFile = str(raw.resultFile, 200);
|
|
64
73
|
return {
|
|
65
74
|
id, state,
|
|
75
|
+
...(job ? { job } : {}),
|
|
76
|
+
...(attemptId ? { attemptId } : {}),
|
|
77
|
+
...(resultFile ? { resultFile } : {}),
|
|
66
78
|
...(startedAt ? { startedAt } : {}), ...(endedAt ? { endedAt } : {}),
|
|
67
79
|
...(installSec !== undefined ? { installSec } : {}), ...(rc !== undefined ? { rc } : {}),
|
|
68
80
|
...(waitReason ? { waitReason } : {}), ...(plannedMin !== undefined ? { plannedMin } : {}),
|
|
@@ -70,6 +82,55 @@ function shardOf(value: unknown): GateShard | null {
|
|
|
70
82
|
};
|
|
71
83
|
}
|
|
72
84
|
|
|
85
|
+
export type GateJobTerminal = 'complete' | 'failed';
|
|
86
|
+
|
|
87
|
+
/** Forget the prior child Job before a shard descends into a retry/split attempt. */
|
|
88
|
+
export function beginGateShardAttempt(shard: GateShard, now = new Date()): GateShard {
|
|
89
|
+
const next: GateShard = { ...shard, state: 'retry', startedAt: now.toISOString() };
|
|
90
|
+
delete next.endedAt;
|
|
91
|
+
delete next.waitReason;
|
|
92
|
+
delete next.host;
|
|
93
|
+
delete next.job;
|
|
94
|
+
delete next.resultFile;
|
|
95
|
+
delete next.attemptId;
|
|
96
|
+
return next;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Close each stale running row when its result marker or Kubernetes Job has terminal evidence.
|
|
101
|
+
* A result marker can close a row even when the Kubernetes status read is unavailable.
|
|
102
|
+
*/
|
|
103
|
+
export function finalizeTerminalGateShards(
|
|
104
|
+
file: GateShardsFile,
|
|
105
|
+
terminalJobs: ReadonlyMap<string, GateJobTerminal>,
|
|
106
|
+
results: ReadonlyMap<string, { completed?: boolean; jobName?: string; attemptId?: string; jobFailed?: boolean; rc?: number | null; reason?: 'timeout' | 'stall' }>,
|
|
107
|
+
now: Date = new Date(),
|
|
108
|
+
staleAfterMs = 120_000,
|
|
109
|
+
): GateShardsFile {
|
|
110
|
+
const active = file.shards.filter((shard) => shard.state === 'running' || shard.state === 'retry');
|
|
111
|
+
if (!active.length) return file;
|
|
112
|
+
const at = now.getTime();
|
|
113
|
+
const ready = active.map((shard) => {
|
|
114
|
+
const result = results.get(shard.id);
|
|
115
|
+
const resultTerminal = result?.completed === true && result.jobName === shard.job && result.attemptId === shard.attemptId;
|
|
116
|
+
const k8sTerminal = shard.job ? terminalJobs.get(shard.job) : undefined;
|
|
117
|
+
const startedAt = shard.startedAt ? Date.parse(shard.startedAt) : Number.NaN;
|
|
118
|
+
if (!resultTerminal && !k8sTerminal) return undefined;
|
|
119
|
+
if (!Number.isFinite(startedAt) || at - startedAt < staleAfterMs) return undefined;
|
|
120
|
+
return { shard, result, state: resultTerminal
|
|
121
|
+
? (result!.reason === 'timeout' ? 'timeout' as const : result!.reason === 'stall' || result!.jobFailed === true ? 'failed' as const : 'done' as const)
|
|
122
|
+
: k8sTerminal === 'failed' ? 'failed' as const : 'done' as const };
|
|
123
|
+
});
|
|
124
|
+
const finalized = ready.filter((entry): entry is NonNullable<typeof entry> => entry !== undefined);
|
|
125
|
+
if (!finalized.length) return file;
|
|
126
|
+
const byId = new Map(finalized.map(({ shard, result, state }) => {
|
|
127
|
+
const current = { ...shard };
|
|
128
|
+
delete current.waitReason;
|
|
129
|
+
return [shard.id, { ...current, state, endedAt: now.toISOString(), ...(result && typeof result.rc === 'number' ? { rc: result.rc } : {}) } satisfies GateShard];
|
|
130
|
+
}));
|
|
131
|
+
return { ...file, updatedAt: now.toISOString(), shards: file.shards.map((shard) => byId.get(shard.id) ?? shard) };
|
|
132
|
+
}
|
|
133
|
+
|
|
73
134
|
function verdictOf(value: unknown): GateShardsVerdict | undefined {
|
|
74
135
|
if (!value || typeof value !== 'object') return undefined;
|
|
75
136
|
const raw = value as Record<string, unknown>;
|
|
@@ -7,7 +7,7 @@ import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
|
7
7
|
import { tmpdir } from 'node:os';
|
|
8
8
|
import { join } from 'node:path';
|
|
9
9
|
import { debug } from '../debug/log.js';
|
|
10
|
-
import {
|
|
10
|
+
import { runSelfGateCliAsync, type SelfGateCliOptions, type SelfGateCliResult } from '../self-implement/gate-cli.js';
|
|
11
11
|
import { dispatchHeavyCheck, isValidGateHost, type DispatchDeps, type DispatchOptions } from '../self-implement/gate-remote.js';
|
|
12
12
|
import { latestPublishedPreviousVersion } from '../../scripts/release-loop/unattended-release.js';
|
|
13
13
|
import { baseVersion, isReleaseVersion } from '../../scripts/release-loop/release-version.js';
|
|
@@ -29,6 +29,8 @@ export interface LightRcOptions {
|
|
|
29
29
|
/** Run on this machine (the remote child is re-invoked with it). */
|
|
30
30
|
local?: boolean;
|
|
31
31
|
shards?: number;
|
|
32
|
+
/** Maximum simultaneously active gate bundles, including per-file RSS samples (default three). */
|
|
33
|
+
shardConcurrency?: number;
|
|
32
34
|
/** OP FU — pass `--fixed-shard-distribution` to self gate (sorted round-robin into `shards`, no RSS pre-measurement).
|
|
33
35
|
* Opt-in; absent = the measured planner, unchanged. Also carried to the remote child. */
|
|
34
36
|
fixedShardDistribution?: boolean;
|
|
@@ -71,7 +73,7 @@ export interface LightRcDeps {
|
|
|
71
73
|
git?: (args: string[], cwd: string) => { rc: number | null; stdout: string };
|
|
72
74
|
previousVersion?: (version: string, ledgerRoot?: string) => string;
|
|
73
75
|
readFile?: (path: string) => string | undefined;
|
|
74
|
-
runGate?: (cwd: string, options: SelfGateCliOptions) => SelfGateCliResult
|
|
76
|
+
runGate?: (cwd: string, options: SelfGateCliOptions) => SelfGateCliResult | Promise<SelfGateCliResult>;
|
|
75
77
|
dispatch?: (opts: DispatchOptions, deps?: DispatchDeps) => Promise<number>;
|
|
76
78
|
/** Extra dispatch deps (runner · settings) — tests drive the real dispatch with a fake host. */
|
|
77
79
|
dispatchDeps?: Omit<DispatchDeps, 'write'>;
|
|
@@ -175,6 +177,7 @@ export async function runLightRc(version: string, opts: LightRcOptions = {}, dep
|
|
|
175
177
|
if (!isReleaseVersion(version)) throw new Error(`release version must be x.y.z: ${version}`);
|
|
176
178
|
const shards = opts.shards ?? LIGHT_RC_DEFAULT_SHARDS;
|
|
177
179
|
if (!Number.isSafeInteger(shards) || shards < 1) throw new Error(`invalid --shards count: ${opts.shards}`);
|
|
180
|
+
if (opts.shardConcurrency !== undefined && (!Number.isSafeInteger(opts.shardConcurrency) || opts.shardConcurrency < 1 || opts.shardConcurrency > 4)) throw new Error(`invalid --shard-concurrency: ${opts.shardConcurrency}`);
|
|
178
181
|
if (opts.remote !== undefined && !isValidGateHost(opts.remote)) throw new Error(`invalid --remote host: ${opts.remote}`);
|
|
179
182
|
const log = opts.log ?? ((line: string) => process.stderr.write(`${line}\n`));
|
|
180
183
|
const cwd = repoRoot(deps);
|
|
@@ -195,7 +198,7 @@ export async function runLightRc(version: string, opts: LightRcOptions = {}, dep
|
|
|
195
198
|
try {
|
|
196
199
|
const dir = checkout?.dir ?? cwd;
|
|
197
200
|
if (checkout) alwaysInclude = readList(dir);
|
|
198
|
-
local = (deps.runGate ??
|
|
201
|
+
local = await (deps.runGate ?? runSelfGateCliAsync)(dir, { base, shards, ...(opts.shardConcurrency !== undefined ? { shardConcurrency: opts.shardConcurrency } : {}), ...(opts.fixedShardDistribution ? { fixedShardDistribution: true } : {}), alwaysInclude, includeImporterTests: true });
|
|
199
202
|
if (opts.rehearsalTui) {
|
|
200
203
|
const command = async (cmd: string, args: string[], tree: string, limitMs?: number) => {
|
|
201
204
|
const run = spawnSync(cmd, args, { cwd: tree, encoding: 'utf8', timeout: limitMs });
|
|
@@ -212,7 +215,7 @@ export async function runLightRc(version: string, opts: LightRcOptions = {}, dep
|
|
|
212
215
|
// Keep the self-gate contract: an unavailable remote leaves this release check unmeasured; do not start a heavy gate locally.
|
|
213
216
|
tool: 'self-gate', repo: cwd, installPwa: true, refs: [base], json: true, commit: measuredCommit,
|
|
214
217
|
// The host re-runs this command with --local (and ELANOUS_GATE_REMOTE_CHILD=1), so it never recurses.
|
|
215
|
-
remoteArgv: (sha) => ['bun', 'bin/elanous.mjs', 'release', 'light-rc', '--version', version, '--base', sha(base), '--head', measuredCommit, '--shards', String(shards), ...(opts.fixedShardDistribution ? ['--fixed-shard-distribution'] : []), '--local', '--json', ...(opts.rehearsalTui ? ['--rehearsal-tui'] : [])],
|
|
218
|
+
remoteArgv: (sha) => ['bun', 'bin/elanous.mjs', 'release', 'light-rc', '--version', version, '--base', sha(base), '--head', measuredCommit, '--shards', String(shards), ...(opts.shardConcurrency !== undefined ? ['--shard-concurrency', String(opts.shardConcurrency)] : []), ...(opts.fixedShardDistribution ? ['--fixed-shard-distribution'] : []), '--local', '--json', ...(opts.rehearsalTui ? ['--rehearsal-tui'] : [])],
|
|
216
219
|
flags: { remote: opts.local ? undefined : opts.remote ?? true, local: !!opts.local },
|
|
217
220
|
runLocal,
|
|
218
221
|
}, {
|
|
@@ -7,7 +7,7 @@ import { listChecklist, setItem } from './checklist.js';
|
|
|
7
7
|
import { judgeLandedCell } from './landed-to-green.js';
|
|
8
8
|
import { evidencePlan, landedButYellow, type MergedChecklistPr } from './landed-but-yellow.js';
|
|
9
9
|
import { assignedVersions, evidenceAdd } from './feature-store.js';
|
|
10
|
-
import { boundMergedTaskCells, candidateMergedTaskCells, closeMergedTaskCard } from '../task-agent/postland-card.js';
|
|
10
|
+
import { boundMergedTaskCells, candidateMergedTaskCells, closeMergedTaskCard, recordMergedTaskImplFindings } from '../task-agent/postland-card.js';
|
|
11
11
|
|
|
12
12
|
export interface MergedPrChecklistDeps {
|
|
13
13
|
readPr?: (number: number, cwd: string) => { state: string; baseRefName: string; title: string; body: string | null; mergedAt: string; url?: string; headRefOid?: string; files?: Array<{ path: string }> };
|
|
@@ -19,13 +19,19 @@ export interface MergedPrChecklistDeps {
|
|
|
19
19
|
closeTaskCard?: typeof closeMergedTaskCard;
|
|
20
20
|
boundTaskCells?: typeof boundMergedTaskCells;
|
|
21
21
|
candidateTaskCells?: typeof candidateMergedTaskCells;
|
|
22
|
+
feedbackStatePath?: string;
|
|
23
|
+
feedbackFollowUp?: NonNullable<Parameters<typeof recordMergedTaskImplFindings>[2]>['followUp'];
|
|
22
24
|
log?: typeof debug.log;
|
|
23
25
|
}
|
|
24
26
|
|
|
27
|
+
function readMergedPr(number: number, cwd: string): NonNullable<MergedPrChecklistDeps['readPr']> extends (number: number, cwd: string) => infer T ? T : never {
|
|
28
|
+
return JSON.parse(execFileSync('gh', ['pr', 'view', String(number), '--json', 'state,baseRefName,title,body,mergedAt,url,headRefOid,files'], { cwd, encoding: 'utf8', timeout: 30_000 }));
|
|
29
|
+
}
|
|
30
|
+
|
|
25
31
|
/** A confirmed main merge is the only entry. The existing checklist matcher owns PR-to-cell decisions. */
|
|
26
32
|
export function syncMergedPrChecklist(number: number, cwd: string, goalFile?: string, deps: MergedPrChecklistDeps = {}): void {
|
|
27
33
|
const log = deps.log ?? debug.log.bind(debug);
|
|
28
|
-
const pr = (deps.readPr ??
|
|
34
|
+
const pr = (deps.readPr ?? readMergedPr)(number, cwd);
|
|
29
35
|
if (pr.state !== 'MERGED' || pr.baseRefName !== 'main') return;
|
|
30
36
|
const merged: MergedChecklistPr = { number, title: pr.title, body: pr.body, mergedAt: pr.mergedAt };
|
|
31
37
|
const versions = deps.versions?.() ?? (() => {
|
|
@@ -116,6 +122,23 @@ export function syncMergedPrChecklist(number: number, cwd: string, goalFile?: st
|
|
|
116
122
|
for (const id of missing) log('release.checklist', 'merged-pr-cell-not-found', { pr: number, id });
|
|
117
123
|
}
|
|
118
124
|
|
|
125
|
+
/** Production merge entry: reconcile synchronously, then await idempotent PR-body feedback before returning. */
|
|
126
|
+
export async function syncMergedPrChecklistWithFeedback(
|
|
127
|
+
number: number,
|
|
128
|
+
cwd: string,
|
|
129
|
+
goalFile?: string,
|
|
130
|
+
deps: MergedPrChecklistDeps = {},
|
|
131
|
+
): Promise<Awaited<ReturnType<typeof recordMergedTaskImplFindings>>> {
|
|
132
|
+
const pr = (deps.readPr ?? readMergedPr)(number, cwd);
|
|
133
|
+
syncMergedPrChecklist(number, cwd, goalFile, { ...deps, readPr: () => pr });
|
|
134
|
+
if (pr.url && pr.headRefOid) {
|
|
135
|
+
return await recordMergedTaskImplFindings({ ...pr, number, url: pr.url, headRefOid: pr.headRefOid }, cwd,
|
|
136
|
+
{ ...(deps.feedbackStatePath ? { statePath: deps.feedbackStatePath } : {}),
|
|
137
|
+
...(deps.feedbackFollowUp ? { followUp: deps.feedbackFollowUp } : {}) });
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
|
|
119
142
|
const LABEL_IDS = '([A-Za-z0-9_-]+(?:[ \\t]*(?:,|·)[ \\t]*[A-Za-z0-9_-]+)*)';
|
|
120
143
|
const LABEL_END = '(?=[ \\t]*$|[ \\t]+[—–·(-])';
|
|
121
144
|
const DESIGNATION = new RegExp(`^ {0,3}(?:#{1,6}[ \\t]+|[-*][ \\t]+)?칸[ \\t]*:[ \\t]*${LABEL_IDS}${LABEL_END}`);
|
|
@@ -87,7 +87,12 @@ export function planRehearsalShards(version: string, root: string, checkout: str
|
|
|
87
87
|
let gatePlanShards: number | null = null;
|
|
88
88
|
try {
|
|
89
89
|
const board = (deps.board ?? readGateShards)(gateShardsPath(version, root));
|
|
90
|
-
|
|
90
|
+
if (board?.version === version && board.shards.length
|
|
91
|
+
&& new Set(board.shards.map(shard => shard.id)).size === board.shards.length) {
|
|
92
|
+
// Split/retry/tail rows are observations, not extra planned shards. Older boards used arbitrary IDs.
|
|
93
|
+
const roots = board.shards.filter(shard => /^pod-\d+$/.test(shard.id));
|
|
94
|
+
gatePlanShards = roots.length || (board.shards.some(shard => /^pod-\d+/.test(shard.id)) ? null : board.shards.length);
|
|
95
|
+
}
|
|
91
96
|
} catch (error) { reasons.push(`persisted gate shard plan unreadable: ${error instanceof Error ? error.message : String(error)}`); }
|
|
92
97
|
let testFiles: number | null = null;
|
|
93
98
|
let measuredFiles = 0;
|
|
@@ -67,6 +67,15 @@ export function planRehearsal(schedules: readonly ReleaseSchedule[], now: Date,
|
|
|
67
67
|
return { status: 'not-yet', version, cutAt, nextStepAt: new Date(cut - open[0]!.minutes * minute).toISOString() };
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
export interface RehearsalRecovery {
|
|
71
|
+
failedShard: string;
|
|
72
|
+
remeasuredFiles: number | null;
|
|
73
|
+
durationMs: number | null;
|
|
74
|
+
poolOverwriteApplied: boolean | null;
|
|
75
|
+
outcome: 'ok' | 'failed';
|
|
76
|
+
error?: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
70
79
|
export interface RehearsalStamp {
|
|
71
80
|
version: string;
|
|
72
81
|
step: StepId;
|
|
@@ -79,6 +88,7 @@ export interface RehearsalStamp {
|
|
|
79
88
|
regressionFiles?: string[];
|
|
80
89
|
result?: LightRcResult;
|
|
81
90
|
hardGate?: HardGateResult;
|
|
91
|
+
recovery?: RehearsalRecovery;
|
|
82
92
|
hardGateRunId?: string;
|
|
83
93
|
hardGateLog?: string;
|
|
84
94
|
/** B6: an unmeasured hard gate always retains a cause, run id and durable local evidence path. */
|
|
@@ -94,6 +104,7 @@ export interface RehearsalOptions {
|
|
|
94
104
|
apply?: boolean;
|
|
95
105
|
checkout?: string;
|
|
96
106
|
ledgerRoot?: string;
|
|
107
|
+
recoveryRun?: string;
|
|
97
108
|
shards?: number;
|
|
98
109
|
remote?: string;
|
|
99
110
|
}
|
|
@@ -109,6 +120,7 @@ export interface RehearsalDeps {
|
|
|
109
120
|
notify?: (text: string) => void | boolean | Promise<void | boolean>;
|
|
110
121
|
git?: (args: string[], cwd: string) => { rc: number | null; stdout: string; stderr?: string };
|
|
111
122
|
leakCheck?: (checkout: string) => { status: number | null; detail?: string };
|
|
123
|
+
resumeGate?: (runId: string, checkout: string) => Promise<{ files: number; durationMs: number; poolOverwriteApplied: boolean; ok: boolean }>;
|
|
112
124
|
}
|
|
113
125
|
|
|
114
126
|
export type RehearsalTickResult = RehearsalPlan & { applied?: boolean; stamps?: RehearsalStamp[]; notificationFailures?: number };
|
|
@@ -495,7 +507,7 @@ export async function runRehearsalTick(opts: RehearsalOptions = {}, deps: Rehear
|
|
|
495
507
|
const introducedCount: number | null = stamp.outcome === 'unmeasured' || stamp.outcome === 'error' ? null : hard.introduced.length;
|
|
496
508
|
const preexistingCount: number | null = introducedCount === null ? null : hard.preexisting;
|
|
497
509
|
const totalFailures: number | null = introducedCount === null || preexistingCount === null ? null : introducedCount + preexistingCount;
|
|
498
|
-
stamp.summary = oneLine(`hard gate ${hard.outcome} · introduced ${introducedCount ?? 'UNKNOWN'} · preexisting ${preexistingCount ?? 'UNKNOWN'} · total failures ${totalFailures ?? 'UNKNOWN'} ·
|
|
510
|
+
stamp.summary = oneLine(`hard gate ${hard.outcome} · introduced ${introducedCount ?? 'UNKNOWN'} · preexisting ${preexistingCount ?? 'UNKNOWN'} · total failures ${totalFailures ?? 'UNKNOWN'} · 원격 Pod · 12 shards · runId ${hardGateRunId} · evidence ${hardGateLog}${cause ? ` · ${cause}` : ''}`);
|
|
499
511
|
} else {
|
|
500
512
|
const shardPlan = opts.shards === undefined ? (deps.shardPlan ?? planRehearsalShards)(plan.version, root, checkout, { ...deps.shardPlanDeps, remoteGate: true }) : undefined;
|
|
501
513
|
if (shardPlan) stamp.shardPlan = shardPlan;
|
|
@@ -520,6 +532,21 @@ export async function runRehearsalTick(opts: RehearsalOptions = {}, deps: Rehear
|
|
|
520
532
|
console.error(line);
|
|
521
533
|
} }, { cwd })))(plan.version, checkout, selection);
|
|
522
534
|
stamp.result = result;
|
|
535
|
+
if (opts.recoveryRun && result.unmeasured !== null) {
|
|
536
|
+
const failedShard = result.unmeasured;
|
|
537
|
+
const started = Date.now();
|
|
538
|
+
try {
|
|
539
|
+
const recovered = await deps.resumeGate?.(opts.recoveryRun, checkout);
|
|
540
|
+
if (!recovered) throw new Error('release resume --from gate is unavailable for this rehearsal');
|
|
541
|
+
stamp.recovery = { failedShard, remeasuredFiles: recovered.files, durationMs: recovered.durationMs,
|
|
542
|
+
poolOverwriteApplied: recovered.poolOverwriteApplied, outcome: recovered.ok ? 'ok' : 'failed',
|
|
543
|
+
...(!recovered.ok ? { error: 'resumed gate did not pass' } : {}) };
|
|
544
|
+
} catch (error) {
|
|
545
|
+
stamp.recovery = { failedShard, remeasuredFiles: null, durationMs: Math.max(0, Date.now() - started),
|
|
546
|
+
poolOverwriteApplied: null, outcome: 'failed',
|
|
547
|
+
error: oneLine(error instanceof Error ? error.message : String(error)) };
|
|
548
|
+
}
|
|
549
|
+
}
|
|
523
550
|
if (regressionFiles.length) stamp.regressionFiles = regressionFiles;
|
|
524
551
|
const shardMismatch = selection.shards !== undefined && result.shards !== selection.shards
|
|
525
552
|
? `selected shards ${selection.shards} but RC reported ${result.shards}` : null;
|
package/src/repl/index.ts
CHANGED
|
@@ -198,6 +198,7 @@ function buildReplTools(): {
|
|
|
198
198
|
specs.push(wakeup.spec);
|
|
199
199
|
dispatchByName.set(wakeup.spec.name, wakeup.dispatch);
|
|
200
200
|
}
|
|
201
|
+
(require('../tui/sidetab/nl-tool.js') as typeof import('../tui/sidetab/nl-tool.js')).registerNextSidetabReplTool(specs, dispatchByName, process as unknown as import('../tui/sidetab/nl-tool.js').NextSidetabIpcProcess);
|
|
201
202
|
const planner = sr.createSearchPlannerState({ maxAutoNarrowCandidates: 2 });
|
|
202
203
|
const dispatch = async (name: string, args: Record<string, unknown>): Promise<unknown> => {
|
|
203
204
|
try {
|
|
@@ -342,6 +343,7 @@ async function runOneTurn(
|
|
|
342
343
|
jsonOutput: boolean,
|
|
343
344
|
nextTuiDelivery?: { pending: PendingTaskNotification[] },
|
|
344
345
|
onJsonDelta?: (delta: string) => void,
|
|
346
|
+
onJsonStatus?: (line: string) => void,
|
|
345
347
|
): Promise<{ reply: string; provider: string; model: string | null; durationMs: number; logPath: string | null }> {
|
|
346
348
|
const startedAt = Date.now();
|
|
347
349
|
const replyChunks: string[] = [];
|
|
@@ -374,6 +376,10 @@ async function runOneTurn(
|
|
|
374
376
|
userText,
|
|
375
377
|
systemPrompt,
|
|
376
378
|
userImages: userImages.length > 0 ? userImages : undefined,
|
|
379
|
+
...(process.env.ELANOUS_TEST_FAKE_LLM === '1' && Number.isFinite(Number(process.env.ELANOUS_TEST_FAKE_LLM_IDLE_TIMEOUT_MS))
|
|
380
|
+
&& Number(process.env.ELANOUS_TEST_FAKE_LLM_IDLE_TIMEOUT_MS) > 0
|
|
381
|
+
? { llmOpts: { streamIdleTimeoutMs: Number(process.env.ELANOUS_TEST_FAKE_LLM_IDLE_TIMEOUT_MS) } }
|
|
382
|
+
: {}),
|
|
377
383
|
onDelta: (d) => {
|
|
378
384
|
if (jsonOutput) {
|
|
379
385
|
replyChunks.push(d);
|
|
@@ -381,6 +387,7 @@ async function runOneTurn(
|
|
|
381
387
|
}
|
|
382
388
|
else process.stdout.write(d);
|
|
383
389
|
},
|
|
390
|
+
onStatusLine: (line) => { onJsonStatus?.(line); },
|
|
384
391
|
tools: replToolSpecs,
|
|
385
392
|
dispatchTool: tools?.dispatch,
|
|
386
393
|
onToolCall: (call) => {
|
|
@@ -785,6 +792,9 @@ export async function runRepl(opts: ReplOpts): Promise<number> {
|
|
|
785
792
|
process.env.ELANOUS_NEXT_TUI_STREAM === '1' && typeof turn.id === 'string'
|
|
786
793
|
? (delta) => { process.stdout.write(`${JSON.stringify({ event: 'delta', turnId: turn.id, text: delta })}\n`); }
|
|
787
794
|
: undefined,
|
|
795
|
+
process.env.ELANOUS_NEXT_TUI_STREAM === '1' && typeof turn.id === 'string'
|
|
796
|
+
? (text) => { process.stdout.write(`${JSON.stringify({ event: 'status', turnId: turn.id, text })}\n`); }
|
|
797
|
+
: undefined,
|
|
788
798
|
);
|
|
789
799
|
} catch (error) {
|
|
790
800
|
if (!backgroundBridge) throw error;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Research-only native fanout. The caller supplies Bloom's question ladder;
|
|
2
|
+
// each axis gets its own direct tool call and evidence stays attributed to it.
|
|
3
|
+
import type { BloomResearchQuestion, ResearchEvidenceEnvelope } from '../auto-research/question-ladder-contract.js';
|
|
4
|
+
import type { WebSearchHit } from '../web-search/provider.js';
|
|
5
|
+
|
|
6
|
+
export interface AxisToolCallPlan {
|
|
7
|
+
questionId: string;
|
|
8
|
+
tool: 'OmniSearch';
|
|
9
|
+
query: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface AxisEvidenceGroup {
|
|
13
|
+
questionId: string;
|
|
14
|
+
evidence: ResearchEvidenceEnvelope[];
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AxisFanoutResult {
|
|
19
|
+
plan: AxisToolCallPlan[];
|
|
20
|
+
axes: AxisEvidenceGroup[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type AxisSearchHit = WebSearchHit & { engine?: string };
|
|
24
|
+
export interface AxisSearchResult {
|
|
25
|
+
hits: AxisSearchHit[];
|
|
26
|
+
errors: string[];
|
|
27
|
+
}
|
|
28
|
+
export type AxisSearch = (query: string) => Promise<AxisSearchHit[] | AxisSearchResult>;
|
|
29
|
+
|
|
30
|
+
export interface AxisFanoutDeps {
|
|
31
|
+
search?: AxisSearch;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Keep every query attached to the Bloom question that produced it. */
|
|
35
|
+
export function planAxisToolCalls(questions: readonly BloomResearchQuestion[]): AxisToolCallPlan[] {
|
|
36
|
+
return questions.flatMap(question => question.searchTerms
|
|
37
|
+
.map(query => query.trim())
|
|
38
|
+
.filter(Boolean)
|
|
39
|
+
.map(query => ({ questionId: question.id, tool: 'OmniSearch' as const, query })));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function directOmniSearch(query: string): Promise<AxisSearchResult> {
|
|
43
|
+
const { dispatchOmniSearch } = await import('../skills/tools/omni-search.js');
|
|
44
|
+
const hits: AxisSearchHit[] = [];
|
|
45
|
+
const result = await dispatchOmniSearch({ query }, { onSource: hit => { hits.push(hit); } });
|
|
46
|
+
if (Object.keys(result.metadata.perEngine).length === 0) {
|
|
47
|
+
throw new Error('no available web-search providers');
|
|
48
|
+
}
|
|
49
|
+
const errors = Object.entries(result.metadata.perEngine)
|
|
50
|
+
.flatMap(([engine, info]) => info.error ? [`${engine}: ${info.error}`] : []);
|
|
51
|
+
return { hits, errors };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function evidenceFromHit(question: BloomResearchQuestion, hit: AxisSearchHit): ResearchEvidenceEnvelope {
|
|
55
|
+
const published = hit.publishedAt;
|
|
56
|
+
const date = published !== undefined && Number.isFinite(published) && published > 0
|
|
57
|
+
? new Date(published) : undefined;
|
|
58
|
+
const observedAt = date && Number.isFinite(date.getTime()) ? date.toISOString() : undefined;
|
|
59
|
+
return {
|
|
60
|
+
questionId: question.id,
|
|
61
|
+
sourceKind: hit.engine ? `web-search:${hit.engine}` : 'web-search',
|
|
62
|
+
source: hit.url,
|
|
63
|
+
...(question.requestedWindow ? { requestedWindow: question.requestedWindow } : {}),
|
|
64
|
+
...(observedAt ? { observedAt } : {}),
|
|
65
|
+
content: [hit.title, hit.snippet].filter(Boolean).join(' — '),
|
|
66
|
+
outcome: hit.snippet ? 'complete' : 'partial',
|
|
67
|
+
truncated: true, // Search snippets are excerpts, not the complete source page.
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function failedEvidence(question: BloomResearchQuestion, query: string, message: string): ResearchEvidenceEnvelope {
|
|
72
|
+
return {
|
|
73
|
+
questionId: question.id,
|
|
74
|
+
sourceKind: 'search-query',
|
|
75
|
+
source: query,
|
|
76
|
+
...(question.requestedWindow ? { requestedWindow: question.requestedWindow } : {}),
|
|
77
|
+
content: message,
|
|
78
|
+
outcome: 'failed',
|
|
79
|
+
truncated: false,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Invoke all axis queries concurrently, preserving ladder order and partial failures. */
|
|
84
|
+
export async function fanOutAxisEvidence(
|
|
85
|
+
questions: readonly BloomResearchQuestion[],
|
|
86
|
+
deps: AxisFanoutDeps = {},
|
|
87
|
+
): Promise<AxisFanoutResult> {
|
|
88
|
+
const plan = planAxisToolCalls(questions);
|
|
89
|
+
if (new Set(questions.map(question => question.id)).size !== questions.length) {
|
|
90
|
+
throw new Error('research axis question IDs must be unique');
|
|
91
|
+
}
|
|
92
|
+
const search = deps.search ?? directOmniSearch;
|
|
93
|
+
const settled = await Promise.allSettled(plan.map(call => search(call.query)));
|
|
94
|
+
const axes: AxisEvidenceGroup[] = questions.map(question => ({ questionId: question.id, evidence: [] }));
|
|
95
|
+
const groups = new Map(axes.map(axis => [axis.questionId, axis]));
|
|
96
|
+
const byQuestion = new Map(questions.map(question => [question.id, question]));
|
|
97
|
+
for (const question of questions) {
|
|
98
|
+
if (!plan.some(call => call.questionId === question.id)) {
|
|
99
|
+
const group = groups.get(question.id)!;
|
|
100
|
+
group.error = 'no search terms';
|
|
101
|
+
group.evidence.push(failedEvidence(question, question.prompt, group.error));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
settled.forEach((outcome, index) => {
|
|
105
|
+
const call = plan[index]!;
|
|
106
|
+
const group = groups.get(call.questionId)!;
|
|
107
|
+
const question = byQuestion.get(call.questionId)!;
|
|
108
|
+
if (outcome.status === 'fulfilled') {
|
|
109
|
+
const response = Array.isArray(outcome.value) ? { hits: outcome.value, errors: [] } : outcome.value;
|
|
110
|
+
if (response.hits.length === 0 && response.errors.length === 0) {
|
|
111
|
+
group.evidence.push({ ...failedEvidence(question, call.query, 'no hits returned'), outcome: 'partial' });
|
|
112
|
+
}
|
|
113
|
+
for (const hit of response.hits) {
|
|
114
|
+
try {
|
|
115
|
+
group.evidence.push(evidenceFromHit(question, hit));
|
|
116
|
+
} catch (err) {
|
|
117
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
118
|
+
group.error = group.error ? `${group.error}; ${message}` : message;
|
|
119
|
+
group.evidence.push(failedEvidence(question, call.query, message));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const message of response.errors) {
|
|
123
|
+
group.error = group.error ? `${group.error}; ${message}` : message;
|
|
124
|
+
group.evidence.push(failedEvidence(question, call.query, message));
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
const message = outcome.reason instanceof Error ? outcome.reason.message : String(outcome.reason);
|
|
128
|
+
group.error = group.error ? `${group.error}; ${message}` : message;
|
|
129
|
+
group.evidence.push(failedEvidence(question, call.query, message));
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
return { plan, axes };
|
|
133
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import type { GraphNodeSpec } from '../self-implement/graph-yaml.js';
|
|
2
|
+
|
|
3
|
+
/** Opaque Bloom 4/5 output. The hook owns the decision boundary, not analysis policy. */
|
|
4
|
+
export interface BloomEdgeAssessment {
|
|
5
|
+
gaps: readonly unknown[];
|
|
6
|
+
contradictions: readonly unknown[];
|
|
7
|
+
verdicts: readonly unknown[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type ResearchEdgeAction = 'add' | 'prune' | 'deepen' | 'stop';
|
|
11
|
+
|
|
12
|
+
export interface ResearchEdgeProposal {
|
|
13
|
+
node: GraphNodeSpec;
|
|
14
|
+
returnTo?: string;
|
|
15
|
+
reason: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ResearchEdgeDecision {
|
|
19
|
+
action: ResearchEdgeAction;
|
|
20
|
+
reason: string;
|
|
21
|
+
evidence: readonly string[];
|
|
22
|
+
/** Ordinal-free, explicitly supplied strength on [0, 1]; never inferred from votes. */
|
|
23
|
+
evidenceStrength?: number;
|
|
24
|
+
/** Optional T3 record-only confidence; never changes the live edge decision. */
|
|
25
|
+
confidence?: number;
|
|
26
|
+
counterEvidenceRefs?: readonly string[];
|
|
27
|
+
outsideViewRefs?: readonly string[];
|
|
28
|
+
proposal?: ResearchEdgeProposal;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ResolvedResearchEdgeDecision extends ResearchEdgeDecision {
|
|
32
|
+
provider: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** T3 evidence is retained beside the current live decision, never applied to it. */
|
|
36
|
+
export interface ResearchEdgeDecisionEnvelope extends ResolvedResearchEdgeDecision {
|
|
37
|
+
recommendation?: ResolvedResearchEdgeDecision;
|
|
38
|
+
votes: readonly ResolvedResearchEdgeDecision[];
|
|
39
|
+
dissent: readonly ResolvedResearchEdgeDecision[];
|
|
40
|
+
counterEvidenceRefs: readonly string[];
|
|
41
|
+
outsideViewRefs: readonly string[];
|
|
42
|
+
agreesWithLive?: boolean;
|
|
43
|
+
mode: 'record-only';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type ResearchEdgeDecisionProvider = (
|
|
47
|
+
assessment: BloomEdgeAssessment,
|
|
48
|
+
) => ResearchEdgeDecision | Promise<ResearchEdgeDecision>;
|
|
49
|
+
|
|
50
|
+
export interface ResearchEdgeDecisionRegistry {
|
|
51
|
+
register(provider: ResearchEdgeDecisionProvider, name?: string, options?: { priority?: number }): () => void;
|
|
52
|
+
decide(assessment: BloomEdgeAssessment): Promise<ResearchEdgeDecisionEnvelope>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const noOpDecision: ResearchEdgeDecision = {
|
|
56
|
+
action: 'stop',
|
|
57
|
+
reason: 'no edge decision provider registered',
|
|
58
|
+
evidence: [],
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/** One registry belongs to one run. With no provider, the graph takes one round and stops. */
|
|
62
|
+
export function createResearchEdgeDecisionRegistry(): ResearchEdgeDecisionRegistry {
|
|
63
|
+
const providers = new Map<symbol, { name: string; decide: ResearchEdgeDecisionProvider; priority?: number }>();
|
|
64
|
+
return {
|
|
65
|
+
register(provider, name = 'registered', options = {}) {
|
|
66
|
+
if (options.priority !== undefined && !Number.isFinite(options.priority)) {
|
|
67
|
+
throw new TypeError('research edge provider priority must be finite when supplied');
|
|
68
|
+
}
|
|
69
|
+
const key = Symbol('research-edge-decision-provider');
|
|
70
|
+
providers.set(key, { name, decide: provider, ...(options.priority === undefined ? {} : { priority: options.priority }) });
|
|
71
|
+
return () => { providers.delete(key); };
|
|
72
|
+
},
|
|
73
|
+
async decide(assessment) {
|
|
74
|
+
const entries = [...providers.values()];
|
|
75
|
+
if (!entries.length) return envelope({ ...noOpDecision, provider: 'default-noop' }, []);
|
|
76
|
+
const results = await Promise.all(entries.map(async (entry) => {
|
|
77
|
+
try {
|
|
78
|
+
const decision = await entry.decide(assessment);
|
|
79
|
+
return isResearchEdgeDecision(decision)
|
|
80
|
+
? { entry, decision }
|
|
81
|
+
: { entry, error: 'returned an invalid decision' };
|
|
82
|
+
} catch (error) {
|
|
83
|
+
return { entry, error: `failed: ${String(error)}` };
|
|
84
|
+
}
|
|
85
|
+
}));
|
|
86
|
+
const valid = results.filter((result): result is { entry: typeof entries[number]; decision: ResearchEdgeDecision } => 'decision' in result);
|
|
87
|
+
const failures = results.filter((result): result is { entry: typeof entries[number]; error: string } => 'error' in result);
|
|
88
|
+
if (!valid.length) return envelope({ action: 'stop', reason: `all edge decision providers failed: ${failures.map(({ entry, error }) => `${entry.name} ${error}`).join('; ')}`, evidence: [], provider: 'composition' }, []);
|
|
89
|
+
if (valid.length === 1 && !failures.length) {
|
|
90
|
+
const [{ entry, decision }] = valid;
|
|
91
|
+
const live = { ...decision, evidence: [...decision.evidence], provider: entry.name };
|
|
92
|
+
return envelope(live, votes(valid));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Agreement composes evidence. Disagreement is resolved by declared evidence strength,
|
|
96
|
+
// then explicit provider priority; an unresolved tie fails closed instead of voting.
|
|
97
|
+
const actions = new Set(valid.map(({ decision }) => decision.action));
|
|
98
|
+
const proposalKeys = new Set(valid.filter(({ decision }) => decision.action === 'add')
|
|
99
|
+
.map(({ decision }) => JSON.stringify(decision.proposal)));
|
|
100
|
+
const conflict = actions.size > 1 || proposalKeys.size > 1;
|
|
101
|
+
let candidates = valid;
|
|
102
|
+
if (conflict) {
|
|
103
|
+
const ranked = valid.map((result) => ({ ...result,
|
|
104
|
+
strength: result.decision.evidenceStrength ?? -1,
|
|
105
|
+
})).sort((a, b) => b.strength - a.strength);
|
|
106
|
+
const top = ranked[0]!;
|
|
107
|
+
const tiedStrength = ranked.filter((item) => item.strength === top.strength);
|
|
108
|
+
if (tiedStrength.length > 1 && tiedStrength.some((item) => item.entry.priority === undefined)) return envelope({
|
|
109
|
+
action: 'stop', reason: `unresolved edge decision conflict: ${tiedStrength.map(({ entry }) => entry.name).join(', ')} (priority unspecified)`,
|
|
110
|
+
evidence: [...new Set(valid.flatMap(({ decision }) => decision.evidence))], provider: 'composition',
|
|
111
|
+
}, votes(valid));
|
|
112
|
+
tiedStrength.sort((a, b) => (b.entry.priority ?? 0) - (a.entry.priority ?? 0));
|
|
113
|
+
const winner = tiedStrength[0]!;
|
|
114
|
+
const tied = tiedStrength.filter((item) => item.entry.priority === winner.entry.priority);
|
|
115
|
+
if (tied.length > 1) return envelope({
|
|
116
|
+
action: 'stop', reason: `unresolved edge decision conflict: ${tied.map(({ entry }) => entry.name).join(', ')}`,
|
|
117
|
+
evidence: [...new Set(valid.flatMap(({ decision }) => decision.evidence))], provider: 'composition',
|
|
118
|
+
}, votes(valid));
|
|
119
|
+
candidates = [winner];
|
|
120
|
+
}
|
|
121
|
+
const winner = candidates[0]!;
|
|
122
|
+
const evidence = [...new Set(valid.flatMap(({ decision }) => decision.evidence))];
|
|
123
|
+
const contributors = valid.map(({ entry }) => entry.name).join(', ');
|
|
124
|
+
const notes = failures.map(({ entry, error }) => `${entry.name} ${error}`);
|
|
125
|
+
const reason = conflict
|
|
126
|
+
? `conflict resolved by ${winner.entry.name} (strength=${winner.decision.evidenceStrength ?? 'unspecified'}, priority=${winner.entry.priority ?? 'unspecified'}); ${winner.decision.reason}`
|
|
127
|
+
: `composed ${contributors}: ${winner.decision.reason}`;
|
|
128
|
+
const evidenceNote = evidence.length ? `; evidence=${evidence.join(' | ')}` : '';
|
|
129
|
+
const live = { ...winner.decision, reason: [...notes, `${reason}${evidenceNote}`].join('; '), evidence, provider: conflict ? winner.entry.name : `composition[${contributors}]` };
|
|
130
|
+
return envelope(live, votes(valid));
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function isResearchEdgeDecision(value: unknown): value is ResearchEdgeDecision {
|
|
136
|
+
if (!isRecord(value) || !['add', 'prune', 'deepen', 'stop'].includes(String(value.action))
|
|
137
|
+
|| typeof value.reason !== 'string' || !value.reason.trim()
|
|
138
|
+
|| !Array.isArray(value.evidence) || !value.evidence.every((item) => typeof item === 'string')
|
|
139
|
+
|| (value.evidenceStrength !== undefined && (typeof value.evidenceStrength !== 'number'
|
|
140
|
+
|| !Number.isFinite(value.evidenceStrength) || value.evidenceStrength < 0 || value.evidenceStrength > 1))) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
if (value.action === 'add') return isResearchEdgeProposal(value.proposal);
|
|
144
|
+
return value.proposal === undefined;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function votes(valid: readonly { entry: { name: string }; decision: ResearchEdgeDecision }[]): ResolvedResearchEdgeDecision[] {
|
|
148
|
+
return valid.map(({ entry, decision }) => {
|
|
149
|
+
const confidence = typeof decision.confidence === 'number' && Number.isFinite(decision.confidence)
|
|
150
|
+
&& decision.confidence >= 0 && decision.confidence <= 1 ? decision.confidence : undefined;
|
|
151
|
+
const counterEvidenceRefs = Array.isArray(decision.counterEvidenceRefs)
|
|
152
|
+
? decision.counterEvidenceRefs.filter((item): item is string => typeof item === 'string') : [];
|
|
153
|
+
const outsideViewRefs = Array.isArray(decision.outsideViewRefs)
|
|
154
|
+
? decision.outsideViewRefs.filter((item): item is string => typeof item === 'string') : [];
|
|
155
|
+
return {
|
|
156
|
+
...decision,
|
|
157
|
+
...(confidence === undefined ? { confidence: undefined } : { confidence }),
|
|
158
|
+
counterEvidenceRefs,
|
|
159
|
+
outsideViewRefs,
|
|
160
|
+
evidence: [...decision.evidence],
|
|
161
|
+
provider: entry.name,
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function envelope(live: ResolvedResearchEdgeDecision, recordedVotes: readonly ResolvedResearchEdgeDecision[]): ResearchEdgeDecisionEnvelope {
|
|
167
|
+
const scored = recordedVotes.filter((vote) => vote.confidence !== undefined);
|
|
168
|
+
const strongest = scored.length ? Math.max(...scored.map((vote) => vote.confidence!)) : undefined;
|
|
169
|
+
const leaders = strongest === undefined ? [] : scored.filter((vote) => vote.confidence === strongest);
|
|
170
|
+
const leaderActions = new Set(leaders.map(({ action }) => action));
|
|
171
|
+
const leaderPayloads = new Set(leaders.map(({ action, proposal }) => JSON.stringify({ action, proposal })));
|
|
172
|
+
const recommendation = !leaders.length ? undefined
|
|
173
|
+
: leaderActions.size > 1 || leaderPayloads.size > 1
|
|
174
|
+
? { action: 'stop' as const, reason: 'conflicting strongest evidence', evidence: [...new Set(leaders.flatMap(({ evidence }) => evidence))], confidence: strongest, provider: 'evidence-composer' }
|
|
175
|
+
: leaders[0];
|
|
176
|
+
const sameLive = (vote: ResolvedResearchEdgeDecision) => vote.action === live.action && JSON.stringify(vote.proposal) === JSON.stringify(live.proposal);
|
|
177
|
+
return {
|
|
178
|
+
...live,
|
|
179
|
+
votes: [...recordedVotes],
|
|
180
|
+
dissent: recommendation ? recordedVotes.filter((vote) => vote.action !== recommendation.action || JSON.stringify(vote.proposal) !== JSON.stringify(recommendation.proposal)) : [],
|
|
181
|
+
counterEvidenceRefs: [...new Set(recordedVotes.flatMap((vote) => vote.counterEvidenceRefs ?? []))],
|
|
182
|
+
outsideViewRefs: [...new Set(recordedVotes.flatMap((vote) => vote.outsideViewRefs ?? []))],
|
|
183
|
+
...(recommendation ? { recommendation, agreesWithLive: sameLive(recommendation) } : {}),
|
|
184
|
+
mode: 'record-only',
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function isResearchEdgeProposal(value: unknown): value is ResearchEdgeProposal {
|
|
189
|
+
return isRecord(value) && isRecord(value.node) && typeof value.node.nodeId === 'string'
|
|
190
|
+
&& typeof value.node.kind === 'string' && typeof value.node.recipe === 'string'
|
|
191
|
+
&& typeof value.reason === 'string' && value.reason.trim().length > 0
|
|
192
|
+
&& (value.returnTo === undefined || typeof value.returnTo === 'string');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
196
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
197
|
+
}
|