elanous 0.2.42 → 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/{X1ucLw10Cds_h614NoEnh → HMXsxdy5MIIcHPMHv1wD4}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/08334415.f0e80896acbef722.js +1 -0
- 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/{2160.a097e7b138ae1c55.js → 118.2a89982fe4276880.js} +1 -1
- 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/1306.967240ede9a0f757.js +24 -0
- package/apps/pwa/out/_next/static/chunks/1344.3b95f3bd1b77a3fe.js +94 -0
- package/apps/pwa/out/_next/static/chunks/{4043.6b91203436c9c86b.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/{6632.0eac1c554f8f2ef3.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/1850-522de4ee34957210.js +1 -0
- 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/{3507.97e1977bc4d5fb0a.js → 1978.eeb60a606dc5deac.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/2043.e233e3b5a3e790f5.js +1 -0
- 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/2216.802962c04f40a26e.js +64 -0
- 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/{5885.0a3e52c8faccec98.js → 239.de075467b5523469.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/249.ba7051590d603c8f.js +226 -0
- 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/2954.bbefc95d6b20e0d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2e0f720a.a0697c08e3806a60.js +1 -0
- 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/{1487.2f67b79444062da6.js → 3349.b5f09ee474d9533e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3503.a47a9755fb4d97b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3506-5f429b3b7e1392b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3843.bad404d008893291.js +77 -0
- 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/4393.28fa5228d0eec217.js +149 -0
- package/apps/pwa/out/_next/static/chunks/4404.7281c847c6e10dfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8673-bab689a55f7e13b9.js → 4415-b9d6a90960920a4a.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/447-5b304de1fe098f43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4484-8ebea83d431e6fae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8262.ddc03e06b733f184.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/{1262.e804feb8fd1acb8c.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/{1063.2fb8a9dc55c731f2.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/{6377.bc7df239edbff244.js → 4891.3f80ba517a3b2373.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4998.810ca8833084caa9.js +62 -0
- package/apps/pwa/out/_next/static/chunks/4f98febc.ea5841d4d616bfb2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3482.a9ae9d2ad6a5bd97.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/5439.3fec6dbce29ecb36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5612-074d9a5e00dfac6a.js +1 -0
- 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/5790.5eb06a653ebd8571.js +34 -0
- 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/{3347.f846266b5e5f3ede.js → 5989.7ecd362c5c44b747.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{73d2eb0e.4966ad55293c801a.js → 5a34fb2f.52f1b4e1baebb48a.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{7a98bc80.fa935989e829f9c2.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/{7411.9b4b8b747dc7b802.js → 6245.1182e007e9d230d9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{b450776b.3db34d8d965f82d3.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/{e8543907.5b040a5f22a0b0e5.js → 6549dad0.2740b25e51bf8f05.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9427.96aa912ddb5801e0.js → 6881.9e7955847640c7fe.js} +17 -17
- 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/7010.1bbd17a7f2b3e376.js +1 -0
- 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/7679.32c40cdd14f20b4a.js +1 -0
- 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/{8138.6c10b2a356d52fca.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/{9415.69e4a21c60c7d2db.js → 8551.f762945c2cda2e95.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8635-57a9d8d9db70f4f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/86961958-4b0689a5048f756b.js +1 -0
- 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/{9a852a62-6192a6ea9346ced3.js → 87f498e5-0881de09f2e44707.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8843.c3197f904c952b81.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3d0154af.5331fec737ffe8c3.js → 892fd990.456232f326cc39c2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8965-135a2c9eaa2464cb.js +1 -0
- 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/9398.1f56e3f17795f43f.js +1 -0
- 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-da787e8a10b8a82e.js +1 -0
- 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/_next/static/css/d1f8bb401740a549.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +23 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/catalog/external-commands.yaml +5 -3
- package/catalog/meta/catalogVersion.yaml +2 -1
- package/catalog/signing/catalog-signing-public.pem +3 -0
- package/graphs/intake/intake-daily.yaml +16 -0
- package/graphs/intake/news-sources.yaml +1 -0
- package/graphs/intake/recipes.yaml +7 -0
- package/graphs/overlays/README.md +6 -0
- package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
- package/graphs/profiles/local.yaml +5 -0
- package/graphs/profiles/pod.yaml +4 -0
- package/graphs/release/release-loop.yaml +33 -17
- package/graphs/units/verbs/make-doc.yaml +1 -0
- package/package.json +6 -2
- package/plugins/demo-absorption-briefing/plugin.json +18 -0
- package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
- package/plugins/demo-browser-hand/plugin.json +13 -0
- package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
- package/plugins/demo-linear-secretary/plugin.json +15 -0
- package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
- package/plugins/demo-plugin-wizard/plugin.json +11 -0
- package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
- package/plugins/demo-research/plugin.json +16 -0
- package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
- package/plugins/demo-video-briefing/plugin.json +15 -0
- package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
- package/scripts/bench-metering-plan.ts +229 -0
- package/scripts/build-signed-catalog.ts +48 -0
- package/scripts/ci-typecheck-main-delta.sh +88 -0
- package/scripts/codex-fallback-live-probe.ts +1 -1
- package/scripts/demo/demo1104-parallel-host.ts +56 -0
- package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
- package/scripts/demo/demo1104-parallel.ts +72 -0
- package/scripts/demo/demo1104-stage.config.ts +21 -0
- package/scripts/demo/demo1104-stage.ts +316 -0
- package/scripts/goal-method-audit.ts +17 -1
- package/scripts/graph-units/land-enqueue.ts +90 -0
- package/scripts/hooks/codex-notify.sh +32 -0
- package/scripts/install.sh +10 -38
- package/scripts/landing-heal/land-plan.ts +57 -0
- package/scripts/public-leak-baseline.txt +0 -1
- package/scripts/release-loop/auto-approve-node.ts +1 -1
- package/scripts/release-loop/docs-node.ts +4 -2
- package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
- package/scripts/release-loop/gate-image-pin.ts +116 -2
- package/scripts/release-loop/gate-method.ts +139 -0
- package/scripts/release-loop/gate-node.ts +395 -43
- package/scripts/release-loop/gate-progress-sim.ts +73 -0
- package/scripts/release-loop/gate-traffic-mode.ts +151 -3
- package/scripts/release-loop/node-verdict.ts +38 -25
- package/scripts/release-loop/notes-repair.ts +18 -1
- package/scripts/release-loop/preflight.ts +544 -10
- 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/unattended-release.ts +20 -9
- package/scripts/release-loop/warm-control-forward.ts +178 -0
- package/scripts/retro-cycle.ts +30 -8
- package/scripts/rhythm/daily.ts +39 -4
- package/scripts/rhythm/linear-progress-sync.ts +311 -0
- package/scripts/ux-sim.ts +7 -1
- package/scripts/video-pipeline.ts +9 -1
- package/scripts/warm-pool-provider-config.ts +35 -7
- package/src/acp/agent-manager.ts +1 -0
- package/src/acp/codex-app-server-agent.ts +33 -0
- package/src/acp/codex-app-server-client.ts +153 -16
- package/src/acp/core-turn-bridge.ts +17 -12
- package/src/acp/event-router.ts +20 -1
- package/src/acp/server.ts +6 -0
- package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
- package/src/agent-mission/claude-headless.ts +4 -1
- package/src/agent-mission/codex-exec.ts +105 -0
- package/src/agent-mission/driver.ts +192 -11
- package/src/agent-mission/grok-auth-status.ts +107 -0
- package/src/agent-mission/hand-hooks.ts +101 -0
- package/src/agent-mission/mission-cli.ts +56 -21
- package/src/agent-mission/mission-hand-reply.ts +118 -0
- package/src/agent-mission/mission-line.ts +180 -0
- package/src/agent-mission/mission-out.ts +256 -18
- package/src/agent-mission/tool-install.ts +122 -11
- package/src/agent-substrate/pr-reviewer.ts +147 -11
- package/src/agent-substrate/self-review-cli.ts +10 -2
- package/src/agents/general-purpose.md +1 -1
- package/src/auto-research/research-fanout.ts +221 -0
- package/src/auto-research/research-turn.ts +362 -31
- package/src/autopilot/mission-codebase-gate.ts +7 -3
- package/src/autopilot/pr-manager.ts +31 -3
- package/src/boot/daemon-tools/self-implement.ts +3 -1
- package/src/boot/daemon-tools/web-search.ts +1 -2
- package/src/briefing/brief-items.ts +55 -11
- package/src/cli/agent-cli.ts +2 -1
- package/src/cli/catalog-cli.ts +31 -0
- package/src/cli/connector-cli.ts +16 -0
- package/src/cli/control-cli.ts +15 -6
- package/src/cli/doctor-fix.ts +2 -2
- package/src/cli/intake-source-cli.ts +44 -8
- package/src/cli/log-event-names.ts +8 -0
- package/src/cli/msg-cli.ts +32 -3
- package/src/cli/pr-cli.ts +21 -1
- package/src/cli/pr-land-heavy-remote.ts +44 -6
- package/src/cli/pr-land-overlap-evidence.ts +13 -1
- package/src/cli/pr-land-pod-shadow-job.ts +143 -5
- package/src/cli/pr-land-pod-shadow.ts +9 -2
- package/src/cli/release-checklist-read-cli.ts +44 -16
- package/src/cli/release-cli.ts +23 -3
- package/src/cli/research-cli.ts +9 -0
- package/src/cli/setup-cli.ts +166 -6
- package/src/cli/setup-keys.ts +199 -0
- package/src/cli/task-plugin-wizard-host.ts +114 -0
- package/src/cli/tasks-cli.ts +54 -9
- package/src/cli/tui-test-cli.ts +190 -0
- package/src/config.ts +4 -2
- package/src/connectors/linear-daily-progress.ts +228 -0
- package/src/connectors/linear-projector.ts +34 -12
- package/src/connectors/linear.ts +151 -7
- 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/deep-turn-bloom.ts +67 -0
- package/src/core-turn/research-policy.ts +43 -0
- package/src/core-turn/run-core-turn.ts +488 -51
- package/src/core-turn/types.ts +4 -0
- package/src/dashboard/chat/acp-chat.ts +10 -0
- package/src/dashboard/classic-sidetab-mission-job.ts +192 -0
- package/src/dashboard/classic-sidetab-mission-pair.ts +82 -0
- package/src/dashboard/classic-sidetab-mission-trio.ts +242 -0
- package/src/dashboard/classic-sidetab-mission.ts +169 -5
- package/src/dashboard/index.ts +387 -14
- package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +8 -0
- package/src/dashboard/mission-cli-consumer.ts +20 -8
- package/src/dashboard/plugin-wizard-runtime.ts +50 -0
- package/src/dashboard/plugin-wizard-tool.ts +55 -0
- package/src/dashboard/sidetab-runtime.ts +3 -1
- package/src/dashboard/terminal-popup-runtime.ts +6 -3
- package/src/dashboard/visible-mission-diagnostics.ts +16 -0
- package/src/decisions/linear-progress-summary.ts +78 -0
- package/src/decisions/linear-progress-sync.ts +152 -0
- package/src/domains/outbound-alert.ts +49 -11
- 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/domains/telegram-kind-route.ts +16 -9
- package/src/graph-runner/arg-allowance.ts +13 -0
- package/src/graph-runner/graph-cli.ts +24 -1
- package/src/graph-runner/graph-grow-llm.ts +3 -1
- package/src/graph-runner/graph-run-api.ts +3 -1
- package/src/graph-runner/runner.ts +310 -46
- package/src/graph-wizard/mission-compose.ts +407 -12
- package/src/harness/dispatch-backpressure.ts +54 -1
- package/src/harness/dispatch-shadow-compare.ts +74 -0
- package/src/harness/harness-cli-command.ts +15 -3
- package/src/harness/harness-pod-dispatch.ts +3 -0
- package/src/harness/skill-exec.ts +21 -9
- package/src/harness/skill-select.ts +1 -1
- package/src/hooks/error-report-cloud.ts +101 -0
- package/src/hooks/receiver.ts +29 -2
- package/src/index.ts +129 -12
- package/src/intake-plane/actions.ts +354 -0
- package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
- package/src/intake-plane/intake-sources.ts +78 -8
- package/src/intake-plane/items.ts +14 -4
- package/src/intake-plane/linear-mission-sync.ts +80 -0
- package/src/intake-plane/linear-secretary-runtime.ts +178 -0
- package/src/intake-plane/linear-wish.ts +227 -1
- package/src/life/life-cli.ts +168 -0
- package/src/life/life-kinds.ts +160 -0
- package/src/live-supply/budget-consumer.ts +78 -0
- package/src/live-supply/read.ts +3 -0
- package/src/live-supply/snapshot.ts +45 -0
- package/src/llm/child-first-llm-observation.ts +112 -0
- package/src/llm/provider-credentials.ts +68 -6
- package/src/llm/provider-failure-evidence.ts +44 -0
- package/src/llm.ts +172 -12
- package/src/maturity/feature-maturity.ts +3 -3
- package/src/mcp/client.ts +7 -0
- package/src/mcp/proxy-runtime.ts +6 -1
- package/src/mcp/server.ts +54 -0
- package/src/msg/msg-sse-server.ts +3 -3
- package/src/msg/msg-store.ts +177 -19
- package/src/native-tool-catalog.ts +36 -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/http-server.ts +37 -1
- package/src/nexus/api/mcp-public-allowlist.ts +2 -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 +22 -2
- package/src/nexus/outbound/format.ts +9 -0
- package/src/nexus/outbound/grokbot-adapter.ts +71 -0
- package/src/nexus/outbound/router.ts +121 -16
- package/src/nexus/setup-status.ts +9 -0
- package/src/nexus/state/state.ts +3 -0
- package/src/oauth/codex-account-store.ts +20 -7
- package/src/oauth/codex-owner-mirror.ts +81 -0
- package/src/oauth/codex.ts +17 -2
- package/src/oauth/fallback-chain.ts +47 -17
- package/src/onboarding/first-run-doctor.ts +8 -1
- package/src/onboarding/first-run.ts +126 -29
- package/src/onboarding/key-setup.ts +103 -0
- package/src/onboarding/menu-answer.ts +13 -0
- package/src/onboarding/secret-prompt.ts +37 -0
- package/src/plugins/install/plugin-install.ts +59 -0
- package/src/pr-tool/census.ts +130 -0
- package/src/preview/terminal.ts +22 -7
- package/src/prompt-enhance/enhance.ts +10 -0
- package/src/pty-shell/pty-control-ipc.ts +4 -1
- package/src/pty-shell/pty-write-provenance.ts +21 -3
- package/src/pty-shell/registry.ts +9 -2
- package/src/registry/catalog-server.ts +232 -0
- package/src/registry/loader.ts +45 -1
- package/src/registry/types.ts +1 -2
- package/src/release-loop/proposal-auto-place.ts +83 -0
- package/src/research/axis-fanout.ts +79 -29
- package/src/research/lenses/second-order.ts +312 -0
- package/src/self-dev/ask-launch-flow.ts +72 -1
- package/src/self-dev/dev-cli.ts +7 -2
- package/src/self-dev/dev-pipeline.ts +5 -0
- package/src/self-dev/draft-residue.ts +64 -5
- package/src/self-dev/draft-sweep.ts +31 -10
- package/src/self-dev/draft-triage-rules.ts +60 -3
- package/src/self-dev/graph-front-nodes.ts +2 -1
- package/src/self-dev/graph-journey-route.ts +76 -21
- package/src/self-dev/launch-preflight.ts +58 -0
- package/src/self-dev/orchestrate.ts +1 -1
- package/src/self-dev/run-supervisor.ts +152 -2
- package/src/self-dev/shard-aggregate.ts +4 -0
- package/src/self-dev/shard-run.ts +36 -15
- package/src/self-implement/abandoned-classification.ts +12 -3
- package/src/self-implement/budget-gate.ts +7 -0
- package/src/self-implement/child-llm-preference.ts +10 -1
- package/src/self-implement/doctor-visit.ts +30 -8
- package/src/self-implement/elanous-tui-spawn.ts +3 -0
- package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
- package/src/self-implement/gate-artifacts.ts +2 -1
- package/src/self-implement/goal-author-cli.ts +4 -2
- package/src/self-implement/goal-author.ts +549 -10
- package/src/self-implement/graph-overlay-yaml.ts +181 -4
- package/src/self-implement/graph-overlay.ts +3 -1
- package/src/self-implement/graph-profile-yaml.ts +107 -0
- package/src/self-implement/graph-yaml.ts +94 -5
- package/src/self-implement/off-diff-evidence.ts +249 -5
- package/src/self-implement/orchestrator.ts +298 -26
- package/src/self-implement/run-chart.ts +6 -3
- package/src/self-implement/run-ledger.ts +51 -1
- package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
- package/src/self-implement/tdd-evidence-tags.ts +9 -0
- package/src/self-implement/test-scenario-request.ts +37 -6
- package/src/self-implement/train-gate-receipt.ts +166 -0
- package/src/self-implement/train-gate-remote.ts +62 -18
- package/src/session/chat.ts +6 -4
- package/src/session/session-fanout.ts +2 -0
- package/src/session/streaming/acp-stream-sink.ts +2 -1
- package/src/session/streaming/chunk-producer.ts +6 -0
- package/src/session/streaming/stream-compositor.ts +3 -2
- package/src/session-runtime/index.ts +74 -6
- package/src/session-runtime/retry-policy.ts +1 -1
- package/src/setup/llm-env-detect.ts +3 -0
- package/src/setup/service-key-catalog.ts +46 -0
- package/src/setup/service-keys.ts +241 -0
- 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 +182 -48
- package/src/skills/tools/agent.ts +23 -4
- package/src/skills/tools/omni-search.ts +127 -27
- package/src/task-agent/parent-host.ts +29 -1
- package/src/task-agent/recall-inject.ts +98 -0
- package/src/task-agent/repair-outcomes.ts +65 -0
- package/src/task-agent/task-hand.ts +46 -14
- package/src/task-orchestrator/dispatcher.ts +14 -1
- package/src/task-orchestrator/linear-capture-events.ts +55 -0
- package/src/task-orchestrator/store.ts +16 -5
- package/src/task-orchestrator/surfaces/pod-artifact-return.ts +23 -1
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +107 -1
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
- package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +21 -9
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +23 -11
- package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +467 -77
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +45 -3
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +210 -14
- package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
- package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
- package/src/task-orchestrator/types.ts +14 -0
- package/src/telegram.ts +14 -16
- package/src/terminal/coding-agent.ts +14 -5
- package/src/terminal/session-registry.ts +1 -1
- package/src/tool-hints/gate.ts +46 -14
- package/src/tool-hints/signals.ts +1 -1
- package/src/tool-hints/types.ts +2 -0
- package/src/tool-runtime/agent-runtime.ts +1 -0
- package/src/tool-runtime/browser-hand-runtime.ts +391 -0
- package/src/tool-runtime/browser-runtime.ts +33 -19
- package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
- package/src/tool-runtime/elanous-linear-secretary-runtime.ts +173 -0
- package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
- package/src/tool-runtime/index.ts +6 -0
- package/src/tool-runtime/types.ts +5 -0
- package/src/tui/entry.ts +51 -8
- package/src/tui/sidetab/attach.ts +252 -11
- package/src/tui/sidetab/herdr-portal.ts +225 -0
- package/src/tui/sidetab/list.ts +3 -2
- package/src/tui-client/next-dashboard-runtime.ts +52 -0
- package/src/user-config.ts +34 -9
- package/src/user-intent/types.ts +4 -3
- package/src/ux-sim/browser-hand.ts +165 -0
- package/src/ux-sim/draft-inventory-builder.ts +199 -0
- package/src/ux-sim/fake-browser-page.ts +81 -0
- package/src/ux-sim/fake-linear-device.ts +31 -0
- package/src/ux-sim/graph-engine-sim.ts +47 -0
- package/src/ux-sim/linear-secretary.ts +208 -0
- package/src/ux-sim/mock-scenario-catalog.json +81 -26
- package/src/ux-sim/mock-scenario-catalog.ts +175 -5
- package/src/ux-sim/onboarding-first-run-device.ts +31 -21
- package/src/ux-sim/release-sim-rig.ts +62 -18
- package/src/ux-sim/scenario.ts +70 -26
- package/src/ux-sim/service-key-setup.ts +113 -0
- package/src/ux-sim/term-slash-device.ts +74 -0
- package/src/ux-sim/turn-throw-sim.ts +31 -0
- package/src/version/packed-revision.json +1 -1
- package/src/web-search/exa.ts +77 -0
- package/src/web-search/index.ts +30 -9
- package/src/web-search/provider.ts +4 -1
- package/src/web-search/x-intent.ts +5 -0
- package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +0 -36
- package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1455-530ca16c7e71baff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +0 -32
- package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +0 -286
- package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +0 -34
- package/apps/pwa/out/_next/static/chunks/2456.b6de0e1c05f28843.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +0 -1
- package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2690.0521c738b7749931.js +0 -115
- package/apps/pwa/out/_next/static/chunks/2974.595d1e29d040cb6a.js +0 -64
- package/apps/pwa/out/_next/static/chunks/3207.a756c95e9ec8c3c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +0 -93
- package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +0 -41
- package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +0 -24
- package/apps/pwa/out/_next/static/chunks/3741.9cf76acaa2ee5298.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +0 -77
- package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4276.336d76d858fcdf1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +0 -148
- package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +0 -74
- package/apps/pwa/out/_next/static/chunks/50061469.0326382241ef3b2d.js +0 -122
- package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +0 -149
- package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +0 -27
- package/apps/pwa/out/_next/static/chunks/53c73f84.373b6160adfa89a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5431-72a1dbde59400691.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6131.348b7d6bdcd267ce.js +0 -226
- package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +0 -90
- package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +0 -104
- package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +0 -94
- package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7279-c199ea83f34338fa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +0 -1
- package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +0 -8
- package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +0 -79
- package/apps/pwa/out/_next/static/chunks/8546-6f03f8ea34dd61d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9249.976f1e69a9d80754.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9353-12bfff0c130104cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9633.ce5bddc56784da72.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9656-374232558fd528d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +0 -62
- package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-0e3d7b9421b79dac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-bf067887b3307423.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +0 -1
- package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
- /package/apps/pwa/out/_next/static/{X1ucLw10Cds_h614NoEnh → HMXsxdy5MIIcHPMHv1wD4}/_ssgManifest.js +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
3
|
import { execFile, spawnSync } from 'node:child_process';
|
|
3
4
|
import { existsSync, linkSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmdirSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
4
5
|
import { dirname, join, resolve, sep } from 'node:path';
|
|
@@ -30,8 +31,18 @@ import { requireInProcessHandler, type InProcessHandlerRegistry } from './in-pro
|
|
|
30
31
|
import { interpolate } from '../workflow-runtime/variables.js';
|
|
31
32
|
import type { BashNode, ClassifyNode, NodeExecContext, NodeOutput, WorkflowDeps } from '../workflow-runtime/types.js';
|
|
32
33
|
import { releaseResumeAcceptedRegressions, releaseResumeGateExecutor, releaseResumeGatePodPool, releaseResumeGateShardReroute, releaseResumeWaiver, type AcceptedRegression, type GateExecutorOverride, type GatePodPoolOverride, type GateShardRerouteOverride } from '../../scripts/release-loop/resume.js';
|
|
34
|
+
import { resolveChildAllowance } from './arg-allowance.js';
|
|
33
35
|
|
|
34
36
|
type BashRun = WorkflowDeps['runBash'];
|
|
37
|
+
|
|
38
|
+
export type GraphGrowthScope = 'harness' | 'task-agent';
|
|
39
|
+
export const GRAPH_GROWTH_SCOPE_ENV = 'ELANOUS_GRAPH_GROWTH_SCOPE';
|
|
40
|
+
const graphGrowthScope = new AsyncLocalStorage<GraphGrowthScope>();
|
|
41
|
+
|
|
42
|
+
/** Scope implicit graph growth to an approved in-process harness dispatch. */
|
|
43
|
+
export function withGraphGrowthScope<T>(scope: GraphGrowthScope, work: () => T): T {
|
|
44
|
+
return graphGrowthScope.run(scope, work);
|
|
45
|
+
}
|
|
35
46
|
const DEFAULT_BASH_TIMEOUT_MS = 5 * 60 * 1_000;
|
|
36
47
|
// Independent of graph YAML and recipe snapshots: an already-wrong saved binding must fail closed.
|
|
37
48
|
const RELEASE_NODE_COMMANDS: Readonly<Record<string, { recipe: string; command?: string }>> = {
|
|
@@ -40,12 +51,14 @@ const RELEASE_NODE_COMMANDS: Readonly<Record<string, { recipe: string; command?:
|
|
|
40
51
|
cutoff: { recipe: 'cmd:cutoff', command: 'bun scripts/release-loop/node-verdict.ts cutoff' },
|
|
41
52
|
'checklist-gate': { recipe: 'cmd:checklist-gate', command: 'bun scripts/release-loop/checklist-gate-node.ts' },
|
|
42
53
|
prefetch: { recipe: 'cmd:docs', command: 'bun scripts/release-loop/docs-node.ts --json' },
|
|
54
|
+
'pre-gate-join': { recipe: 'none' },
|
|
43
55
|
gate: { recipe: 'cmd:gate', command: 'bun scripts/release-loop/gate-node.ts --json' },
|
|
44
56
|
'traffic-gate-passed': { recipe: 'cmd:traffic-gate-passed', command: 'bun scripts/release-loop/traffic-node.ts traffic-gate-passed' },
|
|
45
57
|
'gate-triage': { recipe: 'cmd:gate-triage', command: 'bun scripts/release-loop/gate-triage-node.ts' },
|
|
46
58
|
'mac-smoke': { recipe: 'cmd:mac-smoke', command: 'bun scripts/release-loop/mac-smoke-node.ts' },
|
|
47
59
|
'export-check': { recipe: 'cmd:export-check', command: 'bun scripts/release-loop/export-check-node.ts' },
|
|
48
60
|
pwa: { recipe: 'cmd:pwa', command: 'bun scripts/release-loop/node-verdict.ts pwa' },
|
|
61
|
+
'pre-prepare-join': { recipe: 'none' },
|
|
49
62
|
prepare: { recipe: 'cmd:prepare', command: 'bun scripts/release-loop/prepare-node.ts' },
|
|
50
63
|
upgrade: { recipe: 'cmd:upgrade', command: 'bun scripts/release-loop/upgrade-node.ts' },
|
|
51
64
|
tui: { recipe: 'cmd:docs', command: 'bun scripts/release-loop/docs-node.ts --json' },
|
|
@@ -59,6 +72,7 @@ const RELEASE_NODE_COMMANDS: Readonly<Record<string, { recipe: string; command?:
|
|
|
59
72
|
publish: { recipe: 'cmd:publish-command', command: 'bun scripts/release-loop/publish-node.ts' },
|
|
60
73
|
'npm-publish': { recipe: 'cmd:npm-publish', command: 'bun scripts/release-loop/npm-publish-node.ts' },
|
|
61
74
|
'traffic-npm-published': { recipe: 'cmd:traffic-npm-published', command: 'bun scripts/release-loop/traffic-node.ts traffic-npm-published' },
|
|
75
|
+
'release-post-publish-join': { recipe: 'none' },
|
|
62
76
|
'docs-land': { recipe: 'cmd:docs-land', command: 'bun scripts/release-loop/docs-land-node.ts' },
|
|
63
77
|
verify: { recipe: 'cmd:verify', command: 'bun scripts/release-loop/verify-node.ts' },
|
|
64
78
|
'traffic-verify-complete': { recipe: 'cmd:traffic-verify-complete', command: 'bun scripts/release-loop/traffic-node.ts traffic-verify-complete' },
|
|
@@ -67,7 +81,6 @@ const RELEASE_NODE_COMMANDS: Readonly<Record<string, { recipe: string; command?:
|
|
|
67
81
|
'release-story': { recipe: 'cmd:release-story', command: 'bun scripts/release-story/draft.ts --graph' },
|
|
68
82
|
'ops-upgrade': { recipe: 'cmd:ops-upgrade', command: 'bun scripts/release-loop/ops-upgrade-node.ts' },
|
|
69
83
|
'version-dev-bump': { recipe: 'cmd:version-dev-bump', command: 'bun scripts/release-loop/version-node.ts dev-bump --json' },
|
|
70
|
-
'version-dev-bump-after-failure': { recipe: 'cmd:version-dev-bump', command: 'bun scripts/release-loop/version-node.ts dev-bump --json' },
|
|
71
84
|
done: { recipe: 'none' },
|
|
72
85
|
failed: { recipe: 'none' },
|
|
73
86
|
};
|
|
@@ -91,6 +104,7 @@ const LOOP_TERMINAL_STATUS: Readonly<Record<string, Readonly<Record<string, 'don
|
|
|
91
104
|
function topLevelTerminalStatus(graphId: string, terminal: string): 'done' | 'failed' | undefined {
|
|
92
105
|
const aliases = Object.hasOwn(LOOP_TERMINAL_STATUS, graphId) ? LOOP_TERMINAL_STATUS[graphId] : undefined;
|
|
93
106
|
if (aliases) return Object.hasOwn(aliases, terminal) ? aliases[terminal] : undefined;
|
|
107
|
+
if (terminal === 'needs-human' || terminal === 'rework') return 'failed';
|
|
94
108
|
return terminal === 'done' || terminal === 'failed' ? terminal : undefined;
|
|
95
109
|
}
|
|
96
110
|
|
|
@@ -148,6 +162,8 @@ export interface GraphRunState {
|
|
|
148
162
|
/** Original named terminal when status is its canonical done/failed mapping. */
|
|
149
163
|
reason?: string;
|
|
150
164
|
path: string[];
|
|
165
|
+
/** Dry-run path with each fan-out branch's planned writes expanded before its join. */
|
|
166
|
+
plannedPath?: string[];
|
|
151
167
|
/** startedAt/endedAt (ISO) and seconds are written when the node runs; ledgers before GRAPH-NODE-TIMES (0.2.19) have none. */
|
|
152
168
|
nodes: Array<{ nodeId: string; ok: boolean; exit: number | null; executed: boolean; output?: unknown; error?: string; reason?: string;
|
|
153
169
|
failure?: { errorCode: string; message: string; stage: string }; decidedBy?: string; decidedAt?: string;
|
|
@@ -166,9 +182,21 @@ export interface GraphRunState {
|
|
|
166
182
|
parentRunId?: string;
|
|
167
183
|
/** The entry chosen by a parent call; absent for existing single-entry runs. */
|
|
168
184
|
entryNodeId?: string;
|
|
169
|
-
unitCalls?: Array<{ node: string; unit: string; version: number; hash: string; childRunId: string; exit: string; steps: number; entry?: string }>;
|
|
185
|
+
unitCalls?: Array<{ node: string; unit: string; version: number; hash: string; childRunId: string; exit: string; steps: number; entry?: string; visit?: number; enteredAtMs?: number; exitedAtMs?: number; durationMs?: number }>;
|
|
186
|
+
/** Persisted fan-out child identities and terminal results; successful branches are immutable on resume. */
|
|
187
|
+
fanOuts?: Record<string, { from: string; join: string; branches: Record<string, {
|
|
188
|
+
runId: string; status: 'running' | 'done' | 'failed'; startedAt: string; endedAt?: string;
|
|
189
|
+
artifactSha256?: string; output?: unknown; error?: string; path?: string[];
|
|
190
|
+
}> }>;
|
|
191
|
+
/** Highest visit number handed to each unit in this run; not rewound by a restart, so
|
|
192
|
+
* a resumed run never reuses a (runId, unit, visit) span. */
|
|
193
|
+
unitVisitSeq?: Record<string, number>;
|
|
170
194
|
growth?: GraphGrowth[];
|
|
171
195
|
growthRejections?: Array<{ from: string; outcome: string; reason: string }>;
|
|
196
|
+
growthAttempts?: number;
|
|
197
|
+
/** `rejected` can represent a cap refusal before proposer invocation; `proposal` means the proposer was actually called.
|
|
198
|
+
* Legacy parked states without this field resume append-only, so their first recorded event may be applied/rejected. */
|
|
199
|
+
growthEvents?: Array<{ phase: 'proposal' | 'parked' | 'applied' | 'rejected' | 'undo-available'; from: string; outcome: string; at: string; nodeId?: string; kind?: string; reason?: string; undo?: GraphGrowth['undo'] }>;
|
|
172
200
|
growthPark?: { from: string; outcome: string; reason: string; decisionId: string; decisionRef: string; growth: GraphGrowth; command?: GrowthCommand; approval?: string };
|
|
173
201
|
resume?: { from: string; at: string; previousStatus: GraphRunState['status']; graph?: 'snapshot' | 'current' };
|
|
174
202
|
/** GATE-HOST-EXECUTOR — every explicit input change a resume made (what was set and what it replaced), oldest first. */
|
|
@@ -225,6 +253,8 @@ export async function runGraphClassifyNode(node: ClassifyNode, ctx: NodeExecCont
|
|
|
225
253
|
|
|
226
254
|
export interface GraphRunOptions {
|
|
227
255
|
input?: unknown;
|
|
256
|
+
/** Abort an active graph command and stop before dispatching the next node. */
|
|
257
|
+
signal?: AbortSignal;
|
|
228
258
|
/** Bytes already checked by the tick gate, used for a current-graph start or legacy resume. */
|
|
229
259
|
graphSource?: string;
|
|
230
260
|
dryRun?: boolean;
|
|
@@ -256,9 +286,15 @@ export interface GraphRunOptions {
|
|
|
256
286
|
pinChildUniverse?: boolean;
|
|
257
287
|
/** Release resume: command checkout and cut tip, checked before every Bash dispatch. */
|
|
258
288
|
releaseCommandSource?: { root: string; cutTip: string; git?: (args: string[]) => string };
|
|
289
|
+
/** Internal fan-out child: the parent release ledger's verified cut tip. */
|
|
290
|
+
branchCutTip?: string;
|
|
291
|
+
/** Internal fan-out child: the original release graph snapshot (its entry-only graph is synthetic). */
|
|
292
|
+
branchGraphSnapshot?: { graphSha: string; recipesSha: string };
|
|
293
|
+
/** Parent outputs visible to a fan-out child, before its branch-local outputs. */
|
|
294
|
+
branchParentOutputs?: Readonly<Record<string, unknown>>;
|
|
259
295
|
/** Optional per-run Bloom edge policy hook. */
|
|
260
296
|
researchEdgeDecisionRegistry?: ResearchEdgeDecisionRegistry;
|
|
261
|
-
deps?: { root?: string; runBash?: BashRun; callLLM?: (prompt: string) => Promise<string>; log?: (event: string, data: Record<string, unknown>) => void; beforeNode?: () => void; processStartMs?: (pid: number) => number | null; growthProposer?: GrowthProposer; growthLLM?: (prompt: string) => Promise<string>; classifyGrowthRecipe?: (node: GraphNodeSpec, resolved: { command?: string; approval?: string }) => GrowthRecipeEffect; growthDecision?: GrowthDecisionDeps & { list?: (filters: { status: 'all' }) => DecisionEntry[] }; inProcessHandlers?: InProcessHandlerRegistry };
|
|
297
|
+
deps?: { root?: string; runBash?: BashRun; callLLM?: (prompt: string) => Promise<string>; log?: (event: string, data: Record<string, unknown>) => void; beforeNode?: () => void; processStartMs?: (pid: number) => number | null; monotonicMs?: () => number; growthProposer?: GrowthProposer; growthLLM?: (prompt: string) => Promise<string>; growthScope?: GraphGrowthScope; classifyGrowthRecipe?: (node: GraphNodeSpec, resolved: { command?: string; approval?: string }) => GrowthRecipeEffect; growthDecision?: GrowthDecisionDeps & { list?: (filters: { status: 'all' }) => DecisionEntry[] }; inProcessHandlers?: InProcessHandlerRegistry };
|
|
262
298
|
}
|
|
263
299
|
|
|
264
300
|
/** The command directory must itself be the checkout at the cut tip. */
|
|
@@ -582,7 +618,8 @@ export function lastJsonObject(stdout: unknown): Record<string, unknown> | undef
|
|
|
582
618
|
}
|
|
583
619
|
|
|
584
620
|
/** Reconstruct the run-local edges from the ledger without rewriting the YAML snapshot. */
|
|
585
|
-
|
|
621
|
+
/** Apply validated, run-local edge growth to a graph snapshot. Exported for the graph simulator device. */
|
|
622
|
+
export function withGrowth(graph: GraphTemplateSpec, growth: readonly GraphGrowth[]): GraphTemplateSpec {
|
|
586
623
|
return growth.reduce<GraphTemplateSpec>((current, item) => {
|
|
587
624
|
const edge = current.edges.find((candidate) => candidate.from === item.undo.removeOutcome.from);
|
|
588
625
|
if (!edge || !edge.map || !item.node || item.undo.removeNode !== item.node.nodeId ||
|
|
@@ -598,7 +635,8 @@ function withGrowth(graph: GraphTemplateSpec, growth: readonly GraphGrowth[]): G
|
|
|
598
635
|
}
|
|
599
636
|
|
|
600
637
|
/** 이름 붙은 결과: 산출의 `outcome` 이 그 간선 map 의 키면 그 목적지 — 아니면 종전 ok/fail(exit) → fallback. */
|
|
601
|
-
|
|
638
|
+
/** Production edge selection shared by runGraph and the graph simulator device. */
|
|
639
|
+
export function nextNode(edges: readonly GraphEdgeSpec[], nodeId: string, exitOutcome: 'ok' | 'fail', namedOutcome?: string): string | undefined {
|
|
602
640
|
const edge = edges.find((e) => e.from === nodeId);
|
|
603
641
|
if (!edge) return undefined;
|
|
604
642
|
if (edge.to !== undefined) return edge.to;
|
|
@@ -607,6 +645,38 @@ function nextNode(edges: readonly GraphEdgeSpec[], nodeId: string, exitOutcome:
|
|
|
607
645
|
return edge.map?.[exitOutcome] ?? edge.fallback?.[0]?.node;
|
|
608
646
|
}
|
|
609
647
|
|
|
648
|
+
function releaseRouteReachesKnownIssues(edges: readonly GraphEdgeSpec[], startAt: string): boolean {
|
|
649
|
+
const forbidden = new Set(['publish', 'approve-publish']);
|
|
650
|
+
const seen = new Set<string>();
|
|
651
|
+
let cursor: string | undefined = startAt;
|
|
652
|
+
while (cursor && cursor !== 'known-issues' && !seen.has(cursor)) {
|
|
653
|
+
if (forbidden.has(cursor)) return false;
|
|
654
|
+
seen.add(cursor);
|
|
655
|
+
const edge = edges.find((candidate) => candidate.from === cursor);
|
|
656
|
+
if (!edge) return false;
|
|
657
|
+
if (edge.branches) {
|
|
658
|
+
if (Object.values(edge.branches).flat().some((nodeId) => forbidden.has(nodeId))) return false;
|
|
659
|
+
cursor = edge.join;
|
|
660
|
+
} else {
|
|
661
|
+
cursor = nextNode(edges, cursor, 'ok', 'ok');
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
return cursor === 'known-issues' && ![...seen].some((nodeId) => forbidden.has(nodeId));
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
function fanOutGraphSource(source: string, graph: GraphTemplateSpec, branchNode: string): string {
|
|
668
|
+
const document = parseYaml(source) as Record<string, unknown>;
|
|
669
|
+
const terminals = graph.terminalNodes;
|
|
670
|
+
const done = graph.unit ? terminals.find((terminal) => terminal === 'done')
|
|
671
|
+
: terminals.find((terminal) => topLevelTerminalStatus(graph.graphId, terminal) === 'done');
|
|
672
|
+
const failed = graph.unit ? terminals.find((terminal) => terminal === 'failed')
|
|
673
|
+
: terminals.find((terminal) => topLevelTerminalStatus(graph.graphId, terminal) === 'failed');
|
|
674
|
+
if (!done || !failed) throw new Error(`fan-out requires declared success and failure terminals: ${graph.graphId}`);
|
|
675
|
+
document.entry_node = branchNode;
|
|
676
|
+
document.edges = [{ from: branchNode, on: 'outcome', map: { ok: done, fail: failed, error: failed } }];
|
|
677
|
+
return stringifyYaml(document);
|
|
678
|
+
}
|
|
679
|
+
|
|
610
680
|
type ResolvedUnit = ResolvedGraphUnit;
|
|
611
681
|
export const resolveUnit = resolveGraphUnit;
|
|
612
682
|
|
|
@@ -648,6 +718,12 @@ function validateUnitCallsWithResolver(graph: GraphTemplateSpec, path: string, a
|
|
|
648
718
|
}
|
|
649
719
|
|
|
650
720
|
export async function runGraph(path: string, options: GraphRunOptions = {}): Promise<GraphRunState> {
|
|
721
|
+
const scopedContext = options.deps?.growthScope ?? graphGrowthScope.getStore();
|
|
722
|
+
const envGrowthScope = process.env[GRAPH_GROWTH_SCOPE_ENV];
|
|
723
|
+
// A separate Pod process cannot inherit AsyncLocalStorage. Only the explicit
|
|
724
|
+
// harness handoff is trusted from env; task-agent remains an in-process scope.
|
|
725
|
+
const growthScope = scopedContext ?? (envGrowthScope === 'harness' ? 'harness' : undefined);
|
|
726
|
+
const rejectedGrowthScopeEnv = scopedContext === undefined && envGrowthScope !== undefined && envGrowthScope !== 'harness';
|
|
651
727
|
if (options.resumeRunId && options.runId) throw new Error('runId and resumeRunId cannot be combined');
|
|
652
728
|
if (options.fromNodeId && !options.resumeRunId) throw new Error('--from requires --resume');
|
|
653
729
|
if (options.useCurrentGraph && !options.resumeRunId) throw new Error('--use-current-graph requires --resume');
|
|
@@ -711,7 +787,9 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
711
787
|
})),
|
|
712
788
|
edges: graph.edges.map((edge, index) => ({
|
|
713
789
|
...((document.edges as Record<string, unknown>[])[index] ?? {}), from: edge.from,
|
|
714
|
-
...(edge.to === undefined ? { on: edge.on,
|
|
790
|
+
...(edge.to === undefined ? { on: edge.on, ...(edge.map ? { map: edge.map } : {}),
|
|
791
|
+
...(edge.branches ? { branches: edge.branches, join: edge.join,
|
|
792
|
+
...(edge.warningBranches ? { warning_branches: edge.warningBranches } : {}) } : {}) } : { to: edge.to }),
|
|
715
793
|
...(edge.fallback ? { fallback: edge.fallback } : {}),
|
|
716
794
|
})),
|
|
717
795
|
}) : source;
|
|
@@ -810,17 +888,22 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
810
888
|
...(options.input === undefined ? {} : { input: options.input }),
|
|
811
889
|
...(options.unitContext?.entryNodeId === undefined ? {} : { entryNodeId: options.unitContext.entryNodeId }),
|
|
812
890
|
executed: 0, dryRun: options.dryRun === true, statePath };
|
|
891
|
+
const branchResume = options.fromNodeId ? Object.values(state.fanOuts ?? {}).flatMap((fanout) =>
|
|
892
|
+
fanout.branches[options.fromNodeId!] !== undefined ? [{ fanout, branchId: options.fromNodeId! }] : [])[0] : undefined;
|
|
893
|
+
if (branchResume) {
|
|
894
|
+
throw new Error(`--from cannot resume fan-out branch '${branchResume.branchId}'; resume from fan-out source '${branchResume.fanout.from}' instead`);
|
|
895
|
+
}
|
|
813
896
|
const verifyReleaseSource = (): string | undefined => {
|
|
814
897
|
const source = options.releaseCommandSource;
|
|
815
898
|
if (!source) return undefined;
|
|
816
|
-
const savedCutTip = lastJsonObject(state.nodes.find((node) => node.nodeId === 'version-release')?.output)?.commit;
|
|
817
|
-
if (graphId !== 'release-loop' || !options.resumeRunId || typeof savedCutTip !== 'string' || source.cutTip !== savedCutTip) {
|
|
899
|
+
const savedCutTip = lastJsonObject(state.nodes.find((node) => node.nodeId === 'version-release')?.output)?.commit ?? options.branchCutTip;
|
|
900
|
+
if (graphId !== 'release-loop' || (!options.resumeRunId && !options.branchCutTip) || typeof savedCutTip !== 'string' || source.cutTip !== savedCutTip) {
|
|
818
901
|
throw new Error('release command source differs from the saved cut tip');
|
|
819
902
|
}
|
|
820
903
|
const commandRoot = verifyReleaseCommandRoot(source.root, savedCutTip, source.git);
|
|
821
904
|
// The ledger snapshot must be the recipe that the cut checkout actually carries.
|
|
822
905
|
// HEAD alone does not bind a saved graph to that checkout.
|
|
823
|
-
verifyReleaseRecipeSnapshot(commandRoot, state.graphSnapshot);
|
|
906
|
+
verifyReleaseRecipeSnapshot(commandRoot, options.branchGraphSnapshot ?? state.graphSnapshot);
|
|
824
907
|
return commandRoot;
|
|
825
908
|
};
|
|
826
909
|
verifyReleaseSource();
|
|
@@ -853,8 +936,16 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
853
936
|
if (i > 0) {
|
|
854
937
|
const prior = state.nodes[i - 1]!;
|
|
855
938
|
const reported = lastJsonObject(prior.output)?.outcome;
|
|
856
|
-
const
|
|
857
|
-
|
|
939
|
+
const priorEdge = graph.edges.find((candidate) => candidate.from === prior.nodeId);
|
|
940
|
+
const exitOutcome = prior.ok ? 'ok' : 'fail';
|
|
941
|
+
const namedOutcome = typeof reported === 'string' ? reported : undefined;
|
|
942
|
+
const branchOutcome = priorEdge?.branches && namedOutcome && Object.hasOwn(priorEdge.branches, namedOutcome)
|
|
943
|
+
? namedOutcome : priorEdge?.branches && Object.hasOwn(priorEdge.branches, exitOutcome) ? exitOutcome : undefined;
|
|
944
|
+
const next = branchOutcome !== undefined && priorEdge?.join
|
|
945
|
+
? priorEdge.join : nextNode(graph.edges, prior.nodeId, exitOutcome, namedOutcome);
|
|
946
|
+
if (next !== recorded.nodeId) {
|
|
947
|
+
throw new Error(`saved run path does not follow graph edges: ${prior.nodeId} -> ${recorded.nodeId}, expected ${next ?? '<terminal>'}`);
|
|
948
|
+
}
|
|
858
949
|
} else if (recorded.nodeId !== unitEntryNode) throw new Error('saved run path does not start at entry node');
|
|
859
950
|
if (i < from && !recorded.ok) {
|
|
860
951
|
// A warning-only node explicitly sends every outcome to the same next
|
|
@@ -887,23 +978,15 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
887
978
|
const checked = releaseResumeWaiver(state, { from: options.fromNodeId, waive: options.releaseWaiver.nodeId, reason: options.releaseWaiver.reason, acceptedRegressions: options.releaseWaiver.requestedRegressions });
|
|
888
979
|
if (!checked || JSON.stringify(checked.acceptedRegressions) !== JSON.stringify(options.releaseWaiver.acceptedRegressions) ||
|
|
889
980
|
checked.unmeasured !== options.releaseWaiver.unmeasured) throw new Error('release waiver input changed before restart');
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
while (cursor && !route.has(cursor) && cursor !== 'known-issues') {
|
|
893
|
-
route.add(cursor);
|
|
894
|
-
cursor = nextNode(graph.edges, cursor, 'ok', 'ok');
|
|
981
|
+
if (!releaseRouteReachesKnownIssues(graph.edges, nextNode(graph.edges, options.fromNodeId, 'ok', 'ok') ?? '')) {
|
|
982
|
+
throw new Error('waived node must reach known-issues before publication');
|
|
895
983
|
}
|
|
896
|
-
if (cursor !== 'known-issues' || route.has('publish') || route.has('approve-publish')) throw new Error('waived node must reach known-issues before publication');
|
|
897
984
|
}
|
|
898
985
|
if (options.releaseAcceptedRegressions) {
|
|
899
986
|
if (graphId !== 'release-loop') throw new Error('accepted regressions require the release-loop graph');
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
while (cursor && !route.has(cursor) && cursor !== 'known-issues') {
|
|
903
|
-
route.add(cursor);
|
|
904
|
-
cursor = nextNode(graph.edges, cursor, 'ok', 'ok');
|
|
987
|
+
if (!releaseRouteReachesKnownIssues(graph.edges, options.fromNodeId)) {
|
|
988
|
+
throw new Error('accepted regressions must reach known-issues before publication');
|
|
905
989
|
}
|
|
906
|
-
if (cursor !== 'known-issues' || route.has('publish') || route.has('approve-publish')) throw new Error('accepted regressions must reach known-issues before publication');
|
|
907
990
|
const checked = releaseResumeAcceptedRegressions(state, options.releaseAcceptedRegressions.requested, options.fromNodeId);
|
|
908
991
|
if (JSON.stringify(checked) !== JSON.stringify(options.releaseAcceptedRegressions.acceptedRegressions)) throw new Error('accepted regressions changed before restart');
|
|
909
992
|
state.input = { ...(state.input as Record<string, unknown>), acceptedRegressions: checked };
|
|
@@ -994,7 +1077,16 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
994
1077
|
graph = withGrowth(graph, [parked.growth]);
|
|
995
1078
|
state.growth ??= [];
|
|
996
1079
|
state.growth.push(parked.growth);
|
|
1080
|
+
state.growthEvents ??= [];
|
|
1081
|
+
state.growthEvents.push({ phase: 'applied', from: parked.from, outcome: parked.outcome, at: new Date().toISOString(),
|
|
1082
|
+
nodeId: parked.growth.node.nodeId, kind: parked.growth.node.kind });
|
|
1083
|
+
state.growthEvents.push({ phase: 'undo-available', from: parked.from, outcome: parked.outcome, at: new Date().toISOString(),
|
|
1084
|
+
nodeId: parked.growth.node.nodeId, undo: parked.growth.undo });
|
|
997
1085
|
state.growthRejections!.pop();
|
|
1086
|
+
} else {
|
|
1087
|
+
state.growthEvents ??= [];
|
|
1088
|
+
state.growthEvents.push({ phase: 'rejected', from: parked.from, outcome: parked.outcome, at: new Date().toISOString(),
|
|
1089
|
+
nodeId: parked.growth.node.nodeId, kind: parked.growth.node.kind, reason: 'human rejected growth proposal' });
|
|
998
1090
|
}
|
|
999
1091
|
resumedGrowth = true;
|
|
1000
1092
|
delete state.pending;
|
|
@@ -1033,9 +1125,21 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1033
1125
|
const log = options.unitContext
|
|
1034
1126
|
? (event: string, data: Record<string, unknown>) => baseLog(event, { ...data, parentRunId: options.unitContext!.parentRunId })
|
|
1035
1127
|
: baseLog;
|
|
1128
|
+
if (rejectedGrowthScopeEnv && document.grow === 'on') {
|
|
1129
|
+
log('growth-scope-rejected', { graphId, runId, source: 'env', reason: 'not-allowlisted' });
|
|
1130
|
+
}
|
|
1036
1131
|
const visits = new Map<string, number>();
|
|
1037
1132
|
for (const nodeId of state.path) visits.set(nodeId, (visits.get(nodeId) ?? 0) + 1);
|
|
1133
|
+
// GRAPH-UNIT-SPAN-DURATION: visit index per unit within this run, so enter/exit of
|
|
1134
|
+
// the same (runId, unit, visit) can be paired. The clock source is monotonic and
|
|
1135
|
+
// injectable (fake clock in tests); it never goes backwards in production. The
|
|
1136
|
+
// sequence is carried on the run state so a restart continues it.
|
|
1137
|
+
const unitVisits = new Map<string, number>(Object.entries(state.unitVisitSeq ?? {}));
|
|
1138
|
+
const monotonicMs = options.deps?.monotonicMs ?? (() => performance.now());
|
|
1038
1139
|
let current: string | undefined = options.fromNodeId ?? state.pending?.nodeId ?? state.path.at(-1) ?? unitEntryNode;
|
|
1140
|
+
let growthScopeSkipLogged = false;
|
|
1141
|
+
let growthCapReachedLogged = state.growthRejections?.some((item) =>
|
|
1142
|
+
item.reason === 'growth proposal limit 8 reached' || item.reason === 'growth limit 3 reached') ?? false;
|
|
1039
1143
|
if (!options.resumeRunId) {
|
|
1040
1144
|
mkdirSync(dirname(statePath), { recursive: true });
|
|
1041
1145
|
if (readdirSync(dirname(statePath)).some((file) => file.startsWith(`${runId}.json.`) && file.endsWith('.decision.json'))) {
|
|
@@ -1051,6 +1155,12 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1051
1155
|
writeFileSync(join(`${statePath}.graph`, 'recipes.yaml'), recipeSource, { flag: 'wx' });
|
|
1052
1156
|
}
|
|
1053
1157
|
while (current !== undefined) {
|
|
1158
|
+
if (options.signal?.aborted) {
|
|
1159
|
+
state.status = 'failed';
|
|
1160
|
+
state.reason = 'cancelled';
|
|
1161
|
+
persist();
|
|
1162
|
+
break;
|
|
1163
|
+
}
|
|
1054
1164
|
options.deps?.beforeNode?.();
|
|
1055
1165
|
const node = graph.nodes.find((n) => n.nodeId === current);
|
|
1056
1166
|
if (!node) throw new Error(`undeclared node: ${current}`);
|
|
@@ -1059,8 +1169,12 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1059
1169
|
const resumingCompleted = options.resumeRunId !== undefined && !options.fromNodeId && completed?.nodeId === current &&
|
|
1060
1170
|
state.path.at(-1) === current && !resumingPending;
|
|
1061
1171
|
const usedSteps = state.path.length + (state.unitCalls ?? []).reduce((sum, call) => sum + call.steps, 0);
|
|
1172
|
+
const effectiveRemaining = Math.min(
|
|
1173
|
+
graph.allowance ? graph.allowance.innerSteps - usedSteps : Infinity,
|
|
1174
|
+
options.unitContext ? options.unitContext.remainingSteps - usedSteps : Infinity,
|
|
1175
|
+
);
|
|
1062
1176
|
if (!resumingPending && !resumingCompleted && ((visits.get(current) ?? 0) >= node.maxVisits ||
|
|
1063
|
-
(
|
|
1177
|
+
(effectiveRemaining <= 0 && !graph.terminalNodes.includes(current)))) {
|
|
1064
1178
|
state.status = 'budget-exceeded';
|
|
1065
1179
|
log('budget-exceeded', { graphId, runId, nodeId: current });
|
|
1066
1180
|
persist();
|
|
@@ -1106,17 +1220,25 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1106
1220
|
publishInsideEvent({ kind: 'node', graphId, runId, nodeId: current, phase: 'start' });
|
|
1107
1221
|
log('node-start', { graphId, runId, nodeId: current, visit: visits.get(current), dryRun: state.dryRun });
|
|
1108
1222
|
persist();
|
|
1109
|
-
|
|
1223
|
+
const joinedFanout = Object.values(state.fanOuts ?? {}).find((fanout) => fanout.join === current &&
|
|
1224
|
+
Object.values(fanout.branches).every((branch) => branch.status === 'done' || branch.status === 'failed'));
|
|
1225
|
+
const warningBranches = joinedFanout
|
|
1226
|
+
? graph.edges.find((edge) => edge.from === joinedFanout.from)?.warningBranches ?? [] : [];
|
|
1227
|
+
let ok = approval && !state.dryRun ? state.pending?.decision === 'approved' : joinedFanout
|
|
1228
|
+
? Object.entries(joinedFanout.branches).every(([branchId, branch]) => branch.status === 'done' || warningBranches.includes(branchId)) : true;
|
|
1110
1229
|
let exit: number | null = null;
|
|
1111
1230
|
let error: string | undefined;
|
|
1112
1231
|
let commandFailureReason: string | undefined;
|
|
1113
1232
|
let output: unknown;
|
|
1233
|
+
if (joinedFanout) output = JSON.stringify({ outcome: ok ? 'ok' : 'fail', branches: joinedFanout.branches });
|
|
1114
1234
|
const waiving = options.releaseWaiver?.nodeId === current && waivedRecord !== undefined;
|
|
1115
1235
|
const inProcessHandler = requireInProcessHandler(node.recipe, current, options.deps?.inProcessHandlers);
|
|
1116
1236
|
let handlerExecuted = false;
|
|
1117
1237
|
if (inProcessHandler && !waiving && !state.dryRun && !resumingCompleted) {
|
|
1118
|
-
const outputs: Record<string, unknown> = Object.create(null);
|
|
1238
|
+
const outputs: Record<string, unknown> = Object.assign(Object.create(null), options.branchParentOutputs ?? {});
|
|
1119
1239
|
for (const previous of state.nodes) outputs[previous.nodeId] = lastJsonObject(previous.output) ?? previous.output ?? null;
|
|
1240
|
+
for (const fanout of Object.values(state.fanOuts ?? {})) for (const [branchId, branch] of Object.entries(fanout.branches))
|
|
1241
|
+
if (branch.output !== undefined) outputs[branchId] = lastJsonObject(branch.output) ?? branch.output;
|
|
1120
1242
|
handlerExecuted = true;
|
|
1121
1243
|
debug.log('graph.run', 'handler-dispatch', { graphId, runId, nodeId: current, recipe: node.recipe });
|
|
1122
1244
|
try {
|
|
@@ -1138,9 +1260,11 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1138
1260
|
state.executed++;
|
|
1139
1261
|
}
|
|
1140
1262
|
if (command && !waiving && (!approval || state.dryRun || ok) && (!state.dryRun || command.dry_run_command) && !resumingCompleted) {
|
|
1141
|
-
const outputs: Record<string, unknown> = Object.create(null);
|
|
1263
|
+
const outputs: Record<string, unknown> = Object.assign(Object.create(null), options.branchParentOutputs ?? {});
|
|
1142
1264
|
// 구조 산출(마지막 JSON 줄)이 있으면 그것을, 없으면 원문을 준다 — 다음 노드가 판단을 «값»으로 받는다.
|
|
1143
1265
|
for (const previous of state.nodes) outputs[previous.nodeId] = lastJsonObject(previous.output) ?? previous.output ?? null;
|
|
1266
|
+
for (const fanout of Object.values(state.fanOuts ?? {})) for (const [branchId, branch] of Object.entries(fanout.branches))
|
|
1267
|
+
if (branch.output !== undefined) outputs[branchId] = lastJsonObject(branch.output) ?? branch.output;
|
|
1144
1268
|
const contextPath = join(`${statePath}.contexts`, `${state.path.length}.json`);
|
|
1145
1269
|
mkdirSync(dirname(contextPath), { recursive: true });
|
|
1146
1270
|
writeFileSync(contextPath, JSON.stringify({ graphId, runId, startedAt: state.startedAt, nodeId: current, input: state.input ?? null, outputs }, null, 2) + '\n');
|
|
@@ -1196,7 +1320,8 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1196
1320
|
env.ELANOUS_GRAPH_CONTEXT = contextPath;
|
|
1197
1321
|
env.ELANOUS_GRAPH_DRY_RUN = state.dryRun ? '1' : '0';
|
|
1198
1322
|
env.ELANOUS_GRAPH_DIR = dirname(resolve(path));
|
|
1199
|
-
const ctx = { arguments: '', artifactsDir: dirname(statePath), outputs: {}, resolvedProvider: undefined, resolvedModel: undefined, toolPolicy: {}, env
|
|
1323
|
+
const ctx = { arguments: '', artifactsDir: dirname(statePath), outputs: {}, resolvedProvider: undefined, resolvedModel: undefined, toolPolicy: {}, env,
|
|
1324
|
+
...(options.signal ? { signal: options.signal } : {}) } as NodeExecContext;
|
|
1200
1325
|
const result = await executeBashNode({ id: current, type: 'bash', bash: state.dryRun ? command.dry_run_command! : command.command,
|
|
1201
1326
|
idle_timeout: command.timeout_ms ?? DEFAULT_BASH_TIMEOUT_MS } as BashNode, ctx, { runBash } as WorkflowDeps);
|
|
1202
1327
|
output = result.output;
|
|
@@ -1231,25 +1356,53 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1231
1356
|
if (value !== undefined) inputs[key] = value;
|
|
1232
1357
|
}
|
|
1233
1358
|
const alreadySpent = state.path.length + (state.unitCalls ?? []).reduce((sum, call) => sum + call.steps, 0);
|
|
1234
|
-
const remaining =
|
|
1359
|
+
const remaining = Math.min(
|
|
1360
|
+
graph.allowance ? graph.allowance.innerSteps - alreadySpent : Infinity,
|
|
1361
|
+
options.unitContext ? options.unitContext.remainingSteps - alreadySpent : Infinity,
|
|
1362
|
+
);
|
|
1363
|
+
const requested = Math.min(node.budget!.innerSteps, node.allowance?.innerSteps ?? node.budget!.innerSteps);
|
|
1364
|
+
const allowance = resolveChildAllowance(requested, Math.max(0, remaining));
|
|
1235
1365
|
const childRunId = randomUUID();
|
|
1236
1366
|
const selectedEntry = node.callEntry ?? unit.template.entryNode;
|
|
1237
1367
|
const recordEntry = node.callEntry !== undefined || unit.template.unit?.entries !== undefined;
|
|
1238
1368
|
const info = { graphId, runId, nodeId: current, unit: unit.template.graphId, childRunId, parentRunId: runId,
|
|
1239
1369
|
...(recordEntry ? { entry: selectedEntry } : {}) };
|
|
1240
1370
|
let entered = false;
|
|
1241
|
-
|
|
1371
|
+
let span: { visit: number; enteredAtMs: number } | undefined;
|
|
1372
|
+
if (allowance.kind === 'needs-human') {
|
|
1373
|
+
const exitName = unit.template.unit!.exits.includes('needs-human') ? 'needs-human'
|
|
1374
|
+
: unit.template.unit!.exits.includes('rework') ? 'rework' : undefined;
|
|
1375
|
+
if (!exitName) throw new Error(`unit has no needs-human or rework exit for zero allowance: ${current}`);
|
|
1376
|
+
output = JSON.stringify({ outcome: exitName });
|
|
1377
|
+
ok = false;
|
|
1378
|
+
error = `unit allowance exhausted before execution: ${current}`;
|
|
1379
|
+
debug.log('graph.unit', 'allowance-exhausted', { ...info, requested: allowance.requested, remaining: 0, exit: exitName });
|
|
1380
|
+
log('graph.unit', { ...info, phase: 'allowance-exhausted', requested: allowance.requested, remaining: 0, exit: exitName });
|
|
1381
|
+
} else try {
|
|
1242
1382
|
for (const key of contract.inputs) if (!Object.hasOwn(inputs, key)) throw new Error(`unit input missing: ${current}.${key}`);
|
|
1243
1383
|
if (createHash('sha256').update(readFileSync(unit.path, 'utf8')).digest('hex') !== unit.hash)
|
|
1244
1384
|
throw new Error(`unit source changed before call: ${current}`);
|
|
1245
|
-
|
|
1246
|
-
|
|
1385
|
+
const visitIndex = (unitVisits.get(unit.template.graphId) ?? 0) + 1;
|
|
1386
|
+
unitVisits.set(unit.template.graphId, visitIndex);
|
|
1387
|
+
(state.unitVisitSeq ??= {})[unit.template.graphId] = visitIndex;
|
|
1388
|
+
const enteredAtMs = monotonicMs();
|
|
1389
|
+
span = { visit: visitIndex, enteredAtMs };
|
|
1390
|
+
debug.log('graph.unit', 'enter', { ...info, ...span });
|
|
1391
|
+
log('graph.unit', { ...info, phase: 'enter', ...span });
|
|
1392
|
+
if (allowance.clamped) {
|
|
1393
|
+
debug.log('graph.unit', 'allowance-clamped', { ...info, requested: allowance.requested, granted: allowance.granted, remaining });
|
|
1394
|
+
log('graph.unit', { ...info, phase: 'allowance-clamped', requested: allowance.requested, granted: allowance.granted, remaining });
|
|
1395
|
+
}
|
|
1247
1396
|
entered = true;
|
|
1248
1397
|
const child = await runGraph(unit.path, { runId: childRunId, input: inputs, dryRun: false,
|
|
1398
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
1249
1399
|
pinChildUniverse: options.pinChildUniverse,
|
|
1250
1400
|
unitContext: { parentRunId: runId, ancestors: [...(options.unitContext?.ancestors ?? []), graphId],
|
|
1251
|
-
remainingSteps:
|
|
1401
|
+
remainingSteps: allowance.granted,
|
|
1252
1402
|
...(recordEntry ? { entryNodeId: selectedEntry } : {}) }, deps: options.deps });
|
|
1403
|
+
const exitedAtMs = monotonicMs();
|
|
1404
|
+
// Same (runId, unit, visit): never let a clock that went backwards emit a negative span.
|
|
1405
|
+
const durationMs = Math.max(0, exitedAtMs - enteredAtMs);
|
|
1253
1406
|
const steps = child.path.length + (child.unitCalls ?? []).reduce((sum, call) => sum + call.steps, 0);
|
|
1254
1407
|
const childExit = child.status === 'done' || child.status === 'failed' ? child.path.at(-1) : undefined;
|
|
1255
1408
|
// The last successful record carrying every contracted output is the source;
|
|
@@ -1264,9 +1417,10 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1264
1417
|
state.unitCalls ??= [];
|
|
1265
1418
|
state.unitCalls.push({ node: current, unit: unit.template.graphId, version: unit.template.version,
|
|
1266
1419
|
hash: unit.hash, childRunId, exit: childExit ?? child.status, steps,
|
|
1420
|
+
visit: visitIndex, enteredAtMs, exitedAtMs, durationMs,
|
|
1267
1421
|
...(recordEntry ? { entry: selectedEntry } : {}) });
|
|
1268
1422
|
if (child.status === 'awaiting-approval') throw new Error(`unit cannot pause for approval: ${current}`);
|
|
1269
|
-
if (child.status === 'budget-exceeded' || steps >
|
|
1423
|
+
if (child.status === 'budget-exceeded' || steps > allowance.granted || steps > remaining) {
|
|
1270
1424
|
debug.log('graph.unit', 'budget-exhausted', { ...info, steps, innerSteps: node.budget!.innerSteps });
|
|
1271
1425
|
log('graph.unit', { ...info, phase: 'budget-exhausted', steps });
|
|
1272
1426
|
throw new Error(`unit inner_steps exceeded: ${current}`);
|
|
@@ -1280,14 +1434,21 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1280
1434
|
}
|
|
1281
1435
|
output = JSON.stringify(result);
|
|
1282
1436
|
ok = child.status === 'done';
|
|
1283
|
-
debug.log('graph.unit', 'exit', { ...info, exit: childExit, steps });
|
|
1284
|
-
log('graph.unit', { ...info, phase: 'exit', exit: childExit, steps });
|
|
1437
|
+
debug.log('graph.unit', 'exit', { ...info, exit: childExit, steps, visit: visitIndex, enteredAtMs, exitedAtMs, durationMs });
|
|
1438
|
+
log('graph.unit', { ...info, phase: 'exit', exit: childExit, steps, visit: visitIndex, enteredAtMs, exitedAtMs, durationMs });
|
|
1285
1439
|
} catch (cause) {
|
|
1286
1440
|
ok = false;
|
|
1287
1441
|
error = redactCredentials(cause instanceof Error ? cause.message : String(cause));
|
|
1288
|
-
if (entered) {
|
|
1289
|
-
|
|
1290
|
-
|
|
1442
|
+
if (entered && span) {
|
|
1443
|
+
const exitedAtMs = monotonicMs();
|
|
1444
|
+
const durationMs = Math.max(0, exitedAtMs - span.enteredAtMs);
|
|
1445
|
+
const call = state.unitCalls?.at(-1);
|
|
1446
|
+
if (call && call.childRunId === childRunId) {
|
|
1447
|
+
call.exitedAtMs = exitedAtMs;
|
|
1448
|
+
call.durationMs = durationMs;
|
|
1449
|
+
}
|
|
1450
|
+
debug.log('graph.unit', 'exit', { ...info, error, ...span, exitedAtMs, durationMs });
|
|
1451
|
+
log('graph.unit', { ...info, phase: 'exit', error, ...span, exitedAtMs, durationMs });
|
|
1291
1452
|
}
|
|
1292
1453
|
}
|
|
1293
1454
|
// A rejected invocation has no child ledger and did not execute a unit.
|
|
@@ -1389,7 +1550,7 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1389
1550
|
delete state.pending;
|
|
1390
1551
|
delete state.approvalSourceHash;
|
|
1391
1552
|
}
|
|
1392
|
-
const reported: unknown = waiving || harnessLoopRoute || units.has(current) || handlerExecuted || (resumingCompleted && inProcessHandler) || (prompt && !state.dryRun) || (command && (!state.dryRun || command.dry_run_command)) ? lastJsonObject(resumingCompleted ? completed?.output : output)?.outcome : undefined;
|
|
1553
|
+
const reported: unknown = joinedFanout || waiving || harnessLoopRoute || units.has(current) || handlerExecuted || (resumingCompleted && inProcessHandler) || (prompt && !state.dryRun) || (command && (!state.dryRun || command.dry_run_command)) ? lastJsonObject(resumingCompleted ? completed?.output : output)?.outcome : undefined;
|
|
1393
1554
|
const namedOutcome: string | undefined = typeof reported === 'string' ? reported : undefined;
|
|
1394
1555
|
if (!options.quiet) console.error(`[graph] ${current} ${ok ? 'ok' : 'fail'} (${seconds.toFixed(2)}s)`);
|
|
1395
1556
|
const nodeFailure = state.nodes.at(-1)?.nodeId === current ? state.nodes.at(-1)?.failure : undefined;
|
|
@@ -1406,6 +1567,12 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1406
1567
|
observeModelInputTokens({ scope: 'harness-node', nodeKind: node.kind, runId, nodeId: current });
|
|
1407
1568
|
}
|
|
1408
1569
|
persist();
|
|
1570
|
+
if (options.signal?.aborted) {
|
|
1571
|
+
state.status = 'failed';
|
|
1572
|
+
state.reason = 'cancelled';
|
|
1573
|
+
persist();
|
|
1574
|
+
break;
|
|
1575
|
+
}
|
|
1409
1576
|
if (graph.terminalNodes.includes(current)) {
|
|
1410
1577
|
state.status = !ok ? 'failed' : graph.unit ? (current === 'failed' ? 'failed' : 'done')
|
|
1411
1578
|
: topLevelTerminalStatus(graph.graphId, current)!;
|
|
@@ -1419,30 +1586,62 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1419
1586
|
}
|
|
1420
1587
|
const fromNodeId = current;
|
|
1421
1588
|
const edge = graph.edges.find((candidate) => candidate.from === current);
|
|
1422
|
-
if (!resumedGrowth && document.grow === 'on' && !state.dryRun && namedOutcome !== undefined &&
|
|
1589
|
+
if (!growthScope && !growthScopeSkipLogged && !resumedGrowth && document.grow === 'on' && !state.dryRun && namedOutcome !== undefined &&
|
|
1590
|
+
(state.growthAttempts ?? 0) < 8 && (state.growth?.length ?? 0) < 3 &&
|
|
1423
1591
|
edge?.on === 'outcome' && edge.map && !Object.hasOwn(edge.map, namedOutcome) &&
|
|
1424
1592
|
!state.growth?.some((item) => item.undo.removeOutcome.from === current && item.undo.removeOutcome.outcome === namedOutcome) &&
|
|
1425
1593
|
!state.growthRejections?.some((item) => item.from === current && item.outcome === namedOutcome)) {
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1594
|
+
growthScopeSkipLogged = true;
|
|
1595
|
+
log('growth-skipped-no-scope', { graphId, runId, from: current, outcome: namedOutcome });
|
|
1596
|
+
}
|
|
1597
|
+
if (growthScope && !growthCapReachedLogged && !resumedGrowth && document.grow === 'on' && !state.dryRun && namedOutcome !== undefined &&
|
|
1598
|
+
edge?.on === 'outcome' && edge.map && !Object.hasOwn(edge.map, namedOutcome) &&
|
|
1599
|
+
!state.growth?.some((item) => item.undo.removeOutcome.from === current && item.undo.removeOutcome.outcome === namedOutcome) &&
|
|
1600
|
+
!state.growthRejections?.some((item) => item.from === current && item.outcome === namedOutcome)) {
|
|
1601
|
+
state.growthEvents ??= [];
|
|
1602
|
+
let result: Awaited<ReturnType<typeof proposeGrowth>>;
|
|
1603
|
+
if ((state.growthAttempts ?? 0) >= 8) result = { ok: false, reason: 'growth proposal limit 8 reached' };
|
|
1604
|
+
else if ((state.growth?.length ?? 0) >= 3) result = { ok: false, reason: 'growth limit 3 reached' };
|
|
1605
|
+
else {
|
|
1606
|
+
const at = new Date().toISOString();
|
|
1607
|
+
const input = { graph, nodeId: current, outcome: namedOutcome, runId, output: state.nodes.at(-1)?.output };
|
|
1608
|
+
state.growthEvents.push({ phase: 'proposal', from: current, outcome: namedOutcome, at });
|
|
1609
|
+
state.growthAttempts = (state.growthAttempts ?? 0) + 1;
|
|
1610
|
+
persist();
|
|
1611
|
+
const allowedKinds = new Set(['agent', 'observe', 'judge']);
|
|
1612
|
+
const proposer = options.deps?.growthProposer ?? createLLMGrowthProposer(options.deps?.growthLLM);
|
|
1613
|
+
// Enforce the vocabulary at the runner boundary even when a caller injects a non-LLM proposer.
|
|
1614
|
+
const constrainedProposer: GrowthProposer = async (proposalInput) => {
|
|
1615
|
+
const proposal = await proposer(proposalInput);
|
|
1616
|
+
return proposal && allowedKinds.has(proposal.node.kind) ? proposal : undefined;
|
|
1617
|
+
};
|
|
1618
|
+
result = await proposeGrowth(input, constrainedProposer, (candidate) => {
|
|
1429
1619
|
const resolved = resolveNodeRecipe(candidate, recipes, catalogRoles);
|
|
1430
1620
|
if (!resolved.command && !resolved.approval && candidate.recipe !== 'none') return 'unknown';
|
|
1431
1621
|
return { effect: resolved.approval ? 'unknown' : options.deps?.classifyGrowthRecipe?.(candidate, { command: resolved.command?.command }) ?? 'unknown',
|
|
1432
1622
|
command: resolved.command, approval: resolved.approval?.approval };
|
|
1433
1623
|
}, { ...options.deps?.growthDecision, root }, options.researchEdgeDecisionRegistry);
|
|
1624
|
+
}
|
|
1434
1625
|
if (result.ok) {
|
|
1435
1626
|
graph = result.graph;
|
|
1436
1627
|
state.growth ??= [];
|
|
1437
1628
|
state.growth.push(result.growth);
|
|
1629
|
+
state.growthEvents.push({ phase: 'applied', from: current, outcome: namedOutcome, at: new Date().toISOString(),
|
|
1630
|
+
nodeId: result.growth.node.nodeId, kind: result.growth.node.kind });
|
|
1631
|
+
state.growthEvents.push({ phase: 'undo-available', from: current, outcome: namedOutcome, at: new Date().toISOString(),
|
|
1632
|
+
nodeId: result.growth.node.nodeId, undo: result.growth.undo });
|
|
1438
1633
|
persist();
|
|
1439
1634
|
log('edge-added', { graphId, runId, from: current, outcome: namedOutcome, to: result.growth.node.nodeId });
|
|
1440
1635
|
debug.log('graph.run', 'edge-added', { graphId, runId, from: current, outcome: namedOutcome, to: result.growth.node.nodeId });
|
|
1441
1636
|
publishInsideEvent({ kind: 'edge-added', graphId, runId, from: current, outcome: namedOutcome, to: result.growth.node.nodeId });
|
|
1442
1637
|
} else {
|
|
1443
1638
|
state.growthRejections ??= [];
|
|
1639
|
+
const capped = result.reason === 'growth proposal limit 8 reached' || result.reason === 'growth limit 3 reached';
|
|
1640
|
+
if (capped) growthCapReachedLogged = true;
|
|
1444
1641
|
state.growthRejections.push({ from: current, outcome: namedOutcome, reason: result.reason });
|
|
1445
1642
|
if (result.park && result.growth && result.decisionId && result.decisionRef) {
|
|
1643
|
+
state.growthEvents.push({ phase: 'parked', from: current, outcome: namedOutcome, at: new Date().toISOString(), reason: result.reason,
|
|
1644
|
+
nodeId: result.growth.node.nodeId, kind: result.growth.node.kind, undo: result.growth.undo });
|
|
1446
1645
|
state.status = 'awaiting-approval';
|
|
1447
1646
|
state.pending = { nodeId: current, message: result.reason, since: new Date().toISOString() };
|
|
1448
1647
|
state.growthPark = { from: current, outcome: namedOutcome, reason: result.reason,
|
|
@@ -1451,12 +1650,66 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1451
1650
|
persist();
|
|
1452
1651
|
break;
|
|
1453
1652
|
}
|
|
1653
|
+
state.growthEvents.push({ phase: 'rejected', from: current, outcome: namedOutcome, at: new Date().toISOString(), reason: result.reason,
|
|
1654
|
+
...(result.growth ? { nodeId: result.growth.node.nodeId, kind: result.growth.node.kind, undo: result.growth.undo } : {}) });
|
|
1454
1655
|
}
|
|
1455
1656
|
persist();
|
|
1456
1657
|
}
|
|
1457
1658
|
// A planned harness loop follows its route directly: `changed-files` edges have no runner condition.
|
|
1458
|
-
|
|
1459
|
-
|
|
1659
|
+
const edgeOutcome: 'ok' | 'fail' = state.dryRun && !command?.dry_run_command ? 'ok' : ok ? 'ok' : 'fail';
|
|
1660
|
+
const outgoing = graph.edges.find((candidate) => candidate.from === current);
|
|
1661
|
+
const branchOutcome: string | undefined = namedOutcome !== undefined && outgoing?.branches && Object.hasOwn(outgoing.branches, namedOutcome)
|
|
1662
|
+
? namedOutcome : outgoing?.branches && Object.hasOwn(outgoing.branches, edgeOutcome) ? edgeOutcome : undefined;
|
|
1663
|
+
if (!plannedStep && outgoing?.branches && branchOutcome !== undefined && outgoing.join) {
|
|
1664
|
+
const destinations = outgoing.branches[branchOutcome]!;
|
|
1665
|
+
const fanOutKey: string = `${current}:${branchOutcome}`;
|
|
1666
|
+
const fanout: NonNullable<GraphRunState['fanOuts']>[string] = state.fanOuts?.[fanOutKey] ?? { from: current, join: outgoing.join, branches: {} };
|
|
1667
|
+
if (fanout.join !== outgoing.join) throw new Error(`fan-out state conflicts with graph: ${fanOutKey}`);
|
|
1668
|
+
const runningBranch = destinations.find((id) => fanout.branches[id]?.status === 'running');
|
|
1669
|
+
if (runningBranch) throw new Error(`fan-out branch ${runningBranch} is still marked running; crashed-child recovery is not supported`);
|
|
1670
|
+
state.fanOuts ??= {};
|
|
1671
|
+
state.fanOuts[fanOutKey] = fanout;
|
|
1672
|
+
const selected = destinations.filter((branchId) => fanout.branches[branchId]?.status !== 'done');
|
|
1673
|
+
const launches = selected.map((branchId) => {
|
|
1674
|
+
const runId = randomUUID();
|
|
1675
|
+
fanout.branches[branchId] = { runId, status: 'running', startedAt: new Date().toISOString() };
|
|
1676
|
+
return { branchId, runId };
|
|
1677
|
+
});
|
|
1678
|
+
persist();
|
|
1679
|
+
await Promise.all(launches.map(async ({ branchId, runId }) => {
|
|
1680
|
+
const branch = fanout.branches[branchId]!;
|
|
1681
|
+
try {
|
|
1682
|
+
const child = await runGraph(path, { runId, graphSource: fanOutGraphSource(variantSource, graph, branchId), input: state.input,
|
|
1683
|
+
dryRun: state.dryRun, quiet: true, signal: options.signal, pinChildUniverse: options.pinChildUniverse,
|
|
1684
|
+
releaseCommandSource: options.releaseCommandSource,
|
|
1685
|
+
branchCutTip: lastJsonObject(state.nodes.find((record) => record.nodeId === 'version-release')?.output)?.commit as string | undefined,
|
|
1686
|
+
branchGraphSnapshot: state.graphSnapshot,
|
|
1687
|
+
branchParentOutputs: Object.fromEntries(state.nodes.map((record) => [record.nodeId, lastJsonObject(record.output) ?? record.output ?? null])),
|
|
1688
|
+
researchEdgeDecisionRegistry: options.researchEdgeDecisionRegistry,
|
|
1689
|
+
deps: options.deps });
|
|
1690
|
+
const record = child.nodes.find((item) => item.nodeId === branchId);
|
|
1691
|
+
if (state.dryRun) branch.path = child.path;
|
|
1692
|
+
branch.status = child.status === 'done' && record?.ok ? 'done' : 'failed';
|
|
1693
|
+
if (record?.output !== undefined) {
|
|
1694
|
+
branch.output = record.output;
|
|
1695
|
+
branch.artifactSha256 = createHash('sha256').update(typeof record.output === 'string' ? record.output : JSON.stringify(record.output)).digest('hex');
|
|
1696
|
+
}
|
|
1697
|
+
if (record?.error) branch.error = record.error;
|
|
1698
|
+
else if (child.status !== 'done') branch.error = `branch child run ended ${child.status}`;
|
|
1699
|
+
} catch (cause) {
|
|
1700
|
+
branch.status = 'failed';
|
|
1701
|
+
branch.error = cause instanceof Error ? cause.message : String(cause);
|
|
1702
|
+
}
|
|
1703
|
+
branch.endedAt = new Date().toISOString();
|
|
1704
|
+
persist();
|
|
1705
|
+
return branchId;
|
|
1706
|
+
}));
|
|
1707
|
+
persist();
|
|
1708
|
+
current = outgoing.join;
|
|
1709
|
+
} else {
|
|
1710
|
+
current = plannedStep ? plannedStep.to
|
|
1711
|
+
: nextNode(graph.edges, current, edgeOutcome, namedOutcome);
|
|
1712
|
+
}
|
|
1460
1713
|
resumedGrowth = false;
|
|
1461
1714
|
if (current !== undefined) publishInsideEvent({ kind: 'edge', graphId, runId, from: fromNodeId, to: current });
|
|
1462
1715
|
if (current === undefined) {
|
|
@@ -1467,6 +1720,17 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
|
|
|
1467
1720
|
}
|
|
1468
1721
|
}
|
|
1469
1722
|
}
|
|
1723
|
+
if (state.dryRun && Object.keys(state.fanOuts ?? {}).length > 0) {
|
|
1724
|
+
const fanoutsBySource = new Map<string, NonNullable<GraphRunState['fanOuts']>[string][]>();
|
|
1725
|
+
for (const fanout of Object.values(state.fanOuts!)) {
|
|
1726
|
+
const group = fanoutsBySource.get(fanout.from) ?? [];
|
|
1727
|
+
group.push(fanout);
|
|
1728
|
+
fanoutsBySource.set(fanout.from, group);
|
|
1729
|
+
}
|
|
1730
|
+
state.plannedPath = state.path.flatMap((nodeId) => [nodeId, ...(fanoutsBySource.get(nodeId) ?? []).flatMap((fanout) =>
|
|
1731
|
+
Object.values(fanout.branches).flatMap((branch) => (branch.path ?? []).filter((branchNode) => !graph.terminalNodes.includes(branchNode))))]);
|
|
1732
|
+
persist();
|
|
1733
|
+
}
|
|
1470
1734
|
return state;
|
|
1471
1735
|
} finally {
|
|
1472
1736
|
if (options.resumeRunId && existsSync(resumeLock)) rmdirSync(resumeLock);
|