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
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// 부작용(kubectl·파일)은 주입받는다 — 시험은 가짜 kubectl 로 누른다.
|
|
13
13
|
|
|
14
14
|
import { podSkillsDigest, readSkillEnvFiles, resolvePodSkills } from './pod-skills.js';
|
|
15
|
-
import { emitPodLifecycle, parseSiTaskPodStages, siTaskPodLifecycleEvent, siTaskPodStageShell } from './pod-lifecycle-stages.js';
|
|
15
|
+
import { emitPodLifecycle, parseSiTaskDepsSkipped, parseSiTaskPodStages, siTaskPodK8sTiming, siTaskPodLifecycleEvent, siTaskPodStageShell } from './pod-lifecycle-stages.js';
|
|
16
16
|
import { podSourceScript, type PodSource } from './pod-source-receive.js';
|
|
17
17
|
import { GROUNDING_TOKEN_ENV, GROUNDING_URL_ENV, mintGroundingToken, revokeGroundingRun, type GroundingTokenScope } from '../../grounding/token.js';
|
|
18
18
|
import { POD_CREDENTIAL_GROK_PATH, POD_CREDENTIAL_GITHUB_PATH, POD_GITHUB_CREDENTIAL_TOKEN_ENV, POD_GITHUB_CREDENTIAL_URL_ENV, installationRepositories } from '../../nexus/api/pod-credential-api.js';
|
|
@@ -22,6 +22,7 @@ import { collectPodLedgers, createPodLedgerFollower } from './pod-ledger-collect
|
|
|
22
22
|
import { collectPodArtifacts, podNoResultDiagnostic } from './pod-artifact-return.js';
|
|
23
23
|
import { readPodRepairArtifact } from './pod-repair-commit.js';
|
|
24
24
|
import { isValidAccountName, resolveCodexAccount } from '../../oauth/codex-account.js';
|
|
25
|
+
import { createCodexAccessMirror } from '../../oauth/codex-access-mirror.js';
|
|
25
26
|
import { effectiveInstanceRoot } from '../../instance/resolve.js';
|
|
26
27
|
import { controlInboxEnv } from '../../harness/control-inbox.js';
|
|
27
28
|
import { finishPodFragment, writePodFragment } from '../../harness/self-send-target.js';
|
|
@@ -97,9 +98,15 @@ import { classifyPodExit, extractPodFailureReason, podTerminalRow, type PodExitC
|
|
|
97
98
|
import { kubectlTransientReason, retryKubectlTransient } from './kubectl-transient-retry.js';
|
|
98
99
|
import { OLD_DOOR_STAMP_ENV } from '../../self-dev/old-door.js';
|
|
99
100
|
import { resolveDefaultSourceHead, seedMirrorOnce, type MirrorSeedResult } from './pod-mirror-seed.js';
|
|
101
|
+
import { decideWarmReuse, type WarmReuseEvidenceByConsumer, type WarmReuseSwitchConfig } from './pod-warm-switch.js';
|
|
102
|
+
import type { WarmWorkerCommand } from './pod-warm-worker-protocol.js';
|
|
103
|
+
import type { WarmPodTransportResult } from './pod-warm-worker-pod.js';
|
|
100
104
|
|
|
101
105
|
export type Kubectl = (args: readonly string[], input?: string) => { status: number | null; stdout: string; stderr: string };
|
|
102
106
|
|
|
107
|
+
/** TC supplies the validated candidate/lease transport. UX only forwards its request command. */
|
|
108
|
+
export type WarmPodRequestHook = (request: { command: WarmWorkerCommand }) => Promise<WarmPodTransportResult> | WarmPodTransportResult;
|
|
109
|
+
|
|
103
110
|
// gh auth login may reject installation tokens when validating /user. Its config is
|
|
104
111
|
// still the credential source for gh and setup-git's helper. Install it privately
|
|
105
112
|
// on that failure; rename keeps concurrent readers from seeing a partial token.
|
|
@@ -148,6 +155,11 @@ export interface PodSpawnOptions {
|
|
|
148
155
|
seedMirror?: (o: { host: string; commit: string; cwd: string }) => Promise<MirrorSeedResult | undefined>;
|
|
149
156
|
/** Git tree that has the pinned commit for the mirror seed (default: process.cwd()). */
|
|
150
157
|
mirrorSeedCwd?: string;
|
|
158
|
+
/** TA warm-reuse shadow evidence/config seams. Missing evidence must stay off; no warm candidate is consumed here. */
|
|
159
|
+
warmReuseConfig?: () => WarmReuseSwitchConfig | undefined;
|
|
160
|
+
warmReuseEvidence?: () => WarmReuseEvidenceByConsumer | undefined;
|
|
161
|
+
/** Optional warm-pool observation/preparation hook. It never replaces the feature implementation Job. */
|
|
162
|
+
warmPodRequest?: WarmPodRequestHook;
|
|
151
163
|
/** SI-SEED-DEFAULT — resolves a default source's branch tip for the mirror seed (test seam · default
|
|
152
164
|
* {@link resolveDefaultSourceHead}; none with an injected kubectl unless given). */
|
|
153
165
|
resolveSourceHead?: (o: { repoUrl: string; base?: string; cwd: string }) => Promise<{ sha?: string; reason?: string }>;
|
|
@@ -423,7 +435,7 @@ async function defaultHqLeaseHolder(): Promise<boolean> {
|
|
|
423
435
|
}
|
|
424
436
|
|
|
425
437
|
/** 호스트 계정 → refresh 없는 사본(elanous 저장소 ⊕ codex auth.json) ⊕ gh 토큰. */
|
|
426
|
-
export function hostCredentials(account: string, storePath: string = authStorePath(), ghToken: () => string = defaultGhToken): { elanousAuth: string; codexAuth: string; ghToken: string } {
|
|
438
|
+
export function hostCredentials(account: string, storePath: string = authStorePath(), ghToken: () => string = defaultGhToken, options: { requireExplicitChatgptAuthMode?: boolean } = {}): { elanousAuth: string; codexAuth: string; ghToken: string } {
|
|
427
439
|
// 경로는 해석기로(격리 게이트 · 2026-09-25) — 손으로 `~/.elanous/auth.json` 을 조립하면 test↔prod 격리가 새는 자리가 된다.
|
|
428
440
|
const store = JSON.parse(readFileSync(storePath, 'utf8')) as { version?: number; providers: Record<string, Record<string, unknown>> };
|
|
429
441
|
// ⭐ 기본 계정은 정본 키가 `openai-codex`(이름 없음)이고 홈을 안 적는다 — 기본 위치로 푼다(회전 후보와 같은 해석).
|
|
@@ -431,22 +443,70 @@ export function hostCredentials(account: string, storePath: string = authStorePa
|
|
|
431
443
|
const entry = store.providers[storeKey] as { tokens: Record<string, unknown>; lastRefresh?: string; authMode?: string; codexHome?: string } | undefined;
|
|
432
444
|
const codexHome = entry?.codexHome ?? (entry && account === 'default' ? resolveCodexAccount(envLiteral({ CODEX_HOME: process.env.CODEX_HOME })).home : undefined);
|
|
433
445
|
if (!entry || !codexHome) throw new Error(`${storeKey} 계정이 없거나 codexHome 을 모른다`);
|
|
434
|
-
const codex = JSON.parse(readFileSync(join(codexHome, 'auth.json'), 'utf8')) as { tokens: Record<string, unknown> };
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
+
const codex = JSON.parse(readFileSync(join(codexHome, 'auth.json'), 'utf8')) as { auth_mode?: string; tokens: Record<string, unknown> };
|
|
447
|
+
// Remote parents must not infer this from store metadata; ordinary Pod callers retain the legacy fallback.
|
|
448
|
+
if (options.requireExplicitChatgptAuthMode && codex.auth_mode !== 'chatgpt') throw new Error(`${storeKey} Codex CLI auth_mode must be explicitly chatgpt for remote parent`);
|
|
449
|
+
const mirror = createCodexAccessMirror({ account, store, codexAuth: codex });
|
|
450
|
+
const hoursLeft = (mirror.expiresAt - Date.now()) / 3_600_000;
|
|
451
|
+
if (hoursLeft < 3) throw new PodCodexExpiringError(account, Math.round(hoursLeft * 10) / 10);
|
|
452
|
+
// ⭐ P4(2026-09-26): both stores use the just-checked Codex access token; the stores refresh independently.
|
|
453
|
+
return { elanousAuth: mirror.elanousAuth, codexAuth: mirror.codexAuth, ghToken: ghToken() };
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/** POD-GROK-VALIDITY-FIT (10-17) — the Pod gets a refresh-less grok access copy, so the copy must outlive the Job.
|
|
457
|
+
* It used to require 3 h (= the full POD_JOB_DEADLINE_SECONDS), but the token lives only 6 h and the grok CLI renews it
|
|
458
|
+
* only right before expiry (`grok models`/`grok -p` leave `expires_at` unchanged — node-b refreshOutcome:"unchanged"), and
|
|
459
|
+
* the CLI has no forced-refresh command (`grok --help`/`grok login --help` 10-17: login·logout only). So half of every
|
|
460
|
+
* day refused grok Pod launches (10-17 node-b·node-c·mbp 9 no-launch · 3 hand re-logins).
|
|
461
|
+
* ⇒ The Job is fitted to the token instead: a launch is allowed when the token has at least a minimum Job
|
|
462
|
+
* (POD_GROK_MIN_JOB_SECONDS) plus a margin left, and that launch's `activeDeadlineSeconds` is cut to the token's
|
|
463
|
+
* remaining life minus the margin (`fitPodDeadlineToGrok`) — so a long run ends as a classified DeadlineExceeded
|
|
464
|
+
* instead of a silent mid-run 401. With the host credential relay (pod.groundingUrl) the Pod renews mid-run and
|
|
465
|
+
* nothing is cut. 90 min = the Job cap before 대표 09-26 raised it (only two runs had reached it). */
|
|
466
|
+
export const POD_GROK_MIN_JOB_SECONDS = 90 * 60;
|
|
467
|
+
/** Slack between the fitted Job end and the token expiry (clock skew · Pod scheduling). */
|
|
468
|
+
export const POD_GROK_EXPIRY_MARGIN_MS = 15 * 60_000;
|
|
469
|
+
/** Minimum remaining token life for a grok Pod launch = minimum Job + margin (1 h 45 m). */
|
|
470
|
+
export const POD_GROK_MIN_VALIDITY_MS = POD_GROK_MIN_JOB_SECONDS * 1000 + POD_GROK_EXPIRY_MARGIN_MS;
|
|
471
|
+
|
|
472
|
+
/** «1h45m» · «20m» · «만료» — remaining-time text for refusal lines (no token value). */
|
|
473
|
+
export function formatGrokRemaining(ms: number | null): string {
|
|
474
|
+
if (ms === null || !Number.isFinite(ms)) return '알 수 없음';
|
|
475
|
+
if (ms <= 0) return '만료됨';
|
|
476
|
+
const m = Math.floor(ms / 60_000);
|
|
477
|
+
return m >= 60 ? `${Math.floor(m / 60)}h${String(m % 60).padStart(2, '0')}m` : `${m}m`;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/** Latest `expires_at` among scopes that carry an access key (the token the Pod would get). */
|
|
481
|
+
function grokSubscriptionExpiresAtMs(home?: string): number | null {
|
|
482
|
+
try {
|
|
483
|
+
const scopes = JSON.parse(readFileSync(grokAuthFilePath(home), 'utf8')) as Record<string, { key?: unknown; expires_at?: unknown }>;
|
|
484
|
+
const all = Object.values(scopes).flatMap((s) => (s && typeof s.key === 'string' && s.key && typeof s.expires_at === 'string' && Number.isFinite(Date.parse(s.expires_at)) ? [Date.parse(s.expires_at)] : []));
|
|
485
|
+
return all.length ? Math.max(...all) : null;
|
|
486
|
+
} catch { return null; }
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/** POD-GROK-VALIDITY-FIT — this launch's Job deadline for a refresh-less grok subscription copy.
|
|
490
|
+
* · relay (the Pod can renew from the host) or unknown expiry → the requested deadline as is.
|
|
491
|
+
* · otherwise → min(requested, remaining − margin); below the minimum Job (time passed since the credential check)
|
|
492
|
+
* the launch is refused — the deadline never outlives the token. */
|
|
493
|
+
export function fitPodDeadlineToGrok(o: { requestedSeconds: number; expiresAtMs: number | null; nowMs: number; relay: boolean }):
|
|
494
|
+
{ refused: false; deadlineSeconds: number; fitted: boolean; availableSeconds: number | null } | { refused: true; availableSeconds: number } {
|
|
495
|
+
if (o.relay || o.expiresAtMs === null || !Number.isFinite(o.expiresAtMs)) return { refused: false, deadlineSeconds: o.requestedSeconds, fitted: false, availableSeconds: null };
|
|
496
|
+
const availableSeconds = Math.floor((o.expiresAtMs - o.nowMs - POD_GROK_EXPIRY_MARGIN_MS) / 1000);
|
|
497
|
+
if (availableSeconds < POD_GROK_MIN_JOB_SECONDS) return { refused: true, availableSeconds };
|
|
498
|
+
if (availableSeconds >= o.requestedSeconds) return { refused: false, deadlineSeconds: o.requestedSeconds, fitted: false, availableSeconds };
|
|
499
|
+
return { refused: false, deadlineSeconds: availableSeconds, fitted: true, availableSeconds };
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/** Expiry of the access the Pod will actually use — only scopes with a key, latest wins (same rule as the Pod reader). */
|
|
503
|
+
export function shippedGrokExpiresAtMs(grokAuth: string): number | null {
|
|
504
|
+
try {
|
|
505
|
+
const scopes = JSON.parse(grokAuth) as Record<string, { key?: unknown; expires_at?: unknown }>;
|
|
506
|
+
const all = Object.values(scopes).flatMap((sc) => (sc && typeof sc.key === 'string' && sc.key && typeof sc.expires_at === 'string' && Number.isFinite(Date.parse(sc.expires_at)) ? [Date.parse(sc.expires_at)] : []));
|
|
507
|
+
return all.length ? Math.max(...all) : null;
|
|
508
|
+
} catch { return null; }
|
|
446
509
|
}
|
|
447
|
-
|
|
448
|
-
/** A Pod gets a refresh-less access copy, so the copy must outlive the Job: same rule as the Codex path (3 h). */
|
|
449
|
-
export const POD_GROK_MIN_VALIDITY_MS = 3 * 3600_000;
|
|
450
510
|
/** PODCRED1 (10-05): an App installation token lives ~60 min and the host renews it in the Pod at the ten-minute
|
|
451
511
|
* boundary; below this remaining life at launch the token is observed (`github-app-short-lived`). */
|
|
452
512
|
export const POD_APP_TOKEN_MIN_START_MS = 20 * 60_000;
|
|
@@ -466,13 +526,21 @@ export function hostGrokCredentials(opts: {
|
|
|
466
526
|
home?: string; env?: NodeJS.ProcessEnv; apiKeyOptIn?: boolean; ghToken?: () => string;
|
|
467
527
|
/** Test seams — the host refresh (read-only `grok models`) and the expiry probe. */
|
|
468
528
|
refresh?: () => void; isExpiring?: () => boolean;
|
|
529
|
+
/** Required remaining token life (default POD_GROK_MIN_VALIDITY_MS) — a caller whose Job is not fitted passes its own deadline. */
|
|
530
|
+
minValidityMs?: number; now?: () => number;
|
|
469
531
|
} = {}): { grokAuth?: string; grokApiKey?: string; ghToken: string } {
|
|
470
532
|
let credential = resolveGrokCredential({ home: opts.home, env: opts.env });
|
|
471
533
|
if (credential?.kind === 'subscription') {
|
|
472
|
-
const
|
|
534
|
+
const minValidityMs = opts.minValidityMs ?? POD_GROK_MIN_VALIDITY_MS;
|
|
535
|
+
const expiring = opts.isExpiring ?? (() => isGrokSubscriptionExpiring({ home: opts.home, bufferMs: minValidityMs, ...(opts.now ? { now: opts.now } : {}) }));
|
|
473
536
|
if (expiring()) {
|
|
474
537
|
try { (opts.refresh ?? (() => { refreshGrokSubscriptionToken({ home: opts.home }); }))(); } catch { /* judged below */ }
|
|
475
|
-
if (expiring())
|
|
538
|
+
if (expiring()) {
|
|
539
|
+
const at = grokSubscriptionExpiresAtMs(opts.home);
|
|
540
|
+
const remainingMs = at === null ? null : at - (opts.now ?? Date.now)();
|
|
541
|
+
try { debug.log('pod.grok-credentials', 'refused', { remainingMs, minValidityMs, expiresAt: at === null ? null : new Date(at).toISOString() }); } catch { /* fail-soft */ }
|
|
542
|
+
throw new Error(`grok: 구독 access 토큰 남은 시간 ${formatGrokRemaining(remainingMs)} < Pod 발사 기준 ${formatGrokRemaining(minValidityMs)} — 호스트 갱신(grok models)도 못 늘렸다 · 다음: 호스트에서 grok login --device-auth 후 다시`);
|
|
543
|
+
}
|
|
476
544
|
credential = resolveGrokCredential({ home: opts.home, env: opts.env });
|
|
477
545
|
if (credential?.kind !== 'subscription') throw new Error('grok: 갱신 뒤 구독 자격을 다시 읽지 못했다');
|
|
478
546
|
}
|
|
@@ -554,9 +622,12 @@ export function grokLaunchReadiness(opts: { home?: string; env?: NodeJS.ProcessE
|
|
|
554
622
|
}
|
|
555
623
|
|
|
556
624
|
/** The one launch line for a skipped grok copy — the reader sees why grok left this run's chain. */
|
|
557
|
-
export function podGrokSkippedLine(skip: { reason: PodGrokSkipReason; expiresAt: string | null }): string {
|
|
625
|
+
export function podGrokSkippedLine(skip: { reason: PodGrokSkipReason; expiresAt: string | null }, now?: () => number): string {
|
|
558
626
|
const why = skip.reason === 'missing' ? '구독 자격 없음' : skip.reason === 'expiring' ? '만료 임박' : '만료 임박 · 호스트 갱신 실패';
|
|
559
|
-
|
|
627
|
+
const at = skip.expiresAt ? Date.parse(skip.expiresAt) : NaN;
|
|
628
|
+
const left = skip.reason !== 'missing' && Number.isFinite(at) ? ` · 남은 ${formatGrokRemaining(at - (now ?? Date.now)())} < 기준 ${formatGrokRemaining(POD_GROK_MIN_VALIDITY_MS)}` : '';
|
|
629
|
+
const next = skip.reason === 'missing' ? '' : ' · 다음: 호스트에서 grok login --device-auth';
|
|
630
|
+
return `⚠️ grok 자격 없음(${why}${skip.expiresAt ? ` · 만료 ${skip.expiresAt}` : ''}${left}) — 이 런의 폴백 체인에서 grok 을 뺐다${next}`;
|
|
560
631
|
}
|
|
561
632
|
|
|
562
633
|
/** 키 캐시 관례: `~/.cache/<env 이름 소문자>`(예: OPENROUTER_API_KEY → ~/.cache/openrouter_api_key · src/config.ts 와 같다). */
|
|
@@ -769,7 +840,7 @@ export const POD_ATTEMPT_ANNOTATION = 'elanous.dev/attempt';
|
|
|
769
840
|
export function podRunLabels(o: { runId?: string; parentRunId?: string }): Record<string, string> {
|
|
770
841
|
const run = k8sLabelValue(o.parentRunId ?? o.runId);
|
|
771
842
|
const child = k8sLabelValue(o.runId);
|
|
772
|
-
return { ...(run ? { 'elanous.run': run } : {}), ...(child
|
|
843
|
+
return { ...(run ? { 'elanous.run': run } : {}), ...(child ? { 'elanous.child-run': child } : {}) };
|
|
773
844
|
}
|
|
774
845
|
|
|
775
846
|
/** Pod 메모리 «등급» — 대표 09-27: PWA Pod 골이 16Gi 에서 OOM 으로 죽는다 ⇒ «high» 등급을 옵션으로 고른다.
|
|
@@ -998,7 +1069,7 @@ export function podSigtermTrapScript(seqFile: string = POD_USAGE_PARTIAL_SEQ_FIL
|
|
|
998
1069
|
return `trap '{ [ -n "$si_pid" ] && kill "$si_pid" 2>/dev/null || true; [ -n "\${usage_partial_pid:-}" ] && kill "$usage_partial_pid" 2>/dev/null || true; si_seq=$(cat ${seqFile} 2>/dev/null || true); case "$si_seq" in ""|*[!0-9]*) si_seq=0;; esac; si_seq=$((10#$si_seq + 1)); { [ -f scripts/usage-rollup.ts ] && bun scripts/usage-rollup.ts --since 12h --partial --seq "$si_seq"; } & si_rollup_pid=$!; for si_i in 1 2 3 4 5 6 7 8; do kill -0 "$si_rollup_pid" 2>/dev/null || break; sleep 1; done; kill "$si_rollup_pid" 2>/dev/null || true; wait "$si_rollup_pid" 2>/dev/null || true; exit 143; }' TERM`;
|
|
999
1070
|
}
|
|
1000
1071
|
|
|
1001
|
-
export function podJobManifest(o: { name: string; namespace: string; image: string; workIdentity?: PodWorkIdentity; /** 레지스트리 이미지면 IfNotPresent(노드가 pull) · 반입 이미지면 Never. */ imagePullPolicy?: 'Never' | 'IfNotPresent'; repoUrl: string; source?: PodSource; repairCommitOnly?: { pr: number; baseHead: string }; hostMirror?: string; args: readonly string[]; passEnv: readonly string[]; deadlineSeconds: number; runId?: string; parentRunId?: string; armEnv?: Readonly<Record<string, string>>; hostId?: string; imageCommit?: string | null; skillEnvs?: readonly string[]; memoryLimit?: string; memoryRequest?: string; goalDoc?: string; /** AUTHOR-POD2 — run `harness say` on /creds/feature inside the Pod (authoring happens off the host). */ authorSentence?: boolean; authorGrade?: 'full' | 'lite'; grokCredential?: 'subscription' | 'api_key'; codexAccounts?: readonly string[]; appCredential?: boolean; /** Test seam — default POD_GH_STALE_SECONDS. */ githubStaleSeconds?: number; /** Which goal execution and attempt this Job is — a resumed host verifies it before following the Job (POD9). */ execution?: { key: string; attempt: number }; hostLeaseAdmitted?: boolean; /** POD-ROLE-LLM — OpenRouter 자식 Pod 에 리뷰어용 codex 자격을 깐다. */ reviewerCodexAuth?: boolean; /** BEDROCK-PROVIDER ② — bedrock 자식만: 이름 있는 AWS Secret 의 키(secretKeyRef) ⊕ 리전 ⊕ 이그레스 라벨. */ bedrock?: BedrockPodSpec; /** ZAI-POD-CHILD — glm(ZAI) 자식만: 이름 있는 ZAI Secret 의 키(secretKeyRef) ⊕ 이그레스·동시 상한 라벨(Pod ⊕ Job). */ zai?: ZaiPodSpec; fallbackChain?: { steps: readonly FallbackStep[]; source: 'host' | 'default' }; /** TA-POD-WARMBOOT-PARITY — the child's final line (podResultMarkerShellLine), just before `exit $rc`. */ resultMarkerLine?: string }): Record<string, unknown> {
|
|
1072
|
+
export function podJobManifest(o: { name: string; namespace: string; image: string; workIdentity?: PodWorkIdentity; boundPrNumber?: number; /** 레지스트리 이미지면 IfNotPresent(노드가 pull) · 반입 이미지면 Never. */ imagePullPolicy?: 'Never' | 'IfNotPresent'; repoUrl: string; source?: PodSource; repairCommitOnly?: { pr: number; baseHead: string }; hostMirror?: string; args: readonly string[]; passEnv: readonly string[]; deadlineSeconds: number; runId?: string; parentRunId?: string; armEnv?: Readonly<Record<string, string>>; hostId?: string; imageCommit?: string | null; skillEnvs?: readonly string[]; memoryLimit?: string; memoryRequest?: string; goalDoc?: string; /** AUTHOR-POD2 — run `harness say` on /creds/feature inside the Pod (authoring happens off the host). */ authorSentence?: boolean; authorGrade?: 'full' | 'lite'; grokCredential?: 'subscription' | 'api_key'; codexAccounts?: readonly string[]; appCredential?: boolean; /** Test seam — default POD_GH_STALE_SECONDS. */ githubStaleSeconds?: number; /** Which goal execution and attempt this Job is — a resumed host verifies it before following the Job (POD9). */ execution?: { key: string; attempt: number }; hostLeaseAdmitted?: boolean; /** POD-ROLE-LLM — OpenRouter 자식 Pod 에 리뷰어용 codex 자격을 깐다. */ reviewerCodexAuth?: boolean; /** BEDROCK-PROVIDER ② — bedrock 자식만: 이름 있는 AWS Secret 의 키(secretKeyRef) ⊕ 리전 ⊕ 이그레스 라벨. */ bedrock?: BedrockPodSpec; /** ZAI-POD-CHILD — glm(ZAI) 자식만: 이름 있는 ZAI Secret 의 키(secretKeyRef) ⊕ 이그레스·동시 상한 라벨(Pod ⊕ Job). */ zai?: ZaiPodSpec; /** Codex Job may use the same named Secret only for an explicitly admitted ZAI fallback. */ zaiFallback?: ZaiPodSpec; fallbackChain?: { steps: readonly FallbackStep[]; source: 'host' | 'default' }; /** TA-POD-WARMBOOT-PARITY — the child's final line (podResultMarkerShellLine), just before `exit $rc`. */ resultMarkerLine?: string }): Record<string, unknown> {
|
|
1002
1073
|
if (o.repairCommitOnly && (o.source?.kind !== 'pr' || o.source.number !== o.repairCommitOnly.pr || !/^[0-9a-f]{40}$/.test(o.repairCommitOnly.baseHead) || o.args.includes('--open-pr') || o.args.includes('--merge-by-host') || o.args.includes('--auto-merge'))) {
|
|
1003
1074
|
throw new Error('repair commit-only requires matching PR source and no PR/merge flags');
|
|
1004
1075
|
}
|
|
@@ -1057,6 +1128,9 @@ export function podJobManifest(o: { name: string; namespace: string; image: stri
|
|
|
1057
1128
|
siTaskPodStageShell('clone', 'start'),
|
|
1058
1129
|
podSourceScript(o.source ?? { kind: 'default' }, o.repoUrl, undefined, { stageMarkers: true }),
|
|
1059
1130
|
siTaskPodStageShell('clone', 'end'),
|
|
1131
|
+
// This image already contains runtime dependencies; there is no child install command.
|
|
1132
|
+
// Record that fact before the main command, without treating clone completion as install completion.
|
|
1133
|
+
`printf 'ELANOUS_POD_DEPS skipped %s image-prepared-no-install\\n' "$(date +%s)" || true`,
|
|
1060
1134
|
...(o.repairCommitOnly ? [`[ "$(git rev-parse HEAD)" = '${o.repairCommitOnly.baseHead}' ] || { echo 'ELANOUS_POD_REPAIR_FAILED source-head-mismatch'; exit 8; }`] : []),
|
|
1061
1135
|
...(goalPath ? [
|
|
1062
1136
|
`mkdir -p -- "$(dirname -- ${goalPath})" && cp -- /creds/goal-doc ${goalPath} || exit 6`,
|
|
@@ -1151,7 +1225,7 @@ if [ "$found" -eq 0 ]; then echo ELANOUS_RUN_LEDGER_NONE; fi`,
|
|
|
1151
1225
|
return {
|
|
1152
1226
|
apiVersion: 'batch/v1',
|
|
1153
1227
|
kind: 'Job',
|
|
1154
|
-
metadata: { name: o.name, namespace: o.namespace, labels: { 'elanous.substrate': 'pod', 'elanous.job': o.name, ...podRunLabels(o), ...(o.workIdentity ? podWorkLabels(o.workIdentity) : {}), ...(o.zai ? { [ZAI_POD_EGRESS_LABEL]: 'true' } : {}) },
|
|
1228
|
+
metadata: { name: o.name, namespace: o.namespace, labels: { 'elanous.substrate': 'pod', 'elanous.job': o.name, ...podRunLabels(o), ...(o.workIdentity ? podWorkLabels(o.workIdentity) : {}), ...(o.zai || o.zaiFallback ? { [ZAI_POD_EGRESS_LABEL]: 'true' } : {}) },
|
|
1155
1229
|
...((o.execution || o.hostLeaseAdmitted) ? { annotations: { ...(o.execution ? { [POD_EXECUTION_KEY_ANNOTATION]: o.execution.key, [POD_ATTEMPT_ANNOTATION]: String(o.execution.attempt) } : {}), ...(o.hostLeaseAdmitted ? { [POD_HOST_LEASE_ANNOTATION]: 'true' } : {}) } } : {}) },
|
|
1156
1230
|
spec: {
|
|
1157
1231
|
backoffLimit: 0,
|
|
@@ -1159,7 +1233,7 @@ if [ "$found" -eq 0 ]; then echo ELANOUS_RUN_LEDGER_NONE; fi`,
|
|
|
1159
1233
|
activeDeadlineSeconds: o.deadlineSeconds,
|
|
1160
1234
|
template: {
|
|
1161
1235
|
// ⭐ Pod 라벨 — local 팔만 `elanous.egress/local-llm` 을 단다. docker/h1/policy-local-llm.yaml 이 그 라벨에만 호스트 LLM 포트 «하나»를 연다.
|
|
1162
|
-
metadata: { labels: { 'elanous.job': o.name, ...podRunLabels(o), ...(o.workIdentity ? podWorkLabels(o.workIdentity) : {}), ...(o.armEnv?.ELANOUS_LLM_PROVIDER === 'local' ? { 'elanous.egress/local-llm': 'true' } : {}), ...(o.bedrock ? { [BEDROCK_POD_EGRESS_LABEL]: 'true' } : {}), ...(o.zai ? { [ZAI_POD_EGRESS_LABEL]: 'true' } : {}) } },
|
|
1236
|
+
metadata: { labels: { 'elanous.job': o.name, ...podRunLabels(o), ...(o.workIdentity ? podWorkLabels(o.workIdentity) : {}), ...(o.armEnv?.ELANOUS_LLM_PROVIDER === 'local' ? { 'elanous.egress/local-llm': 'true' } : {}), ...(o.bedrock ? { [BEDROCK_POD_EGRESS_LABEL]: 'true' } : {}), ...(o.zai || o.zaiFallback ? { [ZAI_POD_EGRESS_LABEL]: 'true' } : {}) } },
|
|
1163
1237
|
spec: {
|
|
1164
1238
|
restartPolicy: 'Never',
|
|
1165
1239
|
securityContext: { runAsUser: 1000, fsGroup: 1000 },
|
|
@@ -1175,6 +1249,8 @@ if [ "$found" -eq 0 ]; then echo ELANOUS_RUN_LEDGER_NONE; fi`,
|
|
|
1175
1249
|
...(o.runId ? [{ name: 'ELANOUS_RUN_ID', value: o.runId }] : []),
|
|
1176
1250
|
...(o.parentRunId ? [{ name: 'ELANOUS_PARENT_RUN_ID', value: o.parentRunId }] : []),
|
|
1177
1251
|
...(o.workIdentity?.taskCard ? [{ name: 'ELANOUS_TASK_CARD_ID', value: o.workIdentity.taskCard }] : []),
|
|
1252
|
+
...(o.boundPrNumber && Number.isSafeInteger(o.boundPrNumber) && o.boundPrNumber > 0
|
|
1253
|
+
? [{ name: 'ELANOUS_TASK_BOUND_PR', value: String(o.boundPrNumber) }] : []),
|
|
1178
1254
|
...(o.workIdentity?.slotId ? [{ name: 'ELANOUS_POD_SLOT_ID', value: o.workIdentity.slotId }] : []),
|
|
1179
1255
|
{ name: 'ELANOUS_SUBSTRATE', value: 'pod' },
|
|
1180
1256
|
...Object.entries(controlInboxEnv(POD_CONTROL_INBOX_DIR)).map(([name, value]) => ({ name, value })),
|
|
@@ -1189,7 +1265,7 @@ if [ "$found" -eq 0 ]; then echo ELANOUS_RUN_LEDGER_NONE; fi`,
|
|
|
1189
1265
|
...Object.entries(o.armEnv ?? {}).map(([name, value]) => ({ name, value })),
|
|
1190
1266
|
...o.passEnv.map((key) => ({ name: key, valueFrom: { secretKeyRef: { name: `${o.name}-creds`, key: `env-${key}` } } })),
|
|
1191
1267
|
...(o.bedrock ? bedrockPodEnv(o.bedrock) : []),
|
|
1192
|
-
...(o.zai ? zaiPodEnv(o.zai) : []),
|
|
1268
|
+
...(o.zai || o.zaiFallback ? zaiPodEnv(o.zai ?? o.zaiFallback!) : []),
|
|
1193
1269
|
],
|
|
1194
1270
|
volumeMounts: [{ name: 'creds', mountPath: '/creds', readOnly: true }, ...(o.hostMirror ? [{ name: 'host-mirror', mountPath: '/host-mirror', readOnly: true }] : [])],
|
|
1195
1271
|
}],
|
|
@@ -1342,9 +1418,9 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
1342
1418
|
const timer = setTimeout(() => {
|
|
1343
1419
|
if (stalledStages.has(stage)) return;
|
|
1344
1420
|
stalledStages.add(stage);
|
|
1345
|
-
const pool = options.pool as { waitReason?: () => string | null } | undefined;
|
|
1421
|
+
const pool = options.pool as { waitReason?: (memoryLimit?: string) => string | null } | undefined;
|
|
1346
1422
|
debug.log('harness.launch', 'launch-stalled', { spaceId: input.spaceId, runId: childRunId, stage, waitedSec: Math.round((Date.now() - started) / 1000),
|
|
1347
|
-
reason: (stage === 'pool-slot' ? stageReason['pool-slot'] : (typeof pool?.waitReason === 'function' ? pool.waitReason() : null)) ?? 'not-measured-yet' }, { level: 'warn' });
|
|
1423
|
+
reason: (stage === 'pool-slot' ? stageReason['pool-slot'] : (typeof pool?.waitReason === 'function' ? pool.waitReason(memoryLimit) : null)) ?? 'not-measured-yet' }, { level: 'warn' });
|
|
1348
1424
|
}, stallMs);
|
|
1349
1425
|
(timer as { unref?: () => void }).unref?.();
|
|
1350
1426
|
return () => clearTimeout(timer);
|
|
@@ -1387,7 +1463,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
1387
1463
|
const acquireAdmission = async (): Promise<boolean> => {
|
|
1388
1464
|
if (!options.pool || typeof options.pool.acquireAdmission !== 'function') return true;
|
|
1389
1465
|
const stop = watchStall('admission');
|
|
1390
|
-
try { releaseAdmission = await options.pool.acquireAdmission(input.signal, after); return true; }
|
|
1466
|
+
try { releaseAdmission = await options.pool.acquireAdmission(input.signal, after, { memoryLimit }); return true; }
|
|
1391
1467
|
catch (error) {
|
|
1392
1468
|
// A predecessor closed without merging is not a cancellation: surface it so the queue owner is notified.
|
|
1393
1469
|
if (error instanceof Error && error.message.startsWith('pod lease predecessor blocked')) admissionBlocked = error.message;
|
|
@@ -1432,7 +1508,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
1432
1508
|
const cleanupSecret = () => { kubectl(['-n', namespace, 'delete', 'secret', `${name}-creds`, '--ignore-not-found']); };
|
|
1433
1509
|
let repairResultAnnounced = false;
|
|
1434
1510
|
let repairArtifactReady = false;
|
|
1435
|
-
const collectFullLogs = (unavailableEvent: string, replace?: ReadonlySet<string>, onEvent?: (event: string, data: Record<string, unknown>) => void, childId?: string): { status: 'ok' | 'unavailable' | 'incomplete'; childLedgerIncomplete: boolean; samples: ReturnType<typeof parseMemSamples
|
|
1511
|
+
const collectFullLogs = (unavailableEvent: string, replace?: ReadonlySet<string>, onEvent?: (event: string, data: Record<string, unknown>) => void, childId?: string): { status: 'ok' | 'unavailable' | 'incomplete'; childLedgerIncomplete: boolean; samples: ReturnType<typeof parseMemSamples> } => {
|
|
1436
1512
|
let full: ReturnType<Kubectl>;
|
|
1437
1513
|
try {
|
|
1438
1514
|
full = kubectl(['-n', namespace, 'logs', `job/${name}`, '-c', 'child']);
|
|
@@ -1442,10 +1518,12 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
1442
1518
|
debug.log('self-implement.pod', unavailableEvent, { job: name, reason: error instanceof Error ? error.message : String(error) });
|
|
1443
1519
|
return { status: 'unavailable', childLedgerIncomplete: false, samples: [] };
|
|
1444
1520
|
}
|
|
1445
|
-
const via = /^ELANOUS_POD_SOURCE_VIA (mirror|github)\r?$/m.exec(full.stdout)?.[1];
|
|
1521
|
+
const via = /^ELANOUS_POD_SOURCE_VIA (image|mirror|github)\r?$/m.exec(full.stdout)?.[1];
|
|
1446
1522
|
// #28246 names why the mirror was skipped on the line before `VIA github`; carry it on the same event.
|
|
1447
1523
|
const mirrorSkip = /^ELANOUS_POD_SOURCE_MIRROR_SKIP (no-mount|rev-parse-failed|clone-failed)\r?$/m.exec(full.stdout)?.[1];
|
|
1448
|
-
|
|
1524
|
+
const imageSkip = /^ELANOUS_POD_SOURCE_IMAGE_SKIP ([^\r\n]+)\r?$/m.exec(full.stdout)?.[1];
|
|
1525
|
+
const delta = /^ELANOUS_POD_SOURCE_DELTA (mirror|origin)\r?$/m.exec(full.stdout)?.[1];
|
|
1526
|
+
if (via) debug.log('self-implement.pod', 'source-via', { job: name, via, ...(mirrorSkip ? { mirrorSkip } : {}), ...(imageSkip ? { imageSkip } : {}), ...(delta ? { delta } : {}) });
|
|
1449
1527
|
let ledgerIncomplete = false;
|
|
1450
1528
|
let childLedgerIncomplete = false;
|
|
1451
1529
|
let artifactIncomplete = false;
|
|
@@ -1478,7 +1556,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
1478
1556
|
record('self-implement.pod', 'repair-artifact-incomplete', { job: name, reason: error instanceof Error ? error.message : String(error) });
|
|
1479
1557
|
}
|
|
1480
1558
|
}
|
|
1481
|
-
return { status: ledgerIncomplete || artifactIncomplete ? 'incomplete' : 'ok', childLedgerIncomplete, samples: parseMemSamples(full.stdout)
|
|
1559
|
+
return { status: ledgerIncomplete || artifactIncomplete ? 'incomplete' : 'ok', childLedgerIncomplete, samples: parseMemSamples(full.stdout) };
|
|
1482
1560
|
};
|
|
1483
1561
|
let retryAccount: string | undefined;
|
|
1484
1562
|
let retrySamples: ReturnType<typeof parseMemSamples> = [];
|
|
@@ -1590,6 +1668,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
1590
1668
|
}
|
|
1591
1669
|
bedrockSpec = checked.spec;
|
|
1592
1670
|
}
|
|
1671
|
+
let jobDeadlineSeconds = options.deadlineSeconds ?? POD_JOB_DEADLINE_SECONDS;
|
|
1593
1672
|
const creds = grok
|
|
1594
1673
|
? (options.grokCredentials ?? (() => hostGrokCredentials({ env, apiKeyOptIn: options.grokApiKeyOptIn })))()
|
|
1595
1674
|
: apiKeyChild ? { ghToken: (options.openrouterGhToken ?? defaultGhToken)() }
|
|
@@ -1787,7 +1866,38 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
1787
1866
|
const hostKey = (k: string): string | undefined => k === 'OPENROUTER_API_KEY' && openrouter ? openrouterKey : k === 'ANTHROPIC_API_KEY' && anthropic ? anthropicKey : env[k] ?? (options.readKeyCache ?? defaultReadKeyCache)(k);
|
|
1788
1867
|
const hostFallbackNames = (options.fallbackConfig ?? getUserConfig)().llm.fallbackChain;
|
|
1789
1868
|
const normalizedFallback = normalizeFallbackChain(hostFallbackNames);
|
|
1790
|
-
|
|
1869
|
+
let fallbackSteps = normalizedFallback.chain;
|
|
1870
|
+
let zaiFallbackSpec: ZaiPodSpec | undefined;
|
|
1871
|
+
const codexChild = options.provider === undefined || options.provider === 'openai-codex';
|
|
1872
|
+
if (!codexChild && fallbackSteps.includes('zai')) {
|
|
1873
|
+
fallbackSteps = fallbackSteps.filter(step => step !== 'zai');
|
|
1874
|
+
debug.log('self-implement.pod', 'zai-fallback-unavailable', {
|
|
1875
|
+
job: name, reason: 'non-codex-child',
|
|
1876
|
+
}, { level: 'warn' });
|
|
1877
|
+
}
|
|
1878
|
+
if (codexChild && fallbackSteps.includes('zai')) {
|
|
1879
|
+
const settings = (options.zaiSettings ?? (() => zaiSettingsFromConfig(getUserConfig().llm)))();
|
|
1880
|
+
const poolMembers = (options.pool as { members?: readonly PodPoolMember[] } | undefined)?.members;
|
|
1881
|
+
const contexts = Array.isArray(poolMembers) && poolMembers.length > 0 ? poolMembers.map((m) => m.context) : [context];
|
|
1882
|
+
let active: number | null = 0;
|
|
1883
|
+
for (const c of contexts) {
|
|
1884
|
+
const n = c === context ? countActiveZaiJobs(kubectl, namespace)
|
|
1885
|
+
: countActiveZaiJobs((a, i) => baseKubectl(['--context', c, ...a], i), namespace);
|
|
1886
|
+
if (n === null) { active = null; break; }
|
|
1887
|
+
active += n;
|
|
1888
|
+
}
|
|
1889
|
+
const slot = decideZaiPodSlot({ active, pending: zaiPendingApply.size,
|
|
1890
|
+
maxConcurrent: settings.maxConcurrent, overage: 'stop' });
|
|
1891
|
+
if (slot.route === 'zai') {
|
|
1892
|
+
const checked = checkZaiPodSecret(kubectl, namespace);
|
|
1893
|
+
if (checked.ok) { zaiFallbackSpec = checked.spec; zaiPendingApply.add(name); }
|
|
1894
|
+
else debug.log('self-implement.pod', 'zai-fallback-unavailable', { job: name, reason: 'secret-unavailable' }, { level: 'warn' });
|
|
1895
|
+
} else debug.log('self-implement.pod', 'zai-fallback-unavailable', {
|
|
1896
|
+
job: name, reason: slot.route === 'refuse' ? 'slot-refused' : 'slot-unavailable', active,
|
|
1897
|
+
}, { level: 'warn' });
|
|
1898
|
+
if (!zaiFallbackSpec) fallbackSteps = fallbackSteps.filter(step => step !== 'zai');
|
|
1899
|
+
}
|
|
1900
|
+
const fallbackChain = { steps: fallbackSteps, source: normalizedFallback.usedDefault ? 'default' as const : 'host' as const };
|
|
1791
1901
|
debug.log('self-implement.pod', 'fallback-chain-carried', {
|
|
1792
1902
|
job: name, source: fallbackChain.source, steps: fallbackChain.steps,
|
|
1793
1903
|
...(normalizedFallback.dropped.length ? { droppedCount: normalizedFallback.dropped.length } : {}),
|
|
@@ -1830,9 +1940,12 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
1830
1940
|
let existingExecutionKey: string | undefined;
|
|
1831
1941
|
let existingAttempt = NaN;
|
|
1832
1942
|
let existingChildScript = '';
|
|
1943
|
+
let jobApplyStartedAt: number | undefined;
|
|
1944
|
+
let lifecycleJobUid: string | undefined;
|
|
1833
1945
|
const existing = kubectl(['-n', namespace, 'get', 'job', name, '-o', 'jsonpath={.metadata.uid} {.status.conditions[*].type}']);
|
|
1834
1946
|
const [existingUid = '', ...existingConditions] = existing.status === 0 ? existing.stdout.trim().split(/\s+/u) : [];
|
|
1835
1947
|
const hasExistingJob = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu.test(existingUid);
|
|
1948
|
+
if (hasExistingJob) lifecycleJobUid = existingUid;
|
|
1836
1949
|
let reattach = hasExistingJob && !/Failed|FailureTarget/.test(existingConditions.join(' '));
|
|
1837
1950
|
const failedExisting = hasExistingJob && /Failed|FailureTarget/.test(existingConditions.join(' '));
|
|
1838
1951
|
if (hasExistingJob) {
|
|
@@ -1994,6 +2107,13 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
1994
2107
|
slotId: env.ELANOUS_POD_SLOT_ID,
|
|
1995
2108
|
work: !goalDoc && env.ELANOUS_POD_AUTHOR_ON_POD === '1' && !shard ? 'authoring' : (oomRetried ? retryTier : memoryTier) === 'lite' ? 'lite' : 'harness',
|
|
1996
2109
|
};
|
|
2110
|
+
// TA-POD-WARMBOOT-PARITY shadow only: record the decision on the existing fresh-Job path.
|
|
2111
|
+
// Until a shared warm-candidate contract exists, evidence stays unmeasured and this never changes execution.
|
|
2112
|
+
if (workIdentity.taskCard) {
|
|
2113
|
+
const warmReuseConfig = options.warmReuseConfig?.() ?? (options.kubectl ? undefined : getUserConfig().pod?.warmReuse);
|
|
2114
|
+
const decision = decideWarmReuse('ta', warmReuseConfig, options.warmReuseEvidence?.());
|
|
2115
|
+
debug.log('pod.warm', 'ta-shadow-observation', { ...decision, execution: 'fresh-job' });
|
|
2116
|
+
}
|
|
1997
2117
|
// TA-POD-WARMBOOT-PARITY (GATE-WARM-BOOT parity · #27805): a commit-pinned source on a pool host — put that commit into
|
|
1998
2118
|
// the host mirror first (once per host·commit in this process) so podSourceScript finds it instead of fetching
|
|
1999
2119
|
// from GitHub. Best effort: a failed seed only logs; the Job is applied either way.
|
|
@@ -2034,13 +2154,47 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
2034
2154
|
// TA-POD-WARMBOOT-PARITY (GATE-POD-RESULT-MARKER parity · #27815): this launch's marker is the child's last line.
|
|
2035
2155
|
const resultMarkerLine = resultMarkerOn ? (await import('./pod-result-marker-wait.js')).podResultMarkerShellLine(launchRunId) ?? undefined : undefined;
|
|
2036
2156
|
if (resultMarkerLine) markerToken = launchRunId;
|
|
2037
|
-
|
|
2157
|
+
// POD-GROK-VALIDITY-FIT — without a relay the Pod cannot renew the copy, so the Job ends before the token does.
|
|
2158
|
+
// Measured right before the Job is applied (review r2): setup between the credential check and here takes time.
|
|
2159
|
+
if (grokSubscription) {
|
|
2160
|
+
const shippedExpiresAtMs = shippedGrokExpiresAtMs((creds as { grokAuth: string }).grokAuth);
|
|
2161
|
+
const fit = fitPodDeadlineToGrok({ requestedSeconds: jobDeadlineSeconds, expiresAtMs: shippedExpiresAtMs, nowMs: (options.now ?? Date.now)(), relay: Boolean(credentialRelay) });
|
|
2162
|
+
if (fit.refused) {
|
|
2163
|
+
debug.log('self-implement.pod', 'grok-deadline-refused', { job: name, requestedSeconds: jobDeadlineSeconds, availableSeconds: fit.availableSeconds, minJobSeconds: POD_GROK_MIN_JOB_SECONDS, marginMs: POD_GROK_EXPIRY_MARGIN_MS });
|
|
2164
|
+
cleanupSecret();
|
|
2165
|
+
return { exitCode: 1, output: '', error: { code: 'pod-grok-expiring', message: `grok: 구독 access 토큰 남은 시간 ${formatGrokRemaining(fit.availableSeconds * 1000 + POD_GROK_EXPIRY_MARGIN_MS)} < Pod 발사 기준 ${formatGrokRemaining(POD_GROK_MIN_VALIDITY_MS)} — 발사 직전 재검증 · 다음: 호스트에서 grok login --device-auth 후 다시` } };
|
|
2166
|
+
}
|
|
2167
|
+
debug.log('self-implement.pod', fit.fitted ? 'grok-deadline-fitted' : 'grok-deadline-kept', { job: name, requestedSeconds: jobDeadlineSeconds, deadlineSeconds: fit.deadlineSeconds, availableSeconds: fit.availableSeconds, relay: Boolean(credentialRelay), marginMs: POD_GROK_EXPIRY_MARGIN_MS });
|
|
2168
|
+
jobDeadlineSeconds = fit.deadlineSeconds;
|
|
2169
|
+
}
|
|
2170
|
+
const job = podJobManifest({ name, namespace, fallbackChain, ...(resultMarkerLine ? { resultMarkerLine } : {}), image: jobImage, workIdentity, ...(env.ELANOUS_TASK_BOUND_PR && /^[1-9]\d*$/.test(env.ELANOUS_TASK_BOUND_PR) && Number.isSafeInteger(Number(env.ELANOUS_TASK_BOUND_PR)) ? { boundPrNumber: Number(env.ELANOUS_TASK_BOUND_PR) } : {}), ...(member?.imageRef ? { imagePullPolicy: 'IfNotPresent' as const } : {}), repoUrl, ...(options.source ? { source: options.source } : {}), ...(options.repairCommitOnly ? { repairCommitOnly: options.repairCommitOnly } : {}), ...(hostMirror ? { hostMirror } : {}), args: jobArgs, passEnv: jobPassEnv, deadlineSeconds: jobDeadlineSeconds, ...(goalDoc ? { goalDoc } : env.ELANOUS_POD_AUTHOR_ON_POD === '1' && !shard ? { authorSentence: true, ...(env.ELANOUS_POD_AUTHOR_GRADE === 'lite' || env.ELANOUS_POD_AUTHOR_GRADE === 'full' ? { authorGrade: env.ELANOUS_POD_AUTHOR_GRADE } : {}) } : {}), runId: launchRunId, ...(parentRunId ? { parentRunId } : {}), ...(jobArmEnv ? { armEnv: jobArmEnv } : {}), hostId: resolveHostId(env), skillEnvs: Object.keys(skillEnvs), memoryLimit, memoryRequest, imageCommit: options.imageCommit !== undefined ? options.imageCommit : options.kubectl ? null : podImageFreshness({ image }).imageCommit, ...(grok ? { grokCredential: 'grokAuth' in creds && creds.grokAuth ? 'subscription' as const : 'api_key' as const } : {}), ...(codexAccounts ? { codexAccounts } : {}), ...(hostRefresh ? { appCredential: true } : {}), execution: { key: executionKey, attempt: oomRetried ? 2 : 1 }, hostLeaseAdmitted: !!releaseAdmission, ...(roleCodexCredential ? { reviewerCodexAuth: true } : {}), ...(bedrockSpec ? { bedrock: bedrockSpec } : {}), ...(zaiSpec ? { zai: zaiSpec } : {}), ...(zaiFallbackSpec ? { zaiFallback: zaiFallbackSpec } : {}) }); // kubectl 주입(=시험)이면 docker 를 부르지 않는다
|
|
2038
2171
|
const carriedBranch = goalDoc ? 'goal-doc' as const : env.ELANOUS_POD_AUTHOR_ON_POD === '1' && !shard ? 'author' as const : undefined;
|
|
2039
2172
|
const carriedChildLlm = carriedBranch ? podDelegatedChildLlm(jobArgs) : undefined;
|
|
2173
|
+
jobApplyStartedAt = Date.now();
|
|
2040
2174
|
const a = kubectl(['apply', '-f', '-'], JSON.stringify(job));
|
|
2041
2175
|
zaiPendingApply.delete(name); // apply 뒤엔 Job 라벨이 센다(성공) · 실패면 셀 것이 없다
|
|
2042
2176
|
if (a.status !== 0) { cleanupSecret(); return { exitCode: 1, output: a.stderr, error: { code: 'pod-apply', message: a.stderr.trim() } }; }
|
|
2043
2177
|
releaseAdmission?.applied?.(name, context, namespace);
|
|
2178
|
+
// The injected observer does not acquire a production lease. The gate consumer
|
|
2179
|
+
// must compare the Job result and explicitly finalize before enabling replay.
|
|
2180
|
+
if (!oomRetried && input.warmWorkerCommand && options.warmPodRequest) {
|
|
2181
|
+
setImmediate(() => {
|
|
2182
|
+
try {
|
|
2183
|
+
const request = options.warmPodRequest!({ command: input.warmWorkerCommand! });
|
|
2184
|
+
void Promise.resolve(request)
|
|
2185
|
+
.then((result) => debug.log('pod.warm', 'request-observation', {
|
|
2186
|
+
spaceId: input.spaceId, status: result.status, reason: result.reason, execution: 'fresh-job',
|
|
2187
|
+
}))
|
|
2188
|
+
.catch((error) => debug.log('pod.warm', 'request-unavailable', {
|
|
2189
|
+
spaceId: input.spaceId, reason: error instanceof Error ? error.message : String(error), execution: 'fresh-job',
|
|
2190
|
+
}, { level: 'warn' }));
|
|
2191
|
+
} catch (error) {
|
|
2192
|
+
debug.log('pod.warm', 'request-unavailable', {
|
|
2193
|
+
spaceId: input.spaceId, reason: error instanceof Error ? error.message : String(error), execution: 'fresh-job',
|
|
2194
|
+
}, { level: 'warn' });
|
|
2195
|
+
}
|
|
2196
|
+
});
|
|
2197
|
+
}
|
|
2044
2198
|
// Logged only once the Job is applied — a failed apply carried nothing.
|
|
2045
2199
|
if (carriedBranch && carriedChildLlm) debug.log('self-implement.pod', 'child-llm-carried', { spaceId: input.spaceId, job: name, branch: carriedBranch, provider: carriedChildLlm.provider, model: carriedChildLlm.model ?? null });
|
|
2046
2200
|
if (options.source?.kind === 'bundle') {
|
|
@@ -2068,6 +2222,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
2068
2222
|
}
|
|
2069
2223
|
// ☸️ P2: 비밀의 소유자 = Job — 호스트가 죽어도 Job 의 TTL 삭제와 함께 k8s 가 비밀을 거둔다(자격 사본이 클러스터에 남지 않는다).
|
|
2070
2224
|
const uid = kubectl(['-n', namespace, 'get', 'job', name, '-o', 'jsonpath={.metadata.uid}']).stdout.trim();
|
|
2225
|
+
lifecycleJobUid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu.test(uid) ? uid : undefined;
|
|
2071
2226
|
if (uid) {
|
|
2072
2227
|
const owned = kubectl(['-n', namespace, 'patch', 'secret', `${name}-creds`, '--type=merge', '-p', JSON.stringify({ metadata: { ownerReferences: [{ apiVersion: 'batch/v1', kind: 'Job', name, uid }] } })]);
|
|
2073
2228
|
if (owned.status !== 0) debug.log('self-implement.pod', 'secret-owner-failed', { job: name, stderr: owned.stderr.trim() }, { level: 'warn' });
|
|
@@ -2384,11 +2539,33 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
2384
2539
|
childError: childFailure?.error ?? (disposition?.stage ? 'result-without-error' : 'no-result-line') } : {}) },
|
|
2385
2540
|
state === 'failed' && !oomKilled && failedReason !== 'DeadlineExceeded' ? { compact: { stringMax: 500 } } : undefined);
|
|
2386
2541
|
// POD-LIFECYCLE-STAGES: one `pod.lifecycle stages` line — clone · mirror · run come from the Pod's own
|
|
2387
|
-
// `ELANOUS_POD_STAGE` markers (SI-POD-STAGE-MARKERS), read from
|
|
2542
|
+
// `ELANOUS_POD_STAGE` markers (SI-POD-STAGE-MARKERS), read from that Pod's full named log. ⛔ No `--tail=400` fallback:
|
|
2388
2543
|
// a tail can lose the real `run start` and pair a child-printed look-alike with the real `run end` (review mf) —
|
|
2389
2544
|
// when the full log cannot be read, every stage stays «missing».
|
|
2545
|
+
let k8sTiming: ReturnType<typeof siTaskPodK8sTiming> = {};
|
|
2546
|
+
try {
|
|
2547
|
+
const childRunLabel = k8sLabelValue(liveChildRunId);
|
|
2548
|
+
if (childRunLabel) {
|
|
2549
|
+
const pods = kubectl(['-n', namespace, 'get', 'pods', '-l', `elanous.child-run=${childRunLabel}`, '-o', 'json']);
|
|
2550
|
+
if (pods.status === 0) k8sTiming = siTaskPodK8sTiming(pods.stdout, childRunLabel, name, lifecycleJobUid);
|
|
2551
|
+
}
|
|
2552
|
+
} catch { /* observation only: keep each unavailable timestamp missing */ }
|
|
2553
|
+
let lifecyclePodStages: Record<string, number> = {};
|
|
2554
|
+
let lifecycleDepsSkipped: { at: number; reason: string } | undefined;
|
|
2555
|
+
if (k8sTiming.podName && k8sTiming.podUid) {
|
|
2556
|
+
try {
|
|
2557
|
+
// The stage markers and UID must come from exactly the same Pod. `logs job/<name>`
|
|
2558
|
+
// can choose another Pod when a Job has more than one attempt.
|
|
2559
|
+
const podLogs = kubectl(['-n', namespace, 'logs', k8sTiming.podName, '-c', 'child']);
|
|
2560
|
+
if (podLogs.status === 0) {
|
|
2561
|
+
lifecyclePodStages = parseSiTaskPodStages(podLogs.stdout);
|
|
2562
|
+
lifecycleDepsSkipped = parseSiTaskDepsSkipped(podLogs.stdout);
|
|
2563
|
+
}
|
|
2564
|
+
} catch { /* only this Pod's markers may fill lifecycle stages */ }
|
|
2565
|
+
}
|
|
2390
2566
|
emitPodLifecycle(siTaskPodLifecycleEvent({ runId: liveChildRunId, podJob: name, host: member?.context ?? null, watchStart: waitStartedAt, watchEnd: Date.now(),
|
|
2391
|
-
|
|
2567
|
+
createStart: jobApplyStartedAt,
|
|
2568
|
+
...k8sTiming, podStages: lifecyclePodStages, depsSkipped: lifecycleDepsSkipped, outcome: oomKilled ? 'oom' : state }));
|
|
2392
2569
|
if (oomKilled && reattach && !oomRetried && (!reattachedMemoryLimit || memoryGi(reattachedMemoryLimit) === null)) {
|
|
2393
2570
|
return { exitCode: 1, output: '', error: { code: 'pod-memory-unavailable', message: `Job ${name} 실제 메모리 한도를 확인할 수 없다` } };
|
|
2394
2571
|
}
|
|
@@ -2440,6 +2617,14 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
2440
2617
|
try { const { appendGoalExecutionRecord } = await import('../../self-implement/orchestrator.js'); appendGoalExecutionRecord(goalFile, record); }
|
|
2441
2618
|
catch (error) { debug.log('self-implement.pod', 'goal-record-unavailable', { job: name, childRunId: liveChildRunId, reason: error instanceof Error ? error.message : String(error) }); }
|
|
2442
2619
|
}
|
|
2620
|
+
// The host still has the complete Pod log here. The CLI only retains a short stdout tail,
|
|
2621
|
+
// so preserve the parsed child facts in the parent ledger before that tail is returned.
|
|
2622
|
+
if (state === 'failed' || state === 'aborted') {
|
|
2623
|
+
// Every terminal attempt writes a marker, including one with no parseable child facts.
|
|
2624
|
+
// The next attempt must never inherit an earlier Pod's classification.
|
|
2625
|
+
try { appendRunLedgerEntry({ runId: ledgerRunId, event: 'pod-child-evidence', data: { childEvidence: disposition?.childEvidence ?? null, childRunId: liveChildRunId, job: name } }, ledgerDir); }
|
|
2626
|
+
catch (error) { debug.log('self-implement.pod', 'child-evidence-write-failed', { job: name, childRunId: liveChildRunId, reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' }); }
|
|
2627
|
+
}
|
|
2443
2628
|
const terminalRecord = classifyPodTerminal({ childRunId: liveChildRunId, state, disposition, env,
|
|
2444
2629
|
prBody: options.draftResidue ? undefined : podTerminalPrBody(disposition),
|
|
2445
2630
|
goalText: parentGoal ?? input.feature, at: new Date().toISOString() });
|
|
@@ -2450,7 +2635,7 @@ export function podSelfImplementSpawn(options: PodSpawnOptions = {}): SelfImplem
|
|
|
2450
2635
|
const tail = podRunResultLine(logs, salvage);
|
|
2451
2636
|
if (state === 'aborted') return { exitCode: null, output: tail, error: { code: 'aborted', message: 'aborted — Job deleted' }, ...(disposition ? { disposition } : {}) };
|
|
2452
2637
|
const deadlineExceeded = state === 'failed' && failedReason === 'DeadlineExceeded';
|
|
2453
|
-
const deadlineSeconds =
|
|
2638
|
+
const deadlineSeconds = jobDeadlineSeconds;
|
|
2454
2639
|
if (deadlineExceeded) {
|
|
2455
2640
|
debug.log('self-implement.pod', 'deadline-exceeded', {
|
|
2456
2641
|
job: name,
|