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
|
@@ -55,8 +55,11 @@ export function readRunChart(runId: string, device: RunChartDevice, dir: string)
|
|
|
55
55
|
export function runChartMetrics(entries: readonly RunLedgerEntry[]): { emptyHandoffs: number; unreadHandoffs: number; conflictingVerdicts: number } {
|
|
56
56
|
const cells = entries.filter((e) => e.event === 'run-chart-cell');
|
|
57
57
|
const emptyHandoffs = cells.filter((e) => !String(e.data.handoff ?? '').trim()).length;
|
|
58
|
-
const unreadHandoffs = cells.filter((e) =>
|
|
59
|
-
|
|
58
|
+
const unreadHandoffs = cells.filter((e) => {
|
|
59
|
+
const handoff = String(e.data.handoff ?? '').trim().toLowerCase();
|
|
60
|
+
return handoff !== '' && handoff !== 'none'
|
|
61
|
+
&& !cells.some((next) => next.data.readStopKeys instanceof Array && next.data.readStopKeys.includes(String(e.data.stopKey)));
|
|
62
|
+
}).length;
|
|
60
63
|
const verdicts = new Map<string, Set<string>>();
|
|
61
64
|
for (const cell of cells) {
|
|
62
65
|
const key = `${String(cell.data.device)}\0${String(cell.data.stopKey)}`;
|
|
@@ -90,7 +93,7 @@ export function recordRunChartDecision(input: RunChartDecision): RunChartWriteRe
|
|
|
90
93
|
}
|
|
91
94
|
append.push({ timestamp: new Date().toISOString(), runId: input.runId, event: 'run-chart-cell', data: {
|
|
92
95
|
device: input.device, stopKey: input.stopKey, observed: input.observed.slice(0, 240), verdict: input.verdict,
|
|
93
|
-
action: input.action, handoff: input.handoff, why: input.why.slice(0, 240), readStopKeys: input.readStopKeys.slice(-RUN_CHART_READ_CELLS),
|
|
96
|
+
action: input.action, handoff: input.handoff ?? 'none', why: input.why.slice(0, 240), readStopKeys: input.readStopKeys.slice(-RUN_CHART_READ_CELLS),
|
|
94
97
|
...(input.waitCount === undefined ? {} : { waitCount: input.waitCount }),
|
|
95
98
|
...(input.failureClass === undefined ? {} : { failureClass: input.failureClass }),
|
|
96
99
|
} });
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
1
|
+
import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, statSync, truncateSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
2
3
|
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
3
4
|
import { parse as parseYaml } from 'yaml';
|
|
4
5
|
import { refuseProductionLedgerWriteInTest } from '../harness/ledger-write-guard.js';
|
|
@@ -32,9 +33,15 @@ export interface RunLedgerEntry {
|
|
|
32
33
|
shardIdentityReadFailure?: RunShardIdentityReadFailure;
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
/** Stable signature for an ordered observed route; callers record the evidence basis separately. */
|
|
37
|
+
export function pathSignatureOf(steps: readonly { readonly from: string; readonly to: string; readonly skipped?: readonly string[] }[]): string {
|
|
38
|
+
return createHash('sha256').update(JSON.stringify(steps.map(step => [step.from, step.to, step.skipped ?? []]))).digest('hex').slice(0, 12);
|
|
39
|
+
}
|
|
40
|
+
|
|
35
41
|
const RUN_GRAPH_STEP_EVENTS = new Set([
|
|
36
42
|
'node-enter', 'node-exit', 'edge-taken', 'node-skipped', 'node-added', 'edge-rerouted',
|
|
37
43
|
'unit-expanded', 'unit-collapsed', 'pipeline-node-entry', 'pipeline-node-exit', 'graph-edge-taken',
|
|
44
|
+
'graph.path',
|
|
38
45
|
]);
|
|
39
46
|
|
|
40
47
|
function isRunGraphStepEvent(entry: RunLedgerEntry): boolean {
|
|
@@ -192,6 +199,7 @@ export interface RunOriginData extends Record<string, unknown> {
|
|
|
192
199
|
}
|
|
193
200
|
|
|
194
201
|
export type RunLedgerWriter = (entry: RunLedgerEntry) => void;
|
|
202
|
+
export type RunLedgerBatchWriter = (entries: readonly RunLedgerEntry[]) => void;
|
|
195
203
|
export type RunLedgerReader = (path: string, encoding?: 'utf8') => string | Buffer;
|
|
196
204
|
|
|
197
205
|
/** A live PTY lacks its producer correlation id, or that id lacks an observable JSONL ledger. */
|
|
@@ -820,6 +828,48 @@ export function appendRunLedgerEntry(entry: RunLedgerEntry, dir = runLedgerDir()
|
|
|
820
828
|
}
|
|
821
829
|
}
|
|
822
830
|
|
|
831
|
+
/** Append one run's structural graph events as a rollback-protected ledger batch. */
|
|
832
|
+
export function appendRunLedgerEntries(entries: readonly RunLedgerEntry[], dir = runLedgerDir()): void {
|
|
833
|
+
if (entries.length === 0) return;
|
|
834
|
+
const runId = entries[0]!.runId;
|
|
835
|
+
if (!runId || entries.some((entry) => entry.runId !== runId)) throw new Error('run ledger batch must have one runId');
|
|
836
|
+
if (entries.some((entry) => !isRunGraphStepEvent(entry))) throw new Error('run ledger batch accepts graph-step events only');
|
|
837
|
+
if (refuseProductionLedgerWriteInTest(dir, 'run-ledger')) return;
|
|
838
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
839
|
+
const live = runLedgerPath(runId, dir);
|
|
840
|
+
const devProject = process.env.ELANOUS_DEV_PROJECT;
|
|
841
|
+
withRunLedgerLock(dir, runId, () => {
|
|
842
|
+
restoreArchivedRunLedger(dir, runId);
|
|
843
|
+
let lastSequence = lastRunGraphEventSequence(runId, dir);
|
|
844
|
+
const rows = entries.map((entry) => {
|
|
845
|
+
const sequenced = sequenceRunGraphEvent(entry, lastSequence);
|
|
846
|
+
lastSequence = sequenced.seq ?? (typeof sequenced.data.seq === 'number' ? sequenced.data.seq : lastSequence);
|
|
847
|
+
return sequenced.devProject === undefined && typeof devProject === 'string' && devProject.startsWith('prj-')
|
|
848
|
+
? { ...sequenced, devProject }
|
|
849
|
+
: sequenced;
|
|
850
|
+
});
|
|
851
|
+
const lines = rows.map((row) => `${JSON.stringify(row)}\n`).join('');
|
|
852
|
+
const appendLine = separateAppendedLedgerLine(live, lines);
|
|
853
|
+
const existed = existsSync(live);
|
|
854
|
+
const sizeBefore = existed ? statSync(live).size : 0;
|
|
855
|
+
try {
|
|
856
|
+
appendFileSync(live, appendLine, 'utf8');
|
|
857
|
+
} catch (error) {
|
|
858
|
+
try {
|
|
859
|
+
if (existed) truncateSync(live, sizeBefore);
|
|
860
|
+
else if (existsSync(live)) unlinkSync(live);
|
|
861
|
+
} catch (rollbackError) {
|
|
862
|
+
throw new AggregateError([error, rollbackError], `run ledger batch append and rollback failed: ${runId}`);
|
|
863
|
+
}
|
|
864
|
+
throw error;
|
|
865
|
+
}
|
|
866
|
+
});
|
|
867
|
+
for (const entry of entries) {
|
|
868
|
+
try { recordRunRequestVsEffectiveFromLedger(runId, dir, entry); }
|
|
869
|
+
catch { /* This comparison is observation and cannot fail a committed batch. */ }
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
|
|
823
873
|
/** Caller decision inside `appendRunLedgerEntryChecked`: either `append` exactly one entry, or skip with `result`. */
|
|
824
874
|
export type RunLedgerCheckedAppendDecision<T> =
|
|
825
875
|
| { append: false; result: T }
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { GraphTemplate } from './graph-templates.js';
|
|
2
|
+
import type { GraphTemplateSpec } from './graph-yaml.js';
|
|
3
|
+
import type { RunLedgerEntry } from './run-ledger.js';
|
|
4
|
+
|
|
5
|
+
type RuntimeOverlayGraph = Pick<GraphTemplate, 'nodes' | 'edges'> | Pick<GraphTemplateSpec, 'nodes' | 'edges'>;
|
|
6
|
+
|
|
7
|
+
const DEFAULT_OUTCOME = '$default';
|
|
8
|
+
const ABSENT_ROUTE = '$absent';
|
|
9
|
+
|
|
10
|
+
export interface RuntimeOverlayRunStepsInput {
|
|
11
|
+
readonly runId: string;
|
|
12
|
+
readonly timestamp: string;
|
|
13
|
+
readonly before: RuntimeOverlayGraph;
|
|
14
|
+
readonly after: RuntimeOverlayGraph;
|
|
15
|
+
readonly overlayIds: readonly string[];
|
|
16
|
+
readonly round: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface GraphRoute {
|
|
20
|
+
readonly from: string;
|
|
21
|
+
readonly outcome: string;
|
|
22
|
+
readonly to: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function routesOf(graph: RuntimeOverlayGraph): Map<string, GraphRoute> {
|
|
26
|
+
const routes = new Map<string, GraphRoute>();
|
|
27
|
+
if (!Array.isArray(graph.edges)) {
|
|
28
|
+
const compiledEdges = graph.edges as Readonly<Record<string, readonly string[]>>;
|
|
29
|
+
for (const [from, destinations] of Object.entries(compiledEdges)) {
|
|
30
|
+
for (const [index, to] of destinations.entries()) {
|
|
31
|
+
routes.set(`${from}\u0000${index}`, { from, outcome: String(index), to: String(to) });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return routes;
|
|
35
|
+
}
|
|
36
|
+
for (const edge of graph.edges) {
|
|
37
|
+
if (edge.to !== undefined) {
|
|
38
|
+
routes.set(`${edge.from}\u0000${DEFAULT_OUTCOME}`, { from: edge.from, outcome: DEFAULT_OUTCOME, to: edge.to });
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
for (const [outcome, to] of Object.entries(edge.map ?? {})) {
|
|
42
|
+
routes.set(`${edge.from}\u0000${outcome}`, { from: edge.from, outcome, to: String(to) });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return routes;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function reason(input: RuntimeOverlayRunStepsInput): string {
|
|
49
|
+
return `runtime overlay ${input.overlayIds.join(', ')} applied at round ${input.round}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Convert an already accepted runtime overlay into the existing structural ledger vocabulary. */
|
|
53
|
+
export function runtimeOverlayRunSteps(input: RuntimeOverlayRunStepsInput): RunLedgerEntry[] {
|
|
54
|
+
if (input.overlayIds.length === 0) return [];
|
|
55
|
+
const detail = reason(input);
|
|
56
|
+
const beforeNodes = new Set(input.before.nodes.map((node) => node.nodeId));
|
|
57
|
+
const entries: RunLedgerEntry[] = input.after.nodes
|
|
58
|
+
.filter((node) => !beforeNodes.has(node.nodeId))
|
|
59
|
+
.map((node) => ({
|
|
60
|
+
timestamp: input.timestamp,
|
|
61
|
+
runId: input.runId,
|
|
62
|
+
event: 'node-added',
|
|
63
|
+
data: {
|
|
64
|
+
node: node.nodeId,
|
|
65
|
+
kind: node.kind,
|
|
66
|
+
decider: 'runtime-overlay',
|
|
67
|
+
reason: detail,
|
|
68
|
+
trigger: { overlayIds: input.overlayIds, round: input.round },
|
|
69
|
+
},
|
|
70
|
+
}));
|
|
71
|
+
|
|
72
|
+
const beforeRoutes = routesOf(input.before);
|
|
73
|
+
const afterRoutes = routesOf(input.after);
|
|
74
|
+
const changedRoutes = [...afterRoutes.entries()]
|
|
75
|
+
.filter(([key, route]) => beforeRoutes.get(key)?.to !== route.to)
|
|
76
|
+
.sort(([left], [right]) => left.localeCompare(right));
|
|
77
|
+
for (const [key, route] of changedRoutes) {
|
|
78
|
+
entries.push({
|
|
79
|
+
timestamp: input.timestamp,
|
|
80
|
+
runId: input.runId,
|
|
81
|
+
event: 'edge-rerouted',
|
|
82
|
+
data: {
|
|
83
|
+
from: route.from,
|
|
84
|
+
outcome: route.outcome,
|
|
85
|
+
to: route.to,
|
|
86
|
+
was: beforeRoutes.get(key)?.to ?? ABSENT_ROUTE,
|
|
87
|
+
decider: 'runtime-overlay',
|
|
88
|
+
reason: detail,
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return entries;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export { ABSENT_ROUTE, DEFAULT_OUTCOME };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Stable TDD terminal-evidence tags shared by the producer and Pod result mapper. */
|
|
2
|
+
export const TDD_RED_TAG = 'tdd-red' as const;
|
|
3
|
+
export const TDD_GREEN_TAG = 'tdd-green' as const;
|
|
4
|
+
export const TDD_RECORD_TAGS = [TDD_RED_TAG, TDD_GREEN_TAG] as const;
|
|
5
|
+
export type TddRecordTag = typeof TDD_RECORD_TAGS[number];
|
|
6
|
+
|
|
7
|
+
export function isTddRecordTag(value: unknown): value is TddRecordTag {
|
|
8
|
+
return value === TDD_RED_TAG || value === TDD_GREEN_TAG;
|
|
9
|
+
}
|
|
@@ -28,6 +28,8 @@ export interface TestScenarioRequestInput {
|
|
|
28
28
|
readonly registeredMethodologies: readonly string[];
|
|
29
29
|
/** 라이브 명령의 «출처» — 보통 저작 중인 골 문서의 경로. 없으면 measured 로 못 간다. */
|
|
30
30
|
readonly commandSource?: string;
|
|
31
|
+
/** Multiple authoritative source candidates are retained for review, never chosen by priority. */
|
|
32
|
+
readonly commandSourceCandidates?: readonly string[];
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
export type TestScenarioLiveStatus = 'measured' | 'unmeasured';
|
|
@@ -61,7 +63,25 @@ export function requestTestScenario(input: TestScenarioRequestInput): TestScenar
|
|
|
61
63
|
const canLaunch = input.launch !== null
|
|
62
64
|
&& (input.launch.port !== undefined || (input.launch.entrypoint ?? '').trim() !== '');
|
|
63
65
|
const methodologyAvailable = input.registeredMethodologies.includes(LAUNCH_METHODOLOGY);
|
|
64
|
-
const
|
|
66
|
+
const commandSourceCandidates = [...new Set((input.commandSourceCandidates ?? [])
|
|
67
|
+
.map((candidate) => candidate.trim())
|
|
68
|
+
.filter((candidate) => /^[^:\s]+:[^:\s]+$/u.test(candidate)))];
|
|
69
|
+
const explicitCommandSource = input.commandSource?.trim() || undefined;
|
|
70
|
+
const candidateConflict = commandSourceCandidates.length > 1
|
|
71
|
+
|| (commandSourceCandidates.length === 1 && explicitCommandSource !== undefined && commandSourceCandidates[0] !== explicitCommandSource);
|
|
72
|
+
const commandSource = candidateConflict
|
|
73
|
+
? undefined
|
|
74
|
+
: explicitCommandSource || commandSourceCandidates[0];
|
|
75
|
+
// Ambiguous declarations must use file:key tokens. Preserve a legacy explicit
|
|
76
|
+
// document path as a labeled source token rather than emitting a malformed item.
|
|
77
|
+
const explicitAmbiguityCandidate = explicitCommandSource
|
|
78
|
+
? (/^[^:\s]+:[^:\s]+$/u.test(explicitCommandSource) ? explicitCommandSource : `${explicitCommandSource}:explicit-command-source`)
|
|
79
|
+
: undefined;
|
|
80
|
+
const ambiguityCandidates = [...new Set([
|
|
81
|
+
...commandSourceCandidates,
|
|
82
|
+
...(candidateConflict && explicitAmbiguityCandidate ? [explicitAmbiguityCandidate] : []),
|
|
83
|
+
])];
|
|
84
|
+
const commandSourceAmbiguous = candidateConflict || (!commandSource && commandSourceCandidates.length > 1);
|
|
65
85
|
|
|
66
86
|
if (canLaunch && methodologyAvailable && commandSource) {
|
|
67
87
|
return {
|
|
@@ -76,15 +96,17 @@ export function requestTestScenario(input: TestScenarioRequestInput): TestScenar
|
|
|
76
96
|
}
|
|
77
97
|
|
|
78
98
|
// ⛔ 사유를 «가장 바깥 원인»으로 고른다 — 선언이 없으면 방법론·명령출처를 따질 자리가 아니다.
|
|
79
|
-
const reason =
|
|
80
|
-
? '
|
|
99
|
+
const reason = commandSourceAmbiguous
|
|
100
|
+
? 'ambiguous-command-source'
|
|
101
|
+
: !canLaunch
|
|
102
|
+
? 'no-launch-declaration'
|
|
81
103
|
: !methodologyAvailable
|
|
82
104
|
? 'no-methodology'
|
|
83
105
|
: 'no-command-source';
|
|
84
106
|
return {
|
|
85
107
|
sections: [
|
|
86
108
|
scenarioSection(UNKNOWN_DELIVERABLE, input.acceptanceCriteria),
|
|
87
|
-
unmeasuredLiveSection(reason),
|
|
109
|
+
unmeasuredLiveSection(reason, reason === 'ambiguous-command-source' ? ambiguityCandidates : [], reason === 'ambiguous-command-source' && candidateConflict ? explicitCommandSource : undefined),
|
|
88
110
|
resultReportSection(),
|
|
89
111
|
],
|
|
90
112
|
deliverableType: UNKNOWN_DELIVERABLE,
|
|
@@ -138,13 +160,22 @@ function measuredLiveSection(methodology: string, commandSource: string, launch:
|
|
|
138
160
|
}
|
|
139
161
|
|
|
140
162
|
/** L 층(측정 불가) — ⛔ 방법론·명령출처·기동·눈·기대를 «싣지 않는다»(파서가 금지한다). */
|
|
141
|
-
function unmeasuredLiveSection(reason: string): string {
|
|
163
|
+
function unmeasuredLiveSection(reason: string, candidates: readonly string[] = [], explicitSource?: string): string {
|
|
164
|
+
const prerequisite = reason === 'no-launch-declaration'
|
|
165
|
+
? '골이 `## 산출물을 어떻게 켜나` 절에 `Port:` 또는 `Entrypoint:` 를 선언했으면 됐다'
|
|
166
|
+
: reason === 'ambiguous-command-source'
|
|
167
|
+
? '골이 후보 중 하나를 권위 있는 명령 출처로 확정했으면 됐다'
|
|
168
|
+
: reason === 'no-methodology'
|
|
169
|
+
? '호출자가 등록 방법론 레지스트리에 `deliverable-verify` 를 등록했으면 됐다'
|
|
170
|
+
: '골이 권위 있는 명령 출처를 선언했으면 됐다';
|
|
142
171
|
return [
|
|
143
172
|
'## L. 라이브',
|
|
144
173
|
'',
|
|
145
174
|
'### 상태 `unmeasured`',
|
|
146
175
|
`- 사유: \`${reason}\``,
|
|
147
|
-
'-
|
|
176
|
+
...(reason.startsWith('ambiguous-') ? [`- 후보 목록: ${candidates.join(', ')}`] : []),
|
|
177
|
+
...(explicitSource ? [`- 원래 명시 출처(후보와 별도): \`${explicitSource}\``] : []),
|
|
178
|
+
`- 무엇이 있었으면 됐나: ${prerequisite}`,
|
|
148
179
|
'',
|
|
149
180
|
'> ⚠️ ⛔ 「측정 불가」는 「결함 없음」이 «아니다». 이 골은 라이브 층을 «안 본 채» 끝난다.',
|
|
150
181
|
].join('\n');
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
|
|
5
|
+
import {
|
|
6
|
+
computeReceiptKey,
|
|
7
|
+
gateEnvFingerprint,
|
|
8
|
+
gateLockfileHash,
|
|
9
|
+
GATE_RECEIPT_SCHEMA,
|
|
10
|
+
loadGateReceipts,
|
|
11
|
+
saveGateReceipt,
|
|
12
|
+
type GateReceipt,
|
|
13
|
+
type GateReceiptIdentity,
|
|
14
|
+
} from './gate-receipt-registry.js';
|
|
15
|
+
|
|
16
|
+
export interface TrainGateReceiptInput {
|
|
17
|
+
repo: string;
|
|
18
|
+
commit: string;
|
|
19
|
+
baseSha: string;
|
|
20
|
+
changedFiles: readonly string[];
|
|
21
|
+
deletedFiles?: readonly string[];
|
|
22
|
+
scenarioTests?: readonly string[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface PassedSelfGateReceiptInput extends TrainGateReceiptInput {
|
|
26
|
+
/** Exact artifact emitted by `self gate --artifact-dir`; its pass and typecheck binding are revalidated here. */
|
|
27
|
+
summaryPath: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type Execute = (script: string, cwd: string) => { status: number | null; stdout: string; stderr: string };
|
|
31
|
+
|
|
32
|
+
const SHA40 = /^[0-9a-f]{40}$/i;
|
|
33
|
+
const TEST_FILE = /\.test\.[cm]?[jt]sx?$/;
|
|
34
|
+
const quote = (value: string) => `'${value.replaceAll("'", `'\\''`)}'`;
|
|
35
|
+
|
|
36
|
+
function registryPath(repo: string): string | undefined {
|
|
37
|
+
const result = spawnSync('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], { cwd: repo, encoding: 'utf8', timeout: 10_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
|
|
38
|
+
const commonDir = (result.stdout ?? '').trim();
|
|
39
|
+
return result.status === 0 && commonDir ? join(commonDir, 'elanous-host-regate', 'gate-receipts.json') : undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function identityFor(input: TrainGateReceiptInput, checks?: readonly string[]): GateReceiptIdentity | undefined {
|
|
43
|
+
if (!SHA40.test(input.commit) || !SHA40.test(input.baseSha)) return undefined;
|
|
44
|
+
const bun = spawnSync('bun', ['--version'], { cwd: input.repo, encoding: 'utf8', timeout: 10_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
|
|
45
|
+
const bunVersion = (bun.stdout ?? '').trim();
|
|
46
|
+
if (bun.status !== 0 || !bunVersion) return undefined;
|
|
47
|
+
return {
|
|
48
|
+
headCommit: input.commit,
|
|
49
|
+
baseCommit: input.baseSha,
|
|
50
|
+
bunVersion,
|
|
51
|
+
lockfileHash: gateLockfileHash(input.repo),
|
|
52
|
+
radiusFiles: [...new Set(input.changedFiles)].sort(),
|
|
53
|
+
checks: checks ? [...checks] : [
|
|
54
|
+
'train:changed-file-typecheck',
|
|
55
|
+
...(input.scenarioTests?.length || input.changedFiles.some((file) => TEST_FILE.test(file) && !input.deletedFiles?.includes(file)) ? ['train:deterministic-tests'] : []),
|
|
56
|
+
...(input.scenarioTests ?? []).map((file) => `train:scenario-test:${file}`),
|
|
57
|
+
'train:pwa-build',
|
|
58
|
+
],
|
|
59
|
+
envFingerprint: gateEnvFingerprint(process.env),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Record only after revalidating the exact self-gate summary, then independently measure changed-only interference. */
|
|
64
|
+
export async function recordPassedSelfGateReceipt(
|
|
65
|
+
input: PassedSelfGateReceiptInput,
|
|
66
|
+
detect: (files: readonly string[]) => Promise<{ status: 'no-interference' | 'interference' | 'unmeasurable' }> = async (files) => {
|
|
67
|
+
const { detectTestInterference } = await import('../../scripts/detect-test-interference.js');
|
|
68
|
+
return detectTestInterference(files);
|
|
69
|
+
},
|
|
70
|
+
): Promise<GateReceipt | undefined> {
|
|
71
|
+
let summary: Record<string, unknown>;
|
|
72
|
+
try { summary = JSON.parse(readFileSync(input.summaryPath, 'utf8')) as Record<string, unknown>; }
|
|
73
|
+
catch { return undefined; }
|
|
74
|
+
const typecheck = summary.typecheck as Record<string, unknown> | undefined;
|
|
75
|
+
const cohort = Array.isArray(summary.cohort) ? summary.cohort.filter((file): file is string => typeof file === 'string') : [];
|
|
76
|
+
const changedTestFiles = [...new Set(input.changedFiles.filter((file) => TEST_FILE.test(file)
|
|
77
|
+
&& !input.deletedFiles?.includes(file)))].sort();
|
|
78
|
+
if (summary.head40 !== input.commit || summary.base40 !== input.baseSha || summary.exitCode !== 0
|
|
79
|
+
|| !['passed', 'pass'].includes(String(summary.verdict)) || summary.introduced !== 0
|
|
80
|
+
|| summary.unknown !== 0 || summary.unrunImporters !== 0
|
|
81
|
+
|| typecheck?.status !== 'passed' || typecheck.base40 !== input.baseSha
|
|
82
|
+
|| typecheck.head40 !== input.commit || typecheck.exitCode !== 0 || typecheck.newErrors !== 0
|
|
83
|
+
|| changedTestFiles.some((file) => !cohort.includes(file))) return undefined;
|
|
84
|
+
const testFiles = [...new Set(input.changedFiles.filter((file) => TEST_FILE.test(file)
|
|
85
|
+
&& !input.deletedFiles?.includes(file)))].sort();
|
|
86
|
+
if (!testFiles.length) return undefined;
|
|
87
|
+
const interference = await detect(testFiles);
|
|
88
|
+
if (interference.status !== 'no-interference') return undefined;
|
|
89
|
+
const identity = identityFor(input, ['test-interference:changed-only']);
|
|
90
|
+
const path = process.env.ELANOUS_GATE_RECEIPT_REGISTRY_PATH || registryPath(input.repo);
|
|
91
|
+
if (!identity || !path) return undefined;
|
|
92
|
+
const receipt = passedEvidenceReceipt(identity, input.changedFiles);
|
|
93
|
+
try { saveGateReceipt(path, receipt); }
|
|
94
|
+
catch { return undefined; }
|
|
95
|
+
return receipt;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function scriptFor(input: TrainGateReceiptInput, files: readonly string[]): string {
|
|
99
|
+
const tests = [...new Set([
|
|
100
|
+
...files.filter((file) => TEST_FILE.test(file) && !input.deletedFiles?.includes(file)),
|
|
101
|
+
...(input.scenarioTests ?? []),
|
|
102
|
+
])];
|
|
103
|
+
return [
|
|
104
|
+
`TSC_BASE_REF=${quote(input.baseSha)} bun scripts/ci-typecheck-changed.ts --local`,
|
|
105
|
+
...(tests.length ? [`bun run test:deterministic ${tests.map(quote).join(' ')}`] : []),
|
|
106
|
+
`bun scripts/ci-pwa-build-gate.ts --changed-files ${files.map(quote).join(' ')}`,
|
|
107
|
+
].join(' && ');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function passedEvidenceReceipt(identity: GateReceiptIdentity, files: readonly string[]): GateReceipt {
|
|
111
|
+
const receiptIdentity: GateReceiptIdentity = { ...identity, radiusFiles: [...new Set(files)].sort() };
|
|
112
|
+
return {
|
|
113
|
+
...receiptIdentity,
|
|
114
|
+
schema: GATE_RECEIPT_SCHEMA,
|
|
115
|
+
key: computeReceiptKey(receiptIdentity, 'passed'),
|
|
116
|
+
verdict: 'passed',
|
|
117
|
+
savedAt: new Date().toISOString(),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function runTrainGateWithReceipts(input: TrainGateReceiptInput, execute: Execute = (script, cwd) => {
|
|
122
|
+
const result = spawnSync('sh', ['-c', script], { cwd, encoding: 'utf8', timeout: 120 * 60_000, maxBuffer: 32 * 1024 * 1024 });
|
|
123
|
+
return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '' };
|
|
124
|
+
}): { status: number | null; stdout: string; stderr: string } {
|
|
125
|
+
const context = identityFor(input);
|
|
126
|
+
const path = process.env.ELANOUS_GATE_RECEIPT_REGISTRY_PATH || registryPath(input.repo);
|
|
127
|
+
if (!context || !path) return execute(scriptFor(input, input.changedFiles), input.repo);
|
|
128
|
+
|
|
129
|
+
const changedFiles = [...new Set(input.changedFiles)].sort();
|
|
130
|
+
const result = execute(scriptFor(input, changedFiles), input.repo);
|
|
131
|
+
if (result.status === 0 && changedFiles.length) {
|
|
132
|
+
try { saveGateReceipt(path, passedEvidenceReceipt(context, changedFiles)); }
|
|
133
|
+
catch { /* A receipt is an optimization; a passed gate remains passed if persistence fails. */ }
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (import.meta.main) {
|
|
139
|
+
const raw = process.argv[2];
|
|
140
|
+
try {
|
|
141
|
+
if (!raw) throw new Error('train gate receipt input is required');
|
|
142
|
+
const input = JSON.parse(raw) as TrainGateReceiptInput & Partial<PassedSelfGateReceiptInput>;
|
|
143
|
+
if (input.summaryPath) {
|
|
144
|
+
const receipt = await recordPassedSelfGateReceipt(input as PassedSelfGateReceiptInput);
|
|
145
|
+
const registryFile = process.env.ELANOUS_GATE_RECEIPT_REGISTRY_PATH;
|
|
146
|
+
if (registryFile) {
|
|
147
|
+
const registry = loadGateReceipts(registryFile);
|
|
148
|
+
process.stdout.write(`${String.fromCharCode(10)}__GATE_RECEIPTS__${Buffer.from(JSON.stringify(registry)).toString('base64')}${String.fromCharCode(10)}`);
|
|
149
|
+
}
|
|
150
|
+
if (!receipt) process.exitCode = 1;
|
|
151
|
+
} else {
|
|
152
|
+
const result = runTrainGateWithReceipts({ ...input, repo: process.cwd() });
|
|
153
|
+
process.stdout.write(result.stdout);
|
|
154
|
+
process.stderr.write(result.stderr);
|
|
155
|
+
const registryFile = process.env.ELANOUS_GATE_RECEIPT_REGISTRY_PATH;
|
|
156
|
+
if (registryFile) {
|
|
157
|
+
const registry = loadGateReceipts(registryFile);
|
|
158
|
+
process.stdout.write(`${String.fromCharCode(10)}__GATE_RECEIPTS__${Buffer.from(JSON.stringify(registry)).toString('base64')}${String.fromCharCode(10)}`);
|
|
159
|
+
}
|
|
160
|
+
process.exitCode = result.status ?? 1;
|
|
161
|
+
}
|
|
162
|
+
} catch (error) {
|
|
163
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
164
|
+
process.exitCode = 1;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
* Unlike `dispatchHeavyCheck` it never falls back to a local run: a busy host or an infra failure is «unmeasured».
|
|
4
4
|
* The only local commands are git (cat-file · rev-parse · push · diff). */
|
|
5
5
|
import { debug } from '../debug/log.js';
|
|
6
|
+
import { spawnSync } from 'node:child_process';
|
|
6
7
|
import { parseGateScenario, readGateScenarioFile } from './gate-scenario.js';
|
|
7
8
|
import { getDefaultLogStore } from '../mss/logging/log-store.js';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
|
|
11
|
+
import { saveGateReceipt, type GateReceipt } from './gate-receipt-registry.js';
|
|
8
12
|
import {
|
|
9
13
|
gateRemoteHostCap, realGateRemoteRunner, resolveGateRemoteSettings, runOnRemote,
|
|
10
14
|
type GateRemoteRunner, type GateRemoteSettings, type RemoteRunOutcome,
|
|
@@ -30,6 +34,51 @@ export interface TrainGateInput {
|
|
|
30
34
|
|
|
31
35
|
export interface TrainGateResult { outcome: TrainGateOutcome; host: string; ms?: number; rc?: number; reason?: string }
|
|
32
36
|
|
|
37
|
+
const GATE_RECEIPTS_MARKER = String.fromCharCode(10) + '__GATE_RECEIPTS__';
|
|
38
|
+
|
|
39
|
+
function sharedGateReceiptPath(repo: string, runner: GateRemoteRunner): string | undefined {
|
|
40
|
+
try {
|
|
41
|
+
const result = runner.local('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], repo);
|
|
42
|
+
const commonDir = result.stdout.trim();
|
|
43
|
+
return result.rc === 0 && commonDir ? join(commonDir, 'elanous-host-regate', 'gate-receipts.json') : undefined;
|
|
44
|
+
} catch { return undefined; }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The exact persistent registry used by local train receipt merging. */
|
|
48
|
+
export function gateReceiptRegistryPathForRepo(repo: string): string | undefined {
|
|
49
|
+
const result = spawnSync('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], {
|
|
50
|
+
cwd: repo, encoding: 'utf8', timeout: 10_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER,
|
|
51
|
+
});
|
|
52
|
+
const commonDir = (result.stdout ?? '').trim();
|
|
53
|
+
return result.status === 0 && commonDir ? join(commonDir, 'elanous-host-regate', 'gate-receipts.json') : undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Merge the existing remote-writer marker into the local common-dir registry. Invalid rows fail closed. */
|
|
57
|
+
export function mergeGateReceiptRegistryPayload(payload: string, path: string): number {
|
|
58
|
+
let saved = 0;
|
|
59
|
+
try {
|
|
60
|
+
const rows = JSON.parse(Buffer.from(payload, 'base64').toString('utf8')) as Record<string, unknown>;
|
|
61
|
+
for (const [key, value] of Object.entries(rows)) {
|
|
62
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) continue;
|
|
63
|
+
const receipt = value as GateReceipt;
|
|
64
|
+
if (receipt.key !== key) continue;
|
|
65
|
+
try { saveGateReceipt(path, receipt); saved++; }
|
|
66
|
+
catch { /* Invalid remote records are discarded; local gates remain fail-open. */ }
|
|
67
|
+
}
|
|
68
|
+
} catch { /* A malformed response never changes the measured gate verdict. */ }
|
|
69
|
+
return saved;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function mergeReturnedReceipts(outcome: RemoteRunOutcome, path: string | undefined): RemoteRunOutcome {
|
|
73
|
+
if (outcome.kind !== 'ran' || outcome.rc !== 0 || !path) return outcome;
|
|
74
|
+
const stdout = outcome.stdout.toString('utf8');
|
|
75
|
+
const marker = stdout.lastIndexOf(GATE_RECEIPTS_MARKER);
|
|
76
|
+
if (marker < 0) return outcome;
|
|
77
|
+
const payload = stdout.slice(marker + GATE_RECEIPTS_MARKER.length).trim();
|
|
78
|
+
mergeGateReceiptRegistryPayload(payload, path);
|
|
79
|
+
return { ...outcome, stdout: Buffer.from(stdout.slice(0, marker)) };
|
|
80
|
+
}
|
|
81
|
+
|
|
33
82
|
export interface TrainGateObservation {
|
|
34
83
|
host: string; commit: string; baseSha: string; outcome: TrainGateOutcome;
|
|
35
84
|
rc?: number; ms?: number; reason?: string; changedFiles: number;
|
|
@@ -42,22 +91,6 @@ export interface TrainGateDeps {
|
|
|
42
91
|
observe?: (entry: TrainGateObservation) => void;
|
|
43
92
|
}
|
|
44
93
|
|
|
45
|
-
const quote = (value: string) => `'${value.replaceAll("'", `'\\''`)}'`;
|
|
46
|
-
const TEST_FILE = /\.test\.[cm]?[jt]sx?$/;
|
|
47
|
-
|
|
48
|
-
/** The host-side shell body: each step runs only if the one before it passed. Exported for tests. */
|
|
49
|
-
export function trainGateScript(baseSha: string, changedFiles: readonly string[], deleted: ReadonlySet<string> = new Set(), scenarioTests: readonly string[] = []): string {
|
|
50
|
-
// A deleted test file is a changed path (tsc/PWA reach) but not something to run.
|
|
51
|
-
const changedTests = changedFiles.filter((file) => TEST_FILE.test(file) && !deleted.has(file));
|
|
52
|
-
const tests = scenarioTests.length ? [...new Set([...changedTests, ...scenarioTests])] : changedTests;
|
|
53
|
-
const steps = [
|
|
54
|
-
`TSC_BASE_REF=${quote(baseSha)} bun scripts/ci-typecheck-changed.ts --local`,
|
|
55
|
-
...(tests.length ? [`bun run test:deterministic ${tests.map(quote).join(' ')}`] : []),
|
|
56
|
-
`bun scripts/ci-pwa-build-gate.ts --changed-files ${changedFiles.map(quote).join(' ')}`,
|
|
57
|
-
];
|
|
58
|
-
return steps.join(' && ');
|
|
59
|
-
}
|
|
60
|
-
|
|
61
94
|
async function loadSettings(): Promise<GateRemoteSettings> {
|
|
62
95
|
try {
|
|
63
96
|
const { getUserConfig } = await import('../user-config.js');
|
|
@@ -76,6 +109,10 @@ export const TRAIN_GATE_HOST = 'node-b';
|
|
|
76
109
|
|
|
77
110
|
export async function runTrainGateOnHost(input: TrainGateInput, runner: GateRemoteRunner = realGateRemoteRunner, deps: TrainGateDeps = {}): Promise<TrainGateResult> {
|
|
78
111
|
const settings = input.settings ?? await loadSettings();
|
|
112
|
+
const receiptPath = sharedGateReceiptPath(input.repo, runner);
|
|
113
|
+
// Each remote full gate writes into a fresh scratch registry; returned rows merge into the local shared registry.
|
|
114
|
+
// No existing registry contents are needed for receipt registration.
|
|
115
|
+
const payloadFiles = receiptPath ? [{ env: 'ELANOUS_GATE_RECEIPT_REGISTRY_PATH', content: '{}' }] : undefined;
|
|
79
116
|
const host = settings.host;
|
|
80
117
|
const hostCap = gateRemoteHostCap(settings, host);
|
|
81
118
|
let scenarioTests: string[] = [];
|
|
@@ -110,14 +147,21 @@ export async function runTrainGateOnHost(input: TrainGateInput, runner: GateRemo
|
|
|
110
147
|
const sleep = deps.sleep ?? ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)));
|
|
111
148
|
const now = deps.now ?? Date.now;
|
|
112
149
|
const deadline = now() + settings.slotWaitSeconds * 1000;
|
|
113
|
-
const script = trainGateScript(input.baseSha, input.changedFiles, new Set(input.deletedFiles ?? []), scenarioTests);
|
|
114
150
|
let outcome: RemoteRunOutcome;
|
|
115
151
|
for (;;) {
|
|
116
152
|
try {
|
|
117
153
|
outcome = runOnRemote({
|
|
118
154
|
repo: input.repo, host, mirror: settings.mirror, commit: input.commit, refs: [input.baseSha],
|
|
119
|
-
argv: ['
|
|
155
|
+
argv: ['bun', 'src/self-implement/train-gate-receipt.ts', JSON.stringify({
|
|
156
|
+
repo: input.repo,
|
|
157
|
+
commit: input.commit,
|
|
158
|
+
baseSha: input.baseSha,
|
|
159
|
+
changedFiles: input.changedFiles,
|
|
160
|
+
deletedFiles: input.deletedFiles ?? [],
|
|
161
|
+
scenarioTests,
|
|
162
|
+
})], installPwa: true, hostCap, ...(payloadFiles ? { payloadFiles } : {}),
|
|
120
163
|
}, runner);
|
|
164
|
+
outcome = mergeReturnedReceipts(outcome, receiptPath);
|
|
121
165
|
} catch (error) {
|
|
122
166
|
outcome = { kind: 'infra', reason: `exception: ${error instanceof Error ? error.message : String(error)}` };
|
|
123
167
|
}
|
package/src/session/chat.ts
CHANGED
|
@@ -20,7 +20,7 @@ import { debug } from '../debug/log.js';
|
|
|
20
20
|
import { createRequestSizeGuard, formatRequestSizeStatus, type RequestSizeGuard } from './request-size-guard.js';
|
|
21
21
|
import type { InputSourceKind } from '../input/input-source-kind.js';
|
|
22
22
|
import {
|
|
23
|
-
|
|
23
|
+
getProviderForConfigAsync, streamLLMWithTools, type LLMMessage, type LLMOpts, type LLMProvider,
|
|
24
24
|
type LLMToolSpec, type ContentBlock,
|
|
25
25
|
} from '../llm.js';
|
|
26
26
|
import type { UserConfig } from '../user-config.js';
|
|
@@ -407,7 +407,7 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
|
|
|
407
407
|
reasoningEffort: llmOpts?.reasoningEffort ?? null,
|
|
408
408
|
});
|
|
409
409
|
}
|
|
410
|
-
const provider = opts.provider ??
|
|
410
|
+
const provider = opts.provider ?? await getProviderForConfigAsync(opts.userConfig, llmOpts?.model);
|
|
411
411
|
|
|
412
412
|
// 2) Assemble, trim, call. When images are attached for THIS turn,
|
|
413
413
|
// swap the string content of the latest user message for
|
|
@@ -511,8 +511,9 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
|
|
|
511
511
|
// streamLLMWithTools)으로 라우팅. 미아밍이면 아래 기존 single-turn 경로 그대로(회귀 0).
|
|
512
512
|
const goalLoopCfg = opts.userConfig.llm.goalLoop;
|
|
513
513
|
const armGoalLoop = opts.goalLoop === true || goalLoopCfg?.enabled === true;
|
|
514
|
-
const
|
|
515
|
-
|
|
514
|
+
const armResearchTurn = (opts.utteranceSurface === 'tui' || opts.utteranceSurface === 'ask')
|
|
515
|
+
&& turnTools.length > 0 && isResearchAgentIntent(opts.userText);
|
|
516
|
+
if (armGoalLoop || armResearchTurn) {
|
|
516
517
|
// ⭐ CHILD-CONTEXT-BUDGET(0.2.35 칸) — 구현 자식(self-implement 공간)의 첫 goal-loop
|
|
517
518
|
// 턴에서 실제 effectiveSystemPrompt·turnTools 스키마·userText(골)의 구성 바이트를
|
|
518
519
|
// composeChildContext 로 계측해 child.context-composition 사건 1회로 남긴다.
|
|
@@ -563,6 +564,7 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
|
|
|
563
564
|
},
|
|
564
565
|
},
|
|
565
566
|
...(turnLlmOpts?.model ? { modelOverride: turnLlmOpts.model } : {}),
|
|
567
|
+
...(turnLlmOpts?.reasoningEffort ? { reasoningEffort: turnLlmOpts.reasoningEffort } : {}),
|
|
566
568
|
...(turnLlmOpts?.budgetGrant ? { budgetGrant: turnLlmOpts.budgetGrant } : {}),
|
|
567
569
|
...(guardedTurnLlmOpts?.requestSizeGuard
|
|
568
570
|
? { requestSizeGuard: guardedTurnLlmOpts.requestSizeGuard } : {}),
|
|
@@ -224,6 +224,8 @@ export interface SessionChunkEvent {
|
|
|
224
224
|
seq: number;
|
|
225
225
|
/** 텍스트 델타(누적은 sink 의 라이브핸들이). */
|
|
226
226
|
delta?: string;
|
|
227
|
+
/** Replace the current assistant text accumulated for this stream. */
|
|
228
|
+
textOperation?: 'replace';
|
|
227
229
|
/** 툴 활동(⚙️…✓ inline 렌더용). */
|
|
228
230
|
tool?: { id: string; name: string; phase: 'call' | 'result'; ok?: boolean };
|
|
229
231
|
/** 🧠 추론(모드 gated·선택). */
|
|
@@ -36,7 +36,8 @@ export function createAcpStreamSink(broadcast: AcpBroadcast): StreamingSurfaceSi
|
|
|
36
36
|
if (!sessionId) return;
|
|
37
37
|
if (ev.delta) {
|
|
38
38
|
// push(chunk) 등가 — agent_message_chunk(byte-identical).
|
|
39
|
-
void broadcast(sessionId, { sessionUpdate: 'agent_message_chunk', content: { type: 'text', text: ev.delta }
|
|
39
|
+
void broadcast(sessionId, { sessionUpdate: 'agent_message_chunk', content: { type: 'text', text: ev.delta },
|
|
40
|
+
...(ev.textOperation === 'replace' ? { _meta: { elanous: { textOperation: 'replace' } } } : {}) });
|
|
40
41
|
}
|
|
41
42
|
if (ev.reasoning) {
|
|
42
43
|
// 🧠 추론 — agent_thought_chunk(ACP 의 thought 채널).
|
|
@@ -20,6 +20,7 @@ import { debug } from '../../debug/log.js';
|
|
|
20
20
|
* shadow 시엔 'acp' 구독자 부재 → tg/dc/pwa 미러만. reasoning 채널 추가 지원. */
|
|
21
21
|
export interface AcpChunkProducer {
|
|
22
22
|
delta: (text: string) => void;
|
|
23
|
+
replaceText: (text: string) => void;
|
|
23
24
|
/** ⭐ `result` 는 «결과 단계»에서만 뜻이 있고, 주면 ACP `rawOutput` 으로 실려 나간다.
|
|
24
25
|
*
|
|
25
26
|
* ⛔⭐⭐ **「안 줬다」의 «사유»를 여기서 만들지 않는다.**
|
|
@@ -53,6 +54,11 @@ export function makeAcpChunkProducer(sessionId: string, opts: { streamId?: strin
|
|
|
53
54
|
fo({ streamId, seq: seq++, delta: text });
|
|
54
55
|
deltas++;
|
|
55
56
|
},
|
|
57
|
+
replaceText(text: string): void {
|
|
58
|
+
accum = text;
|
|
59
|
+
fo({ streamId, seq: seq++, delta: text, textOperation: 'replace' });
|
|
60
|
+
deltas++;
|
|
61
|
+
},
|
|
56
62
|
tool(id, name, phase, ok, result): void {
|
|
57
63
|
fo({ streamId, seq: seq++, tool: {
|
|
58
64
|
id, name, phase,
|