elanous 0.2.32 → 0.2.34
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/{IVKr3AlRUVLKsw2fh7eXF → L04y73dlwKeTW-GetaTF3}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +79 -0
- package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +94 -0
- package/apps/pwa/out/_next/static/chunks/{4174.92ed04922709ac9e.js → 1644.35dd25240ae24e4b.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2940-619bfd8ef337c611.js → 1895-60ed0e341c658bd4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5525.86debf231e181813.js → 2124.ed5bf480cea7f85b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +23 -0
- package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +115 -0
- package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +8 -0
- package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6092.a7f99e68b188ca66.js → 2547.dd27303624cb4da8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 2554.3b5e200f5f5cfcd6.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +1 -0
- package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5173-233188df2f42c626.js → 2987-30cf9c2eb7b8bdd5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3541-ce3a5424ed5ad7f1.js → 3001-5a52788c813b6113.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3103.84470c8445962f04.js +34 -0
- package/apps/pwa/out/_next/static/chunks/{6433.fc573af22bbc9ab7.js → 3110.0a7065f25c841818.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3121.779fafe3e44612c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3411-f87314c6c66ebc73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.js → 3414.172ad4ca2d9b08e8.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4745.67d6f99c245af3f7.js → 3498.cf2a15a8a9e5b926.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3819.163d4777f0a597f6.js +32 -0
- package/apps/pwa/out/_next/static/chunks/{5543.a438b8ab5a13ea47.js → 3837.722e053fb9f321ad.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +104 -0
- package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +286 -0
- package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +149 -0
- package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +148 -0
- package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +64 -0
- package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +74 -0
- package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b313b242.cb1265eea908db61.js → 4fa33ebd.21c1bd5b294496e6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.js → 5014f970-22bef0b5210f7d60.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2112-e4efc21a6505d5bc.js → 5028-f0722e6114c313e7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2898.fd781bc7cf01a7b7.js → 5249.96a848656b582a93.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +62 -0
- package/apps/pwa/out/_next/static/chunks/{9407.e49124dedf0f5e72.js → 5446.edf141cff9ef647d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9002.e5658224e3dc1b6f.js → 5489.ec2dd1b5272a19dc.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.js → 5576-82d3703636d5c4b9.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6053-d893974de92e6198.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.js → 6086.913a69e6fa3e4a8b.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +1 -0
- package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +77 -0
- package/apps/pwa/out/_next/static/chunks/{7862.30a8d6482bb238eb.js → 6740.43de73fc427c9fe2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +90 -0
- package/apps/pwa/out/_next/static/chunks/{2871.0bca6137343b3f76.js → 7005.1623d2aea78eb85f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7193-cf355cca5ba6c5d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7386.5d8e7e42e818dfb6.js +287 -0
- package/apps/pwa/out/_next/static/chunks/{7502.ccd5b8065545edd0.js → 7431.3051e9b8a4372d2d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{3583.a05e88cc8d594628.js → 7448.478958ffbbba0ac0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7562.948255cbc3e79d33.js +41 -0
- package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +27 -0
- package/apps/pwa/out/_next/static/chunks/{9989.3694300e5f000b14.js → 7952.b192c31b6a0e00cc.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +36 -0
- package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +1 -0
- package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.js → 8368.014caa8de2f5af34.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9221.7d22eaf353a2d4e7.js → 8548.036c344973968847.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8817.61bb7ffbba502ecb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9398-6aed28f0a96d0d6f.js → 9131-fce7256c4180c4a5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +93 -0
- package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{3278.2e5d15b53a4091c8.js → 9550.d5f76828f972058c.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{2534.e85ae21ad0dac829.js → 9739.8d5f36ac67a3b236.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +1 -0
- package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7a1887c4.f36b88fba31da8fd.js → 9a8cb466.cc9fc9e6e46038aa.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → 9b48c871.204d5d13e7809bd0.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → abb4b98b.163e0f56e84ae35d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-4fb31eb476dcbad3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-d7bff0f0905a662c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-8c66a3b24a745630.js → page-398c0faa173203f7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-04d00ae9b0890349.js → page-df3445b207ceceab.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +122 -0
- package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{ebc7d829.264a0bcb6c750b50.js → ffdc3a04.b9c23c1b28dd4a96.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +22 -22
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +21 -21
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +22 -22
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +22 -22
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +22 -22
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +21 -21
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +21 -21
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +21 -21
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +21 -21
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +21 -21
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/bin/elanous.mjs +9 -2
- package/docs/goal-context/README.md +1 -0
- package/graphs/default-loop.yaml +20 -3
- package/graphs/document-loop.yaml +21 -2
- package/graphs/implement-loop.yaml +6 -0
- package/graphs/journey/SCENARIOS.md +33 -0
- package/graphs/journey/recipes.yaml +1 -0
- package/graphs/journey/ta-journey.yaml +84 -0
- package/graphs/journey/units/author/author.yaml +20 -0
- package/graphs/journey/units/author/recipes.yaml +2 -0
- package/graphs/journey/units/green/green.yaml +20 -0
- package/graphs/journey/units/green/recipes.yaml +2 -0
- package/graphs/journey/units/pr/pr.yaml +20 -0
- package/graphs/journey/units/pr/recipes.yaml +2 -0
- package/graphs/journey/units/remember/recipes.yaml +2 -0
- package/graphs/journey/units/remember/remember.yaml +20 -0
- package/graphs/operate-loop.yaml +21 -2
- package/graphs/overlays/stop-heal-ladder.yaml +1 -1
- package/graphs/release-rehearsal/recipes.yaml +1 -1
- package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
- package/graphs/research-loop.yaml +23 -2
- package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
- package/graphs/units/dispatch-pod/recipes.yaml +14 -0
- package/graphs/units/entry/entry.yaml +50 -0
- package/graphs/units/entry/recipes.yaml +14 -0
- package/graphs/units/harvest/harvest.yaml +25 -0
- package/graphs/units/harvest/recipes.yaml +4 -0
- package/graphs/units/land/land.yaml +45 -0
- package/graphs/units/land/recipes.yaml +3 -0
- package/graphs/units/recipes.yaml +7 -0
- package/graphs/units/recover.yaml +39 -0
- package/graphs/units/reflect/recipes.yaml +3 -0
- package/graphs/units/reflect/reflect.yaml +15 -0
- package/graphs/units/task-agent-recover-review.yaml +17 -0
- package/graphs/units/task-agent-recover-wait.yaml +17 -0
- package/graphs/units/verbs/make-doc.yaml +34 -0
- package/graphs/units/verbs/recipes.yaml +33 -0
- package/graphs/units/verbs/verify.yaml +55 -0
- package/graphs/work/recipes.yaml +2 -0
- package/graphs/work/research-report.yaml +28 -0
- package/package.json +1 -1
- package/scripts/ci-typecheck-changed.ts +69 -16
- package/scripts/docs/generate-graph-anatomy.ts +19 -2
- package/scripts/graph-harvest-unit.ts +22 -0
- package/scripts/graph-units/journey-stub.ts +6 -0
- package/scripts/graph-units/land-enqueue.ts +78 -0
- package/scripts/graph-units/recover-plan.ts +15 -0
- package/scripts/graph-units/reflect-node.ts +88 -0
- package/scripts/graph-units/ta-journey-observe.ts +109 -0
- package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
- package/scripts/graph-units/verbs/verify-stage.ts +75 -0
- package/scripts/graph-units/verbs-envelope.ts +139 -0
- package/scripts/hq/standby-snapshot.ts +25 -0
- package/scripts/public-export.ts +43 -1
- package/scripts/ratchets/train-side-invariants.sh +45 -0
- package/scripts/release-loop/auto-approve-node.ts +30 -16
- package/scripts/release-loop/gate-closure.ts +5 -1
- package/scripts/release-loop/gate-diff.ts +1 -1
- package/scripts/release-loop/gate-node.ts +498 -31
- package/scripts/release-loop/gate-partial.ts +3 -3
- package/scripts/release-loop/gate-radius-shadow.ts +138 -0
- package/scripts/release-loop/gate-traffic-mode.ts +128 -0
- package/scripts/release-loop/gate-triage-node.ts +5 -2
- package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
- package/scripts/release-loop/known-issues-node.ts +77 -8
- package/scripts/release-loop/preflight.ts +93 -7
- package/scripts/release-loop/publish-node.ts +60 -9
- package/scripts/release-loop/resume-cap.ts +56 -0
- package/scripts/release-loop/resume-release.ts +114 -15
- package/scripts/release-loop/resume.ts +24 -1
- package/scripts/release-loop/tui-sim-node.ts +8 -2
- package/scripts/release-loop/unattended-release.ts +8 -2
- package/src/acp/core-turn-bridge.ts +20 -5
- package/src/acp/reasoning-thought-buffer.ts +45 -0
- package/src/agent-substrate/acp-reviewer.ts +52 -12
- package/src/agent-substrate/review-finding-key.ts +53 -0
- package/src/agent-substrate/self-review-cli.ts +126 -5
- package/src/ask-user-question/pending-questions.ts +1 -1
- package/src/autopilot/pr-manager.ts +192 -43
- package/src/chat/tool-render/dispatch.ts +62 -10
- package/src/cli/control-cli.ts +24 -7
- package/src/cli/guardian-cli.ts +10 -0
- package/src/cli/light-entry-route.ts +35 -0
- package/src/cli/llm-detect-cli.ts +23 -1
- package/src/cli/pr-cli.ts +76 -12
- package/src/cli/pr-land-base-read.ts +2 -0
- package/src/cli/pr-land-overlap-evidence.ts +154 -16
- package/src/cli/pr-land-recovery.ts +64 -0
- package/src/cli/pty-takeover-cli.ts +6 -5
- package/src/cli/release-cli.ts +120 -33
- package/src/cli/release-run-if-ready.ts +29 -28
- package/src/cli/release-single-flight.ts +178 -0
- package/src/cli/seat-cli.ts +37 -0
- package/src/cli/setup-cli.ts +40 -1
- package/src/cli/tasks-cli.ts +149 -5
- package/src/control/control-status.ts +8 -3
- package/src/control-plane/ledger.ts +5 -3
- package/src/control-plane/server.ts +5 -3
- package/src/core-turn/short-question.ts +5 -1
- package/src/dashboard/index.ts +36 -67
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
- package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
- package/src/dashboard/input/seat-autowake.ts +56 -3
- package/src/dashboard/seat-boot-preamble.ts +1 -1
- package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
- package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
- package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
- package/src/dashboard/turn-preamble.ts +47 -1
- package/src/dashboard/turn-stream-formatter.ts +34 -1
- package/src/dashboard/turn-stream-runtime.ts +2 -0
- package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
- package/src/domains/guardian-tick.ts +54 -2
- package/src/domains/outbound-alert.ts +3 -2
- package/src/extractors.ts +3 -1
- package/src/git-fs/retry.ts +4 -0
- package/src/git-fs/runner.ts +2 -0
- package/src/graph-runner/runner.ts +114 -44
- package/src/grok/credential.ts +5 -0
- package/src/harness/harness-cli-command.ts +39 -10
- package/src/harness/harness-incidents.ts +4 -0
- package/src/harness/harness-pod-dispatch.ts +38 -1
- package/src/harness/harness-salvage-cli.ts +14 -2
- package/src/index.ts +192 -8
- package/src/intake-plane/already-built-hint.ts +89 -0
- package/src/knowhow/pack.ts +199 -0
- package/src/light-cli.ts +95 -0
- package/src/llm.ts +55 -9
- package/src/loops/budget.ts +95 -0
- package/src/loops/msg-wake.ts +8 -2
- package/src/loops/orchestrator/traffic.ts +132 -1
- package/src/mss/logging/log-store.ts +4 -5
- package/src/nexus/api/graphs-api.ts +22 -3
- package/src/nexus/api/http-server.ts +1 -1
- package/src/nexus/api/ops-api.ts +12 -0
- package/src/oauth/claude-pty-maturity.ts +66 -0
- package/src/oauth/codex-access-mirror.ts +55 -0
- package/src/oauth/fallback-chain.ts +1 -1
- package/src/onboarding/first-run.ts +5 -3
- package/src/onboarding/non-interactive.ts +64 -13
- package/src/onboarding.ts +10 -2
- package/src/ops/overview-collect.ts +36 -1
- package/src/ops/overview.ts +11 -0
- package/src/pr-tool/census.ts +23 -5
- package/src/pr-tool/inflight-registry.ts +160 -7
- package/src/prompt-library/gpt6-family-addendum.ts +14 -1
- package/src/pty-shell/herdr-agent-report.ts +442 -0
- package/src/pty-shell/pty-control-ipc.ts +5 -5
- package/src/pty-shell/pty-write-outcome.ts +24 -6
- package/src/pty-shell/tui-run-state.ts +117 -3
- package/src/release-loop/checklist.ts +79 -5
- package/src/release-loop/feature-store.ts +19 -2
- package/src/release-loop/placement.ts +10 -3
- package/src/release-loop/rehearsal.ts +205 -25
- package/src/release-loop/rubric.ts +16 -2
- package/src/self-dev/draft-sweep.ts +52 -3
- package/src/self-dev/graph-journey-nodes.ts +10 -6
- package/src/self-dev/graph-journey-route.ts +60 -6
- package/src/self-dev/orchestrate.ts +79 -3
- package/src/self-dev/run-supervisor.ts +107 -12
- package/src/self-dev/run-types.ts +5 -1
- package/src/self-implement/gate-baseline.ts +49 -5
- package/src/self-implement/gate-remote.ts +9 -5
- package/src/self-implement/goal-author-identity.ts +66 -0
- package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
- package/src/self-implement/goal-author.ts +4 -120
- package/src/self-implement/graph-overlay-yaml.ts +17 -2
- package/src/self-implement/graph-unit-flatten.ts +103 -0
- package/src/self-implement/graph-unit-resolver.ts +107 -0
- package/src/self-implement/graph-yaml.ts +151 -1
- package/src/self-implement/headless-elanous-driver.ts +1 -0
- package/src/self-implement/knowhow-pack.ts +103 -0
- package/src/self-implement/orchestrator.ts +8 -0
- package/src/self-implement/pod-warm-pool-profile.ts +45 -0
- package/src/self-implement/review-mustfix-class.ts +203 -0
- package/src/self-implement/run-stop.ts +8 -2
- package/src/self-implement/seams.ts +32 -1
- package/src/self-implement/stop-autoheal.ts +25 -1
- package/src/session/chat.ts +27 -0
- package/src/session-runtime/retry-policy.ts +2 -1
- package/src/skills/tools/schedule-wakeup.ts +66 -17
- package/src/steward/release-day.ts +7 -3
- package/src/steward/triage.ts +37 -4
- package/src/task-agent/harvest-unit.ts +141 -0
- package/src/task-agent/live-moves.ts +98 -12
- package/src/task-agent/parent-host.ts +93 -3
- package/src/task-agent/postland-card.ts +80 -1
- package/src/task-agent/rejudge-on-head.ts +112 -26
- package/src/task-agent/repair-branch-cas.ts +4 -1
- package/src/task-agent/repair-cycle.ts +16 -3
- package/src/task-agent/run-identity.ts +4 -3
- package/src/task-agent/shadow.ts +12 -2
- package/src/task-agent/task-hand.ts +54 -7
- package/src/task-agent/work-order-build.ts +22 -0
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +39 -3
- package/src/task-orchestrator/surfaces/pod-command-job.ts +2 -1
- package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
- package/src/task-orchestrator/surfaces/pod-pool.ts +73 -17
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +54 -4
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +26 -3
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +389 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +2 -1
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +223 -38
- package/src/task-orchestrator/surfaces/self-implement.ts +83 -2
- package/src/tool-runtime/truncation-store.ts +4 -0
- package/src/tui-client/dashboard-session.ts +10 -1
- package/src/user-config/coercion.ts +36 -0
- package/src/user-config.ts +18 -41
- package/src/ux-sim/scenario.ts +72 -13
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
- package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
- package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
- package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
- package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
- package/apps/pwa/out/_next/static/chunks/2001.6c7e0fd02190886c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
- package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
- package/apps/pwa/out/_next/static/chunks/3267c0e6.d34854e7b3984a6e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +0 -34
- package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
- package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
- package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
- package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
- package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
- package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
- package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
- package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
- package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
- package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
- package/apps/pwa/out/_next/static/chunks/69-0a2c8209c6d4a158.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
- package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
- package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-a27b1e5a0d1b308f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-32866485913d6a04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-c219f2ed171131be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
- package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
- package/src/cli/g6a-registration-probe.ts +0 -16
- /package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → L04y73dlwKeTW-GetaTF3}/_ssgManifest.js +0 -0
package/src/llm.ts
CHANGED
|
@@ -1586,6 +1586,7 @@ type ResponsesInputItem =
|
|
|
1586
1586
|
export interface MessagesToResponsesInputOpts {
|
|
1587
1587
|
acceptToolImages?: boolean;
|
|
1588
1588
|
acceptUserMessageImages?: boolean;
|
|
1589
|
+
onOrphanToolResult?: (callId: string) => void;
|
|
1589
1590
|
}
|
|
1590
1591
|
|
|
1591
1592
|
/** Exported for tests. Converts the unified LLMMessage shape into the
|
|
@@ -1603,21 +1604,23 @@ export function messagesToResponsesInput(
|
|
|
1603
1604
|
// P-3 §6.9 — user-message image gating (default true; current gpt-5
|
|
1604
1605
|
// family all vision-capable per allowlist).
|
|
1605
1606
|
const acceptUserImages = opts.acceptUserMessageImages ?? true;
|
|
1606
|
-
// First pass — collect
|
|
1607
|
-
//
|
|
1608
|
-
//
|
|
1609
|
-
// matching tool_result followed). Orphans happen when the runtime
|
|
1607
|
+
// First pass — collect both sides of each tool round. Second pass
|
|
1608
|
+
// drops either side when its partner is absent from retained history.
|
|
1609
|
+
// Orphan tool_use blocks happen when the runtime
|
|
1610
1610
|
// pre-empts dispatch (e.g. W5-G early force-synthesis fires
|
|
1611
1611
|
// immediately after the assistant's tool_use stream completes but
|
|
1612
1612
|
// before dispatchTool runs) — codex Responses API hard-rejects
|
|
1613
1613
|
// function_call without function_call_output ("No tool output
|
|
1614
1614
|
// found for function call X" → 400).
|
|
1615
1615
|
const seenToolResultIds = new Set<string>();
|
|
1616
|
+
const seenToolUseIds = new Set<string>();
|
|
1616
1617
|
for (const m of messages) {
|
|
1617
1618
|
if (!Array.isArray(m.content)) continue;
|
|
1618
1619
|
for (const b of m.content) {
|
|
1619
1620
|
if (b && typeof b === 'object' && b.type === 'tool_result' && b.tool_use_id) {
|
|
1620
1621
|
seenToolResultIds.add(b.tool_use_id);
|
|
1622
|
+
} else if (m.role === 'assistant' && b && typeof b === 'object' && b.type === 'tool_use' && b.id) {
|
|
1623
|
+
seenToolUseIds.add(b.id);
|
|
1621
1624
|
}
|
|
1622
1625
|
}
|
|
1623
1626
|
}
|
|
@@ -1695,6 +1698,13 @@ export function messagesToResponsesInput(
|
|
|
1695
1698
|
call_id: b.id,
|
|
1696
1699
|
});
|
|
1697
1700
|
} else if (b.type === 'tool_result') {
|
|
1701
|
+
// A restored/truncated session can retain an output after its
|
|
1702
|
+
// assistant call was removed. Codex rejects that wire item with
|
|
1703
|
+
// "No tool call found for function call output" on every retry.
|
|
1704
|
+
if (!seenToolUseIds.has(b.tool_use_id)) {
|
|
1705
|
+
opts.onOrphanToolResult?.(b.tool_use_id);
|
|
1706
|
+
continue;
|
|
1707
|
+
}
|
|
1698
1708
|
// Image-pipeline P3 (2026-05-05) — when the caller opted in
|
|
1699
1709
|
// (acceptToolImages, set by Codex provider for gpt-5 family)
|
|
1700
1710
|
// AND the tool_result content carries image bytes, emit the
|
|
@@ -4016,6 +4026,13 @@ export const PROVIDERS: Record<string, LLMProvider> = {
|
|
|
4016
4026
|
streamChat: (messages, opts = {}) => makeCodexProvider({ provider: 'openai-codex' }).streamChat!(messages, opts),
|
|
4017
4027
|
chat: (messages, opts = {}) => makeCodexProvider({ provider: 'openai-codex' }).chat!(messages, opts),
|
|
4018
4028
|
},
|
|
4029
|
+
glm: {
|
|
4030
|
+
name: 'glm',
|
|
4031
|
+
get defaultModel() { return configuredZaiProvider().defaultModel; },
|
|
4032
|
+
available: () => zaiCodingPlanAvailable(),
|
|
4033
|
+
streamChat: (messages, opts = {}) => configuredZaiProvider().streamChat!(messages, opts),
|
|
4034
|
+
chat: (messages, opts = {}) => configuredZaiProvider().chat!(messages, opts),
|
|
4035
|
+
},
|
|
4019
4036
|
anthropic: AnthropicProvider,
|
|
4020
4037
|
local: LocalProvider,
|
|
4021
4038
|
gemini: GeminiProvider,
|
|
@@ -4030,6 +4047,11 @@ export const PROVIDERS: Record<string, LLMProvider> = {
|
|
|
4030
4047
|
bedrock: BedrockProvider, // 명시 선택 전용 — 자동 순서·폴백 체인에 «안» 넣는다(src/llm/bedrock-provider.ts)
|
|
4031
4048
|
};
|
|
4032
4049
|
|
|
4050
|
+
function configuredZaiProvider(): LLMProvider {
|
|
4051
|
+
const { getUserConfig } = require('./user-config.js') as typeof import('./user-config.js');
|
|
4052
|
+
return makeZaiCodingPlanProvider(getUserConfig().llm);
|
|
4053
|
+
}
|
|
4054
|
+
|
|
4033
4055
|
const AUTOMATIC_PROVIDER_ORDER = ['grok', 'anthropic', 'gemini', 'local'] as const;
|
|
4034
4056
|
const PROVIDER_DECISION_ORDER = ['grok', 'anthropic', 'openai', 'gemini', 'local', 'openrouter'] as const;
|
|
4035
4057
|
const SUBSCRIPTION_DECISION_ORDER = ['openai-codex', 'grok'] as const;
|
|
@@ -4419,6 +4441,16 @@ function providerByName(name: string): LLMProvider | undefined {
|
|
|
4419
4441
|
return PROVIDERS[name] ?? automaticProviderCandidates().find((candidate) => candidate.name === name);
|
|
4420
4442
|
}
|
|
4421
4443
|
|
|
4444
|
+
function firstAvailableFallbackProvider(attempted: ReadonlySet<string>, opts: LLMOpts): LLMProvider | undefined {
|
|
4445
|
+
// A candidate may lose its credential between chain enumeration and the
|
|
4446
|
+
// switch. Keep scanning the ordered chain instead of stopping at that slot.
|
|
4447
|
+
for (const name of remainingFallbackProviderNames(attempted, opts)) {
|
|
4448
|
+
const candidate = providerByName(name);
|
|
4449
|
+
if (candidate?.available()) return candidate;
|
|
4450
|
+
}
|
|
4451
|
+
return undefined;
|
|
4452
|
+
}
|
|
4453
|
+
|
|
4422
4454
|
function finalizeStreamingProviderModel(provider: LLMProvider, model: string): { provider: LLMProvider; model: string } {
|
|
4423
4455
|
if (!isKnownProviderName(provider.name)) return { provider, model };
|
|
4424
4456
|
|
|
@@ -4821,8 +4853,11 @@ export async function streamLLM(
|
|
|
4821
4853
|
|
|
4822
4854
|
const err: any = consumed.error;
|
|
4823
4855
|
if (err instanceof OverloadFailoverError && !opts.provider) {
|
|
4824
|
-
const switched =
|
|
4825
|
-
|
|
4856
|
+
const switched = activeProvider.name === 'openai-codex'
|
|
4857
|
+
? firstAvailableFallbackProvider(attemptedProviders, opts)
|
|
4858
|
+
: providerByName('grok');
|
|
4859
|
+
if (switched && !attemptedProviders.has(switched.name)
|
|
4860
|
+
&& (activeProvider.name === 'openai-codex' || switched.available()) && full.length === 0) {
|
|
4826
4861
|
debug.log('llm.router', 'overload-failover', {
|
|
4827
4862
|
blockedProvider: activeProvider.name,
|
|
4828
4863
|
fallbackProvider: switched.name,
|
|
@@ -8501,6 +8536,8 @@ export async function streamLLMWithTools(
|
|
|
8501
8536
|
}
|
|
8502
8537
|
}
|
|
8503
8538
|
let turnText = '';
|
|
8539
|
+
// TUI-TURN-NARRATION — 이 라운드에 받은 추론 요약 글자 수(내용은 남기지 않는다).
|
|
8540
|
+
let turnReasoningChars = 0;
|
|
8504
8541
|
turnReasoningDetails = undefined;
|
|
8505
8542
|
const pendingCalls: Array<{
|
|
8506
8543
|
id: string;
|
|
@@ -8638,6 +8675,7 @@ export async function streamLLMWithTools(
|
|
|
8638
8675
|
fullText = fullText.slice(0, fullText.length - turnText.length);
|
|
8639
8676
|
turnText = '';
|
|
8640
8677
|
}
|
|
8678
|
+
turnReasoningChars = 0;
|
|
8641
8679
|
retryDisplay.arm();
|
|
8642
8680
|
turnReasoningDetails = undefined;
|
|
8643
8681
|
evCount = 0;
|
|
@@ -8666,8 +8704,11 @@ export async function streamLLMWithTools(
|
|
|
8666
8704
|
} catch (err) {
|
|
8667
8705
|
if (idleTimer) clearTimeout(idleTimer);
|
|
8668
8706
|
if (err instanceof OverloadFailoverError && !opts.provider) {
|
|
8669
|
-
const switched =
|
|
8670
|
-
|
|
8707
|
+
const switched = activeProvider.name === 'openai-codex'
|
|
8708
|
+
? firstAvailableFallbackProvider(attemptedProviders, opts)
|
|
8709
|
+
: providerByName('grok');
|
|
8710
|
+
if (switched && !attemptedProviders.has(switched.name)
|
|
8711
|
+
&& (activeProvider.name === 'openai-codex' || switched.available()) && evCount === 0) {
|
|
8671
8712
|
debug.log('llm.router', 'overload-failover', {
|
|
8672
8713
|
turn,
|
|
8673
8714
|
blockedProvider: activeProvider.name,
|
|
@@ -8797,6 +8838,7 @@ export async function streamLLMWithTools(
|
|
|
8797
8838
|
// OpenAI-compat `delta.reasoning_content` field — same
|
|
8798
8839
|
// consumer-side semantics as summary_delta, no part index.
|
|
8799
8840
|
// Callers that don't render reasoning skip silently.
|
|
8841
|
+
if (ev.kind !== 'summary_part_added') turnReasoningChars += ev.delta.length;
|
|
8800
8842
|
if (ev.kind === 'summary_part_added') {
|
|
8801
8843
|
handlers.onReasoning?.({
|
|
8802
8844
|
kind: 'summary_part_added',
|
|
@@ -8873,7 +8915,7 @@ export async function streamLLMWithTools(
|
|
|
8873
8915
|
|
|
8874
8916
|
// hang 진단 — for-await(SSE 스트림) 정상 종료 확정. 이 로그가 없으면 codex SSE 스트림 hang.
|
|
8875
8917
|
emitRetryDisplayStep(retryDisplay.settle(turnText));
|
|
8876
|
-
debug.log('llm.stream', 'consume-end', { turn, evCount, lastEvType, textChars: turnText.length, pendingCalls: pendingCalls.length });
|
|
8918
|
+
debug.log('llm.stream', 'consume-end', { turn, evCount, lastEvType, textChars: turnText.length, reasoningChars: turnReasoningChars, pendingCalls: pendingCalls.length });
|
|
8877
8919
|
const turnInfo = {
|
|
8878
8920
|
turn,
|
|
8879
8921
|
durationMs: Date.now() - turnStartedAt,
|
|
@@ -11489,6 +11531,10 @@ function makeCodexProvider(cfg: UCLLMConfig): LLMProvider {
|
|
|
11489
11531
|
const { instructions, input } = messagesToResponsesInput(messages, {
|
|
11490
11532
|
acceptToolImages: codexAcceptToolImages,
|
|
11491
11533
|
acceptUserMessageImages: codexAcceptUserImages,
|
|
11534
|
+
onOrphanToolResult: (callId) => {
|
|
11535
|
+
try { debug.log('llm.codex', 'orphan-tool-output-dropped', { callId }); }
|
|
11536
|
+
catch { /* observation must not block the request */ }
|
|
11537
|
+
},
|
|
11492
11538
|
});
|
|
11493
11539
|
const tools = toCodexResponsesTools(opts.tools, opts.serverTools);
|
|
11494
11540
|
// Codex backend rejects max_output_tokens + temperature — omit.
|
package/src/loops/budget.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
1
3
|
import { ORCHESTRATOR_DEFAULTS, type OrchestratorSeat } from '../user-config.js';
|
|
4
|
+
import { debug } from '../debug/log.js';
|
|
2
5
|
import type { ChecklistItem } from '../release-loop/checklist.js';
|
|
3
6
|
import type { TrafficCell, TrafficProcess, TrafficResult, TrafficSeatRow } from './orchestrator/traffic.js';
|
|
7
|
+
import { withFileLockSync } from '../storage/file-lock.js';
|
|
4
8
|
|
|
5
9
|
const RESOURCE_SEATS: readonly OrchestratorSeat[] = ['OP', 'TC', 'MK', 'UX'];
|
|
6
10
|
|
|
@@ -277,3 +281,94 @@ export function budgetTrafficTick({ processes, now, caps, lastLaunchAt, idleSinc
|
|
|
277
281
|
}
|
|
278
282
|
return { seats, unassigned: launches.filter(process => process.seat === null).length, now, idleMinutes };
|
|
279
283
|
}
|
|
284
|
+
|
|
285
|
+
/** A tick's seat rows as observed: one journal line per tick, kept for the 24h metrics only. */
|
|
286
|
+
export type TrafficTickSample = { at: string; seats: readonly TrafficSeatRow[] };
|
|
287
|
+
|
|
288
|
+
export interface TrafficSampleDeps {
|
|
289
|
+
log?: (category: string, event: string, data: Record<string, unknown>) => void;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** Observation-only journal for 24h metrics: never read for launch decisions. A failure to record costs one metrics sample, never the tick itself. */
|
|
293
|
+
export function recordTrafficSample24h(root: string, sample: TrafficTickSample,
|
|
294
|
+
deps: TrafficSampleDeps = {}): void {
|
|
295
|
+
const log = deps.log ?? debug.log.bind(debug);
|
|
296
|
+
const path = join(root, 'orchestrator', 'traffic-samples-24h.jsonl');
|
|
297
|
+
try {
|
|
298
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
299
|
+
withFileLockSync(`${path}.lock`, () => {
|
|
300
|
+
// A torn final line has no newline; separate it from the next valid JSONL row.
|
|
301
|
+
const previous = existsSync(path) ? readFileSync(path, 'utf8') : '';
|
|
302
|
+
const separator = previous === '' || previous.endsWith('\n') ? '' : '\n';
|
|
303
|
+
appendFileSync(path, `${separator}${JSON.stringify(sample)}\n`);
|
|
304
|
+
});
|
|
305
|
+
log('loop.orchestrator', 'traffic-sample-24h', { at: sample.at, path });
|
|
306
|
+
} catch (error) {
|
|
307
|
+
try { log('loop.orchestrator', 'traffic-sample-24h-failed', { error: String(error).slice(0, 200) }); }
|
|
308
|
+
catch { /* Observation cannot change a recorded decision. */ }
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/** Read the 24h sample journal; torn lines are skipped (same rule as the dispatch ledger). */
|
|
313
|
+
export function readTrafficSamples24h(root: string, now: Date, windowMinutes = 1440): TrafficTickSample[] {
|
|
314
|
+
const path = join(root, 'orchestrator', 'traffic-samples-24h.jsonl');
|
|
315
|
+
if (!existsSync(path)) return [];
|
|
316
|
+
const floor = now.getTime() - windowMinutes * 60_000;
|
|
317
|
+
return readFileSync(path, 'utf8').split('\n').flatMap(line => {
|
|
318
|
+
if (!line.trim()) return [];
|
|
319
|
+
try {
|
|
320
|
+
const parsed = JSON.parse(line) as TrafficTickSample;
|
|
321
|
+
const at = Date.parse(parsed.at);
|
|
322
|
+
if (!Number.isFinite(at) || at < floor || at > now.getTime() || !Array.isArray(parsed.seats)) return [];
|
|
323
|
+
return [parsed];
|
|
324
|
+
} catch { return []; }
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export type TrafficMetrics24h = {
|
|
329
|
+
/** Occupied share of the observed slot budget over all ticks (Σrunning / Σcap). */
|
|
330
|
+
utilizationRate: number;
|
|
331
|
+
running: number;
|
|
332
|
+
capacity: number;
|
|
333
|
+
/** Mean minutes an idle, empty seat has waited for its next launch; null when no waits were observed. */
|
|
334
|
+
meanWaitMinutes: number | null;
|
|
335
|
+
waitSamples: number;
|
|
336
|
+
/** Seat-ticks where a seat ran on borrowed share — its own base share could not keep it. */
|
|
337
|
+
preemptedSeatTicks: number;
|
|
338
|
+
sampledTicks: number;
|
|
339
|
+
windowMinutes: number;
|
|
340
|
+
firstSampleAt: string | null;
|
|
341
|
+
lastSampleAt: string | null;
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
/** Aggregate the 24h traffic metrics from the observation journal. Pure over the given samples. */
|
|
345
|
+
export function computeTrafficMetrics24h(samples: readonly TrafficTickSample[], windowMinutes = 1440): TrafficMetrics24h {
|
|
346
|
+
let running = 0;
|
|
347
|
+
let capacity = 0;
|
|
348
|
+
let waitSum = 0;
|
|
349
|
+
let waitSamples = 0;
|
|
350
|
+
let preemptedSeatTicks = 0;
|
|
351
|
+
for (const sample of samples) {
|
|
352
|
+
for (const row of sample.seats) {
|
|
353
|
+
running += row.running;
|
|
354
|
+
capacity += row.cap;
|
|
355
|
+
if (row.borrowed > 0) preemptedSeatTicks++;
|
|
356
|
+
if (row.idleFor !== null && row.idleFor > 0) {
|
|
357
|
+
waitSum += row.idleFor;
|
|
358
|
+
waitSamples++;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return {
|
|
363
|
+
utilizationRate: capacity > 0 ? Math.round((running / capacity) * 1000) / 1000 : 0,
|
|
364
|
+
running,
|
|
365
|
+
capacity,
|
|
366
|
+
meanWaitMinutes: waitSamples > 0 ? Math.round((waitSum / waitSamples) * 10) / 10 : null,
|
|
367
|
+
waitSamples,
|
|
368
|
+
preemptedSeatTicks,
|
|
369
|
+
sampledTicks: samples.length,
|
|
370
|
+
windowMinutes,
|
|
371
|
+
firstSampleAt: samples[0]?.at ?? null,
|
|
372
|
+
lastSampleAt: samples.at(-1)?.at ?? null,
|
|
373
|
+
};
|
|
374
|
+
}
|
package/src/loops/msg-wake.ts
CHANGED
|
@@ -309,7 +309,7 @@ export async function wakeRecipient(address: string, msgId: number, message: { f
|
|
|
309
309
|
|
|
310
310
|
interface PendingWakeRow { address: string; first_msg_id: number; last_msg_id: number; last_from: string; count: number; since: number; attempts: number; reason: string }
|
|
311
311
|
|
|
312
|
-
export type PendingWakeEvent = 'deferred' | 'redelivered' | 'gave-up' | 'dropped-read';
|
|
312
|
+
export type PendingWakeEvent = 'deferred' | 'redelivered' | 'gave-up' | 'dropped-read' | 'skip';
|
|
313
313
|
|
|
314
314
|
function logPending(event: PendingWakeEvent, data: Record<string, unknown>): void {
|
|
315
315
|
try { debug.log('loops.msg-wake', event, data); } catch { /* observability is fail-open */ }
|
|
@@ -389,8 +389,14 @@ export function redeliverLine(row: Pick<PendingWakeRow, 'address' | 'last_from'
|
|
|
389
389
|
* Re-knock deferred wakes whose TUI is now recorded idle. `target` limits the sweep to one pty (the TUI's own poller).
|
|
390
390
|
* Never throws per row; a row stays pending while the TUI is busy or the 5-minute window is held.
|
|
391
391
|
*/
|
|
392
|
+
// not-live 우주의 재점검은 침묵 대신 이유 한 줄을 남긴다 — 폴러가 15초마다 틱하므로 프로세스당 처음 한 번만(래치).
|
|
393
|
+
let notLiveSkipLogged = false;
|
|
394
|
+
|
|
392
395
|
export async function redeliverPendingWakes(deps: WakeDeps = {}, opts: { target?: string } = {}): Promise<RedeliverOutcome[]> {
|
|
393
|
-
if (!isLive(deps))
|
|
396
|
+
if (!isLive(deps)) {
|
|
397
|
+
if (!notLiveSkipLogged) { notLiveSkipLogged = true; logPending('skip', { reason: 'not-live' }); }
|
|
398
|
+
return [];
|
|
399
|
+
}
|
|
394
400
|
const db = claimDbPath(deps);
|
|
395
401
|
if (!existsSync(db)) return [];
|
|
396
402
|
const conn = openWakeDb(db);
|
|
@@ -9,7 +9,8 @@ import { withFileLockSync } from '../../storage/file-lock.js';
|
|
|
9
9
|
import { getUserConfig, ORCHESTRATOR_DEFAULTS, type OrchestratorLoopConfig, type OrchestratorSeat } from '../../user-config.js';
|
|
10
10
|
import { finishAdvice, measureFinish, type FinishAdvice, type FinishMetrics, type MeasureFinishDeps } from './finish-rate.js';
|
|
11
11
|
import { collectAuthorDepth, type AuthorDepthResult, type CollectAuthorDepthDeps } from './author-depth.js';
|
|
12
|
-
import {
|
|
12
|
+
import { probeDegradation, type DegradationSignal } from './degradation.js';
|
|
13
|
+
import { budgetTrafficTick, computeTrafficMetrics24h, readTrafficSamples24h, recordTrafficSample24h, type TrafficSampleDeps } from '../budget.js';
|
|
13
14
|
|
|
14
15
|
export const TRAFFIC_SEATS = ['OP', 'TC', 'MK', 'UX'] as const;
|
|
15
16
|
export type TrafficCell = Pick<ChecklistItem, 'id' | 'title' | 'owner' | 'status'>;
|
|
@@ -33,6 +34,11 @@ export type DispatchCycle = {
|
|
|
33
34
|
/** Separate journal: never extend or reinterpret seat-requests or per-run state rows. */
|
|
34
35
|
export function recordDispatchCycle(root: string, cycle: DispatchCycle,
|
|
35
36
|
log: (category: string, event: string, data: Record<string, unknown>) => void = debug.log.bind(debug)): void {
|
|
37
|
+
// 상시 게이트 관측: tick launch 노드와 runTrafficTick 이 지나는 이 배선 자체가 항상 켜져 있으므로
|
|
38
|
+
// 24h halt 저널은 이 자리에서 쌓인다 — `--metrics` 수동 읽기에만 매달면 관측 부재로 지표가
|
|
39
|
+
// 언제나 0이 되는 Goodhart 구조가 된다. 관측 전용: append 아래 원장 기록은 절대 막지 않는다.
|
|
40
|
+
try { observeGateHalt(root, { log }); }
|
|
41
|
+
catch { /* 게이트 저널은 관측일 뿐 — dispatch 원장은 관측 실패와 무관하게 기록된다 */ }
|
|
36
42
|
const path = join(root, 'orchestrator', 'dispatch-ledger.jsonl');
|
|
37
43
|
try {
|
|
38
44
|
mkdirSync(dirname(path), { recursive: true });
|
|
@@ -207,6 +213,10 @@ export function runTrafficTick({ processes, now, caps, openCells, nextRound, tot
|
|
|
207
213
|
skipped, dispatch: getUserConfig().loops?.orchestrator?.dispatch ?? ORCHESTRATOR_DEFAULTS.dispatch,
|
|
208
214
|
});
|
|
209
215
|
}
|
|
216
|
+
// 24h metrics journal: observation only, silent on the decision log, never read for this decision path.
|
|
217
|
+
recordTrafficSample24h(root, { at: now.toISOString(), seats: result.seats }, { log: () => {} });
|
|
218
|
+
// 게이트 관측은 위 recordDispatchCycle 상시 배선(과 tick launch 노드의 동일 호출)에서 매 사이클
|
|
219
|
+
// 쌓인다 — 이 틱에서 중복 관측을 또 하지 않는다. 관측 전용, 이 판정 경로는 이 저널을 읽지 않는다.
|
|
210
220
|
let authorShadow: AuthorShadow | null = null;
|
|
211
221
|
let shadowFailure: Record<string, unknown> | null = null;
|
|
212
222
|
try {
|
|
@@ -228,9 +238,129 @@ export function runTrafficTick({ processes, now, caps, openCells, nextRound, tot
|
|
|
228
238
|
return { result, queued, authorShadow };
|
|
229
239
|
}
|
|
230
240
|
|
|
241
|
+
export type GateObservation = { at: string; level: 'L1' | 'L2' | null };
|
|
242
|
+
|
|
243
|
+
/** Map a degradation probe to the gate level that stops place/delegate/launch; L2 is the stronger gate. */
|
|
244
|
+
export function gateLevelOf(signal: Pick<DegradationSignal, 'llm' | 'board'>): 'L1' | 'L2' | null {
|
|
245
|
+
if (!signal.board) return 'L2';
|
|
246
|
+
if (!signal.llm) return 'L1';
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface GateHaltDeps {
|
|
251
|
+
signal?: Pick<DegradationSignal, 'llm' | 'board'>;
|
|
252
|
+
probe?: (root: string) => Pick<DegradationSignal, 'llm' | 'board'>;
|
|
253
|
+
log?: (category: string, event: string, data: Record<string, unknown>) => void;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** Observation-only journal for the 24h gate metric: probe the degradation gates and append the level. */
|
|
257
|
+
export function observeGateHalt(root: string, deps: GateHaltDeps = {}): GateObservation {
|
|
258
|
+
const log = deps.log ?? debug.log.bind(debug);
|
|
259
|
+
const signal = deps.signal ?? deps.probe?.(root) ?? probeDegradation(root);
|
|
260
|
+
const observation: GateObservation = { at: new Date().toISOString(), level: gateLevelOf(signal) };
|
|
261
|
+
const path = join(root, 'orchestrator', 'gate-halt-24h.jsonl');
|
|
262
|
+
try {
|
|
263
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
264
|
+
withFileLockSync(`${path}.lock`, () => {
|
|
265
|
+
const previous = existsSync(path) ? readFileSync(path, 'utf8') : '';
|
|
266
|
+
const separator = previous === '' || previous.endsWith('\n') ? '' : '\n';
|
|
267
|
+
appendFileSync(path, `${separator}${JSON.stringify(observation)}\n`);
|
|
268
|
+
});
|
|
269
|
+
log('loop.orchestrator', 'gate-halt-24h', { ...observation, path });
|
|
270
|
+
} catch (error) {
|
|
271
|
+
try { log('loop.orchestrator', 'gate-halt-24h-failed', { error: String(error).slice(0, 200) }); }
|
|
272
|
+
catch { /* Observation cannot change a recorded decision. */ }
|
|
273
|
+
}
|
|
274
|
+
return observation;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Read the 24h gate journal; torn lines are skipped (same rule as the dispatch ledger). */
|
|
278
|
+
export function readGateObservations24h(root: string, now: Date, windowMinutes = 1440): GateObservation[] {
|
|
279
|
+
const path = join(root, 'orchestrator', 'gate-halt-24h.jsonl');
|
|
280
|
+
if (!existsSync(path)) return [];
|
|
281
|
+
const floor = now.getTime() - windowMinutes * 60_000;
|
|
282
|
+
return readFileSync(path, 'utf8').split('\n').flatMap(line => {
|
|
283
|
+
if (!line.trim()) return [];
|
|
284
|
+
try {
|
|
285
|
+
const parsed = JSON.parse(line) as GateObservation;
|
|
286
|
+
const at = Date.parse(parsed.at);
|
|
287
|
+
if (!Number.isFinite(at) || at < floor || at > now.getTime()) return [];
|
|
288
|
+
if (parsed.level !== null && parsed.level !== 'L1' && parsed.level !== 'L2') return [];
|
|
289
|
+
return [parsed];
|
|
290
|
+
} catch { return []; }
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/** Read the dispatch ledger verbatim journal; torn lines are skipped, kept only for forensics. */
|
|
295
|
+
export function readDispatchLedger(root: string, now: Date, windowMinutes = 1440): DispatchCycle[] {
|
|
296
|
+
const path = join(root, 'orchestrator', 'dispatch-ledger.jsonl');
|
|
297
|
+
if (!existsSync(path)) return [];
|
|
298
|
+
const floor = now.getTime() - windowMinutes * 60_000;
|
|
299
|
+
return readFileSync(path, 'utf8').split('\n').flatMap(line => {
|
|
300
|
+
if (!line.trim()) return [];
|
|
301
|
+
try {
|
|
302
|
+
const parsed = JSON.parse(line) as DispatchCycle;
|
|
303
|
+
const at = Date.parse(parsed.at);
|
|
304
|
+
if (!Number.isFinite(at) || at < floor || at > now.getTime()) return [];
|
|
305
|
+
return [parsed];
|
|
306
|
+
} catch { return []; }
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** Gate-halted minutes: gate-active spans where the verbatim ledger shows zero launch attempts AND the gate's
|
|
311
|
+
* own skip reason (degraded-skip) — a gate-active span with no demand is not halted time. */
|
|
312
|
+
export function gateHaltedLaunchMinutes({ gate, ledger }: {
|
|
313
|
+
gate: readonly GateObservation[];
|
|
314
|
+
ledger?: readonly DispatchCycle[];
|
|
315
|
+
}): { minutes: number; launchAttempts: number; haltedTicks: number; activeObservations: number } {
|
|
316
|
+
const points = gate.map(observation => ({ observation, t: Date.parse(observation.at) }))
|
|
317
|
+
.filter(point => Number.isFinite(point.t)).sort((a, b) => a.t - b.t);
|
|
318
|
+
const cycles = (ledger ?? []).map(cycle => ({ cycle, t: Date.parse(cycle.at) }))
|
|
319
|
+
.filter(entry => Number.isFinite(entry.t));
|
|
320
|
+
let minutes = 0;
|
|
321
|
+
let launchAttempts = 0;
|
|
322
|
+
let haltedTicks = 0;
|
|
323
|
+
let activeObservations = 0;
|
|
324
|
+
for (const point of points) {
|
|
325
|
+
if (point.observation.level !== null) activeObservations++;
|
|
326
|
+
}
|
|
327
|
+
for (let i = 1; i < points.length; i++) {
|
|
328
|
+
if (points[i].observation.level === null || points[i - 1].observation.level === null) continue;
|
|
329
|
+
const from = points[i - 1].t;
|
|
330
|
+
const to = points[i].t;
|
|
331
|
+
const inSpan = cycles.filter(entry => entry.t >= from && entry.t <= to);
|
|
332
|
+
const attempts = inSpan.reduce((sum, entry) => sum + entry.cycle.eligible, 0);
|
|
333
|
+
// Only the ledger's own skip reason proves the gate stopped launches: eligible is structurally 0 while the
|
|
334
|
+
// gate skips, so attempts === 0 alone would also count zero-demand spans as «halted» (Goodhart).
|
|
335
|
+
const gateSkipped = inSpan.reduce((sum, entry) => sum + (entry.cycle.skipped['degraded-skip'] ?? 0), 0);
|
|
336
|
+
launchAttempts += attempts;
|
|
337
|
+
if (attempts === 0 && gateSkipped > 0) {
|
|
338
|
+
haltedTicks++;
|
|
339
|
+
minutes += Math.max(0, (to - from) / 60_000);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return { minutes, launchAttempts, haltedTicks, activeObservations };
|
|
343
|
+
}
|
|
344
|
+
|
|
231
345
|
if (import.meta.main) {
|
|
232
346
|
try {
|
|
233
347
|
const args = process.argv.slice(2);
|
|
348
|
+
if (args.includes('--metrics')) {
|
|
349
|
+
if (args.some(arg => arg !== '--metrics' && arg !== '--json'))
|
|
350
|
+
throw new Error('usage: traffic.ts [--version <판>] [--json] | --metrics [--json]');
|
|
351
|
+
const root = effectiveInstanceRoot();
|
|
352
|
+
const now = new Date();
|
|
353
|
+
const observation = observeGateHalt(root);
|
|
354
|
+
const gate = gateHaltedLaunchMinutes({ gate: readGateObservations24h(root, now), ledger: readDispatchLedger(root, now) });
|
|
355
|
+
const traffic = computeTrafficMetrics24h(readTrafficSamples24h(root, now));
|
|
356
|
+
const report = { at: now.toISOString(), version: devVersion().replace(/-dev\.\d+$/, ''), traffic,
|
|
357
|
+
gate: { ...gate, observation } };
|
|
358
|
+
if (args.includes('--json')) console.log(JSON.stringify(report));
|
|
359
|
+
else {
|
|
360
|
+
const wait = traffic.meanWaitMinutes === null ? '?' : `${traffic.meanWaitMinutes}분`;
|
|
361
|
+
console.log(`traffic-24h utilization=${traffic.utilizationRate} (${traffic.running}/${traffic.capacity}) · mean-wait=${wait} (표본 ${traffic.waitSamples}) · preemptions=${traffic.preemptedSeatTicks} · gate-halt=${gate.minutes}분 (발사시도 ${gate.launchAttempts}) · ticks=${traffic.sampledTicks} · window=${traffic.windowMinutes}분`);
|
|
362
|
+
}
|
|
363
|
+
} else {
|
|
234
364
|
const versionFlag = args.indexOf('--version');
|
|
235
365
|
const version = versionFlag < 0 ? devVersion().replace(/-dev\.\d+$/, '') : args[versionFlag + 1];
|
|
236
366
|
if (!version || version.startsWith('--')
|
|
@@ -253,6 +383,7 @@ if (import.meta.main) {
|
|
|
253
383
|
});
|
|
254
384
|
if (args.includes('--json')) console.log(JSON.stringify({ ...result, mode: cfg.trafficMode, queued, version, authorShadow }));
|
|
255
385
|
else console.log(trafficLine(result, cfg.trafficMode));
|
|
386
|
+
}
|
|
256
387
|
} catch (error) {
|
|
257
388
|
console.error(`traffic: ${error instanceof Error ? error.message : String(error)}`);
|
|
258
389
|
process.exitCode = 1;
|
|
@@ -1132,10 +1132,9 @@ export interface StaleOpenerCheck {
|
|
|
1132
1132
|
}
|
|
1133
1133
|
|
|
1134
1134
|
/** 설치 checkout의 Git 객체 그래프에서 선후를 확인한다. 알 수 없으면 다른 판으로 남긴다. */
|
|
1135
|
-
function revisionRelation(openerSha: string | null | undefined, installedSha: string | null): StaleOpenerCheck['revisionRelation'] {
|
|
1135
|
+
function revisionRelation(openerSha: string | null | undefined, installedSha: string | null, root = resolve(dirname(fileURLToPath(import.meta.url)), '../../..')): StaleOpenerCheck['revisionRelation'] {
|
|
1136
1136
|
if (!openerSha || !installedSha) return 'different';
|
|
1137
1137
|
if (openerSha === installedSha) return 'same';
|
|
1138
|
-
const root = resolve(dirname(fileURLToPath(import.meta.url)), '../../..');
|
|
1139
1138
|
const ancestor = (from: string, to: string): boolean =>
|
|
1140
1139
|
spawnSync('git', ['-C', root, 'merge-base', '--is-ancestor', from, to], { timeout: 2_000, stdio: 'ignore' }).status === 0;
|
|
1141
1140
|
if (ancestor(openerSha, installedSha)) return 'older';
|
|
@@ -1167,17 +1166,17 @@ export interface StaleOpenerAlert {
|
|
|
1167
1166
|
* 전 경로 fail-soft — 수호자가 retention 을 절대 깨지 않는다. */
|
|
1168
1167
|
export function alertStaleLogDbOpeners(
|
|
1169
1168
|
dbPath: string,
|
|
1170
|
-
deps: { openers?: () => LogDbOpenerInfo[]; installedAtMs?: number | null } = {},
|
|
1169
|
+
deps: { openers?: () => LogDbOpenerInfo[]; installedAtMs?: number | null; installedRoot?: string } = {},
|
|
1171
1170
|
): StaleOpenerAlert[] {
|
|
1172
1171
|
const alerts: StaleOpenerAlert[] = [];
|
|
1173
1172
|
try {
|
|
1174
1173
|
// must-fix: 옛 판 판정 마커는 모듈 파일 mtime 이 아니라 «설치 sha 의 설치 시점»이다.
|
|
1175
|
-
const marker = resolveInstalledRevisionMarker();
|
|
1174
|
+
const marker = resolveInstalledRevisionMarker(deps.installedRoot);
|
|
1176
1175
|
const installedAtMs = deps.installedAtMs ?? marker.installedAtMs;
|
|
1177
1176
|
const openers = (deps.openers ?? (() => scanLogDbOpeners(dbPath)))();
|
|
1178
1177
|
for (const opener of openers) {
|
|
1179
1178
|
const relation = opener.revisionSha && marker.sha
|
|
1180
|
-
? revisionRelation(opener.revisionSha, marker.sha) : undefined;
|
|
1179
|
+
? revisionRelation(opener.revisionSha, marker.sha, deps.installedRoot) : undefined;
|
|
1181
1180
|
if (relation === 'different') {
|
|
1182
1181
|
debug.log('log-store.retention', 'different-opener-alert', {
|
|
1183
1182
|
pid: opener.pid, db: dbPath, openerSha: opener.revisionSha, installedSha: marker.sha,
|
|
@@ -6,7 +6,8 @@ import { parse as parseYaml } from 'yaml';
|
|
|
6
6
|
import { elanousStateRoot } from '../../autopilot/state-paths.js';
|
|
7
7
|
import { debug } from '../../debug/log.js';
|
|
8
8
|
import { defaultGraphsDir, loadGraphTemplatesFrom } from '../../self-implement/graph-templates.js';
|
|
9
|
-
import { loadGraphTemplates } from '../../self-implement/graph-yaml.js';
|
|
9
|
+
import { graphVersionHash, loadGraphTemplates, parseGraphTemplateYaml } from '../../self-implement/graph-yaml.js';
|
|
10
|
+
import { flattenGraphTemplate } from '../../self-implement/graph-unit-resolver.js';
|
|
10
11
|
import { validateGraphYaml } from './graph-kinds.js';
|
|
11
12
|
import { parseWizardSteps, readWizardSteps, withWizardSteps } from '../../graph-wizard/saved-steps.js';
|
|
12
13
|
import type { WizardNodeStep } from '../../graph-wizard/steps.js';
|
|
@@ -115,7 +116,7 @@ export async function handleGraphAccessPut(pathname: string, req: Request, deps:
|
|
|
115
116
|
|
|
116
117
|
/** The peer token works only on this graph and the requested read/edit operation. */
|
|
117
118
|
export function graphAccessForRequest(pathname: string, method: string, token: string | null, deps: GraphsApiDeps = {}): boolean {
|
|
118
|
-
const match = /^\/v1\/graphs\/([^/]+)(?:\/(yaml))?$/.exec(pathname);
|
|
119
|
+
const match = /^\/v1\/graphs\/([^/]+)(?:\/(yaml|flat))?$/.exec(pathname);
|
|
119
120
|
const id = match ? resolveId(match[1]!) : null;
|
|
120
121
|
if (!id || !token || !TOKEN_PATTERN.test(token)) return false;
|
|
121
122
|
if (method !== 'GET' && !(method === 'PUT' && match?.[2] === 'yaml')) return false;
|
|
@@ -266,7 +267,7 @@ export function handleGraphsGet(pathname: string, dir = defaultGraphsDir(), deps
|
|
|
266
267
|
return jsonResponse({ graphs: [...(core.ok ? core.graphs : []), ...mine.filter((graph) => !coreIds.has(graph.id))] });
|
|
267
268
|
}
|
|
268
269
|
|
|
269
|
-
const yamlMatch = /^\/v1\/graphs\/([^/]+)\/yaml$/.exec(pathname);
|
|
270
|
+
const yamlMatch = /^\/v1\/graphs\/([^/]+)\/(yaml|flat)$/.exec(pathname);
|
|
270
271
|
if (yamlMatch) {
|
|
271
272
|
const id = resolveId(yamlMatch[1]!);
|
|
272
273
|
if (!id) return jsonResponse({ error: 'bad_request', reason: 'invalid graph id' }, 400);
|
|
@@ -274,6 +275,24 @@ export function handleGraphsGet(pathname: string, dir = defaultGraphsDir(), deps
|
|
|
274
275
|
const coreHit = core.ok ? indexByDeclaredId(coreDir).get(id) : undefined;
|
|
275
276
|
const hit = mineHit ?? coreHit;
|
|
276
277
|
if (!hit) return jsonResponse({ error: 'not-found', id }, 404);
|
|
278
|
+
if (pathname.endsWith('/flat')) {
|
|
279
|
+
const parsed = parseGraphTemplateYaml(hit.text, hit.file);
|
|
280
|
+
const spec = parsed.template;
|
|
281
|
+
if (!spec || parsed.errors.length) return jsonResponse({ error: 'invalid-graph', id, issues: parsed.errors }, 422);
|
|
282
|
+
try {
|
|
283
|
+
const flat = flattenGraphTemplate(spec, join(mineHit ? mineDir : coreDir, hit.file));
|
|
284
|
+
return jsonResponse({
|
|
285
|
+
id, source: mineHit ? 'mine' : 'core', editable: false,
|
|
286
|
+
entry_node: flat.entryNode,
|
|
287
|
+
terminal_nodes: flat.terminalNodes,
|
|
288
|
+
graph_hash: graphVersionHash(flat),
|
|
289
|
+
nodes: flat.nodes.map(({ nodeId, kind, recipe, maxVisits }) => ({ node_id: nodeId, kind, recipe, max_visits: maxVisits })),
|
|
290
|
+
edges: flat.edges.map(({ from, to, on, map, fallback }) => ({ from, ...(to === undefined ? {} : { to }), ...(on === undefined ? {} : { on }), ...(map === undefined ? {} : { map }), ...(fallback === undefined ? {} : { fallback }) })),
|
|
291
|
+
});
|
|
292
|
+
} catch (error) {
|
|
293
|
+
return jsonResponse({ error: 'unit-flatten-failed', id, message: error instanceof Error ? error.message : String(error) }, 422);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
277
296
|
const steps = mineHit ? readWizardSteps(mineDir, id, hit.text) : null;
|
|
278
297
|
return jsonResponse({ id, source: mineHit ? 'mine' : 'core', editable: Boolean(mineHit), yaml: hit.text, ...(steps ? { steps } : {}) });
|
|
279
298
|
}
|
|
@@ -3004,7 +3004,7 @@ export async function routeRequest(
|
|
|
3004
3004
|
return handleGraphAccess(pathname, req);
|
|
3005
3005
|
}
|
|
3006
3006
|
// F-M1 read + P-F1 raw YAML. Writes live in the mutation block and never touch core graphs/.
|
|
3007
|
-
if (method === 'GET' && (pathname === '/v1/graphs' || /^\/v1\/graphs\/[^/]+$/.test(pathname) || /^\/v1\/graphs\/[^/]+\/yaml$/.test(pathname))) {
|
|
3007
|
+
if (method === 'GET' && (pathname === '/v1/graphs' || /^\/v1\/graphs\/[^/]+$/.test(pathname) || /^\/v1\/graphs\/[^/]+\/(?:yaml|flat)$/.test(pathname))) {
|
|
3008
3008
|
return handleGraphsGet(pathname);
|
|
3009
3009
|
}
|
|
3010
3010
|
if (method === 'GET' && /^\/v1\/graphs\/[^/]+\/versions$/.test(pathname)) {
|
package/src/nexus/api/ops-api.ts
CHANGED
|
@@ -221,6 +221,18 @@ export function handleOpsApi(req: Request, metaApi: MetaApiOpts | undefined): Re
|
|
|
221
221
|
? served(jsonResponse(resourcesFromOverview(peeked.snapshot, peeked.pods, peeked.at)))
|
|
222
222
|
: served(jsonResponse({ stale: true })));
|
|
223
223
|
}
|
|
224
|
+
if (pathname === '/v1/ops/loops-map') {
|
|
225
|
+
// LOOP-MAP-API — projects only the shared overview cache's loops snapshot
|
|
226
|
+
// (name·era·beat cell observedAt; null/unmeasured value and reason preserved);
|
|
227
|
+
// no new remote fan-out of its own. Loop-edge joining is a later shard.
|
|
228
|
+
overviewCache ??= createOverviewCache();
|
|
229
|
+
return overviewCache.get()
|
|
230
|
+
.then((overview) => served(jsonResponse({
|
|
231
|
+
generatedAt: overview.generatedAt,
|
|
232
|
+
cacheAgeMs: overview.cacheAgeMs,
|
|
233
|
+
loops: overview.loops.map((loop) => ({ name: loop.name, era: loop.era, beat: loop.beat })),
|
|
234
|
+
})), () => jsonResponse({ error: 'overview-unavailable' }, 500));
|
|
235
|
+
}
|
|
224
236
|
if (pathname === '/v1/ops/seats') {
|
|
225
237
|
const date = url.searchParams.get('date') ?? todayKst();
|
|
226
238
|
if (!DATE.test(date) || Number.isNaN(Date.parse(`${date}T00:00:00+09:00`))) return jsonResponse({ error: 'invalid-date' }, 400);
|