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
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { linesOutsideFencedCode, validateGoalDoneEvidenceCommand } from '../self-implement/goal-author.js';
|
|
2
|
+
|
|
3
|
+
const EVIDENCE_LINE = /^(\s*(?:[-*]\s*)?완료 경계 증거 명령\s*:\s*)(.*?)(\s*)$/;
|
|
4
|
+
|
|
5
|
+
/** Remove known result annotations from an evidence command, preserving every other line. */
|
|
6
|
+
export function normalizeEvidenceCommandLines(document: string): { text: string; warnings: string[]; unrecognized: string[] } {
|
|
7
|
+
const warnings: string[] = [];
|
|
8
|
+
const unrecognized: string[] = [];
|
|
9
|
+
const replacements: Array<{ start: number; old: string; next: string }> = [];
|
|
10
|
+
for (const line of linesOutsideFencedCode(document)) {
|
|
11
|
+
const match = EVIDENCE_LINE.exec(line.text);
|
|
12
|
+
if (!match) continue;
|
|
13
|
+
const original = match[2].trim();
|
|
14
|
+
if (!original) continue;
|
|
15
|
+
let candidate = original.replace(/\s*(?:→|->)\s*0\s+fail\s*$/i, '')
|
|
16
|
+
.replace(/\s*·\s*typecheck\s+PASS\s*$/i, '').trim();
|
|
17
|
+
// Some cards have both annotations; peel them in either order.
|
|
18
|
+
candidate = candidate.replace(/\s*(?:→|->)\s*0\s+fail\s*$/i, '')
|
|
19
|
+
.replace(/\s*·\s*typecheck\s+PASS\s*$/i, '').trim();
|
|
20
|
+
if (candidate.startsWith('`') && candidate.endsWith('`') && candidate.length > 2)
|
|
21
|
+
candidate = candidate.slice(1, -1).trim();
|
|
22
|
+
if (candidate === original) {
|
|
23
|
+
if (/[`→]|->|·\s*typecheck\b/i.test(original)) {
|
|
24
|
+
warnings.push(`완료 경계 증거 명령 정규화 불가: ${original}`);
|
|
25
|
+
unrecognized.push(original);
|
|
26
|
+
}
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
// An unrecognized decoration is never silently converted into a shell command.
|
|
30
|
+
if (!validateGoalDoneEvidenceCommand(candidate).command) {
|
|
31
|
+
warnings.push(`완료 경계 증거 명령 정규화 불가: ${original}`);
|
|
32
|
+
unrecognized.push(original);
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
replacements.push({ start: line.start, old: line.text, next: `${match[1]}${candidate}${match[3]}` });
|
|
36
|
+
warnings.push(`완료 경계 증거 명령 정규화: ${original} → ${candidate}`);
|
|
37
|
+
}
|
|
38
|
+
let text = document;
|
|
39
|
+
for (const replacement of replacements.reverse())
|
|
40
|
+
text = text.slice(0, replacement.start) + replacement.next + text.slice(replacement.start + replacement.old.length);
|
|
41
|
+
return { text, warnings, unrecognized };
|
|
42
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { lstatSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { loadPrivateRedactions, privateRedactionsPath } from '../../scripts/public-export.js';
|
|
3
|
+
import { defaultSshRunner, type SshRunner } from './parent-host.js';
|
|
4
|
+
import { shellQuote } from './task-hand.js';
|
|
5
|
+
|
|
6
|
+
const ALLOWED_HOSTS = new Set(['node-b', 'elangram-wsl', 'host-e-wsl']);
|
|
7
|
+
|
|
8
|
+
/** Give a train host the same private list that release export-check reads on HQ.
|
|
9
|
+
* The list travels only over SSH stdin and is installed atomically at mode 0600.
|
|
10
|
+
* A missing or unreadable list is a failed preflight, never a weaker leak check. */
|
|
11
|
+
export function provisionExportRedactions(
|
|
12
|
+
host: string,
|
|
13
|
+
sourcePath = privateRedactionsPath(),
|
|
14
|
+
ssh: SshRunner = defaultSshRunner,
|
|
15
|
+
): void {
|
|
16
|
+
if (!ALLOWED_HOSTS.has(host)) throw new Error('export redactions host not allowed');
|
|
17
|
+
let payload: string;
|
|
18
|
+
try {
|
|
19
|
+
const stat = lstatSync(sourcePath);
|
|
20
|
+
if (!stat.isFile() || (stat.mode & 0o077) !== 0 || stat.size === 0 || stat.size > 1_048_576) {
|
|
21
|
+
throw new Error('source is not a private regular file');
|
|
22
|
+
}
|
|
23
|
+
if (!loadPrivateRedactions(sourcePath)?.length) throw new Error('source has no redaction entries');
|
|
24
|
+
payload = readFileSync(sourcePath, 'utf8');
|
|
25
|
+
if (payload.includes('\0')) throw new Error('source contains NUL');
|
|
26
|
+
} catch {
|
|
27
|
+
throw new Error('export redactions source unavailable or invalid');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const code = [
|
|
31
|
+
'const fs=require("node:fs"),path=require("node:path"),crypto=require("node:crypto");',
|
|
32
|
+
// Remote SSH execution has no repository resolver module. Match privateRedactionsPath():
|
|
33
|
+
// ELANOUS_EXPORT_REDACTIONS first, then the remote shell HOME default (OP #40040).
|
|
34
|
+
'const home=process.env.HOME?.trim(),override=process.env.ELANOUS_EXPORT_REDACTIONS?.trim();',
|
|
35
|
+
'const file=override||(home?path.join(home,".elanous","export-redactions.tsv"):"");if(!file||!path.isAbsolute(file))process.exit(2);const dir=path.dirname(file);',
|
|
36
|
+
'const bytes=fs.readFileSync(0);if(!bytes.length||bytes.length>1048576||bytes.includes(0))process.exit(2);',
|
|
37
|
+
'fs.mkdirSync(dir,{recursive:true,mode:0o700});fs.chmodSync(dir,0o700);',
|
|
38
|
+
'const temp=file+"."+process.pid+"."+crypto.randomBytes(6).toString("hex")+".tmp";',
|
|
39
|
+
'try{fs.writeFileSync(temp,bytes,{mode:0o600,flag:"wx"});fs.chmodSync(temp,0o600);fs.renameSync(temp,file)}catch{try{fs.rmSync(temp,{force:true})}catch{};process.exit(3)}',
|
|
40
|
+
].join('');
|
|
41
|
+
const result = ssh(host, `umask 077; bun -e ${shellQuote(code)}`, 20_000, payload);
|
|
42
|
+
if (result.status !== 0) throw new Error(`export redactions provision failed (ssh rc=${result.status ?? 'unknown'})`);
|
|
43
|
+
}
|
package/src/task-agent/judge.ts
CHANGED
|
@@ -76,6 +76,62 @@ export function mustFixSignature(mustFix?: readonly string[]): string | undefine
|
|
|
76
76
|
return `fnv1a-${hash.toString(16).padStart(8, '0')}`;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
/**
|
|
80
|
+
* 빈 구현 must-fix 신호(대상 3종) — 리뷰가 이 신호를 담은 must-fix 를 내면 같은 PR 수리(narrow-relaunch)로는 수렴하지 않는다.
|
|
81
|
+
* 결정론 분류만 한다(LLM 경로 없음). 판별은 문구 일치로 하되 오탐을 피해 좁게 잡는다.
|
|
82
|
+
*/
|
|
83
|
+
const EMPTY_IMPLEMENTATION_SIGNALS: readonly { name: string; patterns: readonly RegExp[] }[] = [
|
|
84
|
+
{
|
|
85
|
+
name: '구현 파일 변경 0',
|
|
86
|
+
patterns: [
|
|
87
|
+
/빈 구현/u,
|
|
88
|
+
/empty[- ]implementation/iu,
|
|
89
|
+
/구현 파일[^\n.]{0,8}(없음|없다|미변경)|구현 파일[^\n.]{0,24}변경[^\n.]{0,8}0(?!\d)/u,
|
|
90
|
+
/구현 (diff|변경|차분)[^\n.]{0,8}0(?!\d)/u,
|
|
91
|
+
/implementation files?[^\n.]{0,32}(unchanged|zero|no change)/iu,
|
|
92
|
+
/(no|zero) (implementation|code) (changes|diff)/iu,
|
|
93
|
+
/target diff (is )?0(?!\d)/iu,
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'GOODHART/자기 문구 시험',
|
|
98
|
+
patterns: [/GOODHART/iu, /자기 ?문구/u, /골 문면/u, /goal[ -]?(text|wording)/iu],
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: '대상 경로 미배선',
|
|
102
|
+
patterns: [/미배선/u, /배선되지 않/u, /호출부[^\n.]{0,8}(없음|없다)/u, /not[ -]?wired/iu, /unwired/iu, /no caller/iu, /dead code/iu],
|
|
103
|
+
},
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
/** 빈 구현 must-fix 판정의 수 — 첫 회는 같은 칸 새 발사(재구현), 이미 두 번째면 칸 주인 이관(needs-owner). */
|
|
107
|
+
export type EmptyImplementationMove = 'reimplement' | 'needs-owner';
|
|
108
|
+
|
|
109
|
+
/** 판정 관측 한 줄 — `reason` 이 그대로 관측 로그 문면이다(줄바꿈 없음). */
|
|
110
|
+
export interface EmptyImplementationJudgement {
|
|
111
|
+
move: EmptyImplementationMove;
|
|
112
|
+
signals: readonly string[];
|
|
113
|
+
reason: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 리뷰 must-fix 가 «빈 구현» 신호(구현 파일 변경 0 · GOODHART/자기 문구 시험 · 대상 경로 미배선)를 담는지 결정론 분류한다.
|
|
118
|
+
* 신호를 담으면 narrow-relaunch 대신 재구현 판정 — 같은 칸의 앞 런에서 이미 빈 구현 must-fix 였으면
|
|
119
|
+
* (priorEmptyImplementation ≥ 1) 두 번째이므로 needs-owner. 신호가 없으면 null — 일반 must-fix 는 종전대로 narrow-relaunch.
|
|
120
|
+
*/
|
|
121
|
+
export function judgeEmptyImplementation(
|
|
122
|
+
mustFix: readonly string[] | undefined,
|
|
123
|
+
priorEmptyImplementation = 0,
|
|
124
|
+
): EmptyImplementationJudgement | null {
|
|
125
|
+
const signals: string[] = [];
|
|
126
|
+
for (const { name, patterns } of EMPTY_IMPLEMENTATION_SIGNALS) {
|
|
127
|
+
if ((mustFix ?? []).some(fix => typeof fix === 'string' && patterns.some(pattern => pattern.test(fix)))) signals.push(name);
|
|
128
|
+
}
|
|
129
|
+
if (!signals.length) return null;
|
|
130
|
+
const move: EmptyImplementationMove = priorEmptyImplementation >= 1 ? 'needs-owner' : 'reimplement';
|
|
131
|
+
const disposition = move === 'needs-owner' ? '두 번째 빈 구현 — 칸 주인에게 이관' : '같은 PR 수리로는 수렴 불가 — 같은 칸 새 발사(시험 먼저)';
|
|
132
|
+
return { move, signals, reason: `빈 구현 must-fix(${signals.join(' · ')}) — ${disposition}` };
|
|
133
|
+
}
|
|
134
|
+
|
|
79
135
|
export interface TaskJudgement {
|
|
80
136
|
move: TaskMove;
|
|
81
137
|
stage: 'observing' | 'closing' | 'reviewing' | 'repairing' | 'waiting' | 'escalated';
|
|
@@ -44,6 +44,8 @@ export const PARENT_HOST_ENV = 'ELANOUS_TA_PARENT_HOST';
|
|
|
44
44
|
const DEFAULT_REMOTE_ELANOUS = '$HOME/.local/share/elanous/bin/elanous';
|
|
45
45
|
const DEFAULT_REMOTE_CONFIG_DIR = '$HOME/.elanous';
|
|
46
46
|
const HOST_RE = /^[A-Za-z0-9][A-Za-z0-9._@-]{0,127}$/;
|
|
47
|
+
/** A parent can wait for a child for tens of minutes; the two-minute HTTP refresh floor is too short here. */
|
|
48
|
+
export const PARENT_CHILD_CREDENTIAL_MIN_REMAINING_MS = 60 * 60_000;
|
|
47
49
|
|
|
48
50
|
/** Missing child-provider metadata keeps the established Pod default: the HQ Codex mirror is needed. */
|
|
49
51
|
export function shouldInstallRemoteCodexAccess(effectiveChildProvider: string | undefined): boolean {
|
|
@@ -81,7 +83,7 @@ export function resolveParentHosts(config: ParentHostSetting | undefined, env: N
|
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
/** Capacity sample is read on the host before launch. Unknown or saturated capacity is not a positive weight. */
|
|
84
|
-
export interface ParentHostCapacity { active: number; waiting: number; approvalHeadroom: number; load: number }
|
|
86
|
+
export interface ParentHostCapacity { active: number; waiting: number; limit: number; headroom: number; approvalHeadroom: number; load: number }
|
|
85
87
|
|
|
86
88
|
export interface ParentHostPodFit {
|
|
87
89
|
state: 'fits' | 'never-fits' | 'unmeasured';
|
|
@@ -133,13 +135,13 @@ const LOAD_MARKER = '__ELANOUS_PARENT_LOAD__';
|
|
|
133
135
|
/** Best-effort macOS `ps` fallback; Linux/WSL uses argv boundaries below. */
|
|
134
136
|
export const PARENT_HOST_ACTIVE_FILTER = String.raw`/^(([^ ]+\/)?(bun|node|nodejs) )?([^ ]+\/)?elanous(\.mjs)?( --config-dir [^ ]+)? harness (say|ask)( |$)/ && / --no-auto-merge( |$)/ && !/ --substrate local( |$)/ && !/^([^ ]+\/)?[^ ]*sh -c/`;
|
|
135
137
|
/** Count exact Linux argv entries so Pod-local commands and goal text cannot masquerade as host parents. */
|
|
136
|
-
export const PARENT_HOST_PROC_COUNT_SCRIPT = "count=0; proc_root=${1:-/proc}; for file in \"$proc_root\"/[0-9]*/cmdline; do [ -r \"$file\" ] || continue; argv=(); while IFS= read -r -d '' arg; do argv+=(\"$arg\"); done < \"$file\" 2>/dev/null || true; [ ${#argv[@]} -ge 3 ] || continue; program=\"${argv[0]##*/}\"; case \"$program\" in elanous|elanous.mjs) ;; bun|node|nodejs) script_match=0; for ((i=1; i<${#argv[@]}; i++)); do if [[ \"${argv[i]}\" == */elanous.mjs ]]; then script_match=1; break; fi; [[ \"${argv[i]}\" == harness ]] && break; done; [ \"$script_match\" -eq 1 ] || continue ;; *) continue ;; esac; harness=0; for ((i=0; i+1<${#argv[@]}; i++)); do if [[ \"${argv[i]}\" == harness && ( \"${argv[i+1]}\" == say || \"${argv[i+1]}\" == ask ) ]]; then harness=1; break; fi; done; [ \"$harness\" -eq 1 ] || continue; has_no_auto_merge=0; for arg in \"${argv[@]}\"; do [[ \"$arg\" == --no-auto-merge ]] && has_no_auto_merge=1; done; [ \"$has_no_auto_merge\" -eq 1 ] || continue; local_substrate=0; for ((i=0; i+1<${#argv[@]}; i++)); do if [[ \"${argv[i]}\" == --substrate && \"${argv[i+1]}\" == local ]]; then local_substrate=1; break; fi; done; [ \"$local_substrate\" -eq 1 ] || count=$((count+1)); done; printf '__ELANOUS_PARENT_CAPACITY__%s\\n' \"$count\""
|
|
138
|
+
export const PARENT_HOST_PROC_COUNT_SCRIPT = "count=0; proc_root=${1:-/proc}; for file in \"$proc_root\"/[0-9]*/cmdline; do [ -r \"$file\" ] || continue; argv=(); while IFS= read -r -d '' arg; do argv+=(\"$arg\"); done < \"$file\" 2>/dev/null || true; [ ${#argv[@]} -ge 3 ] || continue; program=\"${argv[0]##*/}\"; case \"$program\" in elanous|elanous.mjs) ;; bun|node|nodejs) script_match=0; for ((i=1; i<${#argv[@]}; i++)); do if [[ \"${argv[i]}\" == */elanous.mjs ]]; then script_match=1; break; fi; [[ \"${argv[i]}\" == harness ]] && break; done; [ \"$script_match\" -eq 1 ] || continue ;; *) continue ;; esac; harness=0; for ((i=0; i+1<${#argv[@]}; i++)); do if [[ \"${argv[i]}\" == harness && ( \"${argv[i+1]}\" == say || \"${argv[i+1]}\" == ask ) ]]; then harness=1; break; fi; done; [ \"$harness\" -eq 1 ] || continue; has_no_auto_merge=0; for arg in \"${argv[@]}\"; do [[ \"$arg\" == --no-auto-merge ]] && has_no_auto_merge=1; done; [ \"$has_no_auto_merge\" -eq 1 ] || continue; local_substrate=0; for ((i=0; i+1<${#argv[@]}; i++)); do if [[ \"${argv[i]}\" == --substrate && \"${argv[i+1]}\" == local ]]; then local_substrate=1; break; fi; done; [ \"$local_substrate\" -eq 1 ] && continue; cgroup_file=${file%cmdline}cgroup; if [ ! -r $cgroup_file ]; then [ ! -d ${file%/cmdline} ] && continue; printf '__ELANOUS_PARENT_CAPACITY_ERROR__cgroup-unreadable\\n'; exit 1; fi; cgroup=$(cat $cgroup_file 2>/dev/null) || { [ ! -d ${file%/cmdline} ] && continue; printf '__ELANOUS_PARENT_CAPACITY_ERROR__cgroup-unreadable\\n'; exit 1; }; case $cgroup in *docker*|*kubepods*|*containerd*|*libpod*|*lxc*) continue;; esac; count=$((count+1)); done; printf '__ELANOUS_PARENT_CAPACITY__%s\\n' \"$count\""
|
|
137
139
|
/** Recent admission decisions are the host's measured approval backlog, not an inferred process count. */
|
|
138
140
|
export function readParentHostCapacity(target: ParentHostConfig, ssh: SshRunner = defaultSshRunner): ParentHostCapacity | null {
|
|
139
141
|
const executable = remotePath(target.elanous ?? DEFAULT_REMOTE_ELANOUS);
|
|
140
142
|
const configDir = remotePath(target.configDir ?? DEFAULT_REMOTE_CONFIG_DIR);
|
|
141
143
|
const unavailable = (reason: string): null => { try { debug.log('task-agent.parent-host', 'capacity-unavailable', { host: target.host, reason }); } catch { /* fail-soft */ } return null; };
|
|
142
|
-
const processCount = `if [ -r /proc/self/cmdline ]; then if command -v bash >/dev/null 2>&1; then bash -c ${shellQuote(PARENT_HOST_PROC_COUNT_SCRIPT)} -- /proc; else printf "${CAPACITY_ERROR_MARKER}bash-unavailable\\n"; exit 1; fi; else parents=$(ps -Ao command) || exit 1; printf '%s\\n' "$parents" | awk '${PARENT_HOST_ACTIVE_FILTER} { n++ } END { print "${CAPACITY_MARKER}" n+0 }'; fi`;
|
|
144
|
+
const processCount = `if [ -r /proc/self/cmdline ]; then if command -v bash >/dev/null 2>&1; then bash -c ${shellQuote(PARENT_HOST_PROC_COUNT_SCRIPT)} -- /proc || exit 1; else printf "${CAPACITY_ERROR_MARKER}bash-unavailable\\n"; exit 1; fi; else parents=$(ps -Ao command) || exit 1; printf '%s\\n' "$parents" | awk '${PARENT_HOST_ACTIVE_FILTER} { n++ } END { print "${CAPACITY_MARKER}" n+0 }'; fi`;
|
|
143
145
|
const script = `${processCount}; `
|
|
144
146
|
+ `${executable} --config-dir ${configDir} logs --event admit-by-usage --since 5m --json --limit 1000 || exit 1; `
|
|
145
147
|
+ `printf '\\n${APPROVAL_MARKER}\\n'; `
|
|
@@ -147,7 +149,8 @@ export function readParentHostCapacity(target: ParentHostConfig, ssh: SshRunner
|
|
|
147
149
|
+ `cores=$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null) || exit 1; printf '${LOAD_MARKER}cores=%s\\n' "$cores"`;
|
|
148
150
|
try {
|
|
149
151
|
const result = ssh(target.host, script, 15_000);
|
|
150
|
-
if (result.status !== 0) return unavailable(result.stdout.includes(`${CAPACITY_ERROR_MARKER}bash-unavailable`) ? 'bash-unavailable'
|
|
152
|
+
if (result.status !== 0) return unavailable(result.stdout.includes(`${CAPACITY_ERROR_MARKER}bash-unavailable`) ? 'bash-unavailable'
|
|
153
|
+
: result.stdout.includes(`${CAPACITY_ERROR_MARKER}cgroup-unreadable`) ? 'cgroup-unreadable' : 'remote-command-failed');
|
|
151
154
|
const activeMatch = new RegExp(`^${CAPACITY_MARKER}(\\d+)$`, 'm').exec(result.stdout);
|
|
152
155
|
const boundary = result.stdout.indexOf(`\n${APPROVAL_MARKER}\n`);
|
|
153
156
|
const logsStart = result.stdout.indexOf('\n');
|
|
@@ -181,12 +184,13 @@ export function readParentHostCapacity(target: ParentHostConfig, ssh: SshRunner
|
|
|
181
184
|
decisions.set(data.runId, data.recommended as number);
|
|
182
185
|
}
|
|
183
186
|
const waiting = [...decisions.values()].filter((n) => n === 0).length;
|
|
184
|
-
|
|
187
|
+
const headroom = Math.max(0, capacity - active - waiting);
|
|
188
|
+
return { active, waiting, limit: capacity, headroom, approvalHeadroom: headroom, load: Math.max(0, cpu / (cores * 100)) };
|
|
185
189
|
} catch { return unavailable('capacity-parse-failed'); }
|
|
186
190
|
}
|
|
187
191
|
|
|
188
192
|
/** Weighted rendezvous rank with evidence fields for launch-time observation. */
|
|
189
|
-
export function rankParentHosts(targets: readonly ParentHostConfig[], runId: string, capacities: Readonly<Record<string, ParentHostCapacity | null>>): Array<{ target: ParentHostConfig; weight: number; score: number }> {
|
|
193
|
+
export function rankParentHosts(targets: readonly ParentHostConfig[], runId: string, capacities: Readonly<Record<string, Pick<ParentHostCapacity, 'approvalHeadroom' | 'load'> | null>>): Array<{ target: ParentHostConfig; weight: number; score: number }> {
|
|
190
194
|
return targets.map((target, index) => {
|
|
191
195
|
const sample = capacities[target.host];
|
|
192
196
|
const weight = sample && Number.isSafeInteger(sample.approvalHeadroom) && sample.approvalHeadroom > 0 && Number.isFinite(sample.load) && sample.load >= 0
|
|
@@ -264,14 +268,22 @@ export interface ParentHostPreflight { ok: boolean; gaps: string[]; warnings: st
|
|
|
264
268
|
export function preflightScript(target: ParentHostConfig): string {
|
|
265
269
|
const elanous = remotePath(target.elanous ?? DEFAULT_REMOTE_ELANOUS);
|
|
266
270
|
const configDir = remotePath(target.configDir ?? DEFAULT_REMOTE_CONFIG_DIR);
|
|
271
|
+
const grokCredentialFloorSeconds = Math.ceil(PARENT_CHILD_CREDENTIAL_MIN_REMAINING_MS / 1_000);
|
|
267
272
|
return [
|
|
268
273
|
`echo "version=$(${elanous} --version 2>/dev/null | tail -1 | cut -d' ' -f1)"`,
|
|
269
274
|
`test -f ${configDir}/config.json && echo config=1`,
|
|
270
275
|
`grep -Eq '"podPool"[[:space:]]*:[[:space:]]*"[^"[:space:]]+' ${configDir}/config.json 2>/dev/null && echo podPool=1`,
|
|
271
276
|
`(cd ${shellQuote(target.cwd)} 2>/dev/null && git rev-parse --is-inside-work-tree >/dev/null 2>&1) && echo repo=1`,
|
|
272
277
|
`command -v kubectl >/dev/null 2>&1 && echo kubectl=1`,
|
|
278
|
+
`{ command -v grok >/dev/null 2>&1 || [ -x "$HOME/.grok/bin/grok" ]; } && echo grokCli=1`,
|
|
279
|
+
`{ command -v codex >/dev/null 2>&1 || [ -x "$HOME/.local/bin/codex" ]; } && echo codexCli=1`,
|
|
273
280
|
`n=$(grep -Ec '^[[:space:]]*"openai-codex(:[^"]*)?"[[:space:]]*:[[:space:]]*\\{' ${configDir}/auth.json 2>/dev/null); echo "codexAccounts=\${n:-0}"`,
|
|
274
281
|
`{ grep -Eq '"key"[[:space:]]*:[[:space:]]*"[^"]+"' "$HOME/.grok/auth.json" 2>/dev/null || [ -n "\${XAI_API_KEY:-}\${GROK_API_KEY:-}\${GROK_CODE_XAI_API_KEY:-}" ]; } && echo grok=1`,
|
|
282
|
+
// The remote host owns its device-auth session. Ignore the legacy HQ mirror entry; it can outlive and mask the host credential.
|
|
283
|
+
// Read only expiry metadata, never credential values, and compare against the shared minimum lifetime.
|
|
284
|
+
`grokProbe=$(if [ ! -f "$HOME/.grok/auth.json" ]; then printf '0|'; else bun -e 'const fs=require("node:fs");try{const auth=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));const entries=Object.entries(auth).filter(([id])=>id!=="https://auth.x.ai::hq-mirror");const hasKey=entries.some(([,entry])=>typeof entry?.key==="string"&&entry.key.length>0);const expiries=entries.filter(([,entry])=>typeof entry?.expires_at==="string").map(([,entry])=>entry.expires_at).sort();process.stdout.write((hasKey?"1":"0")+"|"+(expiries.length?expiries[expiries.length-1]:""))}catch{}' "$HOME/.grok/auth.json" 2>/dev/null; fi); grokOtherKey=\${grokProbe%%|*}; grokExp=\${grokProbe#*|}`,
|
|
285
|
+
`grokFloor=$(date -u -d "@$(( $(date +%s) + ${grokCredentialFloorSeconds} ))" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -r "$(( $(date +%s) + ${grokCredentialFloorSeconds} ))" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || true); grokNow=$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || true)`,
|
|
286
|
+
`grokHost=$(if [ -n "$XAI_API_KEY$GROK_API_KEY$GROK_CODE_XAI_API_KEY" ]; then echo valid; elif [ -z "$grokProbe" ]; then echo unknown; elif [ -z "$grokExp" ]; then [ "$grokOtherKey" = 1 ] && echo unknown || echo missing; elif [ -z "$grokFloor" ] || [ -z "$grokNow" ]; then echo unknown; else printf '%s\n%s\n%s\n' "$grokExp" "$grokFloor" "$grokNow" | awk 'NR==1{e=$0} NR==2{f=$0} NR==3{n=$0} END{if (e >= f) print "valid"; else if (e >= n) print "expiring"; else print "expired"}'; fi); echo "grokHost=$grokHost"`,
|
|
275
287
|
`{ [ -s "\${ELANOUS_KEY_CACHE_DIR:-$HOME/.cache}/openrouter_api_key" ] || [ -n "\${OPENROUTER_API_KEY:-}" ]; } && echo openrouter=1`,
|
|
276
288
|
`true`,
|
|
277
289
|
].join('; ');
|
|
@@ -283,6 +295,8 @@ export interface PreflightInput {
|
|
|
283
295
|
localVersion: string;
|
|
284
296
|
/** HQ 착지 동결이 «발사도 막는» 상태인가 — 원격 부모는 그 동결을 못 본다. */
|
|
285
297
|
launchHoldActive: boolean;
|
|
298
|
+
/** Provider that the detached parent will use for its child. */
|
|
299
|
+
childProvider?: string;
|
|
286
300
|
ssh?: SshRunner;
|
|
287
301
|
}
|
|
288
302
|
|
|
@@ -306,11 +320,34 @@ export function judgeParentHostFacts(facts: Record<string, string>, input: Omit<
|
|
|
306
320
|
if (facts.podPool !== '1' && !input.podPoolOverride) gaps.push('remote-pod-pool-unset');
|
|
307
321
|
if (facts.repo !== '1') gaps.push('remote-repo-missing');
|
|
308
322
|
if (facts.kubectl !== '1') gaps.push('remote-kubectl-missing');
|
|
323
|
+
if (input.childProvider === 'grok' && facts.grokCli !== '1') gaps.push('grok-cli-missing');
|
|
324
|
+
if ((input.childProvider === 'openai-codex' || input.childProvider === 'codex') && facts.codexCli !== '1') gaps.push('codex-cli-missing');
|
|
309
325
|
}
|
|
310
326
|
if (input.launchHoldActive) gaps.push('hq-launch-freeze-active');
|
|
311
327
|
return gaps;
|
|
312
328
|
}
|
|
313
329
|
|
|
330
|
+
/** Host-side Grok credential states the preflight probe reports; HQ never sees the token itself. */
|
|
331
|
+
export type ParentHostGrokCredentialState = 'valid' | 'expiring' | 'expired' | 'missing' | 'unknown';
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* 순수 판정 — 원격 호스트가 스스로 보고한 grok 자격 상태 → **막는** gap 목록(GROK-MIRROR-REAL-SCOPE · 10-20 방향 전환).
|
|
335
|
+
*
|
|
336
|
+
* 왜 경고가 아니라 gap 인가: access-only 미러(4필드)는 원격 grok CLI 1.0.41 에서 `session/new` -32000 으로
|
|
337
|
+
* 거부됐고, HQ refresh_token 복사는 단일 주인 원칙 위반이다. ⇒ 호스트가 각자 device-auth 세션을 스스로
|
|
338
|
+
* 갱신하고, HQ 는 「쓸 수 있나」만 재서 **무효면 Grok 자식 발사 전에** 막는다(발사 뒤 -32000 반복 금지).
|
|
339
|
+
*
|
|
340
|
+
* ⛔ 상태를 «안 보고한» 호스트(구 판)는 막지 않는다 — 모름을 「죽었다」로 읽으면 멀쩡한 호스트가 조용히 빠진다.
|
|
341
|
+
*/
|
|
342
|
+
export function judgeParentHostGrokCredential(facts: Record<string, string>, opts: { childProvider?: string } = {}): string[] {
|
|
343
|
+
if (opts.childProvider !== 'grok' || facts.unreachable) return [];
|
|
344
|
+
const state = facts.grokHost as ParentHostGrokCredentialState | undefined;
|
|
345
|
+
if (state === 'missing') return ['grok-credential-missing'];
|
|
346
|
+
if (state === 'expiring') return ['grok-credential-expiring'];
|
|
347
|
+
if (state === 'expired') return ['grok-credential-expired'];
|
|
348
|
+
return [];
|
|
349
|
+
}
|
|
350
|
+
|
|
314
351
|
/** 순수 판정 — 원격 LLM 자격 사실 → 경고 목록(막지 않는다 · gaps 와 별개). 못 닿은 호스트는 사실이 없으므로 경고도 없다. */
|
|
315
352
|
export function judgeParentHostCredentials(facts: Record<string, string>): string[] {
|
|
316
353
|
if (facts.unreachable) return [];
|
|
@@ -330,7 +367,16 @@ export function preflightParentHost(input: PreflightInput): ParentHostPreflight
|
|
|
330
367
|
const at = line.indexOf('=');
|
|
331
368
|
if (at > 0) facts[line.slice(0, at).trim()] = line.slice(at + 1).trim();
|
|
332
369
|
}
|
|
333
|
-
const gaps = judgeParentHostFacts(facts, { localVersion: input.localVersion, launchHoldActive: input.launchHoldActive, podPoolOverride: Boolean(input.target.podPool) });
|
|
370
|
+
const gaps = judgeParentHostFacts(facts, { localVersion: input.localVersion, launchHoldActive: input.launchHoldActive, podPoolOverride: Boolean(input.target.podPool), ...(input.childProvider ? { childProvider: input.childProvider } : {}) });
|
|
371
|
+
// 호스트 자체 grok 자격은 «경고»가 아니라 발사 전 «차단» 축이다 — 무효면 OP 재로그인 요청 신호를 남긴다.
|
|
372
|
+
const credentialGaps = judgeParentHostGrokCredential(facts, { ...(input.childProvider ? { childProvider: input.childProvider } : {}) });
|
|
373
|
+
if (credentialGaps.length) {
|
|
374
|
+
try {
|
|
375
|
+
debug.log('task-agent.parent-host', 'grok-relogin-required', {
|
|
376
|
+
host: input.target.host, state: facts.grokHost ?? 'unknown', gaps: credentialGaps,
|
|
377
|
+
});
|
|
378
|
+
} catch { /* fail-soft */ }
|
|
379
|
+
}
|
|
334
380
|
const warnings = judgeParentHostCredentials(facts);
|
|
335
381
|
if (warnings.length) {
|
|
336
382
|
try {
|
|
@@ -342,7 +388,8 @@ export function preflightParentHost(input: PreflightInput): ParentHostPreflight
|
|
|
342
388
|
});
|
|
343
389
|
} catch { /* fail-soft */ }
|
|
344
390
|
}
|
|
345
|
-
|
|
391
|
+
const blocking = [...gaps, ...credentialGaps];
|
|
392
|
+
return { ok: blocking.length === 0, gaps: blocking, warnings, facts };
|
|
346
393
|
}
|
|
347
394
|
|
|
348
395
|
/** 원격이 «확실히 안 띄웠다»고 답했다 — 호출부가 로컬로 돌아가도 중복 발사가 아니다. */
|
|
@@ -360,9 +407,7 @@ export function launchRemoteParent(
|
|
|
360
407
|
args: readonly string[],
|
|
361
408
|
env: Record<string, string>,
|
|
362
409
|
ssh: SshRunner = defaultSshRunner,
|
|
363
|
-
grokMirrorResolver: () => OwnerGrokAccessMirror = resolveOwnerGrokAccessMirror,
|
|
364
410
|
effectiveChildProvider?: string,
|
|
365
|
-
now: () => number = Date.now,
|
|
366
411
|
): { pid: number; log: string } {
|
|
367
412
|
const argvProvider = childProviderFromArgs(args);
|
|
368
413
|
if (effectiveChildProvider && argvProvider && argvProvider !== effectiveChildProvider) {
|
|
@@ -371,9 +416,11 @@ export function launchRemoteParent(
|
|
|
371
416
|
const launchArgs = effectiveChildProvider && !argvProvider
|
|
372
417
|
? [...args.slice(0, 2), '--child-llm-provider', effectiveChildProvider, ...args.slice(2)]
|
|
373
418
|
: args;
|
|
419
|
+
// GROK-MIRROR-REAL-SCOPE: 원격 부모는 HQ access 미러를 «설치하지 않는다»(4필드 미러는 grok 1.0.41 에서
|
|
420
|
+
// `session/new` -32000 · HQ refresh_token 복사는 단일 주인 원칙 위반). 호스트가 각자 device-auth 로
|
|
421
|
+
// 자체 갱신 세션을 쓰고, HQ 는 preflight 에서 «유효성»만 재서 무효면 발사 전에 막는다.
|
|
374
422
|
if ((effectiveChildProvider ?? argvProvider) === 'grok') {
|
|
375
|
-
|
|
376
|
-
installRemoteGrokAccess(target, mirror, ssh, now);
|
|
423
|
+
try { debug.log('task-agent.parent-host', 'grok-host-credential', { host: target.host, runId: env.ELANOUS_RUN_ID ?? 'unknown', source: 'host-device-auth' }); } catch { /* fail-soft */ }
|
|
377
424
|
}
|
|
378
425
|
const result = ssh(target.host, remoteLaunchScript(target, launchArgs, env), 30_000);
|
|
379
426
|
const log = remoteParentLogPath(target, env.ELANOUS_RUN_ID ?? 'unknown');
|
|
@@ -2,10 +2,10 @@ import { spawnSync } from 'node:child_process';
|
|
|
2
2
|
import { debug } from '../debug/log.js';
|
|
3
3
|
import { listChecklist, setItemIfSnapshot, type Checklist } from '../release-loop/checklist.js';
|
|
4
4
|
import { judgeLandedCell, parseJudgeSignals, type GreenVerdict } from '../release-loop/landed-to-green.js';
|
|
5
|
-
import { HAND_MOVE_HISTORY_EVENT, LIVE_MOVE_HISTORY_EVENT, LIVE_MOVE_RESULT_EVENT, cardPrNumber, readTaskAgentState, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
|
|
5
|
+
import { HAND_MOVE_HISTORY_EVENT, LIVE_MOVE_HISTORY_EVENT, LIVE_MOVE_RESULT_EVENT, cardPrNumber, readTaskAgentState, taskAgentStatePath, updateTaskCard, recordPostLandImplFindings, type TaskCard } from './task-hand.js';
|
|
6
6
|
import { isGoalOnlyPr } from './judge.js';
|
|
7
7
|
|
|
8
|
-
export interface LandedTaskPr { number: number; url: string; headRefOid: string; state: string; baseRefName: string; mergedAt: string; files?: Array<{ path: string }> }
|
|
8
|
+
export interface LandedTaskPr { number: number; url: string; headRefOid: string; state: string; baseRefName: string; mergedAt: string; body?: string | null; files?: Array<{ path: string }> }
|
|
9
9
|
export interface PostlandDeps {
|
|
10
10
|
statePath?: string;
|
|
11
11
|
versions: readonly string[];
|
|
@@ -144,6 +144,39 @@ export function closeMergedTaskCard(pr: LandedTaskPr, cwd: string, deps: Postlan
|
|
|
144
144
|
return item.id;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
+
/** Awaited postland feedback for the confirmed merge caller; card+PR URL/head must still bind exactly. */
|
|
148
|
+
export async function recordMergedTaskImplFindings(
|
|
149
|
+
pr: LandedTaskPr,
|
|
150
|
+
cwd: string,
|
|
151
|
+
options: { statePath?: string; ledgerDir?: string; followUp?: NonNullable<Parameters<typeof recordPostLandImplFindings>[2]>['followUp'] } = {},
|
|
152
|
+
): Promise<Awaited<ReturnType<typeof recordPostLandImplFindings>> | null> {
|
|
153
|
+
if (pr.state !== 'MERGED' || pr.baseRefName !== 'main' || !pr.url || !pr.headRefOid || pr.body == null) return null;
|
|
154
|
+
const path = options.statePath ?? taskAgentStatePath();
|
|
155
|
+
const tasks = readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(path).tasks ?? {};
|
|
156
|
+
const cards = Object.values(tasks).filter((card) => card.taLand && cardPrNumber(card) === pr.number
|
|
157
|
+
&& typeof card.pr === 'object' && card.pr.url?.replace(/\/+$/, '') === pr.url!.replace(/\/+$/, '')
|
|
158
|
+
&& card.status === 'done' && card.prTerminal?.pr === pr.number
|
|
159
|
+
&& card.prTerminal.head.toLowerCase() === pr.headRefOid!.toLowerCase()
|
|
160
|
+
&& card.prTerminal.url.replace(/\/+$/, '') === pr.url!.replace(/\/+$/, '')
|
|
161
|
+
&& (card.landAttempts ?? []).some((attempt) => attempt.pr === pr.number && attempt.head.toLowerCase() === pr.headRefOid!.toLowerCase()));
|
|
162
|
+
if (cards.length !== 1) {
|
|
163
|
+
debug.log('task-agent', 'impl-findings-skipped', { pr: pr.number, reason: cards.length ? 'ambiguous-postland-card' : 'postland-card-not-bound' });
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
const card = cards[0]!;
|
|
167
|
+
const result = await recordPostLandImplFindings(card, { prBody: pr.body, ask: card.text }, {
|
|
168
|
+
...(options.ledgerDir ? { ledgerDir: options.ledgerDir } : {}),
|
|
169
|
+
...(options.followUp ? { followUp: options.followUp } : {}),
|
|
170
|
+
});
|
|
171
|
+
debug.log('task-agent', 'impl-findings-postland-result', {
|
|
172
|
+
pr: pr.number, card: card.id, appended: result?.appended ?? false,
|
|
173
|
+
lessonIds: result?.lessonIds ?? [], injectedSections: result?.injectedSections ?? [], skippedSections: result?.skippedSections ?? [],
|
|
174
|
+
authoringInjectionBytes: result ? Buffer.byteLength(result.authoringInjection, 'utf8') : 0,
|
|
175
|
+
followUp: result?.followUp?.queued ?? null,
|
|
176
|
+
});
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
|
|
147
180
|
const defaultGit = (cwd: string, args: string[]): { status: number; stdout: string; stderr: string } => {
|
|
148
181
|
const run = spawnSync('git', args, { cwd, encoding: 'utf8' });
|
|
149
182
|
return { status: run.status ?? 1, stdout: run.stdout ?? '', stderr: run.stderr ?? '' };
|
|
@@ -45,14 +45,14 @@ import { remoteLedgerMirrorDir } from './parent-host.js';
|
|
|
45
45
|
import { appendLandOrderRow, joinLandOrderRow } from './land-order-ledger.js';
|
|
46
46
|
import { recordLiveMoveHistory } from './live-move-history.js';
|
|
47
47
|
import { advanceLandedPieceMission } from './mission.js';
|
|
48
|
-
import { runRepairCycle, type RepairLaunchRequest } from './repair-cycle.js';
|
|
48
|
+
import { runRepairCycle, resolveRepairOwner, type RepairLaunchRequest } from './repair-cycle.js';
|
|
49
49
|
import { repairMustFixFromReview, repairReviewDigest } from './repair-review.js';
|
|
50
50
|
import type { RepairCasOutcome, RepairCasRequest } from './repair-branch-cas.js';
|
|
51
51
|
import { configuredMsb1Worker, defaultLandPrHead, defaultPrHead, defaultReviewRepoCandidates, executeLiveLand, executeLiveReview, landRetryPending, remoteTaWorkerCommand, type LiveMoveDeps, type LiveMoveResult, type PrHeadView, type ReviewRepoCandidate, type TaskAgentLiveMove } from './live-moves.js';
|
|
52
52
|
import { capturedLandReview, captureReviewResults, parseReviewResultOutput, pendingReviewResults, reviewResultPath, type ParsedReviewResult } from './review-result-capture.js';
|
|
53
53
|
import { boundPrTerminal, cardPrNumber, LIVE_MOVE_RESULT_EVENT, readTaskCard, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
|
|
54
54
|
import { verifiedTrainLanding, type TrainLanding } from './train-landing.js';
|
|
55
|
-
import { isGoalOnlyPr } from './judge.js';
|
|
55
|
+
import { isGoalOnlyPr, judgeEmptyImplementation } from './judge.js';
|
|
56
56
|
import { defaultPrFiles } from './shadow.js';
|
|
57
57
|
|
|
58
58
|
export const REJUDGE_ON_HEAD_EVENT = 'rejudge-on-head';
|
|
@@ -671,6 +671,50 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
|
|
|
671
671
|
step('repair', 'repair-stopped', 'PR branch name unavailable', true);
|
|
672
672
|
return outcomes;
|
|
673
673
|
}
|
|
674
|
+
// 빈 구현 must-fix — 같은 PR 수리(narrow-relaunch)로는 수렴하지 않는다: 첫 회는 같은 칸 새 발사(시험 먼저), 두 번째는 칸 주인 이관.
|
|
675
|
+
const priorEmpty = (card.history ?? []).filter((entry) => entry.event === REJUDGE_ON_HEAD_EVENT && entry.kind === 'repair'
|
|
676
|
+
&& (entry.effect === 'empty-implementation-reimplement' || entry.effect === 'empty-implementation-needs-owner')).length;
|
|
677
|
+
const emptyJudgement = mustFix?.length ? judgeEmptyImplementation(mustFix, priorEmpty) : null;
|
|
678
|
+
if (emptyJudgement) {
|
|
679
|
+
if (emptyJudgement.move === 'needs-owner') {
|
|
680
|
+
let ownerSeat: string | null = card.seat ?? null;
|
|
681
|
+
try {
|
|
682
|
+
const owner = resolveRepairOwner(card);
|
|
683
|
+
if (owner?.seat) ownerSeat = owner.seat;
|
|
684
|
+
} catch { /* 결정 실패 시 칸 좌석을 유지한다 */ }
|
|
685
|
+
if (ownerSeat) {
|
|
686
|
+
try {
|
|
687
|
+
(deps.notifyRepair ?? (() => {}))(ownerSeat,
|
|
688
|
+
`빈 구현 needs-owner: 칸 ${card.id} PR #${pr} head ${toHead.slice(0, 12)} — ${emptyJudgement.reason} · 칸 주인이 재구현 지시를 결정한다`);
|
|
689
|
+
} catch { /* 통보 실패가 이관을 막지 않는다 */ }
|
|
690
|
+
}
|
|
691
|
+
const handedOver = updateTaskCard(statePath, card.id, (current) => {
|
|
692
|
+
if (!current) return undefined;
|
|
693
|
+
if ((current.history ?? []).some((entry) => entry.event === REJUDGE_ON_HEAD_EVENT && entry.kind === 'repair'
|
|
694
|
+
&& entry.pr === pr && entry.head && sameHead(entry.head, toHead) && entry.effect === 'empty-implementation-needs-owner')) return current;
|
|
695
|
+
return { ...current, status: 'failed',
|
|
696
|
+
history: [...(current.history ?? []), { at: now().toISOString(), event: 'pr-superseded-candidate', kind: 'repair', pr,
|
|
697
|
+
...(toHead ? { head: toHead } : {}), effect: 'superseded-candidate',
|
|
698
|
+
detail: `빈 구현 needs-owner — 옛 PR #${pr} 은 superseded 후보` }] };
|
|
699
|
+
});
|
|
700
|
+
if (handedOver) step('repair', 'empty-implementation-needs-owner',
|
|
701
|
+
`${emptyJudgement.reason} · 칸 주인 ${ownerSeat ?? 'unknown'} 이관 · 옛 PR #${pr} superseded 후보`, true);
|
|
702
|
+
return outcomes;
|
|
703
|
+
}
|
|
704
|
+
const relaunched = updateTaskCard(statePath, card.id, (current) => {
|
|
705
|
+
if (!current) return undefined;
|
|
706
|
+
if ((current.history ?? []).some((entry) => entry.event === REJUDGE_ON_HEAD_EVENT && entry.kind === 'repair'
|
|
707
|
+
&& entry.pr === pr && entry.head && sameHead(entry.head, toHead) && entry.effect === 'empty-implementation-reimplement')) return current;
|
|
708
|
+
return { ...current, status: 'launch-failed',
|
|
709
|
+
text: `${current.text}\n- 재구현 지시(빈 구현 판정): 시험 먼저 — 구현 전에 실패하는 시험(RED)을 먼저 쓰고 구현 파일 변경 0이 되지 않게 한다.`,
|
|
710
|
+
history: [...(current.history ?? []), { at: now().toISOString(), event: 'pr-superseded-candidate', kind: 'repair', pr,
|
|
711
|
+
...(toHead ? { head: toHead } : {}), effect: 'superseded-candidate',
|
|
712
|
+
detail: `빈 구현 재구현 — 옛 PR #${pr} 은 superseded 후보` }] };
|
|
713
|
+
});
|
|
714
|
+
if (relaunched) step('repair', 'empty-implementation-reimplement',
|
|
715
|
+
`${emptyJudgement.reason} · 같은 칸 새 발사(시험 먼저) · 옛 PR #${pr} superseded 후보`, true);
|
|
716
|
+
return outcomes;
|
|
717
|
+
}
|
|
674
718
|
const result = await runRepairCycle({ card, statePath, repo: cwd, pr, head: toHead, branch: view.branch,
|
|
675
719
|
mustFix: mustFix ?? [], liveMoves: deps.liveMoves, now: now(), readFile: read,
|
|
676
720
|
...(deps.requestRepair ? { request: deps.requestRepair } : {}),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** HQ same-PR repair launch and result collection; the reviewed head is the sole source of truth. */
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
3
4
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
5
|
import { dirname, join, resolve, sep } from 'node:path';
|
|
5
6
|
import { debug } from '../debug/log.js';
|
|
@@ -13,13 +14,14 @@ import { applyRepairBundle, type RepairCasOutcome, type RepairCasRequest } from
|
|
|
13
14
|
import { pairMoveId, repairNextMove } from './repair-next-move.js';
|
|
14
15
|
import type { SupervisorGoalDeficit } from '../self-implement/goal-supervisor-fill.js';
|
|
15
16
|
import { loadRunLedger, type RunLedgerEntry } from '../self-implement/run-ledger.js';
|
|
16
|
-
import { parseRepairWorkerResult } from './repair-worker.js';
|
|
17
|
+
import { parseRepairWorkerResult, repairFailureSignature } from './repair-worker.js';
|
|
17
18
|
import { TASK_SEATS, readTaskCard, updateTaskCard, type TaskCard, type TaskChildLlm, type TaskSeat } from './task-hand.js';
|
|
18
19
|
|
|
19
20
|
const WAIT_MS = 90 * 60_000;
|
|
20
21
|
const ESCALATE_MS = 6 * 60 * 60_000;
|
|
21
22
|
const ALERT_CLAIM_STALE_MS = 10 * 60_000;
|
|
22
23
|
const safe = (value: string) => value.replace(/[^A-Za-z0-9._-]/g, '_');
|
|
24
|
+
const reviewSignature = (mustFix: readonly string[]) => createHash('sha256').update(JSON.stringify(mustFix)).digest('hex');
|
|
23
25
|
|
|
24
26
|
export interface RepairLaunchRequest {
|
|
25
27
|
card: string; pr: number; head: string; repo: string; resultPath: string;
|
|
@@ -108,9 +110,9 @@ export async function repairModelAvailability(readInputs: () => Promise<Pick<Bud
|
|
|
108
110
|
export function alternateRepairModel(card: TaskCard, availability: RepairModelAvailability = { codexSubscription: false, grokSubscription: false }): { from: string; to: TaskChildLlm } {
|
|
109
111
|
const last = card.repairs?.at(-1);
|
|
110
112
|
const from = last?.toModel ?? (card.childLlm ? `${card.childLlm.provider}/${card.childLlm.model}` : 'unknown');
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
const glm: TaskChildLlm = { provider: '
|
|
113
|
+
// Pin the full model route; a bare glm-5.3 can be ambiguous in the Pod review path.
|
|
114
|
+
// A failed full GLM repair must never be retried with the smaller flash model.
|
|
115
|
+
const glm: TaskChildLlm = { provider: 'openrouter', model: 'openrouter/z-ai/glm-5.3' };
|
|
114
116
|
const sol: TaskChildLlm = { provider: 'openai-codex', model: 'gpt-6-sol' };
|
|
115
117
|
const grok: TaskChildLlm = { provider: 'grok', model: 'grok-4.6' };
|
|
116
118
|
const tier = card.tier ?? '중';
|
|
@@ -275,6 +277,8 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
|
|
|
275
277
|
}
|
|
276
278
|
}
|
|
277
279
|
const status = applied?.ok ? 'applied' : applied?.unconfirmed ? 'unconfirmed' : 'failed';
|
|
280
|
+
const failureSignature = status === 'failed' && !result.ok
|
|
281
|
+
? result.failureSignature ?? repairFailureSignature(result.reason ?? '') : null;
|
|
278
282
|
// NEXTMOVE-GENERAL-RELAUNCH-MOVEID — 결과 파일의 수 id 를 카드(발사 순간 적은 값)와 짝짓는다. 못 짝지으면 관측만(소비는 그대로).
|
|
279
283
|
const pairing = pairMoveId(latest.moveId, result.moveId);
|
|
280
284
|
if (pairing.kind === 'unpaired') try { debug.log('task-agent', 'move-id-unpaired', { card: card.id, pr, head: latest.head,
|
|
@@ -282,13 +286,16 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
|
|
|
282
286
|
const pairedMoveId = pairing.kind === 'paired' ? { moveId: pairing.moveId } : {};
|
|
283
287
|
try { debug.log('task-agent', 'repair-attempt-result', { card: card.id, pr, head: latest.head,
|
|
284
288
|
runId: latest.runId, failureType: status === 'applied' || status === 'unconfirmed' ? null : result.ok ? 'artifact-or-cas' : 'worker',
|
|
285
|
-
model: latest.toModel, resultPath: latest.resultPath, artifactDir: result.artifactDir ?? null, status, detail
|
|
289
|
+
model: latest.toModel, resultPath: latest.resultPath, artifactDir: result.artifactDir ?? null, status, detail,
|
|
290
|
+
...(result.gateFailureTests ? { gateFailureTests: result.gateFailureTests } : {}) });
|
|
286
291
|
} catch { /* diagnostics cannot change the result */ }
|
|
287
292
|
try {
|
|
288
293
|
updateTaskCard(statePath, card.id, (current) => current?.repairs?.some((entry) => entry.runId === latest.runId
|
|
289
294
|
&& (entry.status === 'requested' || (claimedThisCycle && entry.status === 'unconfirmed' && entry.commit === result?.result?.commit)))
|
|
290
295
|
? { ...current, repairs: current.repairs.map((entry) => entry.runId === latest.runId
|
|
291
|
-
? { ...entry, status, detail, ...(
|
|
296
|
+
? { ...entry, status, detail, ...(failureSignature ? { failureSignature } : {}),
|
|
297
|
+
...(failureSignature?.startsWith('gate:') && result.gateFailureTests ? { gateFailureTests: result.gateFailureTests } : {}),
|
|
298
|
+
...(result?.result && status === 'unconfirmed' ? { commit: result.result.commit,
|
|
292
299
|
bundleSha256: result.result.bundleSha256, bundlePath: join(resolve(result.artifactDir!), 'commit.bundle') } : {}),
|
|
293
300
|
...(applied?.ok ? { commit: applied.toHead } : {}) } : entry),
|
|
294
301
|
history: [...(current.history ?? []), { at: now.toISOString(), event: 'repair-result', pr, head: latest.head,
|
|
@@ -428,10 +435,61 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
|
|
|
428
435
|
return { decision: 'would-repair', reason };
|
|
429
436
|
}
|
|
430
437
|
const next = attempts.length + 1;
|
|
431
|
-
const runId = mintRunId();
|
|
432
438
|
// 결정 순간 만든 수 id — 아래 발사·카드·관측이 «이 값»만 쓴다(다시 만들지 않는다).
|
|
433
439
|
const moveId = judged.moveId;
|
|
434
440
|
const { from, to } = alternateRepairModel(card, availability);
|
|
441
|
+
const nextModel = `${to.provider}/${to.model}`;
|
|
442
|
+
const repeatSignature = latest?.status === 'failed' && latest.head.toLowerCase() === head.toLowerCase()
|
|
443
|
+
&& latest.reviewSignature === reviewSignature(input.mustFix) && latest.failureSignature
|
|
444
|
+
&& (latest.failureSignature.startsWith('gate:sha256:')
|
|
445
|
+
|| latest.failureSignature.startsWith('provider:ambiguous-primary:') && latest.toModel === nextModel)
|
|
446
|
+
? latest.failureSignature : null;
|
|
447
|
+
if (repeatSignature) {
|
|
448
|
+
const prior = latest!;
|
|
449
|
+
const tests = prior.gateFailureTests?.slice(0, 4).join(' | ');
|
|
450
|
+
const reason = `same PR/head/review deterministic repair failure ${repeatSignature}; owner repair required${tests ? ` · ${tests}` : ''}`;
|
|
451
|
+
let recorded = false;
|
|
452
|
+
updateTaskCard(statePath, card.id, (current) => {
|
|
453
|
+
if (!current || current.status !== 'launched' || !current.repairs?.some((entry) =>
|
|
454
|
+
entry.runId === prior.runId && entry.status === 'failed' && entry.failureSignature === repeatSignature
|
|
455
|
+
&& entry.reviewSignature === prior.reviewSignature)
|
|
456
|
+
|| current.history?.some((entry) => entry.event === 'repair-signature-repeat-stopped' && entry.pr === pr
|
|
457
|
+
&& entry.head?.toLowerCase() === head.toLowerCase() && entry.runId === prior.runId)) return undefined;
|
|
458
|
+
recorded = true;
|
|
459
|
+
return { ...current, status: 'failed', history: [...(current.history ?? []),
|
|
460
|
+
{ at: now.toISOString(), event: 'repair-signature-repeat-stopped', pr, head, runId: prior.runId, detail: reason }] };
|
|
461
|
+
});
|
|
462
|
+
if (recorded) try { debug.log('task-agent', 'repair-signature-repeat-stopped', { card: card.id, pr, head,
|
|
463
|
+
signature: repeatSignature, priorRunId: prior.runId, skippedRelaunch: true }); } catch { /* fail-soft */ }
|
|
464
|
+
let notifyClaimed = false;
|
|
465
|
+
updateTaskCard(statePath, card.id, (current) => {
|
|
466
|
+
const history = current?.history ?? [];
|
|
467
|
+
const lastAlert = history.filter((entry) => entry.runId === prior.runId && entry.event.startsWith('repair-repeat-owner-')).at(-1);
|
|
468
|
+
const staleClaim = lastAlert?.event === 'repair-repeat-owner-claimed'
|
|
469
|
+
&& now.getTime() - Date.parse(lastAlert.at) >= ALERT_CLAIM_STALE_MS;
|
|
470
|
+
if (!current || !history.some((entry) => entry.event === 'repair-signature-repeat-stopped'
|
|
471
|
+
&& entry.pr === pr && entry.head?.toLowerCase() === head.toLowerCase() && entry.runId === prior.runId)
|
|
472
|
+
|| lastAlert && lastAlert.event !== 'repair-repeat-owner-failed' && !staleClaim) return undefined;
|
|
473
|
+
notifyClaimed = true;
|
|
474
|
+
return { ...current, history: [...history,
|
|
475
|
+
{ at: now.toISOString(), event: 'repair-repeat-owner-claimed', pr, head, runId: prior.runId, detail: reason }] };
|
|
476
|
+
});
|
|
477
|
+
if (notifyClaimed) {
|
|
478
|
+
let event = 'repair-repeat-owner-sent';
|
|
479
|
+
let detail = reason;
|
|
480
|
+
try {
|
|
481
|
+
(input.notify ?? defaultNotify)(owner.seat, `${reason} · card ${card.id} · owner ${owner.seat} via ${owner.source}`);
|
|
482
|
+
} catch (error) {
|
|
483
|
+
event = 'repair-repeat-owner-failed';
|
|
484
|
+
detail = `${reason} · ${String(error).slice(0, 200)}`;
|
|
485
|
+
}
|
|
486
|
+
updateTaskCard(statePath, card.id, (current) => current?.history?.some((entry) =>
|
|
487
|
+
entry.event === 'repair-repeat-owner-claimed' && entry.runId === prior.runId)
|
|
488
|
+
? { ...current, history: [...current.history, { at: now.toISOString(), event, pr, head, runId: prior.runId, detail }] } : undefined);
|
|
489
|
+
}
|
|
490
|
+
return { decision: 'repair-stopped', reason };
|
|
491
|
+
}
|
|
492
|
+
const runId = mintRunId();
|
|
435
493
|
const resultPath = repairResultPath(statePath, card.id, pr, head, next, runId);
|
|
436
494
|
const goalFile = resultPath.replace(/\.json$/, '.goal.txt');
|
|
437
495
|
const goal = `기존 PR #${pr}의 리뷰 때 head ${head}를 같은 가지에서 수리한다. 새 PR을 열지 말고 아래 must-fix 원문만 고쳐 commit-only 결과를 반환한다.\n\n${input.mustFix.map((item, i) => `${i + 1}. ${item}`).join('\n')}`;
|
|
@@ -442,7 +500,8 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
|
|
|
442
500
|
if (!current || current.status !== 'launched' || (current.repairs ?? []).length !== (card.repairs ?? []).length) return undefined;
|
|
443
501
|
claimed = true;
|
|
444
502
|
return { ...current, repairs: [...(current.repairs ?? []), { pr, head, branch, at: now.toISOString(),
|
|
445
|
-
move: judged.judgement.move, moveId, runId, resultPath, fromModel: from, toModel: `${to.provider}/${to.model}`,
|
|
503
|
+
move: judged.judgement.move, moveId, runId, resultPath, fromModel: from, toModel: `${to.provider}/${to.model}`,
|
|
504
|
+
reviewSignature: reviewSignature(input.mustFix), status: 'requested' }],
|
|
446
505
|
history: [...(current.history ?? []), { at: now.toISOString(), event: 'repair-launched', pr, head, runId,
|
|
447
506
|
effect: judged.judgement.move, moveId, detail: `source pr:${pr} · owner ${owner.seat} via ${owner.source} · must-fix ${input.mustFix.length} · childLlm ${from} → ${to.provider}/${to.model}` }] };
|
|
448
507
|
});
|
|
@@ -473,7 +532,7 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
|
|
|
473
532
|
else {
|
|
474
533
|
passJourneyNode('next-move', { provenance: 'task-agent-repair', outcome: judged.judgement.move, runId,
|
|
475
534
|
data: { card: card.id, source: `pr:${pr}`, pr, head, branch, mustFix: input.mustFix, moveId } });
|
|
476
|
-
recordJourneyEdge(judged.route, 'dispatch', undefined, { moveId });
|
|
535
|
+
recordJourneyEdge(judged.route, 'dispatch', undefined, { moveId, runId, card: card.id, pr, head });
|
|
477
536
|
}
|
|
478
537
|
} catch (error) {
|
|
479
538
|
const detail = `repair observation failed after worker launch: ${error instanceof Error ? error.message : String(error)}`;
|