elanous 0.2.43 → 0.2.44
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/{Om5xS9jpjSXJCeTNGYEi4 → HMXsxdy5MIIcHPMHv1wD4}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{3557ac4a.c8931684475018ad.js → 08334415.f0e80896acbef722.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1032-78ba4f6391258cab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1082-53f86a26e03d309d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1109-7d0e264f6f2edbc7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1124-7c26330402481143.js +1 -0
- package/apps/pwa/out/_next/static/chunks/118.2a89982fe4276880.js +23 -0
- package/apps/pwa/out/_next/static/chunks/1244.6c435dbf1bf21d8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1252.9e665904d3aa3b1a.js +32 -0
- package/apps/pwa/out/_next/static/chunks/1266.a46cc33cb6a72d75.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{3955.6922286237f2ac2b.js → 1306.967240ede9a0f757.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1344.3b95f3bd1b77a3fe.js +94 -0
- package/apps/pwa/out/_next/static/chunks/{5628.6ddb2d5ffba4ff4c.js → 1401.22dfe92640a2b1ac.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/1431-f7c78bd5be21e011.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1451-cdd35a8a0b31834b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2573.387a707f6f9d720c.js → 1694.18debfd77562e56d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1708-f03d587b7a7545c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1775-fa7152bdeff6c95f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/178-4da509cd7266672a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7910-6f139bcafd238b9f.js → 1850-522de4ee34957210.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1876-c6f6e0ddcc76c6a1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1976.097066b072432242.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1406.a1dc2ab6f8449374.js → 1978.eeb60a606dc5deac.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{3402.44b565b314f2263c.js → 2043.e233e3b5a3e790f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2150.71b94e3348107c83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2158.ebc6fc5a10280ab7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3694.e0099884345f0198.js → 2216.802962c04f40a26e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2294.7890edcfa046c97d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/235.c89aaae4bcd6233a.js +74 -0
- package/apps/pwa/out/_next/static/chunks/239.de075467b5523469.js +287 -0
- package/apps/pwa/out/_next/static/chunks/{1200.6a37c202f9f17e9a.js → 249.ba7051590d603c8f.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/2571.a6ac4e26c8618403.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2610.e149cd564a08913e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2705.9816f3c244f8b85f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2801.afeb8a4dae22f85f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3935.16701e33f8982dc9.js → 2954.bbefc95d6b20e0d8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{aa57532f.510551854ff239b1.js → 2e0f720a.a0697c08e3806a60.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3042.96ec235fe41c8d4e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3097-8e358f158acef46b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3205-93b1abe28b4fb16a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3273.b4434f0dcae7eb29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3311.9cbc43ea0c90d60c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5930.8b4df3b46c32b05a.js → 3349.b5f09ee474d9533e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5866.366966af47fdde5d.js → 3503.a47a9755fb4d97b0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3506-5f429b3b7e1392b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7900.096f455c7c1efc53.js → 3843.bad404d008893291.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3877-4b40e530b47e3bf9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/435-ce2958253cf7de61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8588.d1c6a2903727ce87.js → 4393.28fa5228d0eec217.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/4404.7281c847c6e10dfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8062-7cd0bcc7f01455ba.js → 4415-b9d6a90960920a4a.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{8313-dfa1021bb58a46d6.js → 447-5b304de1fe098f43.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4484-8ebea83d431e6fae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6944.309f4e3ea54d1537.js → 4502.bdcc877abd437a05.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4599-f95790fc5c65b8df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3072.01338851ca21a6f7.js → 46.57c783fa4884714f.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/463-b9114e411f33728e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4659.a57d1f0c5d754cd2.js +36 -0
- package/apps/pwa/out/_next/static/chunks/4722-a847e7a28115035f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8986.8e2e4efbfa655c59.js → 4757.67c6d7473a038e78.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4874-c86f878ec4502ad3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4891.3f80ba517a3b2373.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8205.282ca4bb62d54a0a.js → 4998.810ca8833084caa9.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/4f98febc.ea5841d4d616bfb2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5789.2da35c258292e1e5.js → 5052.7dbb12a55d4f18f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5166-ca73b3e361085a6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5180-039f4a18b07ad387.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5232.5a2ce4daf7a9e11d.js +115 -0
- package/apps/pwa/out/_next/static/chunks/{9770.5f75bc6088b16109.js → 5439.3fec6dbce29ecb36.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1313-19f737e0222c4444.js → 5612-074d9a5e00dfac6a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5675-01989d524a84c505.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5751.af641a1adf5ec697.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5758-c6cb98714d18ab0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/578eded8.b582637306e16964.js +122 -0
- package/apps/pwa/out/_next/static/chunks/{3969.272ee7f9fd6c62e5.js → 5790.5eb06a653ebd8571.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5853-4033e5bd5afbe06b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5904.97d70bb7f46b2db7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6540.c7bef57ad8f90a87.js → 5989.7ecd362c5c44b747.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{0ad6802e.ae7afb63fdcb4491.js → 5a34fb2f.52f1b4e1baebb48a.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{0966f8a1.745fcd44f64a87ea.js → 5a5078f8.2099200e5ea95e16.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6036-c302c34ff0b3d410.js +1 -0
- package/apps/pwa/out/_next/static/chunks/606.ef81c313381f4264.js +1 -0
- package/apps/pwa/out/_next/static/chunks/616.1af54a928b1ba704.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6201.bc936f71f613a8e9.js +41 -0
- package/apps/pwa/out/_next/static/chunks/6204-fdc86e0e64c4f92d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2144.25b292396712196d.js → 6245.1182e007e9d230d9.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{363bfab3.9623b9f89363541f.js → 63699a35.17262e162bc514b2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6420.494801a80030160c.js +27 -0
- package/apps/pwa/out/_next/static/chunks/{d96660fb.cbc21a2a88539dbb.js → 6549dad0.2740b25e51bf8f05.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/{5564.9e72532188f57586.js → 6881.9e7955847640c7fe.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/6931.fcdfb94141e67b3d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6991-8e081c6ce38c0ba1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3903.3ef4656c67572764.js → 7010.1bbd17a7f2b3e376.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7029.d1466acf55fae2ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7152-a123aa8e129c131f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7455.196168fffac3b9c4.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7638.6ca4770dd1129138.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7649-f37d76260e5e2a5a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2312.0c8b61e22d3136d7.js → 7679.32c40cdd14f20b4a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7751.04bfbd16b4c6cd0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7864.b1ff31d4030b8994.js +148 -0
- package/apps/pwa/out/_next/static/chunks/7869-c47bd2c075c1fefa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4199.ce86b281fd0a60b7.js → 8442.2f09ca969d631615.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8445.2738dbd59a78c78c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8447.5510c439f9938c6d.js +286 -0
- package/apps/pwa/out/_next/static/chunks/8551.f762945c2cda2e95.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8635-57a9d8d9db70f4f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{fb7d20d5-6892502b6ee39ca6.js → 86961958-4b0689a5048f756b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8709.3c6019bb18f8554f.js +8 -0
- package/apps/pwa/out/_next/static/chunks/8759.c999528a0a907bf6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/87f498e5-0881de09f2e44707.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8843.c3197f904c952b81.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{cb0f8df8.09a4a6be97e3fc5f.js → 892fd990.456232f326cc39c2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{837-81336ebaca8198a8.js → 8965-135a2c9eaa2464cb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8971-8d3b9c96f8a6c958.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9059.c8598d96f8e5e9cd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9115.90447ae198b84eae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9147.d9b0a02e0babc9b4.js +93 -0
- package/apps/pwa/out/_next/static/chunks/9204-83075f4b70c61cdc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9244-c32ef14b5dc72bdf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/930.2a9a30f964350c66.js +90 -0
- package/apps/pwa/out/_next/static/chunks/{8637.90f92d5c8db4732c.js → 9398.1f56e3f17795f43f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9527.3e5ad31c891c5fcb.js +79 -0
- package/apps/pwa/out/_next/static/chunks/9571-4ac933e774d1225c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-9fc644de2d8edae3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-0c9dace2db62bee8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f5e65c3dc9d89f2a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-2a9c19b9a140b7b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-61533ad92141adfb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-112004ced6fd0329.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-f733318c237a49d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-51ea677d2d33bbc0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-428b41f2f9566e3c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-1b29396ea90a61e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-cf83ec613ac904bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-3f4c0ecbc284bb5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-b63c322f54f70cc6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-fe328c4ee9aac6b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-bfb855c584f0fb98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-9fc644de2d8edae3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-47b1710c110eabd7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-42895214458bc6d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-d03de0ebd8366e23.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-3ed6c47e4b1c61c2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-ae653e9bf261c738.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-23f3f0a0209c0ac4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-88c691273aae66f9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e187ac52a95538b3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-6e45828daed1295e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-edb5d7287bb46186.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-4a7eaacd93c3f6a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ca073d43d74cc84.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1e9fee67b1199436.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-df1283ea963c6816.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-19fcf8d8301ccd18.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-5ab699e0303bbb40.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7cde0d29756984c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-9d4c598e8ee22f7a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-cc1609a71f44ec62.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7659a9a1345bfaa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-0afef60ecc0c4af5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-a3553949f8f34f5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-9fc644de2d8edae3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-057a69702f3c67c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-c0f0e570f3f74c73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-1825071ae34e3b89.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-6244e3e135d8ccfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-0a815f34367b6db6.js → page-da787e8a10b8a82e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-1316d32498e2be42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-4df94572e343de2e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-708969f7475e88c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c58add08c919a1dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-a24847f45e5d5bf9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-acfec65a3a60e22e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-3dfc598e6fbde245.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-c658a626118411b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-4c73685fd891445b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-6310f7e5de7dd01d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-51c326bf48610be1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-d0beadf754da59b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-acd243bfbf3f6732.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/overlays/README.md +6 -0
- package/graphs/release/release-loop.yaml +33 -17
- package/graphs/units/verbs/make-doc.yaml +1 -0
- package/package.json +1 -1
- package/scripts/bench-metering-plan.ts +229 -0
- package/scripts/demo/demo1104-parallel-host.ts +56 -0
- package/scripts/demo/demo1104-parallel.ts +72 -0
- package/scripts/public-leak-baseline.txt +0 -1
- package/scripts/release-loop/docs-node.ts +4 -2
- package/scripts/release-loop/gate-image-pin.ts +116 -2
- package/scripts/release-loop/gate-node.ts +217 -25
- package/scripts/release-loop/gate-progress-sim.ts +73 -0
- package/scripts/release-loop/notes-repair.ts +18 -1
- package/scripts/release-loop/preflight.ts +188 -8
- package/scripts/release-loop/render-warm-control-manifest.ts +22 -0
- package/scripts/release-loop/resume-release.ts +9 -7
- package/scripts/release-loop/resume.ts +13 -4
- package/scripts/release-loop/warm-control-forward.ts +178 -0
- package/scripts/retro-cycle.ts +30 -8
- package/scripts/rhythm/daily.ts +4 -1
- package/scripts/rhythm/linear-progress-sync.ts +28 -15
- package/scripts/ux-sim.ts +7 -1
- package/scripts/warm-pool-provider-config.ts +6 -1
- package/src/agent-mission/grok-auth-status.ts +78 -18
- package/src/agent-mission/mission-out.ts +2 -2
- package/src/agent-substrate/pr-reviewer.ts +147 -11
- package/src/agent-substrate/self-review-cli.ts +10 -2
- package/src/auto-research/research-fanout.ts +221 -0
- package/src/auto-research/research-turn.ts +282 -36
- package/src/autopilot/mission-codebase-gate.ts +7 -3
- package/src/cli/control-cli.ts +15 -6
- package/src/cli/log-event-names.ts +8 -0
- package/src/cli/setup-keys.ts +20 -8
- package/src/cli/tui-test-cli.ts +9 -5
- package/src/control-plane/ledger.ts +42 -4
- package/src/control-plane/member-tokens.ts +25 -2
- package/src/control-plane/ports.ts +8 -3
- package/src/control-plane/server.ts +26 -5
- package/src/core-turn/research-policy.ts +7 -1
- package/src/core-turn/run-core-turn.ts +186 -39
- package/src/core-turn/types.ts +2 -0
- package/src/dashboard/classic-sidetab-mission-job.ts +113 -24
- package/src/dashboard/classic-sidetab-mission-pair.ts +3 -2
- package/src/dashboard/classic-sidetab-mission-trio.ts +35 -12
- package/src/dashboard/classic-sidetab-mission.ts +2 -0
- package/src/dashboard/index.ts +9 -1
- package/src/dashboard/sidetab-runtime.ts +2 -0
- package/src/dashboard/visible-mission-diagnostics.ts +16 -0
- package/src/domains/retro-cycle-observation.ts +43 -0
- package/src/domains/retro-cycle.ts +13 -2
- package/src/domains/retro-proposals.ts +92 -0
- package/src/domains/retro-report.ts +6 -1
- package/src/graph-runner/graph-cli.ts +24 -1
- package/src/graph-runner/graph-grow-llm.ts +3 -1
- package/src/graph-runner/runner.ts +226 -30
- package/src/harness/harness-cli-command.ts +4 -2
- package/src/harness/harness-pod-dispatch.ts +3 -0
- package/src/index.ts +2 -2
- package/src/llm/child-first-llm-observation.ts +112 -0
- package/src/llm/provider-credentials.ts +60 -4
- package/src/llm/provider-failure-evidence.ts +44 -0
- package/src/llm.ts +170 -11
- package/src/mcp/client.ts +7 -0
- package/src/mcp/proxy-runtime.ts +6 -1
- package/src/mcp/server.ts +54 -0
- package/src/native-tool-catalog.ts +2 -2
- package/src/nexus/api/consult-requests.ts +18 -6
- package/src/nexus/api/discord-trigger-bot.ts +6 -6
- package/src/nexus/api/graphs-api.ts +4 -2
- package/src/nexus/api/grokbot-trigger-bot.ts +206 -0
- package/src/nexus/api/telegram-trigger-bot.ts +6 -6
- package/src/nexus/boot/register-mcp-clients.ts +114 -8
- package/src/nexus/index.ts +15 -0
- package/src/nexus/outbound/grokbot-adapter.ts +71 -0
- package/src/nexus/outbound/router.ts +33 -13
- package/src/oauth/codex-owner-mirror.ts +47 -10
- package/src/onboarding/first-run.ts +44 -6
- package/src/preview/terminal.ts +22 -7
- package/src/prompt-enhance/enhance.ts +10 -0
- package/src/pty-shell/pty-write-provenance.ts +21 -3
- package/src/pty-shell/registry.ts +9 -2
- package/src/release-loop/proposal-auto-place.ts +83 -0
- package/src/research/axis-fanout.ts +40 -5
- package/src/research/lenses/second-order.ts +312 -0
- package/src/self-dev/dev-cli.ts +3 -1
- package/src/self-dev/draft-sweep.ts +31 -10
- package/src/self-dev/draft-triage-rules.ts +60 -3
- package/src/self-dev/run-supervisor.ts +152 -2
- package/src/self-implement/goal-author.ts +208 -23
- package/src/self-implement/graph-overlay-yaml.ts +151 -0
- package/src/self-implement/graph-yaml.ts +68 -2
- package/src/self-implement/orchestrator.ts +62 -15
- package/src/self-implement/test-scenario-request.ts +37 -6
- package/src/session/chat.ts +2 -2
- package/src/session-runtime/index.ts +37 -5
- package/src/sidetab-core/model.ts +205 -10
- package/src/sidetab-core/visible-agent-mission-pair.ts +51 -0
- package/src/sidetab-core/visible-agent-mission.ts +105 -47
- package/src/skills/tools/omni-search.ts +4 -2
- package/src/task-agent/parent-host.ts +19 -1
- package/src/task-agent/recall-inject.ts +98 -0
- package/src/task-agent/task-hand.ts +26 -7
- package/src/task-orchestrator/surfaces/pod-artifact-return.ts +19 -1
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +15 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +21 -9
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +460 -96
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +45 -3
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +38 -8
- package/src/tool-hints/gate.ts +45 -14
- package/src/tool-hints/signals.ts +1 -1
- package/src/tool-hints/types.ts +2 -0
- package/src/tool-runtime/browser-hand-runtime.ts +11 -1
- package/src/tool-runtime/browser-runtime.ts +31 -18
- package/src/tool-runtime/elanous-linear-secretary-runtime.ts +152 -36
- package/src/tool-runtime/types.ts +2 -0
- package/src/tui/entry.ts +27 -7
- package/src/tui/sidetab/attach.ts +112 -0
- package/src/tui/sidetab/list.ts +3 -2
- package/src/tui-client/next-dashboard-runtime.ts +52 -0
- package/src/ux-sim/draft-inventory-builder.ts +2 -1
- package/src/ux-sim/linear-secretary.ts +4 -12
- package/src/ux-sim/mock-scenario-catalog.json +32 -29
- package/src/ux-sim/mock-scenario-catalog.ts +55 -3
- package/src/ux-sim/release-sim-rig.ts +62 -18
- package/src/ux-sim/service-key-setup.ts +63 -0
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/114.2b90424d1a3ce84c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1151-5c2bb8f002ca2dd6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1261-a616d5728e02e624.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1357.3bbef3976c37f94a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1362-20adddfaf662b0fa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1737-9491fc6ab29b9ec6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1803-4f91a8e7dcaf042c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1961.a81b12872c3e93a9.js +0 -23
- package/apps/pwa/out/_next/static/chunks/1970cf59.2d4d8ce5d6c81853.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1971-8890f3962ba7ee0a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2073-ba274e00e4f9efb4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2268-53861f339e0b65a2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/273.f156eee28f11af77.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2873.d2140e5a82546401.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3091.a5a4143dea33d197.js +0 -90
- package/apps/pwa/out/_next/static/chunks/3095.dc44586a5f83b86d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3113.d7472bbc27d580c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3228-9650b6447b6fa288.js +0 -1
- package/apps/pwa/out/_next/static/chunks/360.ae9f9f4c33c395e8.js +0 -79
- package/apps/pwa/out/_next/static/chunks/3638.80412ea63aae8f3f.js +0 -286
- package/apps/pwa/out/_next/static/chunks/3744.54f87db52acfd1ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4311-6dd3144002cc0c2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4426-2b230fad00c88930.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4445.7990c76b3751a918.js +0 -115
- package/apps/pwa/out/_next/static/chunks/4447-14c5161fa59166c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4856-b0b8075bba8c53f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4870-de370d65e73c0bb5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4885-2c989165c4b29fad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4894.fec2ca9e99caefa2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5093.8f04b7f8cb899a95.js +0 -94
- package/apps/pwa/out/_next/static/chunks/5122-2bb177cebf89e19a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5154.5f56dc3902e3d275.js +0 -36
- package/apps/pwa/out/_next/static/chunks/529.64ff7257180b2ac9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5394.5dabeb0c62293a28.js +0 -93
- package/apps/pwa/out/_next/static/chunks/5461.08bf2404ff38ec85.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5474-22e08a85583209b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5567-265df39ed8fe9dcb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5570-a94ae19811cb2046.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5574-b47c9ef2dceff1fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5730.43d7ccc09988e646.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5824.da9527b15a3221e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5963-c4d8469c52a0828b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6001.ec4049ceb3c43418.js +0 -27
- package/apps/pwa/out/_next/static/chunks/6120-471f03db1e299c0c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6175-41479e643aca1878.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6291.a2de4f9787637075.js +0 -104
- package/apps/pwa/out/_next/static/chunks/6400-6699907c3537436a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6428.1f4327d6ae5fdf9a.js +0 -287
- package/apps/pwa/out/_next/static/chunks/644.02cb026fa44bcd0a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6466-6c87d60d3dd174fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6773.d4264665ab31bec0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6822.3c789f1a8443e774.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7261-8ff69d3b2ee671fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7266.084c6bbc70035140.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7271.5c0100e7320aa856.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7429-bf5731358c8f2f68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7464.01f7a0ae1215fbe7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7479.0fcad5f37eb64f0c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7483.427a2fe2049e388d.js +0 -148
- package/apps/pwa/out/_next/static/chunks/7502-be74718178e13e56.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7530.0889722b19572065.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7645.5b2ee3ad45c55ea3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7788.7d1c79f1a8e18946.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7966.f71c8958d1637548.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8073.f6cf2f2c71aafbd0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8201.190b94088980f430.js +0 -74
- package/apps/pwa/out/_next/static/chunks/8447.7963352ef5f71b76.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8574-868e8129525ef6d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/868.6e953be05bcf6dca.js +0 -41
- package/apps/pwa/out/_next/static/chunks/8706-e1fe0309343a2273.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8749-06384cdfc4520add.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8861-cc1fa1c7b920fa8e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8967-7dfebf710c9dec9d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8997-3c564dbb3b58b055.js +0 -1
- package/apps/pwa/out/_next/static/chunks/923.2034d10ae91e9c20.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9312.bc1b89c5d4368033.js +0 -1
- package/apps/pwa/out/_next/static/chunks/943.39ae5e82f4f1893f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9469.0500480de55fb205.js +0 -32
- package/apps/pwa/out/_next/static/chunks/9810-2543267050e58b82.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9870.8419702475254745.js +0 -8
- package/apps/pwa/out/_next/static/chunks/9941-376d1b74d51b01a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9958.385434ab04241758.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-deea1450b17cb8dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-70985b904f8650ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a2e15e33e56a4353.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-fc72ce2db12d6ca9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-be03e41f9436ebd9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-35a35999382da3f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-3ff5b1e6ca88b848.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-a65101300a0ee5c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-3aca5b6d67dba511.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-45b8ab0a71e61314.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-53046e282d4cda8e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-17809e60e8354c17.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-fd2442d347bf5898.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-e9d720d6fc082e21.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-6b8b4267bab0a677.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-deea1450b17cb8dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-8bcf6233ac7c17af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-7cc25591cfc2126f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-053e871f35c9beba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-eff819f0c2d5e084.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-4d7e9d8db5274a87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-2b2d8f5aa5f69ad4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-0b8f92c5062e68b1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1bd9d0fdac2ced3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-9ee28f7df07428ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-44b7a1ff468c6648.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-cbc6523711dc1b65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-fdad47899c2695be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-79a8b5fee4c20871.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-03e8ac9606aeaffb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-4cd55c55ec287e2f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-db17b4305404161e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-30041d848350fd02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c540da022dbf86b0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-9399efc538da057f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ca2d09128c585ca4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-0e2635aecd343038.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ef7f4399b6b7726e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-deea1450b17cb8dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-caf530535b875468.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-eaa20c1543a5fd8e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-c541eb1b75120f61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-ab5e213eda9479f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-e858ba0ed9393b68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-1638ee9dd6e0582f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-4cf5a399109391f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b4396321238798ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-cb72bfd21006781a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-6135d0242afbc434.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a1dccf907eddb856.js +0 -1
- package/apps/pwa/out/_next/static/chunks/c7945435-b44d4dbe90ba0dcb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ea514caa.05a24f78d9dffe5f.js +0 -122
- package/apps/pwa/out/_next/static/chunks/framework-e8a911e19b1be41f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-7022f418fabba021.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-e5f15df755756a1e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-4525f91e36940c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-140f0e519c085b0f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-8f22ef63dcb865b1.js +0 -1
- /package/apps/pwa/out/_next/static/{Om5xS9jpjSXJCeTNGYEi4 → HMXsxdy5MIIcHPMHv1wD4}/_ssgManifest.js +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { spawn, spawnSync } from 'node:child_process';
|
|
3
|
-
import { appendFileSync, chmodSync, copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { appendFileSync, chmodSync, copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { hostname, tmpdir } from 'node:os';
|
|
5
5
|
import { createHash, randomUUID } from 'node:crypto';
|
|
6
|
-
import { basename, dirname, join, resolve } from 'node:path';
|
|
6
|
+
import { basename, dirname, isAbsolute, join, resolve } from 'node:path';
|
|
7
7
|
import { debug, redactSecretText } from '../../src/debug/log.js';
|
|
8
8
|
import { registerStandaloneLogSink } from '../../src/domains/standalone-log-sink.js';
|
|
9
9
|
import { landingFreezeMessage, readLandingFreeze } from '../../src/release-loop/landing-freeze.js';
|
|
@@ -20,7 +20,8 @@ import { planGateRadiusShadow, shadowActual, writeGateRadiusShadow, type GateRad
|
|
|
20
20
|
import { planHardRehearsalRadius, partialGateImagesMatch, preflightGateExecutionIdentity, preflightGateImageDigest } from './gate-radius-live';
|
|
21
21
|
import { actualGatePodImageDigest, gateBaselineReceipt, gateEnvFingerprint, gateGraphPins, gateSourcePins, parseGatePodRuntimeIdentity,
|
|
22
22
|
POD_SWEEP_INTEGRATION_ONLY } from './gate-baseline-receipt';
|
|
23
|
-
import { gateImagePinPath,
|
|
23
|
+
import { gateImagePinPath, normalizeGateImageDigest, pinnedGateImageSync as buildPinnedGateImageSync, readGateImagePin,
|
|
24
|
+
readGateImagePinForRun, replaceGateImagePin, resolveGateImagePin, writeGateImagePin } from './gate-image-pin.js';
|
|
24
25
|
import { gateReceiptRegistryPath, planGateTrainReceiptCarry } from './gate-train-receipts.js';
|
|
25
26
|
import { gateEnvFingerprint as gateReceiptEnvFingerprint, gateLockfileHash } from '../../src/self-implement/gate-receipt-registry.js';
|
|
26
27
|
import { SPAWN_SYNC_MAX_BUFFER } from '../../src/util/spawn-sync-output.js';
|
|
@@ -36,13 +37,15 @@ import { emitNodeResult, readGraphContext } from './node-verdict.js';
|
|
|
36
37
|
import { isGateExecutor, type GateExecutor } from './gate-executor.js';
|
|
37
38
|
import { runPodCommand, parsePodCpu, podCpuMillis, resolvePodCpu, podCommandImageFor, type RunPodCommandOptions, type PodCommandResult, type PodCpu } from '../../src/task-orchestrator/surfaces/pod-command-job.js';
|
|
38
39
|
import { POD_BUN_CACHE_HOST_PATH, parseInstallSeconds, podBunCacheVolume } from '../../src/task-orchestrator/surfaces/pod-bun-cache.js';
|
|
39
|
-
import { PodPoolScheduler, parsePodPool, checkPodPool, defaultRemoteRun, snapshotWarmPoolMembers, type PodPoolMember } from '../../src/task-orchestrator/surfaces/pod-pool.js';
|
|
40
|
+
import { NODE_REGISTRY, PodPoolScheduler, parsePodPool, checkPodPool, defaultRemoteRun, snapshotWarmPoolMembers, syncPoolImages, type PodPoolMember } from '../../src/task-orchestrator/surfaces/pod-pool.js';
|
|
40
41
|
import { POD_INSTALL_SLOTS_DEFAULT, POD_INSTALL_SLOTS_HOST_PATH, installSlotScript } from '../../src/task-orchestrator/surfaces/pod-install-slots.js';
|
|
41
42
|
import { gateDepsInstallScript, parseGateDeps } from '../../src/task-orchestrator/surfaces/pod-gate-deps.js';
|
|
42
43
|
import { warmReferenceFromJobArtifacts, writeWarmJobManifest } from './gate-warm-artifacts.js';
|
|
43
44
|
import { assessWarmWorkerShadow, parseWarmWorkerReply, type WarmWorkerCommand, type WarmWorkerFileResult, type WarmWorkerKey } from '../../src/task-orchestrator/surfaces/pod-warm-worker-protocol.js';
|
|
44
45
|
import type { WarmPodTransportResult } from '../../src/task-orchestrator/surfaces/pod-warm-worker-pod.js';
|
|
45
|
-
import { requestWarmPodReplay, finalizeWarmPodReplay, quarantineWarmPodReplay, type WarmReplayResult } from '../../src/task-orchestrator/surfaces/pod-warm-worker-provider.js';
|
|
46
|
+
import { configureWarmPodProvider, loadWarmPodProvider, requestWarmPodReplay, finalizeWarmPodReplay, quarantineWarmPodReplay, type WarmReplayInput, type WarmReplayResult } from '../../src/task-orchestrator/surfaces/pod-warm-worker-provider.js';
|
|
47
|
+
import { DEFAULT_CONTROL_PORT } from '../../src/control-plane/server.js';
|
|
48
|
+
import { createRunScopedWarmControlForward, startWarmControlPortForward } from './warm-control-forward.js';
|
|
46
49
|
import { resolveWarmPoolProfile } from '../../src/self-implement/pod-warm-pool-profile.js';
|
|
47
50
|
import { decideWarmReuse, type WarmReuseSwitchConfig, type WarmReuseEvidence } from '../../src/task-orchestrator/surfaces/pod-warm-switch.js';
|
|
48
51
|
import { getUserConfig } from '../../src/user-config.js';
|
|
@@ -111,6 +114,8 @@ function redactedGateLogTail(input: string): string {
|
|
|
111
114
|
* Every field falls back to the real tool, so an absent seam is today's behaviour byte for byte.
|
|
112
115
|
*/
|
|
113
116
|
export interface GateTools {
|
|
117
|
+
/** Graph run identity passed to pool admission for shadow observations. */
|
|
118
|
+
graphRunId?: string | null;
|
|
114
119
|
/** Wall clock the gate measures with; absent = `Date.now`. */
|
|
115
120
|
now?: () => number;
|
|
116
121
|
/** The Pod Job runner (the fake Pod stage of a scenario); absent = the positional `podCommand`, else `runPodCommand`. */
|
|
@@ -340,14 +345,64 @@ export interface GateOptions {
|
|
|
340
345
|
}
|
|
341
346
|
|
|
342
347
|
/** Gate-profile opt-in wires the producer only for the process entry, never a test runner seam. */
|
|
343
|
-
export function withWarmGateHooks(opts: GateOptions, config: unknown, injectedRunner = false
|
|
348
|
+
export function withWarmGateHooks(opts: GateOptions, config: unknown, injectedRunner = false,
|
|
349
|
+
onWarmCleanup?: (cleanup: () => Promise<void>) => void): GateOptions {
|
|
344
350
|
if (injectedRunner || !opts.pod || resolveWarmPoolProfile(config) !== 'gate') return opts;
|
|
345
351
|
const warmReuseConfig = config && typeof config === 'object' && 'pod' in config
|
|
346
352
|
&& config.pod && typeof config.pod === 'object' && 'warmReuse' in config.pod
|
|
347
353
|
? config.pod.warmReuse as WarmReuseSwitchConfig : undefined;
|
|
348
|
-
|
|
354
|
+
const lifecycle = createRunScopedWarmControlForward(async () => {
|
|
355
|
+
const configPath = process.env.ELANOUS_WARM_POD_PROVIDER_CONFIG;
|
|
356
|
+
if (!configPath) throw new Error('warm provider config unavailable');
|
|
357
|
+
const target = warmProviderTarget(configPath);
|
|
358
|
+
const forward = await startWarmControlPortForward({ context: target.context, namespace: target.namespace,
|
|
359
|
+
service: 'elanous-control', remotePort: DEFAULT_CONTROL_PORT });
|
|
360
|
+
try {
|
|
361
|
+
const provider = loadWarmPodProvider(configPath, { runtimeOverrides: { controlUrl: forward.url } });
|
|
362
|
+
configureWarmPodProvider(provider);
|
|
363
|
+
return forward;
|
|
364
|
+
} catch (error) {
|
|
365
|
+
await forward.stop();
|
|
366
|
+
throw error;
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
const replay: NonNullable<GateOptions['pod']>['warmReplay'] = async (input) => {
|
|
370
|
+
try { await lifecycle.ensure(); }
|
|
371
|
+
catch (error) {
|
|
372
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
373
|
+
debug.log('pod.warm.control-forward', 'unavailable', { reason, fallback: 'fresh-job' }, { level: 'error' });
|
|
374
|
+
return { command: null, transport: { status: 'fallback', reason: 'control-unavailable', reply: null } };
|
|
375
|
+
}
|
|
376
|
+
return requestWarmPodReplay(input);
|
|
377
|
+
};
|
|
378
|
+
const cleanup = async () => {
|
|
379
|
+
try { await lifecycle.stop(); }
|
|
380
|
+
finally { configureWarmPodProvider(null); }
|
|
381
|
+
};
|
|
382
|
+
onWarmCleanup?.(cleanup);
|
|
383
|
+
return { ...opts, pod: { ...opts.pod, warmReplay: replay,
|
|
349
384
|
warmFinalize: finalizeWarmPodReplay, warmQuarantine: quarantineWarmPodReplay, warmProducerEnabled: true, warmReuseConfig } };
|
|
350
385
|
}
|
|
386
|
+
|
|
387
|
+
function warmProviderTarget(path: string): { context: string; namespace: string } {
|
|
388
|
+
if (!isAbsolute(path) || (statSync(path).mode & 0o077) !== 0) throw new Error('warm provider config must be private');
|
|
389
|
+
const parsed: unknown = JSON.parse(readFileSync(path, 'utf8'));
|
|
390
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) throw new Error('invalid warm provider config');
|
|
391
|
+
const data = parsed as { candidates?: Array<{ spec?: { kubectlContext?: string; namespace?: string } }>;
|
|
392
|
+
poolTemplates?: Array<{ spec?: { kubectlContext?: string; namespace?: string } }> };
|
|
393
|
+
const rows = [...(data.candidates ?? []), ...(data.poolTemplates ?? [])];
|
|
394
|
+
const targets = new Map<string, { context: string; namespace: string }>();
|
|
395
|
+
for (const row of rows) {
|
|
396
|
+
const context = row.spec?.kubectlContext;
|
|
397
|
+
const namespace = row.spec?.namespace;
|
|
398
|
+
if (typeof context !== 'string' || !context || typeof namespace !== 'string' || !namespace)
|
|
399
|
+
throw new Error('warm provider target is incomplete');
|
|
400
|
+
targets.set(`${context}/${namespace}`, { context, namespace });
|
|
401
|
+
}
|
|
402
|
+
if (targets.size !== 1) throw new Error('warm control forward requires one cluster and namespace per gate run');
|
|
403
|
+
return [...targets.values()][0]!;
|
|
404
|
+
}
|
|
405
|
+
|
|
351
406
|
export interface GateResult {
|
|
352
407
|
outcome: 'ok' | 'regression' | 'error';
|
|
353
408
|
commit: string;
|
|
@@ -1702,7 +1757,45 @@ export interface GateAdmission {
|
|
|
1702
1757
|
acquire(signal: AbortSignal): Promise<() => void>;
|
|
1703
1758
|
/** The pool-wide reading admission waits on (recommended · limitedBy · memorySlots); null before any reading. */
|
|
1704
1759
|
waitReason(): string | null;
|
|
1760
|
+
/** Optional deterministic-test observation override; production uses poolGateAdmission's unknown-only provider. */
|
|
1761
|
+
priorityShadowObservation?(gateWaiting: boolean): GatePriorityShadowObservation;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
export type GatePriorityImageState = 'verified' | 'mismatch' | 'unknown';
|
|
1765
|
+
export interface GatePriorityShadowObservation {
|
|
1766
|
+
gateRunId: string | null;
|
|
1767
|
+
host: string | null;
|
|
1768
|
+
competingRunId: string | null;
|
|
1769
|
+
competingHost: string | null;
|
|
1770
|
+
gateImageState: GatePriorityImageState;
|
|
1771
|
+
competingImageState: GatePriorityImageState;
|
|
1772
|
+
gateWaiting: boolean;
|
|
1773
|
+
lowerPriorityWaiting: boolean | null;
|
|
1774
|
+
}
|
|
1775
|
+
export interface GatePriorityShadowDecision extends GatePriorityShadowObservation {
|
|
1776
|
+
event: 'gate-priority-shadow-decision';
|
|
1777
|
+
decision: 'gate-first' | 'no-contention' | 'insufficient-evidence';
|
|
1778
|
+
selectionRationale: string;
|
|
1705
1779
|
}
|
|
1780
|
+
|
|
1781
|
+
/** A shadow-only policy decision; it has no pool or Pod handle and cannot change runtime state. */
|
|
1782
|
+
export function gatePriorityShadowDecision(input: GatePriorityShadowObservation): GatePriorityShadowDecision {
|
|
1783
|
+
const base = { event: 'gate-priority-shadow-decision' as const, ...input };
|
|
1784
|
+
if (!input.gateWaiting || input.lowerPriorityWaiting === false) {
|
|
1785
|
+
return { ...base, decision: 'no-contention', selectionRationale: !input.gateWaiting ? 'gate-not-waiting' : 'no-lower-priority-waiter-observed' };
|
|
1786
|
+
}
|
|
1787
|
+
if (input.lowerPriorityWaiting !== true) {
|
|
1788
|
+
return { ...base, decision: 'insufficient-evidence', selectionRationale: 'lower-priority-wait-state-unknown' };
|
|
1789
|
+
}
|
|
1790
|
+
if (!input.gateRunId || !input.competingRunId || !input.host || input.host !== input.competingHost) {
|
|
1791
|
+
return { ...base, decision: 'insufficient-evidence', selectionRationale: 'same-host-run-identities-unavailable' };
|
|
1792
|
+
}
|
|
1793
|
+
if (input.gateImageState !== 'verified' || input.competingImageState !== 'verified') {
|
|
1794
|
+
return { ...base, decision: 'insufficient-evidence', selectionRationale: 'image-state-not-verified' };
|
|
1795
|
+
}
|
|
1796
|
+
return { ...base, decision: 'gate-first', selectionRationale: 'same-host-contention-and-verified-gate-image; gate-policy-priority' };
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1706
1799
|
export const GATE_ADMISSION_WAIT_SECONDS_DEFAULT = 1800;
|
|
1707
1800
|
/** Queue pressure scales the default wait but never creates an unbounded admission timer. */
|
|
1708
1801
|
export function gateAdmissionWaitSeconds(shards: number, slots: number): number {
|
|
@@ -1752,17 +1845,38 @@ export function defaultGateMemberProbe(member: PodPoolMember, tools: GateTools =
|
|
|
1752
1845
|
return !member.sshHost || (tools.remoteRun ?? defaultRemoteRun)(member.sshHost, 'true').status === 0;
|
|
1753
1846
|
}
|
|
1754
1847
|
|
|
1755
|
-
export function poolGateAdmission(pool: PodPoolScheduler
|
|
1756
|
-
|
|
1848
|
+
export function poolGateAdmission(pool: PodPoolScheduler, gateRunId: string | null = null,
|
|
1849
|
+
priorityShadowObservation?: (gateWaiting: boolean) => GatePriorityShadowObservation): GateAdmission {
|
|
1850
|
+
const singleHost = pool.members.length === 1 ? (pool.members[0]!.sshHost ?? hostname()) : null;
|
|
1851
|
+
// The optional provider is a deterministic test seam only. Production never fabricates a competitor or image fact.
|
|
1852
|
+
return {
|
|
1853
|
+
acquire: (signal) => pool.acquireAdmission(signal, undefined, { gate: true }),
|
|
1854
|
+
waitReason: () => pool.waitReason(),
|
|
1855
|
+
// At admission time a multi-host pool has not selected a host yet. Existing measurements do not expose
|
|
1856
|
+
// competing run ids or image states, so keep those unknown rather than deriving them from Job names.
|
|
1857
|
+
priorityShadowObservation: priorityShadowObservation ?? ((gateWaiting) => ({ gateRunId, host: singleHost, competingRunId: null, competingHost: null,
|
|
1858
|
+
gateImageState: 'unknown', competingImageState: 'unknown', gateWaiting, lowerPriorityWaiting: null })),
|
|
1859
|
+
};
|
|
1757
1860
|
}
|
|
1758
|
-
export async function admitGateShard(admission: GateAdmission | undefined, o: { waitMs: number; onWait: (reason: string) => void; reasonPollMs?: number; firstReasonMs?: number
|
|
1861
|
+
export async function admitGateShard(admission: GateAdmission | undefined, o: { waitMs: number; onWait: (reason: string) => void; reasonPollMs?: number; firstReasonMs?: number;
|
|
1862
|
+
onPriorityShadow?: (decision: GatePriorityShadowDecision) => void }): Promise<GateAdmissionResult> {
|
|
1759
1863
|
const noop = () => {};
|
|
1760
1864
|
if (!admission || !(o.waitMs > 0)) return { outcome: 'off', waitedMs: 0, release: noop };
|
|
1761
1865
|
const started = Date.now();
|
|
1762
1866
|
const controller = new AbortController();
|
|
1763
1867
|
let timedOut = false;
|
|
1764
1868
|
let lastReason: string | undefined;
|
|
1765
|
-
|
|
1869
|
+
let priorityShadowLogged = false;
|
|
1870
|
+
const tell = () => {
|
|
1871
|
+
lastReason = gateAdmissionWaitText(admission.waitReason());
|
|
1872
|
+
if (!priorityShadowLogged && admission.priorityShadowObservation) {
|
|
1873
|
+
priorityShadowLogged = true;
|
|
1874
|
+
const decision = gatePriorityShadowDecision(admission.priorityShadowObservation(true));
|
|
1875
|
+
if (o.onPriorityShadow) o.onPriorityShadow(decision);
|
|
1876
|
+
else debug.log('release-loop.gate', 'gate-priority-shadow-decision', decision);
|
|
1877
|
+
}
|
|
1878
|
+
o.onWait(lastReason);
|
|
1879
|
+
};
|
|
1766
1880
|
const deadline = setTimeout(() => { timedOut = true; controller.abort(); }, o.waitMs);
|
|
1767
1881
|
// A grant inside the first moment never touches the shard row (no flapping in shards.json).
|
|
1768
1882
|
let ticker: ReturnType<typeof setInterval> | undefined;
|
|
@@ -1805,6 +1919,27 @@ export function createGateRunner(repo: string, remote?: string, commandOverride?
|
|
|
1805
1919
|
const ssh = tools.ssh ?? defaultSshCommand;
|
|
1806
1920
|
const remoteRun = tools.remoteRun ?? defaultRemoteRun;
|
|
1807
1921
|
const runPod = tools.podCommand ?? podCommand;
|
|
1922
|
+
const pinnedGateImageSync = (pod: NonNullable<GateOptions['pod']>, commit: string): RunPodCommandOptions['syncImages'] | undefined => {
|
|
1923
|
+
const hasDigest = Boolean(pod.pinnedImageDigest?.trim());
|
|
1924
|
+
const hasRunId = Boolean(pod.pinnedRunId?.trim());
|
|
1925
|
+
if (hasDigest !== hasRunId) throw new Error('gate pinned image: both pinnedImageDigest and pinnedRunId are required');
|
|
1926
|
+
if (!hasDigest) return undefined;
|
|
1927
|
+
return async (members, image, localCommit) => {
|
|
1928
|
+
if (localCommit !== commit) throw new Error('gate pinned image: requested source commit changed');
|
|
1929
|
+
const probe = preflightGateImageDigest;
|
|
1930
|
+
const poolSpecFor = (member: PodPoolMember) => `${member.context}${member.sshHost ? `@${member.sshHost}` : ''}:${member.capacity}#${member.registry ?? NODE_REGISTRY}`;
|
|
1931
|
+
const result = buildPinnedGateImageSync({ runId: pod.pinnedRunId!, commit, digest: pod.pinnedImageDigest!, image,
|
|
1932
|
+
members: members.map((member) => ({ context: member.context, registry: member.registry ?? NODE_REGISTRY })),
|
|
1933
|
+
probeTagDigest: (member) => {
|
|
1934
|
+
const candidate = members.find((row) => row.context === member.context && (row.registry ?? NODE_REGISTRY) === member.registry);
|
|
1935
|
+
return candidate ? probe(poolSpecFor(candidate), commit) : null;
|
|
1936
|
+
} });
|
|
1937
|
+
for (const drift of result.tagDrifts) debug.log('release-loop.gate', 'image-tag-drift', {
|
|
1938
|
+
...drift, action: 'skip-push-use-pinned-digest',
|
|
1939
|
+
}, { level: 'warn' });
|
|
1940
|
+
return result.images;
|
|
1941
|
+
};
|
|
1942
|
+
};
|
|
1808
1943
|
// GATE-HOSTMIRROR-EXPLICIT: resolved once per runner and handed to every podCommand (shard · retry · recheck).
|
|
1809
1944
|
let gateMirror: GateHostMirror | undefined;
|
|
1810
1945
|
const gateHostMirror = (pod: NonNullable<GateOptions['pod']>): { hostMirror?: string } => {
|
|
@@ -1847,6 +1982,9 @@ export function createGateRunner(repo: string, remote?: string, commandOverride?
|
|
|
1847
1982
|
if (!pod.pool || !Number.isSafeInteger(shardCount) || shardCount < 1
|
|
1848
1983
|
|| !Number.isSafeInteger(deadlineSeconds) || deadlineSeconds < 1
|
|
1849
1984
|
|| !Number.isSafeInteger(isolationConcurrency) || isolationConcurrency < 1) throw new Error('invalid pod sweep options');
|
|
1985
|
+
const hasPinnedDigest = Boolean(pod.pinnedImageDigest?.trim());
|
|
1986
|
+
const hasPinnedRunId = Boolean(pod.pinnedRunId?.trim());
|
|
1987
|
+
if (hasPinnedDigest !== hasPinnedRunId) throw new Error('gate pinned image: both pinnedImageDigest and pinnedRunId are required');
|
|
1850
1988
|
const head = await command('git', ['rev-parse', 'HEAD'], tree);
|
|
1851
1989
|
check(head, 'cut tree HEAD');
|
|
1852
1990
|
const commit = head.output.trim();
|
|
@@ -1975,7 +2113,7 @@ export function createGateRunner(repo: string, remote?: string, commandOverride?
|
|
|
1975
2113
|
const admissionWaitSeconds = pod.admissionWaitSeconds ?? gateAdmissionWaitSeconds(shards.length, rootSlots);
|
|
1976
2114
|
if (!Number.isSafeInteger(admissionWaitSeconds) || admissionWaitSeconds < 0) throw new Error('invalid pod sweep options');
|
|
1977
2115
|
// An injected pool (tests) runs without admission unless `pod.admission` is passed; the gate's own pool asks it.
|
|
1978
|
-
const gateAdmission = pod.admission ?? tools.admission ?? (poolOverride ? undefined : poolGateAdmission(poolScheduler));
|
|
2116
|
+
const gateAdmission = pod.admission ?? tools.admission ?? (poolOverride ? undefined : poolGateAdmission(poolScheduler, tools.graphRunId ?? null));
|
|
1979
2117
|
debug.log('release-loop.gate', 'pod-admission', { waitSeconds: admissionWaitSeconds, source: pod.admissionWaitSeconds !== undefined ? 'config' : 'default', enabled: !!gateAdmission && admissionWaitSeconds > 0,
|
|
1980
2118
|
rootSlots, shards: shards.length });
|
|
1981
2119
|
// GATE-POD-STALL-FAILFAST: a shard with no test output within the stall window is stopped and recorded unmeasured.
|
|
@@ -2355,7 +2493,8 @@ export function createGateRunner(repo: string, remote?: string, commandOverride?
|
|
|
2355
2493
|
stamp('poolPlaced'); jobContext = member.context; jobContextForCapture = member.context; placedOn = member.context; placed();
|
|
2356
2494
|
if (branch === '-tail') tailPlacedHost = member.context;
|
|
2357
2495
|
}, skipMembers, depth === 0 && branch === '' && hostRetries === 0 && !retriedNoOutput && !batchIsolation && skipMembers.size === 0), clone: true, source: { kind: 'commit', sha: commit },
|
|
2358
|
-
...(pod.imagePin === 'cut-commit' ? { imageCommit: commit } : {}),
|
|
2496
|
+
...(pod.imagePin === 'cut-commit' || pod.pinnedImageDigest || pod.pinnedRunId ? { imageCommit: commit } : {}),
|
|
2497
|
+
...(pod.pinnedImageDigest || pod.pinnedRunId ? { syncImages: pinnedGateImageSync(pod, commit)! } : {}), deadlineSeconds: shardDeadline,
|
|
2359
2498
|
...gateHostMirror(pod),
|
|
2360
2499
|
...(multiHost ? { statusUnreadableMs: memberUnreadableSeconds * 1000 } : {}),
|
|
2361
2500
|
...(bunCache ? { bunCache } : {}),
|
|
@@ -2982,7 +3121,9 @@ export function createGateRunner(repo: string, remote?: string, commandOverride?
|
|
|
2982
3121
|
let producer: RunPodCommandOptions['warmProducer'];
|
|
2983
3122
|
if (leased && replay?.transport.status === 'observed' && replay.transport.reason === 'complete') {
|
|
2984
3123
|
if (warmCommandMatchesRequest(leased, warmRequest!) && leased.podName && leased.podUid
|
|
2985
|
-
&& leased.podContext && leased.image?.endsWith(`@${leased.key.imageDigest}`)
|
|
3124
|
+
&& leased.podContext && leased.image?.endsWith(`@${leased.key.imageDigest}`)
|
|
3125
|
+
&& (!pod.pinnedImageDigest || (normalizeGateImageDigest(pod.pinnedImageDigest) !== null
|
|
3126
|
+
&& normalizeGateImageDigest(leased.key.imageDigest) === normalizeGateImageDigest(pod.pinnedImageDigest)))) {
|
|
2986
3127
|
producer = { pod: leased.podName, podUid: leased.podUid, context: leased.podContext, image: leased.image,
|
|
2987
3128
|
commit, files: ['package.json', 'bun.lock'] };
|
|
2988
3129
|
} else await quarantine('gate-producer-identity');
|
|
@@ -2996,7 +3137,9 @@ export function createGateRunner(repo: string, remote?: string, commandOverride?
|
|
|
2996
3137
|
run: process.env.ELANOUS_RUN_ID || attemptId, phase: 'release-gate', requestedAt: new Date().toISOString(),
|
|
2997
3138
|
graphNode: 'gate-triage', commit, reason: `release gate recheck ${files.length} files`, pool: pod.pool,
|
|
2998
3139
|
memReq: POD_ISOLATION_MEMORY_LIMIT, warmReused: !!producer },
|
|
2999
|
-
source: { kind: 'commit', sha: commit }, deadlineSeconds, ...(producer ? { warmProducer: producer, image: producer.image
|
|
3140
|
+
source: { kind: 'commit', sha: commit }, deadlineSeconds, ...(producer ? { warmProducer: producer, image: producer.image } : {}),
|
|
3141
|
+
...(producer || pod.pinnedImageDigest || pod.pinnedRunId ? { imageCommit: commit } : {}),
|
|
3142
|
+
...(pod.pinnedImageDigest || pod.pinnedRunId ? { syncImages: pinnedGateImageSync(pod, commit)! } : {}),
|
|
3000
3143
|
...(bunCache ? { bunCache } : {}), ...gateHostMirror(pod),
|
|
3001
3144
|
...(installSlots > 0 ? { installSlots: POD_INSTALL_SLOTS_HOST_PATH } : {}), ...(pod.cpu ? { cpu: pod.cpu } : {}),
|
|
3002
3145
|
memoryLimit: POD_ISOLATION_MEMORY_LIMIT, name: `gate-recheck-${randomUUID()}`, command: ['bash', '-lc', shell] });
|
|
@@ -3349,9 +3492,10 @@ export function saveBaselineFileCache(ledger: string, commit: string, rows: Base
|
|
|
3349
3492
|
} finally { if (existsSync(temp)) rmSync(temp); }
|
|
3350
3493
|
}
|
|
3351
3494
|
|
|
3352
|
-
export async function judgeGate(opts: GateOptions, runner: GateRunner = createGateRunner(opts.repo ?? process.cwd(), opts.remote),
|
|
3495
|
+
export async function judgeGate(opts: GateOptions, runner: GateRunner = createGateRunner(opts.repo ?? process.cwd(), opts.remote, undefined, undefined, undefined, undefined, { graphRunId: opts.graphRunId ?? null }),
|
|
3353
3496
|
imageProbe: typeof preflightGateImageDigest = preflightGateImageDigest,
|
|
3354
|
-
identityProbe: typeof preflightGateExecutionIdentity = preflightGateExecutionIdentity
|
|
3497
|
+
identityProbe: typeof preflightGateExecutionIdentity = preflightGateExecutionIdentity,
|
|
3498
|
+
syncImages: typeof syncPoolImages = syncPoolImages): Promise<GateResult> {
|
|
3355
3499
|
if (opts.pod?.warmReplay) opts = { ...opts, pod: { ...opts.pod,
|
|
3356
3500
|
warmShadowScope: { requested: false, attempts: 0 } } };
|
|
3357
3501
|
const explicitConfig = getElanousConfigDirOverride();
|
|
@@ -3430,11 +3574,22 @@ export async function judgeGate(opts: GateOptions, runner: GateRunner = createGa
|
|
|
3430
3574
|
const pinPath = gateImagePinPath(root, opts.version, pinRunId);
|
|
3431
3575
|
const gateImageTag = `${podCommandImageFor([], true).split(':')[0]}:${opts.commit.slice(0, 12)}`;
|
|
3432
3576
|
let savedPin: ReturnType<typeof readGateImagePin>;
|
|
3577
|
+
let supersededPin: ReturnType<typeof readGateImagePinForRun> = null;
|
|
3578
|
+
let stalePinNeedsSuperseding = false;
|
|
3433
3579
|
try { savedPin = existsSync(pinPath) ? readGateImagePin(pinPath, pinRunId, gateImageTag, opts.commit) : null; }
|
|
3434
3580
|
catch (error) {
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3581
|
+
let prior: ReturnType<typeof readGateImagePinForRun> = null;
|
|
3582
|
+
try { prior = readGateImagePinForRun(pinPath, pinRunId, gateImageTag); } catch { /* Keep invalid or corrupt pins fail-closed. */ }
|
|
3583
|
+
if (!prior || prior.commit === opts.commit.toLowerCase()) {
|
|
3584
|
+
debug.log('release-loop.gate', 'image-pin', { runId: pinRunId, currentImages, decision: 'fail-closed',
|
|
3585
|
+
reason: 'saved-image-pin-invalid', error: String(error).slice(0, 300) }, { level: 'error' });
|
|
3586
|
+
throw new Error('gate resume refused: saved image digest pin is invalid');
|
|
3587
|
+
}
|
|
3588
|
+
supersededPin = prior;
|
|
3589
|
+
stalePinNeedsSuperseding = true;
|
|
3590
|
+
savedPin = null;
|
|
3591
|
+
debug.log('release-loop.gate', 'image-pin', { runId: pinRunId, currentImages, decision: 'stale-tip-detected',
|
|
3592
|
+
priorCommit: supersededPin.commit, nextCommit: opts.commit.toLowerCase() });
|
|
3438
3593
|
}
|
|
3439
3594
|
const savedDigest = savedPin?.digest ?? null;
|
|
3440
3595
|
let previouslyExecuted = false;
|
|
@@ -3449,11 +3604,34 @@ export async function judgeGate(opts: GateOptions, runner: GateRunner = createGa
|
|
|
3449
3604
|
} catch { previouslyExecuted = true; }
|
|
3450
3605
|
}
|
|
3451
3606
|
}
|
|
3452
|
-
if (!savedDigest && previouslyExecuted) {
|
|
3607
|
+
if (!savedDigest && previouslyExecuted && !supersededPin) {
|
|
3453
3608
|
debug.log('release-loop.gate', 'image-pin', { runId: opts.graphRunId, savedDigest: null, currentImages,
|
|
3454
3609
|
decision: 'fail-closed', reason: 'resume-pin-missing' }, { level: 'error' });
|
|
3455
3610
|
throw new Error('gate resume refused: saved image digest pin is missing');
|
|
3456
3611
|
}
|
|
3612
|
+
const hasPoolImage = [...poolImages.values()].some((images) => images.some((image) => normalizeGateImageDigest(image) !== null));
|
|
3613
|
+
if (!savedDigest && !hasPoolImage) {
|
|
3614
|
+
let syncResults: Awaited<ReturnType<typeof syncPoolImages>>;
|
|
3615
|
+
try { syncResults = await syncImages(members, podCommandImageFor([], true), opts.commit); }
|
|
3616
|
+
catch (error) {
|
|
3617
|
+
debug.log('release-loop.gate', 'image-pin', { runId: pinRunId, decision: 'fail-closed',
|
|
3618
|
+
reason: 'initial-image-sync-failed', error: String(error).slice(0, 300) }, { level: 'error' });
|
|
3619
|
+
throw new Error('gate image pin refused: initial image sync failed');
|
|
3620
|
+
}
|
|
3621
|
+
const failedSyncs = memberSpecs.filter((member) => !syncResults.get(member.context)?.ok);
|
|
3622
|
+
if (failedSyncs.length) {
|
|
3623
|
+
debug.log('release-loop.gate', 'image-pin', { runId: pinRunId, decision: 'fail-closed', reason: 'initial-image-sync-failed',
|
|
3624
|
+
failed: failedSyncs.map((member) => ({ context: member.context, result: syncResults.get(member.context) ?? null })) }, { level: 'error' });
|
|
3625
|
+
throw new Error('gate image pin refused: initial image sync failed');
|
|
3626
|
+
}
|
|
3627
|
+
for (const member of memberSpecs) {
|
|
3628
|
+
const digest = imageProbe(member.spec, opts.commit);
|
|
3629
|
+
currentImages[member.context] = digest;
|
|
3630
|
+
poolImages.set(member.context, digest ? [digest] : []);
|
|
3631
|
+
}
|
|
3632
|
+
debug.log('release-loop.gate', 'image-pin', { runId: pinRunId, decision: 'initial-image-sync',
|
|
3633
|
+
outcomes: [...syncResults].map(([context, result]) => ({ context, ok: result.ok, action: result.action })), currentImages });
|
|
3634
|
+
}
|
|
3457
3635
|
const resolution = resolveGateImagePin({ ...(savedDigest ? { savedDigest } : {}),
|
|
3458
3636
|
...(!savedDigest ? { initialDigest: [...poolImages.values()].flat().find(Boolean) ?? null } : {}), poolImages });
|
|
3459
3637
|
if (!resolution.ok) {
|
|
@@ -3464,7 +3642,11 @@ export async function judgeGate(opts: GateOptions, runner: GateRunner = createGa
|
|
|
3464
3642
|
const selected = memberSpecs.filter((member) => resolution.eligiblePools.includes(member.context));
|
|
3465
3643
|
if (!selected.length) throw new Error('gate image pin refused: no eligible pool');
|
|
3466
3644
|
if (!savedDigest) {
|
|
3467
|
-
try {
|
|
3645
|
+
try {
|
|
3646
|
+
if (stalePinNeedsSuperseding) {
|
|
3647
|
+
replaceGateImagePin(pinPath, pinRunId, resolution.digest, gateImageTag, opts.commit, gateImageTag, supersededPin!.commit);
|
|
3648
|
+
} else writeGateImagePin(pinPath, pinRunId, resolution.digest, gateImageTag, opts.commit);
|
|
3649
|
+
}
|
|
3468
3650
|
catch (error) {
|
|
3469
3651
|
debug.log('release-loop.gate', 'image-pin', { runId: pinRunId, pinnedDigest: resolution.digest,
|
|
3470
3652
|
currentImages, decision: 'fail-closed', reason: 'pin-write-failed', error: String(error).slice(0, 300) }, { level: 'error' });
|
|
@@ -4431,11 +4613,12 @@ export async function runGateNode(argv: string[], env: NodeJS.ProcessEnv, runner
|
|
|
4431
4613
|
judge: (opts: GateOptions, runner?: GateRunner, imageProbe?: typeof preflightGateImageDigest) => Promise<GateResult> = judgeGate,
|
|
4432
4614
|
imageProbe: typeof preflightGateImageDigest = preflightGateImageDigest): Promise<number> {
|
|
4433
4615
|
const start = Date.now();
|
|
4434
|
-
let result: GateResult;
|
|
4616
|
+
let result: GateResult | undefined;
|
|
4435
4617
|
let version = '';
|
|
4436
4618
|
let graphRunId: string | null = null;
|
|
4437
4619
|
let autohealStoreRoot = '';
|
|
4438
4620
|
let placement: { executor: string | null; host: string | null } | undefined;
|
|
4621
|
+
let warmControlCleanup: (() => Promise<void>) | undefined;
|
|
4439
4622
|
try {
|
|
4440
4623
|
const parsed = parseOptions(argv, env);
|
|
4441
4624
|
let config: unknown = null;
|
|
@@ -4443,9 +4626,10 @@ export async function runGateNode(argv: string[], env: NodeJS.ProcessEnv, runner
|
|
|
4443
4626
|
try { config = getUserConfig(); }
|
|
4444
4627
|
catch (error) { debug.log('release-loop.gate', 'warm-profile-unavailable', { error: String(error) }); }
|
|
4445
4628
|
}
|
|
4446
|
-
const opts = parsed === 'help' ? parsed : withWarmGateHooks(parsed, config, !!runner
|
|
4629
|
+
const opts = parsed === 'help' ? parsed : withWarmGateHooks(parsed, config, !!runner,
|
|
4630
|
+
cleanup => { warmControlCleanup = cleanup; });
|
|
4447
4631
|
if (opts !== 'help' && opts.warmPrecutCanary) {
|
|
4448
|
-
const canaryRunner = runner ?? createGateRunner(opts.repo ?? process.cwd(), opts.remote);
|
|
4632
|
+
const canaryRunner = runner ?? createGateRunner(opts.repo ?? process.cwd(), opts.remote, undefined, undefined, undefined, undefined, { graphRunId: opts.graphRunId ?? null });
|
|
4449
4633
|
const warmPrecutTestSeam = (runner as (GateRunner & { warmPrecutCanaryTestSeam?: {
|
|
4450
4634
|
config: unknown; hooks: Pick<NonNullable<GateOptions['pod']>, 'warmReplay' | 'warmFinalize' | 'warmQuarantine' | 'warmReuseConfig'>;
|
|
4451
4635
|
} }) | undefined)?.warmPrecutCanaryTestSeam;
|
|
@@ -4483,7 +4667,15 @@ export async function runGateNode(argv: string[], env: NodeJS.ProcessEnv, runner
|
|
|
4483
4667
|
} catch (error) {
|
|
4484
4668
|
result = { outcome: 'error', commit: '', introduced: [], preexisting: 0, fixed: 0, knownEnv: 0, knownEnvCleared: [], stalledEnv: [], rcNonzeroNoFailures: [], durationMs: Date.now() - start, error: String(error) };
|
|
4485
4669
|
placement ??= requestedGateExecutor(argv, env);
|
|
4670
|
+
} finally {
|
|
4671
|
+
try { await warmControlCleanup?.(); }
|
|
4672
|
+
catch (error) {
|
|
4673
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
4674
|
+
debug.log('pod.warm.control-forward', 'cleanup-failed', { version, reason }, { level: 'error' });
|
|
4675
|
+
if (typeof result !== 'undefined') result = { ...result, outcome: 'error', error: [result.error, reason].filter(Boolean).join('; ') };
|
|
4676
|
+
}
|
|
4486
4677
|
}
|
|
4678
|
+
if (!result) throw new Error('release gate returned without a result');
|
|
4487
4679
|
if (versionPattern.test(version) && result.stalledShards?.length) {
|
|
4488
4680
|
result.autoheals = result.stalledShards.map((shard, index) => {
|
|
4489
4681
|
const shardKey = `pod-${shard.shard}`;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic E4 fixture: emit a fixed fake-Pod gate-progress sequence through
|
|
3
|
+
* the real standalone debug-log sink. It never starts a gate, Pod, SSH, or kubectl.
|
|
4
|
+
* Run only with ELANOUS_STATE_DIR pointing at an isolated directory (config
|
|
5
|
+
* follows the resolved state root), then inspect it with `eln logs --category release-loop.gate`.
|
|
6
|
+
*/
|
|
7
|
+
import { randomUUID } from 'node:crypto';
|
|
8
|
+
import { mkdirSync, realpathSync } from 'node:fs';
|
|
9
|
+
import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
10
|
+
import { debug } from '../../src/debug/log.js';
|
|
11
|
+
import { effectiveInstanceRoot, prodInstanceRoot } from '../../src/instance/resolve.js';
|
|
12
|
+
import { getElanousConfigDir } from '../../src/elanous-config-dir.js';
|
|
13
|
+
import { registerStandaloneLogSink } from '../../src/domains/standalone-log-sink.js';
|
|
14
|
+
|
|
15
|
+
const scenario = [
|
|
16
|
+
{ completed: 0, total: 3, elapsedMs: 0 },
|
|
17
|
+
{ completed: 1, total: 3, elapsedMs: 1_000 },
|
|
18
|
+
{ completed: 3, total: 3, elapsedMs: 3_000 },
|
|
19
|
+
] as const;
|
|
20
|
+
|
|
21
|
+
function isInside(path: string, root: string): boolean {
|
|
22
|
+
const comparablePath = process.platform === 'darwin' ? path.toLocaleLowerCase('en-US') : path;
|
|
23
|
+
const comparableRoot = process.platform === 'darwin' ? root.toLocaleLowerCase('en-US') : root;
|
|
24
|
+
const rel = relative(comparableRoot, comparablePath);
|
|
25
|
+
return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function canonicalRoot(path: string): string {
|
|
29
|
+
let cursor = resolve(path);
|
|
30
|
+
const suffix: string[] = [];
|
|
31
|
+
for (;;) {
|
|
32
|
+
try { return join(realpathSync(cursor), ...suffix.reverse()); }
|
|
33
|
+
catch (error) {
|
|
34
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;
|
|
35
|
+
const parent = dirname(cursor);
|
|
36
|
+
if (parent === cursor) throw error;
|
|
37
|
+
suffix.push(basename(cursor));
|
|
38
|
+
cursor = parent;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function emitGateProgressSimulation(runId?: string): Promise<void> {
|
|
44
|
+
const stateRoot = effectiveInstanceRoot();
|
|
45
|
+
const configRoot = getElanousConfigDir();
|
|
46
|
+
const actualProdRoot = canonicalRoot(prodInstanceRoot());
|
|
47
|
+
const actualStateRoot = canonicalRoot(stateRoot);
|
|
48
|
+
const actualConfigRoot = canonicalRoot(configRoot);
|
|
49
|
+
const overlapsProductionRoot = [actualStateRoot, actualConfigRoot].some((root) =>
|
|
50
|
+
isInside(root, actualProdRoot) || isInside(actualProdRoot, root));
|
|
51
|
+
if (overlapsProductionRoot) {
|
|
52
|
+
throw new Error('refusing to emit mock gate events into the production instance; set ELANOUS_STATE_DIR to an isolated path');
|
|
53
|
+
}
|
|
54
|
+
// Logs are written below effectiveInstanceRoot() by logsDbPath(); check both resolver roots before creating either.
|
|
55
|
+
mkdirSync(stateRoot, { recursive: true });
|
|
56
|
+
mkdirSync(configRoot, { recursive: true });
|
|
57
|
+
if (!await registerStandaloneLogSink('release-loop')) {
|
|
58
|
+
throw new Error('could not register the isolated standalone logs.db sink');
|
|
59
|
+
}
|
|
60
|
+
const effectiveRunId = runId?.trim() || randomUUID();
|
|
61
|
+
for (const step of scenario) {
|
|
62
|
+
debug.log('release-loop.gate', 'progress', {
|
|
63
|
+
runId: effectiveRunId,
|
|
64
|
+
scenario: 'e4-fixed-pod-shards',
|
|
65
|
+
executor: 'pod',
|
|
66
|
+
host: 'mock-pod-host-1',
|
|
67
|
+
...step,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
process.stdout.write(`${JSON.stringify({ runId: effectiveRunId, scenario: 'e4-fixed-pod-shards', events: scenario.length, stateRoot: actualStateRoot })}\n`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (import.meta.main) await emitGateProgressSimulation(process.argv[2] || undefined);
|
|
@@ -12,6 +12,23 @@ export const REPAIR_MODEL = 'openrouter/z-ai/glm-5.3';
|
|
|
12
12
|
export type Translator = (line: string, model: string) => Promise<string>;
|
|
13
13
|
export type RepairResult = { text: string; translatedLines: number[]; error?: string };
|
|
14
14
|
|
|
15
|
+
/** Avoid sending a different provider's configured API key to OpenRouter. */
|
|
16
|
+
export function notesRepairLlmConfig(config: ReturnType<typeof getUserConfig>, model = REPAIR_MODEL) {
|
|
17
|
+
const isOpenRouterConfig = config.llm.provider === 'openrouter';
|
|
18
|
+
const llm = { ...config.llm, provider: 'openrouter' as const, model };
|
|
19
|
+
if (isOpenRouterConfig) {
|
|
20
|
+
llm.apiKey = config.llm.apiKey;
|
|
21
|
+
llm.baseUrl = config.llm.baseUrl;
|
|
22
|
+
} else {
|
|
23
|
+
delete llm.apiKey;
|
|
24
|
+
delete llm.baseUrl;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
...config,
|
|
28
|
+
llm,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
15
32
|
function koreanProseLines(text: string): Array<{ index: number; line: string }> {
|
|
16
33
|
let fence: { char: string; length: number } | undefined;
|
|
17
34
|
return text.split(/\r?\n/).flatMap((line, index) => {
|
|
@@ -58,7 +75,7 @@ export async function repairKoreanMarkdown(text: string, translate: Translator,
|
|
|
58
75
|
export const glmTranslator: Translator = async (line, model) => {
|
|
59
76
|
if (model !== REPAIR_MODEL) throw new Error(`unexpected translator model: ${model}`);
|
|
60
77
|
const config = getUserConfig();
|
|
61
|
-
const llmConfig =
|
|
78
|
+
const llmConfig = notesRepairLlmConfig(config, model);
|
|
62
79
|
const provider = getProviderForConfig(llmConfig, model);
|
|
63
80
|
if (provider.name !== 'openrouter' || !provider.available()) throw new Error('OpenRouter credentials unavailable for openrouter/z-ai/glm-5.3');
|
|
64
81
|
const messages: LLMMessage[] = [
|