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
|
@@ -43,6 +43,157 @@ export interface OverlayParseResult {
|
|
|
43
43
|
readonly errors: readonly GraphParseIssue[];
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/** Injected ARG promotion evidence used by the graph-promote rehearsal.
|
|
47
|
+
* This input is deliberately separate from the production run ledger: a fixture
|
|
48
|
+
* can exercise the decision path, but its output is always labelled mock-only. */
|
|
49
|
+
export interface ArgPromotionEvidenceEvent {
|
|
50
|
+
readonly runId: string;
|
|
51
|
+
readonly timestamp: string;
|
|
52
|
+
readonly trigger: string;
|
|
53
|
+
readonly phase: 'adaptation' | 'baseline' | 'shadow';
|
|
54
|
+
readonly landed?: boolean;
|
|
55
|
+
readonly shadowAccepted?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ArgPromotionCandidate {
|
|
59
|
+
readonly overlayId: string;
|
|
60
|
+
readonly target: string;
|
|
61
|
+
readonly appliesWhen: string;
|
|
62
|
+
readonly patch: readonly OverlayPatchOp[];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface ArgPromotionEvaluation {
|
|
66
|
+
readonly mockOnly: true;
|
|
67
|
+
readonly verdict: 'eligible-for-human-pr' | 'held';
|
|
68
|
+
readonly blockers: readonly string[];
|
|
69
|
+
readonly metrics: {
|
|
70
|
+
readonly trigger: string;
|
|
71
|
+
readonly adaptationRuns: number;
|
|
72
|
+
readonly adaptationLandingRate: number | null;
|
|
73
|
+
readonly baselineRuns: number;
|
|
74
|
+
readonly baselineLandingRate: number | null;
|
|
75
|
+
readonly landingDelta: number | null;
|
|
76
|
+
readonly adaptationWindowDays: number | null;
|
|
77
|
+
readonly shadowObservations: number;
|
|
78
|
+
readonly shadowWindowDays: number | null;
|
|
79
|
+
};
|
|
80
|
+
readonly proposal?: {
|
|
81
|
+
readonly action: 'proposal-only';
|
|
82
|
+
readonly promoted_from: readonly string[];
|
|
83
|
+
readonly evidence: Readonly<Record<string, unknown>>;
|
|
84
|
+
readonly overlay: {
|
|
85
|
+
readonly overlay_id: string;
|
|
86
|
+
readonly target: string;
|
|
87
|
+
readonly stage: 'launch';
|
|
88
|
+
readonly applies_when: string;
|
|
89
|
+
readonly patch: readonly OverlayPatchOp[];
|
|
90
|
+
};
|
|
91
|
+
readonly rollback: 'open a human-reviewed demotion PR if the 7-day landing rate declines';
|
|
92
|
+
readonly patentReview: 'ELA-53 human review pending';
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const PROMOTION_DAY_MS = 24 * 60 * 60 * 1000;
|
|
97
|
+
|
|
98
|
+
function promotionSpanDays(events: readonly ArgPromotionEvidenceEvent[]): number | null {
|
|
99
|
+
if (events.length < 2) return null;
|
|
100
|
+
const times = events.map((event) => Date.parse(event.timestamp));
|
|
101
|
+
if (times.some((time) => !Number.isFinite(time))) return null;
|
|
102
|
+
return (Math.max(...times) - Math.min(...times)) / PROMOTION_DAY_MS;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Evaluate injected evidence without reading a production ledger, writing an overlay, or opening a PR. */
|
|
106
|
+
export function evaluateArgPromotionFixture(input: {
|
|
107
|
+
readonly trigger: string;
|
|
108
|
+
readonly candidate: ArgPromotionCandidate;
|
|
109
|
+
readonly events: readonly ArgPromotionEvidenceEvent[];
|
|
110
|
+
}): ArgPromotionEvaluation {
|
|
111
|
+
if (input === null || typeof input !== 'object' || Array.isArray(input)) throw new Error('ARG promotion fixture root must be an object');
|
|
112
|
+
const { trigger, candidate, events } = input;
|
|
113
|
+
if (typeof trigger !== 'string' || typeof candidate !== 'object' || candidate === null || Array.isArray(candidate)
|
|
114
|
+
|| typeof candidate.overlayId !== 'string' || typeof candidate.target !== 'string' || typeof candidate.appliesWhen !== 'string'
|
|
115
|
+
|| !Array.isArray(candidate.patch) || !Array.isArray(events)) {
|
|
116
|
+
throw new Error('ARG promotion fixture requires trigger, candidate object, patch array and events array');
|
|
117
|
+
}
|
|
118
|
+
if (!trigger.trim() || !candidate.overlayId.trim() || !candidate.target.trim() || !candidate.appliesWhen.trim()) {
|
|
119
|
+
throw new Error('ARG promotion fixture requires trigger, overlayId, target and appliesWhen');
|
|
120
|
+
}
|
|
121
|
+
if (candidate.patch.length === 0) throw new Error('ARG promotion candidate patch must not be empty');
|
|
122
|
+
for (const operation of candidate.patch) {
|
|
123
|
+
if (operation === null || typeof operation !== 'object' || !['add', 'replace', 'remove'].includes(operation.op)
|
|
124
|
+
|| typeof operation.path !== 'string' || !operation.path.startsWith('/')
|
|
125
|
+
|| (operation.op !== 'remove' && !('value' in operation))) {
|
|
126
|
+
throw new Error('ARG promotion candidate contains an invalid JSON Patch operation');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const runIds = new Set<string>();
|
|
130
|
+
for (const rawEvent of events) {
|
|
131
|
+
if (rawEvent === null || typeof rawEvent !== 'object' || Array.isArray(rawEvent)) throw new Error('ARG promotion fixture contains a non-object event');
|
|
132
|
+
const event = rawEvent as ArgPromotionEvidenceEvent;
|
|
133
|
+
if (typeof event.runId !== 'string' || !event.runId.trim() || typeof event.timestamp !== 'string'
|
|
134
|
+
|| !Number.isFinite(Date.parse(event.timestamp)) || typeof event.trigger !== 'string' || !event.trigger.trim()
|
|
135
|
+
|| !['adaptation', 'baseline', 'shadow'].includes(event.phase)) {
|
|
136
|
+
throw new Error('ARG promotion fixture contains an invalid event');
|
|
137
|
+
}
|
|
138
|
+
if (runIds.has(event.runId)) throw new Error(`ARG promotion fixture repeats runId ${event.runId}`);
|
|
139
|
+
runIds.add(event.runId);
|
|
140
|
+
if ((event.phase === 'adaptation' || event.phase === 'baseline') && typeof event.landed !== 'boolean') {
|
|
141
|
+
throw new Error(`ARG promotion ${event.phase} event requires landed`);
|
|
142
|
+
}
|
|
143
|
+
if (event.phase === 'shadow' && typeof event.shadowAccepted !== 'boolean') {
|
|
144
|
+
throw new Error('ARG promotion shadow event requires shadowAccepted');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const matching = events.filter((event) => event.trigger === trigger);
|
|
149
|
+
const adaptations = matching.filter((event) => event.phase === 'adaptation');
|
|
150
|
+
const baseline = matching.filter((event) => event.phase === 'baseline');
|
|
151
|
+
const shadow = matching.filter((event) => event.phase === 'shadow');
|
|
152
|
+
const rate = (rows: readonly ArgPromotionEvidenceEvent[]): number | null => rows.length === 0
|
|
153
|
+
? null : rows.filter((event) => event.landed === true).length / rows.length;
|
|
154
|
+
const adaptationLandingRate = rate(adaptations);
|
|
155
|
+
const baselineLandingRate = rate(baseline);
|
|
156
|
+
const landingDelta = adaptationLandingRate === null || baselineLandingRate === null
|
|
157
|
+
? null : adaptationLandingRate - baselineLandingRate;
|
|
158
|
+
const adaptationSpanDays = promotionSpanDays(adaptations);
|
|
159
|
+
const baselineSpanDays = promotionSpanDays(baseline);
|
|
160
|
+
const adaptationWindowDays = adaptationSpanDays === null || baselineSpanDays === null
|
|
161
|
+
? null : Math.min(adaptationSpanDays, baselineSpanDays);
|
|
162
|
+
const shadowWindowDays = promotionSpanDays(shadow);
|
|
163
|
+
const evidenceEnd = Math.max(...[...adaptations, ...baseline].map((event) => Date.parse(event.timestamp)));
|
|
164
|
+
const shadowStart = Math.min(...shadow.map((event) => Date.parse(event.timestamp)));
|
|
165
|
+
const blockers: string[] = [];
|
|
166
|
+
if (adaptations.length < 5) blockers.push('same-trigger-adaptations-below-5');
|
|
167
|
+
if (baseline.length === 0) blockers.push('same-trigger-baseline-missing');
|
|
168
|
+
if (landingDelta === null || landingDelta < 0.2 - Number.EPSILON) blockers.push('landing-improvement-below-20pp');
|
|
169
|
+
if (adaptationWindowDays === null || adaptationWindowDays < 7) blockers.push('adaptation-evidence-window-under-7-days');
|
|
170
|
+
if (shadow.length < 2 || shadowWindowDays === null || shadowWindowDays < 7) blockers.push('shadow-window-under-7-days');
|
|
171
|
+
if (!Number.isFinite(evidenceEnd) || !Number.isFinite(shadowStart) || shadowStart < evidenceEnd) blockers.push('shadow-starts-before-evidence-window');
|
|
172
|
+
if (shadow.some((event) => event.shadowAccepted !== true)) blockers.push('shadow-evaluation-declined');
|
|
173
|
+
|
|
174
|
+
const metrics = { trigger, adaptationRuns: adaptations.length, adaptationLandingRate,
|
|
175
|
+
baselineRuns: baseline.length, baselineLandingRate, landingDelta, adaptationWindowDays,
|
|
176
|
+
shadowObservations: shadow.length, shadowWindowDays };
|
|
177
|
+
if (blockers.length > 0) return { mockOnly: true, verdict: 'held', blockers, metrics };
|
|
178
|
+
const promotedFrom = adaptations.map((event) => event.runId).sort();
|
|
179
|
+
return {
|
|
180
|
+
mockOnly: true, verdict: 'eligible-for-human-pr', blockers, metrics,
|
|
181
|
+
proposal: {
|
|
182
|
+
action: 'proposal-only', promoted_from: promotedFrom,
|
|
183
|
+
evidence: {
|
|
184
|
+
source: 'injected-mock-fixture', trigger, adaptationRuns: promotedFrom,
|
|
185
|
+
baselineRuns: baseline.map((event) => event.runId).sort(),
|
|
186
|
+
adaptationLandingRate, baselineLandingRate, landingDelta,
|
|
187
|
+
adaptationWindowDays, shadowRunIds: shadow.map((event) => event.runId).sort(), shadowWindowDays,
|
|
188
|
+
},
|
|
189
|
+
overlay: { overlay_id: candidate.overlayId, target: candidate.target, stage: 'launch',
|
|
190
|
+
applies_when: candidate.appliesWhen, patch: candidate.patch },
|
|
191
|
+
rollback: 'open a human-reviewed demotion PR if the 7-day landing rate declines',
|
|
192
|
+
patentReview: 'ELA-53 human review pending',
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
46
197
|
const STAGES = new Set<OverlayStage>(['launch', 'runtime', 'heal']);
|
|
47
198
|
const OPS = new Set(['add', 'replace', 'remove']);
|
|
48
199
|
|
|
@@ -167,8 +318,10 @@ export function applyGraphOverlays(
|
|
|
167
318
|
rejections.push({ kind: 'unknown-target', overlayId: overlay.overlayId, target: overlay.target });
|
|
168
319
|
continue;
|
|
169
320
|
}
|
|
321
|
+
const beforeNodes = new Map(next.nodes.map((node) => [node.nodeId, node]));
|
|
170
322
|
const beforeVisits = new Map(next.nodes.map((node) => [node.nodeId, node.maxVisits]));
|
|
171
|
-
const beforeRoutes =
|
|
323
|
+
const beforeRoutes = graphRouteMap(next);
|
|
324
|
+
const beforeEdgeMap = edgeMapOf(next);
|
|
172
325
|
for (const op of overlay.patch) {
|
|
173
326
|
const resolved = resolvePointer(next, op.path);
|
|
174
327
|
if (!resolved) { rejections.push({ kind: 'bad-pointer', overlayId: overlay.overlayId, path: op.path }); continue; }
|
|
@@ -190,15 +343,27 @@ export function applyGraphOverlays(
|
|
|
190
343
|
if (op.op === 'remove') delete bag[key]; else bag[key] = op.value;
|
|
191
344
|
} else rejections.push({ kind: 'bad-pointer', overlayId: overlay.overlayId, path: op.path });
|
|
192
345
|
}
|
|
346
|
+
for (const node of next.nodes) {
|
|
347
|
+
if (beforeNodes.has(node.nodeId)) continue;
|
|
348
|
+
patches.push({ overlayId: overlay.overlayId, field: 'node-added', node: node.nodeId, kind: node.kind, maxVisits: node.maxVisits });
|
|
349
|
+
}
|
|
350
|
+
const afterRoutes = graphRouteMap(next);
|
|
351
|
+
for (const [key, route] of afterRoutes) {
|
|
352
|
+
const before = beforeRoutes.get(key);
|
|
353
|
+
if (before && before.to !== route.to) {
|
|
354
|
+
patches.push({ overlayId: overlay.overlayId, field: 'edge-rerouted', from: route.from, outcome: route.outcome, was: before.to, to: route.to });
|
|
355
|
+
}
|
|
356
|
+
}
|
|
193
357
|
for (const node of next.nodes) {
|
|
194
358
|
const before = beforeVisits.get(node.nodeId);
|
|
195
359
|
if (before !== undefined && before !== node.maxVisits) {
|
|
196
360
|
patches.push({ overlayId: overlay.overlayId, field: 'maxVisits', node: node.nodeId, before, after: node.maxVisits });
|
|
197
361
|
}
|
|
198
362
|
}
|
|
199
|
-
const
|
|
200
|
-
for (const
|
|
201
|
-
const
|
|
363
|
+
const afterEdgeMap = edgeMapOf(next);
|
|
364
|
+
for (const node of Object.keys(beforeEdgeMap)) {
|
|
365
|
+
const before = beforeEdgeMap[node] ?? [];
|
|
366
|
+
const after = afterEdgeMap[node] ?? [];
|
|
202
367
|
if (before.length !== after.length || before.some((destination, index) => destination !== after[index])) {
|
|
203
368
|
patches.push({ overlayId: overlay.overlayId, field: 'routes', node, before, after });
|
|
204
369
|
}
|
|
@@ -246,6 +411,18 @@ export function applyGraphOverlays(
|
|
|
246
411
|
return { ok: true, template: next, overlayIds: applied, patches };
|
|
247
412
|
}
|
|
248
413
|
|
|
414
|
+
/** Keep outcome names while comparing route changes; the compiled edge map deliberately drops them. */
|
|
415
|
+
function graphRouteMap(template: GraphTemplateSpec): Map<string, { from: string; outcome: string; to: string }> {
|
|
416
|
+
const routes = new Map<string, { from: string; outcome: string; to: string }>();
|
|
417
|
+
for (const [index, edge] of template.edges.entries()) {
|
|
418
|
+
if (edge.to) routes.set(`${edge.from}\u0000direct\u0000${index}`, { from: edge.from, outcome: '', to: edge.to });
|
|
419
|
+
for (const [outcome, to] of Object.entries(edge.map ?? {})) {
|
|
420
|
+
routes.set(`${edge.from}\u0000${edge.on ?? 'outcome'}\u0000${outcome}`, { from: edge.from, outcome, to });
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return routes;
|
|
424
|
+
}
|
|
425
|
+
|
|
249
426
|
export interface OverlayLoadResult {
|
|
250
427
|
readonly overlays: readonly GraphOverlaySpec[];
|
|
251
428
|
readonly errors: readonly GraphParseIssue[];
|
|
@@ -26,7 +26,9 @@ export type OverlayRejection =
|
|
|
26
26
|
|
|
27
27
|
export type OverlayPatch =
|
|
28
28
|
| { readonly overlayId: string; readonly field: 'maxVisits'; readonly node: string; readonly before: number; readonly after: number }
|
|
29
|
-
| { readonly overlayId: string; readonly field: 'routes'; readonly node: string; readonly before: readonly string[]; readonly after: readonly string[] }
|
|
29
|
+
| { readonly overlayId: string; readonly field: 'routes'; readonly node: string; readonly before: readonly string[]; readonly after: readonly string[] }
|
|
30
|
+
| { readonly overlayId: string; readonly field: 'node-added'; readonly node: string; readonly kind: string; readonly maxVisits: number }
|
|
31
|
+
| { readonly overlayId: string; readonly field: 'edge-rerouted'; readonly from: string; readonly outcome: string; readonly was: string; readonly to: string };
|
|
30
32
|
|
|
31
33
|
export type OverlayResult =
|
|
32
34
|
| { ok: true; template: GraphTemplate; patches: readonly OverlayPatch[] }
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { parse as parseYaml } from 'yaml';
|
|
5
|
+
import { evaluateOverlayCondition, parseOverlayCondition } from './graph-overlay-condition.js';
|
|
6
|
+
import type { GraphParseIssue } from './graph-yaml.js';
|
|
7
|
+
|
|
8
|
+
/** L1 profile: a deterministic state bundle and references to already-declared overlays. */
|
|
9
|
+
export interface GraphProfileSpec {
|
|
10
|
+
readonly profileId: string;
|
|
11
|
+
readonly appliesWhen: string;
|
|
12
|
+
readonly state: Readonly<Record<string, string | number | boolean>>;
|
|
13
|
+
readonly overlays: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface GraphProfileParseResult {
|
|
17
|
+
readonly profile?: GraphProfileSpec;
|
|
18
|
+
readonly errors: readonly GraphParseIssue[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function parseGraphProfileYaml(source: string, label = '<inline>'): GraphProfileParseResult {
|
|
22
|
+
let raw: unknown;
|
|
23
|
+
try { raw = parseYaml(source); }
|
|
24
|
+
catch (error) {
|
|
25
|
+
return { errors: [{ path: label, message: `YAML 파싱 실패: ${error instanceof Error ? error.message : String(error)}` }] };
|
|
26
|
+
}
|
|
27
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw))
|
|
28
|
+
return { errors: [{ path: label, message: 'YAML 최상위가 맵이 아니다' }] };
|
|
29
|
+
const doc = raw as Record<string, unknown>;
|
|
30
|
+
const errors: GraphParseIssue[] = [];
|
|
31
|
+
const profileId = typeof doc.profile_id === 'string' && /^[a-z][a-z0-9-]*$/.test(doc.profile_id) ? doc.profile_id : undefined;
|
|
32
|
+
if (!profileId) errors.push({ path: `${label}/profile_id`, message: 'profile_id는 소문자·숫자·하이픈 식별자여야 한다' });
|
|
33
|
+
const appliesWhen = typeof doc.applies_when === 'string' ? doc.applies_when : undefined;
|
|
34
|
+
if (!appliesWhen || !parseOverlayCondition(appliesWhen).ok)
|
|
35
|
+
errors.push({ path: `${label}/applies_when`, message: 'applies_when은 오버레이 조건 한 개(key op literal)여야 한다' });
|
|
36
|
+
const stateRaw = doc.state;
|
|
37
|
+
const state: Record<string, string | number | boolean> = {};
|
|
38
|
+
if (!stateRaw || typeof stateRaw !== 'object' || Array.isArray(stateRaw)) {
|
|
39
|
+
errors.push({ path: `${label}/state`, message: 'state는 스칼라 값만 담는 맵이어야 한다' });
|
|
40
|
+
} else {
|
|
41
|
+
for (const [key, value] of Object.entries(stateRaw as Record<string, unknown>)) {
|
|
42
|
+
if (!/^[a-z_][a-z0-9_]*$/i.test(key) || !['string', 'number', 'boolean'].includes(typeof value)
|
|
43
|
+
|| (typeof value === 'number' && !Number.isFinite(value))) {
|
|
44
|
+
errors.push({ path: `${label}/state/${key}`, message: 'state 키와 값은 조건 파서가 다루는 키·문자열·유한수·불리언이어야 한다' });
|
|
45
|
+
} else state[key] = value as string | number | boolean;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const overlaysRaw = doc.overlays;
|
|
49
|
+
const overlays = Array.isArray(overlaysRaw) ? overlaysRaw.filter((value): value is string => typeof value === 'string') : undefined;
|
|
50
|
+
if (!Array.isArray(overlaysRaw) || !overlays || overlays.length !== overlaysRaw.length || new Set(overlays).size !== overlays.length)
|
|
51
|
+
errors.push({ path: `${label}/overlays`, message: 'overlays는 중복 없는 문자열 목록이어야 한다' });
|
|
52
|
+
if (errors.length > 0) return { errors };
|
|
53
|
+
return { profile: { profileId: profileId!, appliesWhen: appliesWhen!, state, overlays: overlays! }, errors };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface GraphProfileLoadResult {
|
|
57
|
+
readonly profiles: readonly GraphProfileSpec[];
|
|
58
|
+
readonly errors: readonly GraphParseIssue[];
|
|
59
|
+
readonly scannedFiles: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function loadGraphProfiles(dir: string): GraphProfileLoadResult {
|
|
63
|
+
let files: string[];
|
|
64
|
+
try { files = readdirSync(dir).filter((file) => file.endsWith('.yaml') || file.endsWith('.yml')).sort(); }
|
|
65
|
+
catch (error) { return { profiles: [], errors: [{ path: dir, message: `프로필 디렉토리를 못 읽었다: ${error instanceof Error ? error.message : String(error)}` }], scannedFiles: 0 }; }
|
|
66
|
+
const errors: GraphParseIssue[] = [];
|
|
67
|
+
const profiles: GraphProfileSpec[] = [];
|
|
68
|
+
for (const file of files) {
|
|
69
|
+
try {
|
|
70
|
+
const parsed = parseGraphProfileYaml(readFileSync(join(dir, file), 'utf8'), file);
|
|
71
|
+
errors.push(...parsed.errors);
|
|
72
|
+
if (parsed.profile) profiles.push(parsed.profile);
|
|
73
|
+
} catch (error) { errors.push({ path: file, message: `읽기 실패: ${error instanceof Error ? error.message : String(error)}` }); }
|
|
74
|
+
}
|
|
75
|
+
const seen = new Set<string>();
|
|
76
|
+
for (const profile of profiles) {
|
|
77
|
+
if (seen.has(profile.profileId)) errors.push({ path: `${dir}/${profile.profileId}`, message: `profile_id '${profile.profileId}'가 중복이다` });
|
|
78
|
+
seen.add(profile.profileId);
|
|
79
|
+
}
|
|
80
|
+
return errors.length ? { profiles: [], errors, scannedFiles: files.length } : { profiles, errors, scannedFiles: files.length };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function defaultProfilesDir(): string {
|
|
84
|
+
return join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'graphs', 'profiles');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface GraphProfileSelection {
|
|
88
|
+
readonly applied: readonly GraphProfileSpec[];
|
|
89
|
+
readonly errors: readonly string[];
|
|
90
|
+
readonly state: Readonly<Record<string, unknown>>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Match all profiles deterministically; conflicting owned state rejects the whole profile set. */
|
|
94
|
+
export function selectGraphProfiles(
|
|
95
|
+
profiles: readonly GraphProfileSpec[],
|
|
96
|
+
state: Readonly<Record<string, unknown>>,
|
|
97
|
+
): GraphProfileSelection {
|
|
98
|
+
const applied = profiles.filter((profile) => evaluateOverlayCondition(profile.appliesWhen, state).kind === 'applies');
|
|
99
|
+
const owned = new Map<string, string | number | boolean>();
|
|
100
|
+
const errors: string[] = [];
|
|
101
|
+
for (const profile of applied) for (const [key, value] of Object.entries(profile.state)) {
|
|
102
|
+
if (owned.has(key) && owned.get(key) !== value) errors.push(`profile state conflict: ${key} (${String(owned.get(key))} vs ${String(value)})`);
|
|
103
|
+
else owned.set(key, value);
|
|
104
|
+
}
|
|
105
|
+
if (errors.length) return { applied: [], errors, state };
|
|
106
|
+
return { applied, errors, state: { ...state, ...Object.fromEntries(owned) } };
|
|
107
|
+
}
|
|
@@ -37,6 +37,8 @@ export interface GraphNodeSpec {
|
|
|
37
37
|
/** Entry selected by this call when a unit exposes more than one entry. */
|
|
38
38
|
readonly callEntry?: string;
|
|
39
39
|
readonly budget?: { readonly innerSteps: number };
|
|
40
|
+
/** ARG L upper bound inherited by this child graph call. */
|
|
41
|
+
readonly allowance?: { readonly innerSteps: number };
|
|
40
42
|
/** L1: skip this optional node when a measured state condition holds. */
|
|
41
43
|
readonly skipWhen?: string;
|
|
42
44
|
}
|
|
@@ -48,6 +50,11 @@ export interface GraphEdgeSpec {
|
|
|
48
50
|
/** 조건부 엣지 — 라우터가 읽는 «상태 키». ⛔ 값은 코드가 낸다(RFC §4.3 ⑵). */
|
|
49
51
|
readonly on?: string;
|
|
50
52
|
readonly map?: Readonly<Record<string, string>>;
|
|
53
|
+
/** Explicit fan-out destinations keyed by outcome. Each selected branch runs concurrently and joins at `join`. */
|
|
54
|
+
readonly branches?: Readonly<Record<string, readonly string[]>>;
|
|
55
|
+
readonly join?: string;
|
|
56
|
+
/** Failed warning branches remain visible in the join output but do not fail the barrier. */
|
|
57
|
+
readonly warningBranches?: readonly string[];
|
|
51
58
|
/** 심이 «주입 안 됐을 때» 내려가는 순서. `requires` 는 그 심 이름들. */
|
|
52
59
|
readonly fallback?: readonly { readonly node: string; readonly requires: readonly string[]; readonly observed?: number }[];
|
|
53
60
|
readonly observed?: number;
|
|
@@ -65,6 +72,8 @@ export interface GraphTemplateSpec {
|
|
|
65
72
|
/** 문서 전용 변경이면 gate 노드를 건너뛸 수 있다는 템플릿 정책. */
|
|
66
73
|
readonly docsOnlyGateSkip?: boolean;
|
|
67
74
|
readonly state?: readonly string[];
|
|
75
|
+
/** ARG L upper bound for this graph's total executed steps. */
|
|
76
|
+
readonly allowance?: { readonly innerSteps: number };
|
|
68
77
|
/** ⭐ 런 계약(선택) — 이 그래프가 «기본으로» 요구하는 실행 칸 등. 발사 인자가 덮는다(graph-run-contract.ts). */
|
|
69
78
|
readonly runContract?: GraphRunContractSpec;
|
|
70
79
|
readonly unit?: { readonly inputs: readonly string[]; readonly outputs: readonly string[]; readonly exits: readonly string[]; readonly entries?: readonly string[] };
|
|
@@ -148,6 +157,14 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
148
157
|
|
|
149
158
|
const terminalNodes = asArray(doc.terminal_nodes).filter((v): v is string => typeof v === 'string');
|
|
150
159
|
if (terminalNodes.length === 0) errors.push({ path: `${label}/terminal_nodes`, message: 'terminal_nodes 가 비었다 — 끝날 수 없는 그래프다' });
|
|
160
|
+
let allowance: GraphTemplateSpec['allowance'];
|
|
161
|
+
if (doc.allowance !== undefined) {
|
|
162
|
+
const value = doc.allowance as Record<string, unknown> | undefined;
|
|
163
|
+
if (!value || typeof value !== 'object' || Array.isArray(value) || !Number.isSafeInteger(value.inner_steps) ||
|
|
164
|
+
(value.inner_steps as number) < 1 || Object.keys(value).some(key => key !== 'inner_steps'))
|
|
165
|
+
errors.push({ path: `${label}/allowance/inner_steps`, message: 'inner_steps 는 1 이상의 안전한 정수여야 한다' });
|
|
166
|
+
else allowance = { innerSteps: value.inner_steps as number };
|
|
167
|
+
}
|
|
151
168
|
|
|
152
169
|
const journeyStages = doc.journey_stages;
|
|
153
170
|
if (journeyStages !== undefined && (!Array.isArray(journeyStages) || journeyStages.length === 0
|
|
@@ -202,21 +219,28 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
202
219
|
: undefined;
|
|
203
220
|
// A subgraph node becomes a unit call only when it names `call:`; without it the node keeps the
|
|
204
221
|
// pre-unit meaning (catalog role / recipe node), so existing declarations stay valid.
|
|
205
|
-
if (kind === 'subgraph' && (n.call !== undefined || n.budget !== undefined || n.call_entry !== undefined)) {
|
|
222
|
+
if (kind === 'subgraph' && (n.call !== undefined || n.budget !== undefined || n.allowance !== undefined || n.call_entry !== undefined)) {
|
|
206
223
|
if (typeof n.call !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._-]*@(?:\^?[1-9]\d*)$/.test(n.call))
|
|
207
224
|
errors.push({ path: `${at}/call`, message: 'call 은 id@정수판 또는 id@^주판이어야 한다' });
|
|
208
225
|
const budget = n.budget as Record<string, unknown> | undefined;
|
|
209
226
|
if (!budget || typeof budget !== 'object' || Array.isArray(budget) ||
|
|
210
227
|
!Number.isSafeInteger(budget.inner_steps) || (budget.inner_steps as number) < 1 || Object.keys(budget).some(key => key !== 'inner_steps'))
|
|
211
228
|
errors.push({ path: `${at}/budget/inner_steps`, message: 'inner_steps 는 1 이상의 안전한 정수여야 한다' });
|
|
229
|
+
if (n.allowance !== undefined) {
|
|
230
|
+
const childAllowance = n.allowance as Record<string, unknown> | undefined;
|
|
231
|
+
if (!childAllowance || typeof childAllowance !== 'object' || Array.isArray(childAllowance) ||
|
|
232
|
+
!Number.isSafeInteger(childAllowance.inner_steps) || (childAllowance.inner_steps as number) < 1 ||
|
|
233
|
+
Object.keys(childAllowance).some(key => key !== 'inner_steps'))
|
|
234
|
+
errors.push({ path: `${at}/allowance/inner_steps`, message: 'inner_steps 는 1 이상의 안전한 정수여야 한다' });
|
|
235
|
+
}
|
|
212
236
|
if (!contractRaw || !Array.isArray(contractRaw.inputs) || !contractRaw.inputs.every(v => typeof v === 'string') ||
|
|
213
237
|
!Array.isArray(contractRaw.outputs) || !contractRaw.outputs.every(v => typeof v === 'string'))
|
|
214
238
|
errors.push({ path: `${at}/contract`, message: 'subgraph 에는 inputs·outputs 계약이 필요하다' });
|
|
215
239
|
if (recipe !== 'none') errors.push({ path: `${at}/recipe`, message: 'subgraph 는 recipe 를 실행하지 않는다' });
|
|
216
240
|
if (n.call_entry !== undefined && (typeof n.call_entry !== 'string' || !n.call_entry.trim()))
|
|
217
241
|
errors.push({ path: `${at}/call_entry`, message: 'call_entry 는 비어 있지 않은 노드 id 여야 한다' });
|
|
218
|
-
} else if (kind !== 'subgraph' && (n.call !== undefined || n.budget !== undefined || n.call_entry !== undefined)) {
|
|
219
|
-
errors.push({ path: at, message: 'call·call_entry·budget 은 subgraph 전용이다' });
|
|
242
|
+
} else if (kind !== 'subgraph' && (n.call !== undefined || n.budget !== undefined || n.allowance !== undefined || n.call_entry !== undefined)) {
|
|
243
|
+
errors.push({ path: at, message: 'call·call_entry·budget·allowance 은 subgraph 전용이다' });
|
|
220
244
|
}
|
|
221
245
|
// ⛔ 계약이 없으면 「이 노드가 무엇을 할 수 있나」를 답할 수 없다 — 경고로 남긴다(거절은 오버레이 쪽).
|
|
222
246
|
if (contract === undefined) warnings.push({ path: `${at}/contract`, message: '계약(inputs·tools·outputs)이 없다 — 권한을 코드에서만 알 수 있다' });
|
|
@@ -235,6 +259,9 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
235
259
|
...(kind === 'subgraph' && n.budget && typeof n.budget === 'object' && !Array.isArray(n.budget) &&
|
|
236
260
|
typeof (n.budget as Record<string, unknown>).inner_steps === 'number'
|
|
237
261
|
? { budget: { innerSteps: (n.budget as { inner_steps: number }).inner_steps } } : {}),
|
|
262
|
+
...(kind === 'subgraph' && n.allowance && typeof n.allowance === 'object' && !Array.isArray(n.allowance) &&
|
|
263
|
+
typeof (n.allowance as Record<string, unknown>).inner_steps === 'number'
|
|
264
|
+
? { allowance: { innerSteps: (n.allowance as { inner_steps: number }).inner_steps } } : {}),
|
|
238
265
|
...(typeof n.skip_when === 'string' ? { skipWhen: n.skip_when } : {}),
|
|
239
266
|
});
|
|
240
267
|
}
|
|
@@ -251,14 +278,19 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
251
278
|
if (!known.has(from)) { errors.push({ path: `${at}/from`, message: `'${from}' 은 선언된 노드가 아니다` }); continue; }
|
|
252
279
|
const hasTo = typeof e.to === 'string';
|
|
253
280
|
const hasMap = e.map !== null && typeof e.map === 'object';
|
|
281
|
+
const hasBranches = e.branches !== null && typeof e.branches === 'object' && !Array.isArray(e.branches);
|
|
254
282
|
if (e.when !== undefined && (typeof e.when !== 'string' || !parseOverlayCondition(e.when).ok))
|
|
255
283
|
errors.push({ path: `${at}/when`, message: 'when 은 오버레이 조건 한 개(key op literal)여야 한다' });
|
|
256
284
|
if (e.when !== undefined && (L1_PROTECTED_ROUTE_NODES.has(from) || nodes.some(node => node.nodeId === from && node.kind === 'gate') || terminalNodes.includes(from)))
|
|
257
285
|
errors.push({ path: `${at}/when`, message: `'${from}' 의 필수 검증·착지 결과는 when 간선으로 덮을 수 없다` });
|
|
258
286
|
if (e.when !== undefined && (!hasTo || hasMap || e.on !== undefined))
|
|
259
287
|
errors.push({ path: `${at}/when`, message: 'when 은 to 간선에서만 쓴다' });
|
|
260
|
-
if (hasTo
|
|
261
|
-
errors.push({ path: at, message: 'to
|
|
288
|
+
if (!hasTo && !hasMap && !hasBranches) {
|
|
289
|
+
errors.push({ path: at, message: 'to 또는 map/branches 조합을 써야 한다' });
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
if (hasTo && (hasMap || hasBranches)) {
|
|
293
|
+
errors.push({ path: at, message: 'to 는 map·branches 와 함께 쓸 수 없다' });
|
|
262
294
|
continue;
|
|
263
295
|
}
|
|
264
296
|
const map: Record<string, string> = {};
|
|
@@ -270,6 +302,35 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
270
302
|
}
|
|
271
303
|
if (typeof e.on !== 'string') errors.push({ path: `${at}/on`, message: 'map 을 쓰면 on(라우터가 읽는 상태 키)이 필요하다' });
|
|
272
304
|
}
|
|
305
|
+
let branches: Record<string, readonly string[]> | undefined;
|
|
306
|
+
let warningBranches: readonly string[] | undefined;
|
|
307
|
+
if (hasBranches) {
|
|
308
|
+
branches = {};
|
|
309
|
+
for (const [outcome, destinations] of Object.entries(e.branches as Record<string, unknown>)) {
|
|
310
|
+
if (!Array.isArray(destinations) || destinations.length < 2 || !destinations.every((value) => typeof value === 'string')) {
|
|
311
|
+
errors.push({ path: `${at}/branches/${outcome}`, message: 'branches 목적지는 두 개 이상의 노드 id 목록이어야 한다' });
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (new Set(destinations).size !== destinations.length)
|
|
315
|
+
errors.push({ path: `${at}/branches/${outcome}`, message: 'branches 목적지는 중복될 수 없다' });
|
|
316
|
+
for (const [index, destination] of destinations.entries()) {
|
|
317
|
+
if (!known.has(destination)) errors.push({ path: `${at}/branches/${outcome}/${index}`, message: `'${destination}' 는 선언된 노드가 아니다` });
|
|
318
|
+
}
|
|
319
|
+
branches[outcome] = destinations as string[];
|
|
320
|
+
}
|
|
321
|
+
if (typeof e.on !== 'string' || typeof e.join !== 'string' || !known.has(e.join))
|
|
322
|
+
errors.push({ path: at, message: 'branches 에는 on 과 선언된 join 노드가 필요하다' });
|
|
323
|
+
if (e.fallback !== undefined || e.when !== undefined) errors.push({ path: at, message: 'branches 는 fallback·when 과 함께 쓸 수 없다' });
|
|
324
|
+
if (hasMap && Object.keys(map).some((outcome) => Object.hasOwn(e.branches as object, outcome)))
|
|
325
|
+
errors.push({ path: `${at}/branches`, message: 'map 과 branches 의 outcome 키는 겹칠 수 없다' });
|
|
326
|
+
if (e.warning_branches !== undefined) {
|
|
327
|
+
if (!Array.isArray(e.warning_branches) || e.warning_branches.some((branch) => typeof branch !== 'string' || !branch.trim()) ||
|
|
328
|
+
new Set(e.warning_branches).size !== e.warning_branches.length ||
|
|
329
|
+
e.warning_branches.some((branch) => !Object.values(branches!).some((destinations) => destinations.includes(branch as string)))) {
|
|
330
|
+
errors.push({ path: `${at}/warning_branches`, message: 'warning_branches 는 중복 없는 branches 목적지 목록이어야 한다' });
|
|
331
|
+
} else warningBranches = e.warning_branches as string[];
|
|
332
|
+
}
|
|
333
|
+
}
|
|
273
334
|
if (hasTo && !known.has(e.to as string)) { errors.push({ path: `${at}/to`, message: `'${String(e.to)}' 는 선언된 노드가 아니다` }); continue; }
|
|
274
335
|
|
|
275
336
|
const fallback = asArray(e.fallback).flatMap((f, fi) => {
|
|
@@ -287,6 +348,7 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
287
348
|
from,
|
|
288
349
|
...(hasTo ? { to: e.to as string } : {}),
|
|
289
350
|
...(hasMap ? { on: String(e.on), map } : {}),
|
|
351
|
+
...(branches ? { on: String(e.on), branches, join: String(e.join), ...(warningBranches ? { warningBranches } : {}) } : {}),
|
|
290
352
|
...(fallback.length > 0 ? { fallback } : {}),
|
|
291
353
|
...(typeof e.observed === 'number' ? { observed: e.observed } : {}),
|
|
292
354
|
...(typeof e.when === 'string' ? { when: e.when } : {}),
|
|
@@ -304,6 +366,25 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
304
366
|
if (!edges.some(candidate => candidate.from === edge.from && candidate.when === undefined))
|
|
305
367
|
errors.push({ path: `${label}/edges/${edge.from}/when`, message: 'when 간선에는 모호·미관측 때 탈 무조건 기본 간선이 필요하다' });
|
|
306
368
|
}
|
|
369
|
+
const fanOutDestinations = new Map<string, string>();
|
|
370
|
+
const fanOutJoins = new Map<string, string>();
|
|
371
|
+
for (const edge of edges) {
|
|
372
|
+
if (!edge.branches || !edge.join) continue;
|
|
373
|
+
const sourceNode = nodes.find(node => node.nodeId === edge.from);
|
|
374
|
+
if (sourceNode && sourceNode.maxVisits !== 1) errors.push({ path: `${label}/edges/${edge.from}/branches`, message: 'fan-out 출발 노드는 재방문할 수 없어 max_visits: 1 이어야 한다' });
|
|
375
|
+
if (fanOutJoins.has(edge.join) && fanOutJoins.get(edge.join) !== edge.from) errors.push({ path: `${label}/edges/${edge.from}/join`, message: 'join 노드는 하나의 fan-out barrier만 소유할 수 있다' });
|
|
376
|
+
fanOutJoins.set(edge.join, edge.from);
|
|
377
|
+
if (edge.join === edge.from || Object.values(edge.branches).some((branches) => branches.includes(edge.join!)))
|
|
378
|
+
errors.push({ path: `${label}/edges/${edge.from}/join`, message: 'join 노드는 fan-out source나 branch 목적지일 수 없다' });
|
|
379
|
+
for (const branch of new Set(Object.values(edge.branches).flat())) {
|
|
380
|
+
if (fanOutDestinations.has(branch) && fanOutDestinations.get(branch) !== edge.from) errors.push({ path: `${label}/edges/${edge.from}/branches`, message: `branch '${branch}' 는 하나의 fan-out source 에서만 실행할 수 있다` });
|
|
381
|
+
fanOutDestinations.set(branch, edge.from);
|
|
382
|
+
if (edges.some(candidate => candidate.from === branch)) errors.push({ path: `${label}/edges/${edge.from}/branches`, message: `branch '${branch}' 는 단일 노드만 지원하며 후속 간선은 허용되지 않는다` });
|
|
383
|
+
}
|
|
384
|
+
const joinEdge = edges.find((candidate) => candidate.from === edge.join && candidate.on === 'outcome');
|
|
385
|
+
if (!joinEdge?.map || !Object.hasOwn(joinEdge.map, 'ok') || !Object.hasOwn(joinEdge.map, 'fail'))
|
|
386
|
+
errors.push({ path: `${label}/edges/${edge.join}`, message: 'fan-out join 은 ok·fail 출구를 모두 선언해야 한다' });
|
|
387
|
+
}
|
|
307
388
|
|
|
308
389
|
if (entryNode !== undefined && !known.has(entryNode)) errors.push({ path: `${label}/entry_node`, message: `'${entryNode}' 는 선언된 노드가 아니다` });
|
|
309
390
|
for (const t of terminalNodes) if (!known.has(t)) errors.push({ path: `${label}/terminal_nodes`, message: `'${t}' 는 선언된 노드가 아니다` });
|
|
@@ -358,6 +439,7 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
358
439
|
...(loop ? { loop } : {}),
|
|
359
440
|
...(typeof doc.docs_only_gate_skip === 'boolean' ? { docsOnlyGateSkip: doc.docs_only_gate_skip } : {}),
|
|
360
441
|
...(Array.isArray(doc.state) ? { state: doc.state.filter((v): v is string => typeof v === 'string') } : {}),
|
|
442
|
+
...(allowance ? { allowance } : {}),
|
|
361
443
|
...(runContract.spec ? { runContract: runContract.spec } : {}),
|
|
362
444
|
},
|
|
363
445
|
errors, warnings,
|
|
@@ -512,6 +594,13 @@ export function edgeMapOf(template: GraphTemplateSpec): Record<string, string[]>
|
|
|
512
594
|
const push = (t: string) => { if (!targets.includes(t)) targets.push(t); };
|
|
513
595
|
if (edge.to) push(edge.to);
|
|
514
596
|
for (const t of Object.values(edge.map ?? {})) push(t);
|
|
597
|
+
for (const destinations of Object.values(edge.branches ?? {})) for (const destination of destinations) {
|
|
598
|
+
push(destination);
|
|
599
|
+
if (edge.join) {
|
|
600
|
+
const branchTargets = edges[destination] ?? (edges[destination] = []);
|
|
601
|
+
if (!branchTargets.includes(edge.join)) branchTargets.push(edge.join);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
515
604
|
for (const fb of edge.fallback ?? []) push(fb.node);
|
|
516
605
|
}
|
|
517
606
|
return edges;
|