elanous 0.2.31 → 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/{LSXfY0u9QtfDbejY0Ukf_ → 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-0a07363b130182a1.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-df3445b207ceceab.js +1 -0
- 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/_next/static/css/b5d88eba78a3d7bf.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 +26 -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/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 +11 -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 +95 -17
- 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/measure-si-task-cpu.ts +143 -0
- package/scripts/public-export.ts +43 -1
- package/scripts/ratchets/test-interference-patterns.allowlist.txt +0 -2
- 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/prepare-node.ts +102 -4
- 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 +36 -9
- package/src/acp/elanous-extensions.ts +3 -0
- package/src/acp/reasoning-thought-buffer.ts +45 -0
- package/src/acp/server.ts +3 -0
- package/src/acp/tool-trace.ts +186 -11
- package/src/agent/self-ambient-cache.ts +156 -0
- package/src/agent/self-ambient.ts +8 -1
- package/src/agent/task-notification.ts +5 -0
- package/src/agent-substrate/acp-reviewer.ts +52 -12
- package/src/agent-substrate/pr-reviewer.ts +3 -1
- 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/ask-user-question/tool.ts +22 -0
- package/src/autopilot/build/llm-conflict-merge.ts +56 -10
- package/src/autopilot/pr-manager.ts +213 -46
- package/src/capture/frame-state-detect.ts +39 -0
- package/src/capture/tui-self-report.ts +134 -6
- package/src/chat/index.ts +61 -15
- package/src/chat/pickers/modal-runtime.ts +6 -0
- package/src/chat/pickers/modals.ts +8 -2
- package/src/chat/tool-render/dispatch.ts +62 -10
- package/src/cli/ask-bare.ts +1 -0
- package/src/cli/control-cli.ts +24 -7
- package/src/cli/guardian-cli.ts +10 -0
- package/src/cli/import-cli.ts +12 -0
- package/src/cli/light-entry-route.ts +35 -0
- package/src/cli/llm-detect-cli.ts +23 -1
- package/src/cli/log-event-names.ts +10 -0
- package/src/cli/msg-cli.ts +1 -0
- package/src/cli/pod-cli.ts +14 -3
- package/src/cli/pr-cli.ts +140 -41
- package/src/cli/pr-land-base-read.ts +36 -0
- package/src/cli/pr-land-heavy-remote.ts +81 -25
- package/src/cli/pr-land-overlap-evidence.ts +200 -18
- package/src/cli/pr-land-pod-shadow-job.ts +26 -3
- package/src/cli/pr-land-recovery.ts +64 -0
- package/src/cli/pr-land-refusal.ts +20 -5
- package/src/cli/pty-takeover-cli.ts +94 -19
- 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/sim-cli.ts +18 -0
- package/src/cli/tasks-cli.ts +149 -5
- package/src/context-bus/ops-events.ts +6 -2
- 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/run-core-turn.ts +1 -0
- package/src/core-turn/run-goal-loop.ts +21 -0
- package/src/core-turn/short-question.ts +5 -1
- package/src/core-turn/types.ts +3 -0
- package/src/dashboard/acp-active-model.ts +42 -1
- package/src/dashboard/background-jobs-status.ts +66 -0
- package/src/dashboard/index.ts +153 -111
- package/src/dashboard/input/agent-wake.ts +242 -0
- package/src/dashboard/input/chat-main-entry-runtime.ts +5 -0
- 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/external-input-host.ts +23 -9
- package/src/dashboard/input/mouse-wiring.ts +108 -11
- package/src/dashboard/input/seat-autowake.ts +56 -3
- package/src/dashboard/log-click-runtime.ts +118 -2
- 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 +163 -41
- package/src/dashboard/turn-session-layers.ts +4 -2
- package/src/dashboard/turn-start-segments.ts +222 -0
- 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/display/prompt-row-owner.ts +146 -0
- package/src/display/resize-listener.ts +33 -2
- package/src/domains/guardian-tick.ts +54 -2
- package/src/domains/outbound-alert.ts +3 -2
- package/src/extractors.ts +3 -1
- package/src/fold-stack.ts +4 -2
- package/src/git-fs/index.ts +263 -36
- 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/gate-reserve.ts +87 -0
- package/src/harness/harness-cli-command.ts +39 -10
- package/src/harness/harness-incidents.ts +17 -0
- package/src/harness/harness-pod-dispatch.ts +38 -1
- package/src/harness/harness-queue.ts +15 -0
- package/src/harness/harness-salvage-cli.ts +14 -2
- package/src/index.ts +198 -12
- package/src/input/external-input-queue.ts +34 -9
- 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/route-decision.ts +36 -0
- package/src/llm/tool-loop-steered-rejection.ts +8 -0
- package/src/llm-request-shape.ts +209 -0
- package/src/llm.ts +221 -276
- package/src/loops/budget.ts +95 -0
- package/src/loops/msg-wake.ts +8 -2
- package/src/loops/orchestrator/tick.ts +24 -2
- package/src/loops/orchestrator/traffic.ts +132 -1
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/mss/logging/log-store.ts +4 -5
- package/src/mss/logging/render-categories.ts +5 -0
- 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 +70 -2
- package/src/pr-tool/census.ts +41 -8
- package/src/pr-tool/inflight-registry.ts +296 -0
- 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-manifest.ts +12 -3
- package/src/pty-shell/pty-write-outcome.ts +24 -6
- package/src/pty-shell/tui-run-state.ts +151 -6
- 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/seat-loop/traffic-signal.ts +2 -1
- package/src/self-dev/ask-launch-flow.ts +13 -0
- package/src/self-dev/draft-residue.ts +243 -24
- 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-dev/shard-plan.ts +11 -3
- package/src/self-dev/shard-run.ts +103 -10
- package/src/self-implement/elanous-tui-spawn.ts +14 -0
- package/src/self-implement/follow-up-placement.ts +79 -0
- package/src/self-implement/gate-artifacts.ts +15 -4
- package/src/self-implement/gate-baseline.ts +145 -10
- package/src/self-implement/gate-cli.ts +7 -2
- package/src/self-implement/gate-remote.ts +35 -6
- 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/host-regate.ts +36 -4
- package/src/self-implement/knowhow-pack.ts +103 -0
- package/src/self-implement/orchestrator.ts +109 -11
- 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-ledger.ts +16 -14
- 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/index.ts +22 -267
- package/src/session-runtime/retry-policy.ts +2 -1
- package/src/shell-runner/background-surface.ts +15 -5
- package/src/skills/tools/agent.ts +39 -6
- package/src/skills/tools/list-dir.ts +11 -0
- package/src/skills/tools/schedule-wakeup.ts +457 -0
- package/src/skills/tools/shell.ts +245 -3
- package/src/status/bar.ts +26 -0
- package/src/steward/digest-delivery.ts +118 -0
- package/src/steward/hold-hygiene.ts +120 -0
- package/src/steward/release-day.ts +7 -3
- package/src/steward/triage.ts +47 -4
- package/src/surface/shell-runner-boot.ts +5 -2
- 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 +76 -5
- 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 +67 -12
- package/src/task-orchestrator/surfaces/pod-lease.ts +98 -0
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
- package/src/task-orchestrator/surfaces/pod-pool.ts +76 -18
- package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +10 -6
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +54 -4
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +548 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +389 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runner.ts +90 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +158 -3
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +230 -43
- package/src/task-orchestrator/surfaces/self-implement.ts +83 -2
- package/src/tool-runtime/truncation-store.ts +4 -0
- package/src/tui/chat/execution-badge.ts +5 -1
- package/src/tui/input-lag-probe.ts +230 -0
- package/src/tui-client/dashboard-session.ts +10 -1
- package/src/tui.ts +4 -0
- package/src/user-config/coercion.ts +36 -0
- package/src/user-config.ts +18 -41
- package/src/ux-sim/scenario.ts +314 -0
- 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-50625904996a8fa8.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/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-92f87bd108322f66.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-bf3634a117322df7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-3535a4a69f1fafaa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-b9f51447f757fbf2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-2ebb8fd59b9461f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-a2fc4e49a4fa4ba8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-5a503541353e60a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-6025101384e361a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-f4b630cc8b5273cd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-a645f00a06483e9a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-61ac22cbab1ee4ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e9bab7413b028b28.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c992eafe028b642e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-e547e6ce55f1fb33.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-d27e1b9850fd54bf.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-805ac2e137b7a121.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-0fec29c7ba01894b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-339a07410cd6f36b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-349f2752d8cd37ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-d5c6dcf31c25cecc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-2fd93ed8c9f16580.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-9b564dbff0fefc35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-62f4475d3c38fb9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-814ba51385225776.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-397d479626e5a459.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-af1bba4e3251b728.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ad3be5e7d3fdce9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-f219ccdbc0bf27df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4da93ad35d4a8d28.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-456666766e5ce6fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-7404e377e8adb8c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-14456240ed2a36ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-3a658d5fa6d16a25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-0157de6e85f8bb6b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-841d73d4ac44ed49.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6f43a3d1146e6377.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-521ee23ac8c0abfa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-a9992ee285efaa83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-3d48e85fa89ec04f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-d2ced71132fac9b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-f08358bdf251adb9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-233c71cd5f68f0d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-70151d78de2f375e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-dcac33a3e2cb72c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-149dc1caba411bb9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0448145ccd5c45c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-9cb0c444903da65d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-17e504c396e0e389.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/apps/pwa/out/_next/static/css/3f5fc6f96e2cf7b2.css +0 -1
- package/src/cli/g6a-registration-probe.ts +0 -16
- /package/apps/pwa/out/_next/static/{LSXfY0u9QtfDbejY0Ukf_ → L04y73dlwKeTW-GetaTF3}/_ssgManifest.js +0 -0
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);
|
|
@@ -3,7 +3,9 @@ import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renam
|
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
import { CardStore, taskCardsDir, type TaskCard } from '../../task-cards/card-store.js';
|
|
5
5
|
import { Database } from 'bun:sqlite';
|
|
6
|
-
import { type ChecklistItem } from '../../release-loop/checklist.js';
|
|
6
|
+
import { checklistDevVersion, listChecklist, type ChecklistItem } from '../../release-loop/checklist.js';
|
|
7
|
+
import { readTrafficSignal } from '../../seat-loop/traffic-signal.js';
|
|
8
|
+
import { runHoldHygiene, type HygieneCell, type HygieneDeps } from '../../steward/hold-hygiene.js';
|
|
7
9
|
import { effectiveInstanceRoot } from '../../instance/resolve.js';
|
|
8
10
|
import { getUserConfig, ORCHESTRATOR_DEFAULTS, resolveConfiguredAgentRoleLlm, type OrchestratorLoopConfig } from '../../user-config.js';
|
|
9
11
|
import { rubricPriority } from '../../release-loop/rubric.js';
|
|
@@ -63,6 +65,8 @@ export type RebalanceAdapter = (version: string) => Promise<{ decisions: unknown
|
|
|
63
65
|
export interface TickDeps {
|
|
64
66
|
root?: string; now?: Date | (() => Date); mode?: Mode; runId?: string; window?: Window;
|
|
65
67
|
heartbeatIntervalMs?: number;
|
|
68
|
+
hygieneCells?: () => HygieneCell[];
|
|
69
|
+
hygienePaths?: Pick<HygieneDeps, 'trafficPath' | 'metaPath' | 'dispatcherDir'>;
|
|
66
70
|
cards?: () => TaskCard[]; split?: SplitAdapter; placeCell?: PlaceAdapter;
|
|
67
71
|
degradation?: () => { llm: boolean; board: boolean };
|
|
68
72
|
gridHosts?: readonly GridHost[];
|
|
@@ -888,7 +892,25 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
|
|
|
888
892
|
}
|
|
889
893
|
}
|
|
890
894
|
}
|
|
891
|
-
} else if (node === 'report')
|
|
895
|
+
} else if (node === 'report') {
|
|
896
|
+
if (mode === 'live') {
|
|
897
|
+
try {
|
|
898
|
+
const signal = readTrafficSignal(deps.hygienePaths?.trafficPath);
|
|
899
|
+
const versions = signal && !('unreadable' in signal) && signal.versions?.length ? signal.versions : [checklistDevVersion()];
|
|
900
|
+
let cells: HygieneCell[] = [];
|
|
901
|
+
if (deps.hygieneCells) cells = deps.hygieneCells();
|
|
902
|
+
else if (signal && !('unreadable' in signal) && signal.hold?.length) {
|
|
903
|
+
for (const version of versions) {
|
|
904
|
+
try { cells.push(...listChecklist(version).items); }
|
|
905
|
+
catch (error) { observe('hold-hygiene-checklist-unreadable', `${version}:${String(error).slice(0, 100)}`, 0); }
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
const sent = runHoldHygiene({ root, now, cells, ...deps.hygienePaths });
|
|
909
|
+
for (const notice of sent) observe('exchange', `hold-hygiene:${notice.key}`, 1, SEAT_LOOP_IDS[notice.to]);
|
|
910
|
+
} catch (error) { observe('hold-hygiene-failed', String(error).slice(0, 160), 0); }
|
|
911
|
+
}
|
|
912
|
+
(deps.print ?? console.log)(reportLine(state));
|
|
913
|
+
}
|
|
892
914
|
state.nodes[node] = 'ok';
|
|
893
915
|
} else if (state.nodes[node] !== 'ok') {
|
|
894
916
|
// A rerun of a node that already completed keeps its result (review round 3): only never-run nodes become skipped.
|
|
@@ -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;
|
|
@@ -82,7 +82,7 @@ export const FEATURE_MATURITY = {
|
|
|
82
82
|
onboarding: 'beta', login: 'stable', session: 'beta', chat: 'stable', repl: 'stable',
|
|
83
83
|
agent: 'stable', registry: 'beta', tier: 'stable', local: 'beta', scheduler: 'beta',
|
|
84
84
|
attach: 'beta', wf: 'beta', nexus: 'stable', phone: 'beta', token: 'beta',
|
|
85
|
-
acp: 'beta', voice: 'beta',
|
|
85
|
+
acp: 'beta', voice: 'beta', sim: 'beta',
|
|
86
86
|
'run-detached': 'system', dogfood: 'system', run: 'system',
|
|
87
87
|
},
|
|
88
88
|
// Canonical names only; aliases inherit their command's grade at lookup.
|
|
@@ -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,
|
|
@@ -79,6 +79,11 @@ export const RENDER_CATEGORY_EXEMPTIONS: ReadonlyMap<string, string> = new Map([
|
|
|
79
79
|
// ⛔ 접두 전체(`dashboard`)를 풀지 «않는다» — 그러면 진짜 렌더 소음이 되살아난다. 이 둘만 뗀다.
|
|
80
80
|
['dashboard.turn-typeahead', 'Mid-turn input queueing decisions — which key was consumed, what was queued, and when it drains. Turn-control judgment, not frame noise.'],
|
|
81
81
|
['dashboard.streaming-key', 'Streaming-window key ownership — whether a key reached the streaming dispatcher at all. This is the probe that answers "is the ladder live?", so it must survive render mute.'],
|
|
82
|
+
// ⛔ 2026-10-17 (`TUI-H8-SEAT-BOOT-LOG-MUTED`) — 자리 부트 카드는 «항상성» 이벤트다(렌더 소음 아님).
|
|
83
|
+
// `/session new` 뒤 카드가 실렸는지를 `logs --all --include-test` 로도 0행으로 만들어
|
|
84
|
+
// «카드가 빠졌다»와 «음소거됐다»를 가를 수 없었다. 접두 전체는 풀지 않고 이것만 뗀다.
|
|
85
|
+
// (`tui.autoturn`·`tui.wakeup`·`tui.autowake` 는 `tui` 가 렌더 접두가 아니라 애초에 안 잘린다.)
|
|
86
|
+
['dashboard.seat-boot', 'Seat boot card lifecycle — conversation-start, card-injected, card-skipped. Homeostasis evidence that the seat card reached the turn, not frame noise.'],
|
|
82
87
|
]);
|
|
83
88
|
|
|
84
89
|
/** Reject an exemption without its required, human-readable rationale. */
|
|
@@ -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);
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { debug } from '../debug/log.js';
|
|
2
|
+
import { classifyLedgerRun, queryUsageOutcomes, type UsageOutcomesDeps } from '../budget/usage-outcomes.js';
|
|
3
|
+
import { loadRunLedger } from '../self-implement/run-ledger.js';
|
|
4
|
+
|
|
1
5
|
export type ClaudePtyMaturity =
|
|
2
6
|
| { readonly mature: true }
|
|
3
7
|
| { readonly mature: false; readonly why: 'too-few-samples' | 'completion-below-70' | 'unknown-screen-above-10' | 'intervention-above-0.2' | 'sample-unreadable' };
|
|
@@ -9,6 +13,68 @@ export type ClaudePtyMaturitySample = {
|
|
|
9
13
|
readonly interventionCount: number;
|
|
10
14
|
};
|
|
11
15
|
|
|
16
|
+
/** Read the latest Claude PTY runs from the run ledger without changing the ledger or fallback path. */
|
|
17
|
+
export function collectClaudePtyMaturitySample(
|
|
18
|
+
deps: UsageOutcomesDeps & { readonly limit?: number },
|
|
19
|
+
): ClaudePtyMaturitySample | null {
|
|
20
|
+
const limit = deps.limit ?? 10;
|
|
21
|
+
const nowMs = deps.nowMs ?? Date.now();
|
|
22
|
+
let runCount = 0;
|
|
23
|
+
let completedCount = 0;
|
|
24
|
+
let readable = Number.isSafeInteger(limit) && limit > 0;
|
|
25
|
+
let sample: ClaudePtyMaturitySample | null = null;
|
|
26
|
+
|
|
27
|
+
if (readable) {
|
|
28
|
+
const ledgers: { readonly runId: string; readonly entries: NonNullable<ReturnType<NonNullable<UsageOutcomesDeps['load']>>> }[] = [];
|
|
29
|
+
const load = deps.load ?? loadRunLedger;
|
|
30
|
+
try {
|
|
31
|
+
// The maturity sample is over the latest runs, not over a recent time window.
|
|
32
|
+
// Number.MAX_SAFE_INTEGER days covers the full JavaScript Date range.
|
|
33
|
+
const report = queryUsageOutcomes(Number.MAX_SAFE_INTEGER, {
|
|
34
|
+
...deps,
|
|
35
|
+
load: (runId, dir, read) => {
|
|
36
|
+
const entries = load(runId, dir, read);
|
|
37
|
+
if (entries) ledgers.push({ runId, entries });
|
|
38
|
+
return entries;
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
const runs = ledgers.flatMap(({ runId, entries }) => {
|
|
42
|
+
const classified = classifyLedgerRun(entries, nowMs);
|
|
43
|
+
return classified?.provider === 'claude-pty' ? [{ runId, entries, classified }] : [];
|
|
44
|
+
}).sort((left, right) => right.classified.atMs - left.classified.atMs || right.runId.localeCompare(left.runId))
|
|
45
|
+
.slice(0, limit);
|
|
46
|
+
runCount = runs.length;
|
|
47
|
+
completedCount = runs.filter(({ classified }) => classified.outcome === 'landed').length;
|
|
48
|
+
readable = report.unreadableLedgers === 0 && runs.every(({ entries }) => {
|
|
49
|
+
const hasUnknownScreens = entries.some((entry) => Object.hasOwn(entry.data, 'claudePtyUnknownScreens'));
|
|
50
|
+
const hasInterventions = entries.some((entry) => Object.hasOwn(entry.data, 'humanInterventions'));
|
|
51
|
+
const unknownScreens = entries.find((entry) => Object.hasOwn(entry.data, 'claudePtyUnknownScreens'))?.data.claudePtyUnknownScreens;
|
|
52
|
+
const interventions = entries.find((entry) => Object.hasOwn(entry.data, 'humanInterventions'))?.data.humanInterventions;
|
|
53
|
+
return hasUnknownScreens && hasInterventions
|
|
54
|
+
&& typeof unknownScreens === 'number' && Number.isSafeInteger(unknownScreens) && unknownScreens >= 0
|
|
55
|
+
&& typeof interventions === 'number' && Number.isSafeInteger(interventions) && interventions >= 0;
|
|
56
|
+
});
|
|
57
|
+
if (readable) {
|
|
58
|
+
sample = runs.reduce<ClaudePtyMaturitySample>((total, { entries }) => {
|
|
59
|
+
const unknownScreens = entries.find((entry) => Object.hasOwn(entry.data, 'claudePtyUnknownScreens'))!.data.claudePtyUnknownScreens as number;
|
|
60
|
+
const interventions = entries.find((entry) => Object.hasOwn(entry.data, 'humanInterventions'))!.data.humanInterventions as number;
|
|
61
|
+
return {
|
|
62
|
+
runCount: total.runCount + 1,
|
|
63
|
+
completedCount: total.completedCount,
|
|
64
|
+
unknownScreenCount: total.unknownScreenCount + unknownScreens,
|
|
65
|
+
interventionCount: total.interventionCount + interventions,
|
|
66
|
+
};
|
|
67
|
+
}, { runCount: 0, completedCount, unknownScreenCount: 0, interventionCount: 0 });
|
|
68
|
+
}
|
|
69
|
+
} catch {
|
|
70
|
+
readable = false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
debug.log('oauth.claude-pty', 'maturity-sample', { runCount, completedCount, readable });
|
|
75
|
+
return readable ? sample : null;
|
|
76
|
+
}
|
|
77
|
+
|
|
12
78
|
/** 최근 런의 계수만 판정한다. 표본을 못 읽거나 계수가 불가능하면 성숙으로 추정하지 않는다. */
|
|
13
79
|
export function judgeClaudePtyMaturity(sample: ClaudePtyMaturitySample | null | undefined): ClaudePtyMaturity {
|
|
14
80
|
if (!sample || ![sample.runCount, sample.completedCount, sample.unknownScreenCount, sample.interventionCount]
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** Codex access-only credential copies for hosts that must never own refresh authority. */
|
|
2
|
+
|
|
3
|
+
export interface CodexAccessMirrorInput {
|
|
4
|
+
account: string;
|
|
5
|
+
store: { version?: number; providers: Record<string, Record<string, unknown>> };
|
|
6
|
+
codexAuth: { [key: string]: unknown; auth_mode?: string; tokens: Record<string, unknown> };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface CodexAccessMirror {
|
|
10
|
+
/** Minimal elanous auth store containing only this account's access token. */
|
|
11
|
+
elanousAuth: string;
|
|
12
|
+
/** Codex CLI auth document with refresh authority removed. */
|
|
13
|
+
codexAuth: string;
|
|
14
|
+
expiresAt: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Build the same refresh-less access-token copies used by Pod credentials. */
|
|
18
|
+
export function createCodexAccessMirror(input: CodexAccessMirrorInput): CodexAccessMirror {
|
|
19
|
+
const storeKey = input.account === 'default' ? 'openai-codex' : `openai-codex:${input.account}`;
|
|
20
|
+
const entry = input.store.providers[storeKey] as {
|
|
21
|
+
tokens?: Record<string, unknown>; lastRefresh?: string; authMode?: string;
|
|
22
|
+
} | undefined;
|
|
23
|
+
if (!entry?.tokens) throw new Error(`${storeKey} 계정이 없다`);
|
|
24
|
+
|
|
25
|
+
const accessToken = input.codexAuth.tokens.access_token;
|
|
26
|
+
if (typeof accessToken !== 'string' || !accessToken) throw new Error(`${storeKey} access token 이 없다`);
|
|
27
|
+
// The Codex auth document is the authority for its own auth_mode. Store metadata
|
|
28
|
+
// remains available in elanousAuth, but must not be synthesized into auth.json.
|
|
29
|
+
const authMode = input.codexAuth.auth_mode;
|
|
30
|
+
if (authMode !== undefined && (typeof authMode !== 'string' || !authMode.trim())) throw new Error(`${storeKey} Codex CLI auth_mode 가 비어 있다`);
|
|
31
|
+
let payload: { exp?: unknown };
|
|
32
|
+
try {
|
|
33
|
+
payload = JSON.parse(Buffer.from(accessToken.split('.')[1] ?? '', 'base64url').toString('utf8')) as { exp?: unknown };
|
|
34
|
+
} catch { throw new Error(`${storeKey} access token 만료를 읽을 수 없다`); }
|
|
35
|
+
const expiresAt = Number(payload.exp) * 1000;
|
|
36
|
+
if (!Number.isFinite(expiresAt) || expiresAt <= 0) throw new Error(`${storeKey} access token 만료를 읽을 수 없다`);
|
|
37
|
+
|
|
38
|
+
const elanousAuth = JSON.stringify({
|
|
39
|
+
version: input.store.version ?? 1,
|
|
40
|
+
providers: {
|
|
41
|
+
'openai-codex': {
|
|
42
|
+
tokens: { ...entry.tokens, accessToken, expiresAt, refreshToken: '', refresh_token: '' },
|
|
43
|
+
lastRefresh: entry.lastRefresh,
|
|
44
|
+
authMode: entry.authMode,
|
|
45
|
+
chatGPT: { accountId: input.codexAuth.tokens.account_id },
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
const codexAuth = JSON.stringify({
|
|
50
|
+
...input.codexAuth,
|
|
51
|
+
auth_mode: authMode,
|
|
52
|
+
tokens: { ...input.codexAuth.tokens, refresh_token: '', refreshToken: '' },
|
|
53
|
+
});
|
|
54
|
+
return { elanousAuth, codexAuth, expiresAt };
|
|
55
|
+
}
|
|
@@ -28,7 +28,7 @@ import type { ClaudePtyMaturity } from './claude-pty-maturity.js';
|
|
|
28
28
|
* 그 grok 마저 못 쓰면 갈 곳이 없었다 — 이 칸을 grok «뒤»에 두면 그때만 크레딧으로 돌아온다.
|
|
29
29
|
* ⛔ 첫 칸의 크레딧 금지(`codexQuotaPolicy`)는 그대로다 — 이 칸은 «체인이 여기까지 왔을 때»만 돈을 쓴다.
|
|
30
30
|
* ⛔ 기본 체인에는 «없다» — 돈이라 사람이 config 에 «명시»할 때만 켜진다. */
|
|
31
|
-
export const FALLBACK_STEPS = ['codex-rotate', 'grok', 'claude-pty', 'openrouter', 'codex-credits'] as const;
|
|
31
|
+
export const FALLBACK_STEPS = ['codex-rotate', 'grok', 'zai', 'claude-pty', 'openrouter', 'codex-credits'] as const;
|
|
32
32
|
export type FallbackStep = (typeof FALLBACK_STEPS)[number];
|
|
33
33
|
|
|
34
34
|
/** 기본 체인 — ⛔⭐ **2026-08-20 에 `grok` 이 «기본»으로 들어왔다**(대표 지시).
|