elanous 0.2.31 → 0.2.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/{LSXfY0u9QtfDbejY0Ukf_ → L04y73dlwKeTW-GetaTF3}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +79 -0
- package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +94 -0
- package/apps/pwa/out/_next/static/chunks/{4174.92ed04922709ac9e.js → 1644.35dd25240ae24e4b.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2940-619bfd8ef337c611.js → 1895-60ed0e341c658bd4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5525.86debf231e181813.js → 2124.ed5bf480cea7f85b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +23 -0
- package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +115 -0
- package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +8 -0
- package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6092.a7f99e68b188ca66.js → 2547.dd27303624cb4da8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 2554.3b5e200f5f5cfcd6.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +1 -0
- package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5173-233188df2f42c626.js → 2987-30cf9c2eb7b8bdd5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3541-ce3a5424ed5ad7f1.js → 3001-5a52788c813b6113.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3103.84470c8445962f04.js +34 -0
- package/apps/pwa/out/_next/static/chunks/{6433.fc573af22bbc9ab7.js → 3110.0a7065f25c841818.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3121.779fafe3e44612c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3411-f87314c6c66ebc73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.js → 3414.172ad4ca2d9b08e8.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4745.67d6f99c245af3f7.js → 3498.cf2a15a8a9e5b926.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3819.163d4777f0a597f6.js +32 -0
- package/apps/pwa/out/_next/static/chunks/{5543.a438b8ab5a13ea47.js → 3837.722e053fb9f321ad.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +104 -0
- package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +286 -0
- package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +149 -0
- package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +148 -0
- package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +64 -0
- package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +74 -0
- package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b313b242.cb1265eea908db61.js → 4fa33ebd.21c1bd5b294496e6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.js → 5014f970-22bef0b5210f7d60.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2112-e4efc21a6505d5bc.js → 5028-f0722e6114c313e7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2898.fd781bc7cf01a7b7.js → 5249.96a848656b582a93.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +62 -0
- package/apps/pwa/out/_next/static/chunks/{9407.e49124dedf0f5e72.js → 5446.edf141cff9ef647d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9002.e5658224e3dc1b6f.js → 5489.ec2dd1b5272a19dc.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.js → 5576-82d3703636d5c4b9.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6053-d893974de92e6198.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.js → 6086.913a69e6fa3e4a8b.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +1 -0
- package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +77 -0
- package/apps/pwa/out/_next/static/chunks/{7862.30a8d6482bb238eb.js → 6740.43de73fc427c9fe2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +90 -0
- package/apps/pwa/out/_next/static/chunks/{2871.0bca6137343b3f76.js → 7005.1623d2aea78eb85f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7193-cf355cca5ba6c5d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7386.5d8e7e42e818dfb6.js +287 -0
- package/apps/pwa/out/_next/static/chunks/{7502.ccd5b8065545edd0.js → 7431.3051e9b8a4372d2d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{3583.a05e88cc8d594628.js → 7448.478958ffbbba0ac0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7562.948255cbc3e79d33.js +41 -0
- package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +27 -0
- package/apps/pwa/out/_next/static/chunks/{9989.3694300e5f000b14.js → 7952.b192c31b6a0e00cc.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +36 -0
- package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +1 -0
- package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.js → 8368.014caa8de2f5af34.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9221.7d22eaf353a2d4e7.js → 8548.036c344973968847.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8817.61bb7ffbba502ecb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9398-6aed28f0a96d0d6f.js → 9131-fce7256c4180c4a5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +93 -0
- package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{3278.2e5d15b53a4091c8.js → 9550.d5f76828f972058c.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{2534.e85ae21ad0dac829.js → 9739.8d5f36ac67a3b236.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +1 -0
- package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7a1887c4.f36b88fba31da8fd.js → 9a8cb466.cc9fc9e6e46038aa.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → 9b48c871.204d5d13e7809bd0.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → abb4b98b.163e0f56e84ae35d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-4fb31eb476dcbad3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-d7bff0f0905a662c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-0a07363b130182a1.js → page-398c0faa173203f7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-df3445b207ceceab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +122 -0
- package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{ebc7d829.264a0bcb6c750b50.js → ffdc3a04.b9c23c1b28dd4a96.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +1 -0
- package/apps/pwa/out/_next/static/css/b5d88eba78a3d7bf.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +26 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +23 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/bin/elanous.mjs +9 -2
- package/docs/goal-context/README.md +1 -0
- package/graphs/default-loop.yaml +20 -3
- package/graphs/document-loop.yaml +21 -2
- package/graphs/implement-loop.yaml +11 -0
- package/graphs/journey/SCENARIOS.md +33 -0
- package/graphs/journey/recipes.yaml +1 -0
- package/graphs/journey/ta-journey.yaml +84 -0
- package/graphs/journey/units/author/author.yaml +20 -0
- package/graphs/journey/units/author/recipes.yaml +2 -0
- package/graphs/journey/units/green/green.yaml +20 -0
- package/graphs/journey/units/green/recipes.yaml +2 -0
- package/graphs/journey/units/pr/pr.yaml +20 -0
- package/graphs/journey/units/pr/recipes.yaml +2 -0
- package/graphs/journey/units/remember/recipes.yaml +2 -0
- package/graphs/journey/units/remember/remember.yaml +20 -0
- package/graphs/operate-loop.yaml +21 -2
- package/graphs/overlays/stop-heal-ladder.yaml +1 -1
- package/graphs/release-rehearsal/recipes.yaml +1 -1
- package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
- package/graphs/research-loop.yaml +23 -2
- package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
- package/graphs/units/dispatch-pod/recipes.yaml +14 -0
- package/graphs/units/entry/entry.yaml +50 -0
- package/graphs/units/entry/recipes.yaml +14 -0
- package/graphs/units/harvest/harvest.yaml +25 -0
- package/graphs/units/harvest/recipes.yaml +4 -0
- package/graphs/units/land/land.yaml +45 -0
- package/graphs/units/land/recipes.yaml +3 -0
- package/graphs/units/recipes.yaml +7 -0
- package/graphs/units/recover.yaml +39 -0
- package/graphs/units/reflect/recipes.yaml +3 -0
- package/graphs/units/reflect/reflect.yaml +15 -0
- package/graphs/units/task-agent-recover-review.yaml +17 -0
- package/graphs/units/task-agent-recover-wait.yaml +17 -0
- package/graphs/units/verbs/make-doc.yaml +34 -0
- package/graphs/units/verbs/recipes.yaml +33 -0
- package/graphs/units/verbs/verify.yaml +55 -0
- package/graphs/work/recipes.yaml +2 -0
- package/graphs/work/research-report.yaml +28 -0
- package/package.json +1 -1
- package/scripts/ci-typecheck-changed.ts +95 -17
- package/scripts/docs/generate-graph-anatomy.ts +19 -2
- package/scripts/graph-harvest-unit.ts +22 -0
- package/scripts/graph-units/journey-stub.ts +6 -0
- package/scripts/graph-units/land-enqueue.ts +78 -0
- package/scripts/graph-units/recover-plan.ts +15 -0
- package/scripts/graph-units/reflect-node.ts +88 -0
- package/scripts/graph-units/ta-journey-observe.ts +109 -0
- package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
- package/scripts/graph-units/verbs/verify-stage.ts +75 -0
- package/scripts/graph-units/verbs-envelope.ts +139 -0
- package/scripts/hq/standby-snapshot.ts +25 -0
- package/scripts/measure-si-task-cpu.ts +143 -0
- package/scripts/public-export.ts +43 -1
- package/scripts/ratchets/test-interference-patterns.allowlist.txt +0 -2
- package/scripts/ratchets/train-side-invariants.sh +45 -0
- package/scripts/release-loop/auto-approve-node.ts +30 -16
- package/scripts/release-loop/gate-closure.ts +5 -1
- package/scripts/release-loop/gate-diff.ts +1 -1
- package/scripts/release-loop/gate-node.ts +498 -31
- package/scripts/release-loop/gate-partial.ts +3 -3
- package/scripts/release-loop/gate-radius-shadow.ts +138 -0
- package/scripts/release-loop/gate-traffic-mode.ts +128 -0
- package/scripts/release-loop/gate-triage-node.ts +5 -2
- package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
- package/scripts/release-loop/known-issues-node.ts +77 -8
- package/scripts/release-loop/preflight.ts +93 -7
- package/scripts/release-loop/prepare-node.ts +102 -4
- package/scripts/release-loop/publish-node.ts +60 -9
- package/scripts/release-loop/resume-cap.ts +56 -0
- package/scripts/release-loop/resume-release.ts +114 -15
- package/scripts/release-loop/resume.ts +24 -1
- package/scripts/release-loop/tui-sim-node.ts +8 -2
- package/scripts/release-loop/unattended-release.ts +8 -2
- package/src/acp/core-turn-bridge.ts +36 -9
- package/src/acp/elanous-extensions.ts +3 -0
- package/src/acp/reasoning-thought-buffer.ts +45 -0
- package/src/acp/server.ts +3 -0
- package/src/acp/tool-trace.ts +186 -11
- package/src/agent/self-ambient-cache.ts +156 -0
- package/src/agent/self-ambient.ts +8 -1
- package/src/agent/task-notification.ts +5 -0
- package/src/agent-substrate/acp-reviewer.ts +52 -12
- package/src/agent-substrate/pr-reviewer.ts +3 -1
- package/src/agent-substrate/review-finding-key.ts +53 -0
- package/src/agent-substrate/self-review-cli.ts +126 -5
- package/src/ask-user-question/pending-questions.ts +1 -1
- package/src/ask-user-question/tool.ts +22 -0
- package/src/autopilot/build/llm-conflict-merge.ts +56 -10
- package/src/autopilot/pr-manager.ts +213 -46
- package/src/capture/frame-state-detect.ts +39 -0
- package/src/capture/tui-self-report.ts +134 -6
- package/src/chat/index.ts +61 -15
- package/src/chat/pickers/modal-runtime.ts +6 -0
- package/src/chat/pickers/modals.ts +8 -2
- package/src/chat/tool-render/dispatch.ts +62 -10
- package/src/cli/ask-bare.ts +1 -0
- package/src/cli/control-cli.ts +24 -7
- package/src/cli/guardian-cli.ts +10 -0
- package/src/cli/import-cli.ts +12 -0
- package/src/cli/light-entry-route.ts +35 -0
- package/src/cli/llm-detect-cli.ts +23 -1
- package/src/cli/log-event-names.ts +10 -0
- package/src/cli/msg-cli.ts +1 -0
- package/src/cli/pod-cli.ts +14 -3
- package/src/cli/pr-cli.ts +140 -41
- package/src/cli/pr-land-base-read.ts +36 -0
- package/src/cli/pr-land-heavy-remote.ts +81 -25
- package/src/cli/pr-land-overlap-evidence.ts +200 -18
- package/src/cli/pr-land-pod-shadow-job.ts +26 -3
- package/src/cli/pr-land-recovery.ts +64 -0
- package/src/cli/pr-land-refusal.ts +20 -5
- package/src/cli/pty-takeover-cli.ts +94 -19
- package/src/cli/release-cli.ts +120 -33
- package/src/cli/release-run-if-ready.ts +29 -28
- package/src/cli/release-single-flight.ts +178 -0
- package/src/cli/seat-cli.ts +37 -0
- package/src/cli/setup-cli.ts +40 -1
- package/src/cli/sim-cli.ts +18 -0
- package/src/cli/tasks-cli.ts +149 -5
- package/src/context-bus/ops-events.ts +6 -2
- package/src/control/control-status.ts +8 -3
- package/src/control-plane/ledger.ts +5 -3
- package/src/control-plane/server.ts +5 -3
- package/src/core-turn/run-core-turn.ts +1 -0
- package/src/core-turn/run-goal-loop.ts +21 -0
- package/src/core-turn/short-question.ts +5 -1
- package/src/core-turn/types.ts +3 -0
- package/src/dashboard/acp-active-model.ts +42 -1
- package/src/dashboard/background-jobs-status.ts +66 -0
- package/src/dashboard/index.ts +153 -111
- package/src/dashboard/input/agent-wake.ts +242 -0
- package/src/dashboard/input/chat-main-entry-runtime.ts +5 -0
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
- package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
- package/src/dashboard/input/external-input-host.ts +23 -9
- package/src/dashboard/input/mouse-wiring.ts +108 -11
- package/src/dashboard/input/seat-autowake.ts +56 -3
- package/src/dashboard/log-click-runtime.ts +118 -2
- package/src/dashboard/seat-boot-preamble.ts +1 -1
- package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
- package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
- package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
- package/src/dashboard/turn-preamble.ts +163 -41
- package/src/dashboard/turn-session-layers.ts +4 -2
- package/src/dashboard/turn-start-segments.ts +222 -0
- package/src/dashboard/turn-stream-formatter.ts +34 -1
- package/src/dashboard/turn-stream-runtime.ts +2 -0
- package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
- package/src/display/prompt-row-owner.ts +146 -0
- package/src/display/resize-listener.ts +33 -2
- package/src/domains/guardian-tick.ts +54 -2
- package/src/domains/outbound-alert.ts +3 -2
- package/src/extractors.ts +3 -1
- package/src/fold-stack.ts +4 -2
- package/src/git-fs/index.ts +263 -36
- package/src/git-fs/retry.ts +4 -0
- package/src/git-fs/runner.ts +2 -0
- package/src/graph-runner/runner.ts +114 -44
- package/src/grok/credential.ts +5 -0
- package/src/harness/gate-reserve.ts +87 -0
- package/src/harness/harness-cli-command.ts +39 -10
- package/src/harness/harness-incidents.ts +17 -0
- package/src/harness/harness-pod-dispatch.ts +38 -1
- package/src/harness/harness-queue.ts +15 -0
- package/src/harness/harness-salvage-cli.ts +14 -2
- package/src/index.ts +198 -12
- package/src/input/external-input-queue.ts +34 -9
- package/src/intake-plane/already-built-hint.ts +89 -0
- package/src/knowhow/pack.ts +199 -0
- package/src/light-cli.ts +95 -0
- package/src/llm/route-decision.ts +36 -0
- package/src/llm/tool-loop-steered-rejection.ts +8 -0
- package/src/llm-request-shape.ts +209 -0
- package/src/llm.ts +221 -276
- package/src/loops/budget.ts +95 -0
- package/src/loops/msg-wake.ts +8 -2
- package/src/loops/orchestrator/tick.ts +24 -2
- package/src/loops/orchestrator/traffic.ts +132 -1
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/mss/logging/log-store.ts +4 -5
- package/src/mss/logging/render-categories.ts +5 -0
- package/src/nexus/api/graphs-api.ts +22 -3
- package/src/nexus/api/http-server.ts +1 -1
- package/src/nexus/api/ops-api.ts +12 -0
- package/src/oauth/claude-pty-maturity.ts +66 -0
- package/src/oauth/codex-access-mirror.ts +55 -0
- package/src/oauth/fallback-chain.ts +1 -1
- package/src/onboarding/first-run.ts +5 -3
- package/src/onboarding/non-interactive.ts +64 -13
- package/src/onboarding.ts +10 -2
- package/src/ops/overview-collect.ts +36 -1
- package/src/ops/overview.ts +70 -2
- package/src/pr-tool/census.ts +41 -8
- package/src/pr-tool/inflight-registry.ts +296 -0
- package/src/prompt-library/gpt6-family-addendum.ts +14 -1
- package/src/pty-shell/herdr-agent-report.ts +442 -0
- package/src/pty-shell/pty-control-ipc.ts +5 -5
- package/src/pty-shell/pty-manifest.ts +12 -3
- package/src/pty-shell/pty-write-outcome.ts +24 -6
- package/src/pty-shell/tui-run-state.ts +151 -6
- package/src/release-loop/checklist.ts +79 -5
- package/src/release-loop/feature-store.ts +19 -2
- package/src/release-loop/placement.ts +10 -3
- package/src/release-loop/rehearsal.ts +205 -25
- package/src/release-loop/rubric.ts +16 -2
- package/src/seat-loop/traffic-signal.ts +2 -1
- package/src/self-dev/ask-launch-flow.ts +13 -0
- package/src/self-dev/draft-residue.ts +243 -24
- package/src/self-dev/draft-sweep.ts +52 -3
- package/src/self-dev/graph-journey-nodes.ts +10 -6
- package/src/self-dev/graph-journey-route.ts +60 -6
- package/src/self-dev/orchestrate.ts +79 -3
- package/src/self-dev/run-supervisor.ts +107 -12
- package/src/self-dev/run-types.ts +5 -1
- package/src/self-dev/shard-plan.ts +11 -3
- package/src/self-dev/shard-run.ts +103 -10
- package/src/self-implement/elanous-tui-spawn.ts +14 -0
- package/src/self-implement/follow-up-placement.ts +79 -0
- package/src/self-implement/gate-artifacts.ts +15 -4
- package/src/self-implement/gate-baseline.ts +145 -10
- package/src/self-implement/gate-cli.ts +7 -2
- package/src/self-implement/gate-remote.ts +35 -6
- package/src/self-implement/goal-author-identity.ts +66 -0
- package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
- package/src/self-implement/goal-author.ts +4 -120
- package/src/self-implement/graph-overlay-yaml.ts +17 -2
- package/src/self-implement/graph-unit-flatten.ts +103 -0
- package/src/self-implement/graph-unit-resolver.ts +107 -0
- package/src/self-implement/graph-yaml.ts +151 -1
- package/src/self-implement/headless-elanous-driver.ts +1 -0
- package/src/self-implement/host-regate.ts +36 -4
- package/src/self-implement/knowhow-pack.ts +103 -0
- package/src/self-implement/orchestrator.ts +109 -11
- package/src/self-implement/pod-warm-pool-profile.ts +45 -0
- package/src/self-implement/review-mustfix-class.ts +203 -0
- package/src/self-implement/run-ledger.ts +16 -14
- package/src/self-implement/run-stop.ts +8 -2
- package/src/self-implement/seams.ts +32 -1
- package/src/self-implement/stop-autoheal.ts +25 -1
- package/src/session/chat.ts +27 -0
- package/src/session-runtime/index.ts +22 -267
- package/src/session-runtime/retry-policy.ts +2 -1
- package/src/shell-runner/background-surface.ts +15 -5
- package/src/skills/tools/agent.ts +39 -6
- package/src/skills/tools/list-dir.ts +11 -0
- package/src/skills/tools/schedule-wakeup.ts +457 -0
- package/src/skills/tools/shell.ts +245 -3
- package/src/status/bar.ts +26 -0
- package/src/steward/digest-delivery.ts +118 -0
- package/src/steward/hold-hygiene.ts +120 -0
- package/src/steward/release-day.ts +7 -3
- package/src/steward/triage.ts +47 -4
- package/src/surface/shell-runner-boot.ts +5 -2
- package/src/task-agent/harvest-unit.ts +141 -0
- package/src/task-agent/live-moves.ts +98 -12
- package/src/task-agent/parent-host.ts +93 -3
- package/src/task-agent/postland-card.ts +80 -1
- package/src/task-agent/rejudge-on-head.ts +112 -26
- package/src/task-agent/repair-branch-cas.ts +4 -1
- package/src/task-agent/repair-cycle.ts +16 -3
- package/src/task-agent/run-identity.ts +4 -3
- package/src/task-agent/shadow.ts +12 -2
- package/src/task-agent/task-hand.ts +76 -5
- package/src/task-agent/work-order-build.ts +22 -0
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +39 -3
- package/src/task-orchestrator/surfaces/pod-command-job.ts +67 -12
- package/src/task-orchestrator/surfaces/pod-lease.ts +98 -0
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
- package/src/task-orchestrator/surfaces/pod-pool.ts +76 -18
- package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +10 -6
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +54 -4
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +548 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +389 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runner.ts +90 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +158 -3
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +230 -43
- package/src/task-orchestrator/surfaces/self-implement.ts +83 -2
- package/src/tool-runtime/truncation-store.ts +4 -0
- package/src/tui/chat/execution-badge.ts +5 -1
- package/src/tui/input-lag-probe.ts +230 -0
- package/src/tui-client/dashboard-session.ts +10 -1
- package/src/tui.ts +4 -0
- package/src/user-config/coercion.ts +36 -0
- package/src/user-config.ts +18 -41
- package/src/ux-sim/scenario.ts +314 -0
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
- package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
- package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
- package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
- package/apps/pwa/out/_next/static/chunks/1834-50625904996a8fa8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
- package/apps/pwa/out/_next/static/chunks/2001.6c7e0fd02190886c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
- package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
- package/apps/pwa/out/_next/static/chunks/3267c0e6.d34854e7b3984a6e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +0 -34
- package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
- package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
- package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
- package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
- package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
- package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
- package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
- package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
- package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
- package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
- package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
- package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8097-92f87bd108322f66.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
- package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-bf3634a117322df7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-3535a4a69f1fafaa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-b9f51447f757fbf2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-2ebb8fd59b9461f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-a2fc4e49a4fa4ba8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-5a503541353e60a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-6025101384e361a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-f4b630cc8b5273cd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-a645f00a06483e9a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-61ac22cbab1ee4ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e9bab7413b028b28.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c992eafe028b642e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-e547e6ce55f1fb33.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-d27e1b9850fd54bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-805ac2e137b7a121.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-0fec29c7ba01894b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-339a07410cd6f36b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-349f2752d8cd37ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-d5c6dcf31c25cecc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-2fd93ed8c9f16580.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-9b564dbff0fefc35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-62f4475d3c38fb9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-814ba51385225776.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-397d479626e5a459.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-af1bba4e3251b728.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ad3be5e7d3fdce9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-f219ccdbc0bf27df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4da93ad35d4a8d28.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-456666766e5ce6fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-7404e377e8adb8c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-14456240ed2a36ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-3a658d5fa6d16a25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-0157de6e85f8bb6b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-841d73d4ac44ed49.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6f43a3d1146e6377.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-521ee23ac8c0abfa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-a9992ee285efaa83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-3d48e85fa89ec04f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-d2ced71132fac9b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-f08358bdf251adb9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-233c71cd5f68f0d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-70151d78de2f375e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-dcac33a3e2cb72c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-149dc1caba411bb9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0448145ccd5c45c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-9cb0c444903da65d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-17e504c396e0e389.js +0 -1
- package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
- package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
- package/apps/pwa/out/_next/static/css/3f5fc6f96e2cf7b2.css +0 -1
- package/src/cli/g6a-registration-probe.ts +0 -16
- /package/apps/pwa/out/_next/static/{LSXfY0u9QtfDbejY0Ukf_ → L04y73dlwKeTW-GetaTF3}/_ssgManifest.js +0 -0
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { execFileSync } from 'node:child_process';
|
|
11
11
|
import { createHash, randomBytes } from 'node:crypto';
|
|
12
12
|
import { mkdirSync, readFileSync, statSync, writeFileSync, type Stats } from 'node:fs';
|
|
13
|
-
import { dirname, join, resolve } from 'node:path';
|
|
13
|
+
import { dirname, join, posix, resolve } from 'node:path';
|
|
14
14
|
import { fileURLToPath } from 'node:url';
|
|
15
15
|
import { parse as parseYaml } from 'yaml';
|
|
16
16
|
import { validateUnitCalls } from '../graph-runner/runner.js';
|
|
@@ -28,6 +28,10 @@ import { applyRunIdentityTag, applyRunIdentityTags, deriveBirthIdentity, parseRu
|
|
|
28
28
|
import { parseWorkOrder, renderWorkOrderGoal, WORK_ORDER_FILE_PATTERN, type WorkOrder } from './work-order.js';
|
|
29
29
|
import { inspectPrelaunchAlreadyDone, type AlreadyDoneDecision, type AlreadyDoneCandidate,
|
|
30
30
|
type PrelaunchGitRunnerForTest } from './prelaunch-already-done.js';
|
|
31
|
+
import { draftReleaseComment } from '../self-dev/draft-triage-rules.js';
|
|
32
|
+
import { parseAskTargetPathHints, parseAskTargetPathHintsResult } from '../self-dev/launch-preflight-text.js';
|
|
33
|
+
import { inspectGoalDoneBoundary } from '../self-implement/goal-author.js';
|
|
34
|
+
import { INFLIGHT_REGISTRY_FILE, registerInflight } from '../pr-tool/inflight-registry.js';
|
|
31
35
|
|
|
32
36
|
export interface ResolveHandTextDeps {
|
|
33
37
|
cwd: string;
|
|
@@ -207,6 +211,8 @@ export interface TaskCardMove { kind: 'launch' | 'wait'; command?: string[]; rea
|
|
|
207
211
|
export interface TaskCard {
|
|
208
212
|
id: string;
|
|
209
213
|
text: string;
|
|
214
|
+
/** 첫 줄 대상 경로 라벨에서 확인한 저장소 상대 경로. 필드 부재는 경로를 모른다는 뜻이다. */
|
|
215
|
+
targetPaths?: string[];
|
|
210
216
|
seat?: TaskSeat;
|
|
211
217
|
checklistId?: string;
|
|
212
218
|
/** Explicit release version for an adopted PR; post-land still confirms the cell exists there. */
|
|
@@ -228,8 +234,11 @@ export interface TaskCard {
|
|
|
228
234
|
* launch-failed = 발사기가 띄우기에 실패했다(사유는 history 마지막 칸) — 다음 수는 다시 발사.
|
|
229
235
|
* failed = 발사된 런이 PR·수확 가지 없이 죽었거나 끝내 안 떴다(TA-JUDGE-DEAD-RUN · `card-evidence.ts`) — 사유
|
|
230
236
|
* (`failed/needs-owner|needs-relaunch — …`)는 history 마지막 칸 · 자동 재발사하지 않는다(사람/판단부 몫).
|
|
237
|
+
* landed-by-hand = 실패 카드에 묶인 PR을 사람이 손수 병합해 main 에 안착시켰다(TA-CARD-MERGE-RECONCILE ·
|
|
238
|
+
* `postland-card.ts` `reconcileHandMergedCard`) — 이전 status·사유는 history `hand-move` 줄에 보존된다.
|
|
239
|
+
* landed = 병합된 merge 커밋이 카드의 land attempt head 와 정확히 일치해 에이전트 착지로 확정했다(같은 정산 경로).
|
|
231
240
|
*/
|
|
232
|
-
status: 'handed' | 'launched' | 'launch-failed' | 'failed' | 'done';
|
|
241
|
+
status: 'handed' | 'launched' | 'launch-failed' | 'failed' | 'landed-by-hand' | 'landed' | 'done';
|
|
233
242
|
history: TaskCardEvent[];
|
|
234
243
|
/** 미션 카드만 — 조각 카드 id(순서대로) · 쪼갠 출처(`mission.ts` splitMission). */
|
|
235
244
|
pieces?: string[];
|
|
@@ -289,7 +298,7 @@ export interface TaskCard {
|
|
|
289
298
|
* REJUDGE base-stale — `base-stale` (overlap evidence gate base went stale with PR-file overlap) waits for a re-gate on a new base;
|
|
290
299
|
* only after that re-gate passes is the attempt consumed (`openLandAttempts`) and the same head may land once more.
|
|
291
300
|
*/
|
|
292
|
-
landAttempts?: Array<{ pr: number; head: string; at: string; ok?: boolean; detail?: string; class?: 'infra' | 'judgement' | 'base-stale'; reason?: string }>;
|
|
301
|
+
landAttempts?: Array<{ pr: number; head: string; at: string; ok?: boolean; detail?: string; class?: 'infra' | 'judgement' | 'base-stale' | 'recovery'; reason?: string }>;
|
|
293
302
|
/** TA-LIVE-LAND-2 — `tasks hand --ta-land`: this card's run leaves the merge to the task agent (propose-land). */
|
|
294
303
|
taLand?: true;
|
|
295
304
|
/** TASKS-HAND-CHILD-LLM — `tasks hand --child-llm <provider>/<model> [--child-llm-effort <level>]` → 발사 인자 `--child-llm-provider/-model/-effort`. */
|
|
@@ -338,6 +347,16 @@ export function boundPrTerminal(card: Pick<TaskCard, 'pr' | 'prTerminal'>): Task
|
|
|
338
347
|
return marker && typeof card.pr === 'object' && card.pr.number === marker.pr && card.pr.url === marker.url ? marker : undefined;
|
|
339
348
|
}
|
|
340
349
|
|
|
350
|
+
/**
|
|
351
|
+
* DRAFT-CLAIM-AUTO-2 — 포기 경로(failed · launch-failed)로 끝난 카드가 PR 을 남겼으면 그 PR 에 달 «🔧 처리 끝» 문면.
|
|
352
|
+
* 이 조각은 순수 함수만 — 실제 PR 코멘트(gh) · draft-sweep 배선은 다음 조각. launched · handed · PR 없음은 null.
|
|
353
|
+
*/
|
|
354
|
+
export function abandonedDraftReleaseNote(card: Pick<TaskCard, 'id' | 'status' | 'pr'>, at: Date): { pr: number; body: string } | null {
|
|
355
|
+
if (card.status !== 'failed' && card.status !== 'launch-failed') return null;
|
|
356
|
+
const pr = cardPrNumber(card);
|
|
357
|
+
return pr === undefined ? null : { pr, body: draftReleaseComment(at, `${card.id} 포기 경로 — 자동`) };
|
|
358
|
+
}
|
|
359
|
+
|
|
341
360
|
/** A uniquely launched code-PR card may own a draft through its PR or its opening run. */
|
|
342
361
|
export function draftTaskOwner(cards: readonly TaskCard[], draft: { number: number; runId?: string | null }): TaskCard | undefined {
|
|
343
362
|
const owners = cards.filter((card) => card.status === 'launched' && (card.completion ?? 'code-pr') === 'code-pr'
|
|
@@ -421,6 +440,25 @@ export function readTaskCard(id: string, path = taskAgentStatePath()): TaskCard
|
|
|
421
440
|
return readState(path).tasks?.[id];
|
|
422
441
|
}
|
|
423
442
|
|
|
443
|
+
function canonicalTargetPaths(paths: readonly string[]): string[] {
|
|
444
|
+
return [...new Set(paths.filter((path): path is string => typeof path === 'string').map((path) => posix.normalize(path))
|
|
445
|
+
.filter((path) => path !== '.' && path !== '..' && !posix.isAbsolute(path)
|
|
446
|
+
&& !path.startsWith('../') && !path.includes('\\') && !/^[A-Za-z]:\//.test(path)))].sort();
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/** 같은 저장소 경로를 만지는 착지 전 카드만 돌려준다. 경로 미기록 카드는 추측하지 않는다. */
|
|
450
|
+
export function cardsTouchingPaths(cards: readonly TaskCard[], paths: readonly string[]): Array<{
|
|
451
|
+
card: TaskCard; checklistId?: string; runId?: string; pr?: number; paths: string[];
|
|
452
|
+
}> {
|
|
453
|
+
const wanted = new Set(canonicalTargetPaths(paths));
|
|
454
|
+
if (wanted.size === 0) return [];
|
|
455
|
+
return cards.filter((card) => card.status === 'launched' && !card.postLand && !card.trainLanding && !card.prTerminal)
|
|
456
|
+
.map((card) => ({ card, paths: canonicalTargetPaths(card.targetPaths ?? []).filter((path) => wanted.has(path)) }))
|
|
457
|
+
.filter((item) => item.paths.length > 0)
|
|
458
|
+
.map(({ card, paths }) => ({ card, ...(card.checklistId ? { checklistId: card.checklistId } : {}),
|
|
459
|
+
...(card.runId ? { runId: card.runId } : {}), ...(cardPrNumber(card) !== undefined ? { pr: cardPrNumber(card) } : {}), paths }));
|
|
460
|
+
}
|
|
461
|
+
|
|
424
462
|
export const CLOSED_BY_HAND_EVENT = 'closed-by-hand';
|
|
425
463
|
|
|
426
464
|
/** 카드를 손으로 닫는다 — 상태를 `failed` 로 두고 history 에 한 줄(`closed-by-hand`)을 남긴다. 이미 손으로 닫은 카드는 그대로 돌려준다(멱등). */
|
|
@@ -539,7 +577,7 @@ export function shellQuote(arg: string): string {
|
|
|
539
577
|
}
|
|
540
578
|
|
|
541
579
|
/** 발사기에 넘기는 연결 — env(`ELANOUS_RUN_ID`)를 자식 환경에 얹으면 하니스 런이 `runId` 로 돈다(`resolveRunIdentity` 상속). launchId 는 카드에만 남는 발사 토큰이다. */
|
|
542
|
-
export interface TaskLaunchContext { runId: string; launchId: string; env: Record<string, string>; cardLabelContext?: TaskCardLabelContext }
|
|
580
|
+
export interface TaskLaunchContext { runId: string; launchId: string; env: Record<string, string>; cardLabelContext?: TaskCardLabelContext; substrate?: 'pod'; podGoal?: string; effectiveChildProvider?: string }
|
|
543
581
|
/** 발사기가 «이 런 id 로 띄웠다»고 돌려주는 영수증 — 없으면 카드에 런 id 를 적지 않는다(추측하지 않는다). */
|
|
544
582
|
export interface TaskLaunchReceipt {
|
|
545
583
|
runId?: string;
|
|
@@ -644,6 +682,8 @@ export function dispatchDeliverableCompletion(id: string, input: { ref: string;
|
|
|
644
682
|
export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
645
683
|
const text = opts.text.trim();
|
|
646
684
|
if (!text) throw new Error('과제 한 줄이 비어 있다');
|
|
685
|
+
const targetPathHints = parseAskTargetPathHintsResult(text);
|
|
686
|
+
const targetPaths = canonicalTargetPaths(targetPathHints.paths);
|
|
647
687
|
if (opts.seat !== undefined && !TASK_SEATS.includes(opts.seat)) throw new Error(`자리는 ${TASK_SEATS.join('|')} 중 하나다: ${opts.seat}`);
|
|
648
688
|
if (opts.completion !== undefined && !COMPLETION_KINDS.includes(opts.completion)) throw new Error(`종결 종류는 ${COMPLETION_KINDS.join('|')} 중 하나다: ${opts.completion}`);
|
|
649
689
|
for (const [flag, value] of [['--goal', opts.goal], ['--milestone', opts.milestone]] as const) {
|
|
@@ -695,6 +735,7 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
|
695
735
|
const path = opts.statePath ?? taskAgentStatePath();
|
|
696
736
|
const card: TaskCard = {
|
|
697
737
|
id, text,
|
|
738
|
+
...(!targetPathHints.labelMissing ? { targetPaths } : {}),
|
|
698
739
|
...(opts.seat ? { seat: opts.seat } : {}),
|
|
699
740
|
...(opts.checklistId ? { checklistId: opts.checklistId } : {}),
|
|
700
741
|
...(opts.checklistVersion !== undefined ? { checklistVersion: opts.checklistVersion } : {}),
|
|
@@ -735,6 +776,7 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
|
735
776
|
if (!owned.ok) throw new TaskCardSupersededError(next.id);
|
|
736
777
|
};
|
|
737
778
|
writeCard(path, card);
|
|
779
|
+
try { debug.log('task-agent.hand', 'target-paths', { card: id, count: targetPaths.length, labelMissing: targetPathHints.labelMissing }); } catch { /* fail-soft */ }
|
|
738
780
|
try { debug.log('task-agent.graph-select', !selected.composition ? 'composition-missing' : selected.error ? 'composition-invalid' : 'composition-selected', {
|
|
739
781
|
completion, file: selected.composition?.file ?? `graphs/work/${completion}.yaml`,
|
|
740
782
|
unitsResolved: selected.unitsResolved, missingUnits: selected.missingUnits,
|
|
@@ -748,6 +790,17 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
|
748
790
|
}
|
|
749
791
|
if (mode === 'shadow') return { card, move, mode, launched: false, ...(project ? { cwd: project.target } : {}) };
|
|
750
792
|
if (!opts.launcher) throw new Error('--live 인데 launcher 가 없다');
|
|
793
|
+
if (completion === 'code-pr' && card.checklistId) {
|
|
794
|
+
const { missing } = inspectGoalDoneBoundary(text);
|
|
795
|
+
if (missing.length > 0) {
|
|
796
|
+
const reason = `goal-revision-required: 완료 경계 누락 ${missing.join(' · ')} — 골 문면을 고친 뒤 다시 넘기세요`;
|
|
797
|
+
const failed: TaskCard = { ...card, status: 'failed', history: [...card.history,
|
|
798
|
+
{ at: (opts.now ?? (() => new Date()))().toISOString(), event: 'goal-revision-required', detail: reason }] };
|
|
799
|
+
writeCard(path, failed);
|
|
800
|
+
try { debug.log('task-agent.hand', 'done-boundary-missing', { taskId: id, checklistId: card.checklistId ?? null, missing, reason }); } catch { /* fail-soft */ }
|
|
801
|
+
throw new Error(`${reason} (카드 ${id})`);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
751
804
|
let prelaunch: AlreadyDoneDecision;
|
|
752
805
|
try { prelaunch = completion === 'code-pr'
|
|
753
806
|
? (opts.prelaunchInspector ?? ((input, target) => inspectPrelaunchAlreadyDone(input, target,
|
|
@@ -766,9 +819,14 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
|
766
819
|
const runId = mintRunId();
|
|
767
820
|
const launchId = `tl-${randomBytes(6).toString('hex')}`;
|
|
768
821
|
const context: TaskLaunchContext = { runId, launchId, env: { [HARNESS_RUN_ID_ENV]: runId, ELANOUS_TASK_CARD_ID: card.id,
|
|
822
|
+
...(cardPrNumber(card) ? { ELANOUS_TASK_BOUND_PR: String(cardPrNumber(card)) } : {}),
|
|
769
823
|
...(card.checklistId ? { ELANOUS_POD_SLOT_ID: card.checklistId } : {}),
|
|
770
824
|
...(card.seat ? { ELANOUS_POD_OWNER_KIND: 'seat', ELANOUS_POD_OWNER_ID: card.seat } : {}),
|
|
771
|
-
...(card.taLand ? { [TA_LAND_ENV]: '1' } : {}) }, cardLabelContext: taskCardLabelContext(card)
|
|
825
|
+
...(card.taLand ? { [TA_LAND_ENV]: '1' } : {}) }, cardLabelContext: taskCardLabelContext(card),
|
|
826
|
+
// An omitted card provider uses the established Pod default. Carry the effective value explicitly so
|
|
827
|
+
// remote-parent code never has to infer a provider from the serialized CLI argv.
|
|
828
|
+
effectiveChildProvider: card.childLlm?.provider ?? 'openai-codex',
|
|
829
|
+
...(completion === 'code-pr' && selected.launcher === 'harness-say' ? { substrate: 'pod' as const, podGoal: card.text } : {}) };
|
|
772
830
|
let receipt: void | TaskLaunchReceipt;
|
|
773
831
|
try {
|
|
774
832
|
receipt = await opts.launcher(move.command!, project?.target, context);
|
|
@@ -796,6 +854,19 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
|
796
854
|
],
|
|
797
855
|
};
|
|
798
856
|
writeCard(path, launched);
|
|
857
|
+
// INFLIGHT-REGISTRY — 출발 때 맥락을 남긴다(머지 때 같은 파일 줄의 의도를 스마트 머지가 읽는다 · 착지하면 지운다).
|
|
858
|
+
try {
|
|
859
|
+
const [head = '', ...rest] = text.split(/\r?\n/);
|
|
860
|
+
const intentLines = (/^\s*(?:대상\s*경로|target\s*paths?)\s*[::]/i.test(head) ? rest : [head, ...rest])
|
|
861
|
+
.filter((line) => !/^\s*(?:[-*]\s*)?완료 경계 (?:코드|실물|증거 명령)\s*:/.test(line));
|
|
862
|
+
registerInflight({
|
|
863
|
+
runId: boundRunId ?? runId, cell: card.checklistId ?? card.id, cardId: card.id,
|
|
864
|
+
intent: intentLines.join(' ').trim() || text,
|
|
865
|
+
files: parseAskTargetPathHints(text),
|
|
866
|
+
}, { path: join(dirname(path), INFLIGHT_REGISTRY_FILE), ...(opts.now ? { now: opts.now } : {}) });
|
|
867
|
+
} catch (error) {
|
|
868
|
+
try { debug.log('pr-tool.inflight', 'register-failed', { taskId: id, error: String((error as Error)?.message ?? error).slice(0, 200) }, { level: 'warn' }); } catch { /* fail-soft */ }
|
|
869
|
+
}
|
|
799
870
|
try { debug.log('task-agent', 'launched', { taskId: id, seat: card.seat ?? null, runId: boundRunId ?? null }); } catch { /* fail-soft */ }
|
|
800
871
|
if (boundRunId) {
|
|
801
872
|
try { debug.log('task-agent', 'card-run-bound', { card: id, runId: boundRunId, launchId }); } catch { /* fail-soft */ }
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { parseWorkOrder, type WorkOrder } from './work-order.js';
|
|
2
|
+
|
|
3
|
+
export interface BuildWorkOrderInput {
|
|
4
|
+
cellId: string;
|
|
5
|
+
version: string;
|
|
6
|
+
lifeId?: string;
|
|
7
|
+
priority?: string;
|
|
8
|
+
peers?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Build the normalized nine-field core from already-grounded inputs; no CLI, filesystem, or launch side effects. */
|
|
12
|
+
export function buildWorkOrder(input: BuildWorkOrderInput): WorkOrder {
|
|
13
|
+
const parsed = parseWorkOrder(JSON.stringify({
|
|
14
|
+
cellId: input.cellId,
|
|
15
|
+
lifeId: input.lifeId,
|
|
16
|
+
version: input.version,
|
|
17
|
+
priority: input.priority,
|
|
18
|
+
peers: input.peers,
|
|
19
|
+
}));
|
|
20
|
+
if (!parsed.ok) throw new Error(parsed.reason);
|
|
21
|
+
return parsed.order;
|
|
22
|
+
}
|
|
@@ -17,6 +17,17 @@ export type PodProviderPlan =
|
|
|
17
17
|
| { provider: 'grok'; excluded: PodAccountPlan['excluded']; grokSubscriptionEligible: boolean }
|
|
18
18
|
| { provider: null; reasons: string[]; grokSubscriptionEligible: boolean };
|
|
19
19
|
|
|
20
|
+
/** Effective cap used by the Pod broker; callers carrying an owner-approved selection must carry this same value. */
|
|
21
|
+
export function podAccountThresholdPercent(name: string, options: {
|
|
22
|
+
excludeAt?: number;
|
|
23
|
+
thresholdPercentByAccount?: Readonly<Record<string, unknown>>;
|
|
24
|
+
} = {}): number {
|
|
25
|
+
return codexAccountThresholdPercent(name, {
|
|
26
|
+
thresholdPercent: options.excludeAt ?? POD_ACCOUNT_EXCLUDE_AT_PERCENT,
|
|
27
|
+
thresholdPercentByAccount: options.thresholdPercentByAccount,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
20
31
|
/** Pod 의 codex → grok 선택. 자격 종류는 과금 동의와 별도로 판단한다. */
|
|
21
32
|
export function planPodProvider(input: {
|
|
22
33
|
codexCandidates: readonly RotationCandidate[];
|
|
@@ -85,9 +96,7 @@ export function planPodAccounts(
|
|
|
85
96
|
const known: RotationCandidate[] = [];
|
|
86
97
|
const unknown: RotationCandidate[] = [];
|
|
87
98
|
for (const c of candidates) {
|
|
88
|
-
const threshold = typeof options === 'number'
|
|
89
|
-
? excludeAt
|
|
90
|
-
: codexAccountThresholdPercent(c.name, { thresholdPercent: excludeAt, thresholdPercentByAccount });
|
|
99
|
+
const threshold = typeof options === 'number' ? excludeAt : podAccountThresholdPercent(c.name, { excludeAt, thresholdPercentByAccount });
|
|
91
100
|
if (c.reached === true) { excluded.push({ name: c.name, why: 'quota reached' }); continue; }
|
|
92
101
|
if (c.usedPercent !== undefined && c.usedPercent >= threshold) { excluded.push({ name: c.name, why: `used ${c.usedPercent}% ≥ ${threshold}%` }); continue; }
|
|
93
102
|
(c.usedPercent === undefined ? unknown : known).push(c);
|
|
@@ -113,6 +122,33 @@ export function planPodAccounts(
|
|
|
113
122
|
return { usable, excluded };
|
|
114
123
|
}
|
|
115
124
|
|
|
125
|
+
/** HQ selects one owner account before remote-parent launch; keep the configured rotation order. */
|
|
126
|
+
export function planOwnerCodexMirrorCandidates(candidates: readonly RotationCandidate[], options: {
|
|
127
|
+
accountOrder: readonly string[];
|
|
128
|
+
thresholdPercentByAccount?: Readonly<Record<string, unknown>>;
|
|
129
|
+
}): RotationCandidate[] {
|
|
130
|
+
const usable = new Set(planPodAccounts(candidates, { thresholdPercentByAccount: options.thresholdPercentByAccount }).usable);
|
|
131
|
+
const rank = (name: string): number => {
|
|
132
|
+
const index = options.accountOrder.indexOf(name);
|
|
133
|
+
return index < 0 ? options.accountOrder.length : index;
|
|
134
|
+
};
|
|
135
|
+
return candidates.map((candidate, index) => ({ candidate, index })).filter(({ candidate }) => usable.has(candidate.name))
|
|
136
|
+
.sort((a, b) => rank(a.candidate.name) - rank(b.candidate.name) || a.index - b.index)
|
|
137
|
+
.map(({ candidate }) => candidate);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Remote owner-mirror runs may plan against exactly the account HQ selected and its measured usage. */
|
|
141
|
+
export function ownerCodexMirrorCandidate(candidates: readonly RotationCandidate[], account: string, usedPercent?: number): RotationCandidate[] {
|
|
142
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(account)) return [];
|
|
143
|
+
return candidates.filter((candidate) => candidate.name === account).map((candidate) => {
|
|
144
|
+
const ownerCandidate = { ...candidate };
|
|
145
|
+
delete ownerCandidate.usedPercent;
|
|
146
|
+
ownerCandidate.reached = false;
|
|
147
|
+
const measured = usedPercent !== undefined && Number.isFinite(usedPercent) ? usedPercent : undefined;
|
|
148
|
+
return { ...ownerCandidate, reached: false, ...(measured !== undefined ? { usedPercent: measured } : {}) };
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
116
152
|
/** Job 마다 다음 계정 — 잔량 순으로 돌려 가며. 쓸 계정이 없으면 만들 때 이유를 대고 던진다. */
|
|
117
153
|
export function makePodAccountBroker(plan: PodAccountPlan): () => string {
|
|
118
154
|
if (plan.usable.length === 0) {
|
|
@@ -34,6 +34,8 @@ import {
|
|
|
34
34
|
|
|
35
35
|
/** CLI `--deadline` 생략 시 — 기존 Pod Job 수명 상한과 같다. */
|
|
36
36
|
export const POD_COMMAND_DEADLINE_SECONDS = POD_JOB_DEADLINE_SECONDS;
|
|
37
|
+
/** An opt-in shadow cannot let a synchronous kubectl call hide its host deadline for two minutes. */
|
|
38
|
+
export const POD_COMMAND_CANCEL_KUBECTL_TIMEOUT_MS = 15_000;
|
|
37
39
|
|
|
38
40
|
export const POD_NETWORK_SKILLS = ['omni-crawl', 'omni-digest'] as const;
|
|
39
41
|
export const POD_LITE_IMAGE = 'elanous-harness-lite:local';
|
|
@@ -414,6 +416,12 @@ export interface RunPodCommandOptions {
|
|
|
414
416
|
* elsewhere. Omitted = poll without a bound (unchanged for every caller but the release gate).
|
|
415
417
|
*/
|
|
416
418
|
statusUnreadableMs?: number;
|
|
419
|
+
/** Optional caller cancellation. Omitted callers keep their existing polling behavior. */
|
|
420
|
+
signal?: AbortSignal;
|
|
421
|
+
/** Optional host wall-clock deadline; checked even when a synchronous kubectl delayed the abort timer. */
|
|
422
|
+
hostDeadlineAtMs?: number;
|
|
423
|
+
/** Clock seam for deadline checks. */
|
|
424
|
+
nowMs?: () => number;
|
|
417
425
|
kubectl?: Kubectl;
|
|
418
426
|
/** A caller-owned scheduler is self-capped: acquires count only its own Jobs, never cluster occupancy (POOLGLOBAL-REG). */
|
|
419
427
|
poolScheduler?: PodPoolScheduler;
|
|
@@ -486,14 +494,35 @@ export function podCommandTargetCommit(o: { remote: boolean; gitHead: () => stri
|
|
|
486
494
|
return o.localImageCommit();
|
|
487
495
|
}
|
|
488
496
|
|
|
497
|
+
/** Only opt-in callers can stop waiting on a pre-Job async operation. Late rejections stay observed. */
|
|
498
|
+
function awaitPodCommandAbort<T>(pending: Promise<T>, signal?: AbortSignal): Promise<T> {
|
|
499
|
+
if (!signal) return pending;
|
|
500
|
+
return new Promise<T>((resolve, reject) => {
|
|
501
|
+
const onAbort = () => { signal.removeEventListener('abort', onAbort); reject(signal.reason ?? new Error('pod command aborted')); };
|
|
502
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
503
|
+
pending.then(
|
|
504
|
+
(value) => { signal.removeEventListener('abort', onAbort); resolve(value); },
|
|
505
|
+
(error) => { signal.removeEventListener('abort', onAbort); reject(error); },
|
|
506
|
+
);
|
|
507
|
+
if (signal.aborted) onAbort();
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
|
|
489
511
|
/** 풀 자리 · 이미지 판 · Job 적용 · 완료 대기 · 산출 회수 · Secret 정리. */
|
|
490
512
|
export async function runPodCommand(options: RunPodCommandOptions): Promise<PodCommandResult> {
|
|
513
|
+
const nowMs = options.nowMs ?? Date.now;
|
|
514
|
+
const ensureLive = () => {
|
|
515
|
+
if (options.signal?.aborted) throw options.signal.reason ?? new Error('pod command aborted');
|
|
516
|
+
if (options.hostDeadlineAtMs !== undefined && nowMs() >= options.hostDeadlineAtMs) throw new Error('pod shadow: host timeout');
|
|
517
|
+
};
|
|
518
|
+
ensureLive();
|
|
491
519
|
const command = [...options.command];
|
|
492
520
|
if (command.length === 0) throw new Error('pod command: 명령이 비었다');
|
|
493
521
|
const skills = [...new Set((options.skills ?? []).map((s) => s.trim()).filter(Boolean))];
|
|
494
522
|
const llm = options.llm;
|
|
495
523
|
const log = options.log ?? ((c, e, d) => debug.log(c, e, d));
|
|
496
|
-
const baseKubectl = options.kubectl ??
|
|
524
|
+
const baseKubectl = options.kubectl ?? ((args: readonly string[], input?: string) =>
|
|
525
|
+
defaultKubectl(args, input, options.signal ? POD_COMMAND_CANCEL_KUBECTL_TIMEOUT_MS : undefined));
|
|
497
526
|
const sleep = options.sleep ?? ((ms: number) => new Promise<void>((r) => setTimeout(r, ms)));
|
|
498
527
|
const namespace = options.namespace ?? 'elanous-test';
|
|
499
528
|
const image = options.image ?? podCommandImageFor(skills, options.clone === true, options.lite === true);
|
|
@@ -534,22 +563,37 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
534
563
|
// concurrency cap — its Jobs count against the spec caps, not the cluster's goal Pods (#24253 → 0.2.15 gate ran 1 shard).
|
|
535
564
|
const selfCapped = options.poolScheduler !== undefined;
|
|
536
565
|
for (;;) {
|
|
537
|
-
|
|
566
|
+
ensureLive();
|
|
567
|
+
const acquiring = pool.tryAcquire(undefined, undefined, { selfCapped, signal: options.signal });
|
|
568
|
+
try { member = await awaitPodCommandAbort(acquiring, options.signal); }
|
|
569
|
+
catch (error) {
|
|
570
|
+
// If cancellation won the await at the same instant acquisition completed, return that lease.
|
|
571
|
+
void acquiring.then((late) => { if (late) pool!.release(late); }, () => {});
|
|
572
|
+
throw error;
|
|
573
|
+
}
|
|
538
574
|
if (member) break;
|
|
539
|
-
await sleep(options.pollMs ?? 15_000);
|
|
575
|
+
await awaitPodCommandAbort(sleep(options.pollMs ?? 15_000), options.signal);
|
|
540
576
|
}
|
|
541
577
|
}
|
|
578
|
+
if (options.signal?.aborted) {
|
|
579
|
+
if (member && pool) pool.release(member);
|
|
580
|
+
ensureLive();
|
|
581
|
+
}
|
|
542
582
|
const currentContext = member || options.kubectl ? null : baseKubectl(['config', 'current-context']);
|
|
543
583
|
const context = member?.context ?? (currentContext?.status === 0 ? currentContext.stdout.trim() : '');
|
|
544
|
-
const
|
|
545
|
-
const
|
|
584
|
+
const kubectlRaw: Kubectl = (args, stdin) => baseKubectl(context ? ['--context', context, ...args] : [...args], stdin);
|
|
585
|
+
const kubectl: Kubectl = (args, stdin) => { ensureLive(); const result = kubectlRaw(args, stdin); ensureLive(); return result; };
|
|
586
|
+
const cleanupSecret = () => { kubectlRaw(['-n', namespace, 'delete', 'secret', '-l', own, '--ignore-not-found']); };
|
|
546
587
|
const artifactRoot = options.artifactsRoot ?? `${effectiveInstanceRoot()}/pod-artifacts`;
|
|
547
588
|
const artifactsDir = `${artifactRoot}/${name}`;
|
|
589
|
+
let jobApplied = false;
|
|
548
590
|
try {
|
|
591
|
+
ensureLive();
|
|
549
592
|
if (!context && !options.kubectl) throw new Error('pod command: kubectl context 를 확인할 수 없다');
|
|
550
593
|
let grokAuth: string | undefined;
|
|
551
594
|
if (llm === 'grok') {
|
|
552
|
-
|
|
595
|
+
// POD-GROK-VALIDITY-FIT — this Job's deadline is not fitted to the token, so the copy must outlive the whole Job.
|
|
596
|
+
const creds = (options.grokCredentials ?? (() => hostGrokCredentials({ env, apiKeyOptIn: false, minValidityMs: deadlineSeconds * 1000 })))();
|
|
553
597
|
if (!creds.grokAuth) throw new Error('grok: 구독 자격 없음 · API 키 opt-in 꺼짐 또는 키 없음');
|
|
554
598
|
let parsed: unknown;
|
|
555
599
|
try { parsed = JSON.parse(creds.grokAuth); } catch { throw new Error('grok: Pod 구독 자격 JSON 이 아니다'); }
|
|
@@ -573,7 +617,7 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
573
617
|
const localSkillsDigest = options.kubectl ? null : image === POD_LITE_IMAGE
|
|
574
618
|
? podSkillsDigest(POD_NETWORK_SKILLS, resolve(import.meta.dir, '../../../skills')).digest
|
|
575
619
|
: podSkillsDigest(resolvePodSkills(env).skills).digest;
|
|
576
|
-
const syncs = await (options.syncImages ?? syncPoolImages)([member], image, imageCommit, { localSkillsDigest });
|
|
620
|
+
const syncs = await awaitPodCommandAbort((options.syncImages ?? syncPoolImages)([member], image, imageCommit, { localSkillsDigest }), options.signal);
|
|
577
621
|
const synced = syncs.get(member.context);
|
|
578
622
|
if (synced && !synced.ok) throw new Error(`pod command: 이미지 판을 못 맞췄다: ${synced.detail}`);
|
|
579
623
|
if (synced?.imageRef) member = { ...member, imageRef: synced.imageRef };
|
|
@@ -586,8 +630,8 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
586
630
|
const seedMirror = options.seedMirror ?? (options.kubectl ? undefined : seedMirrorOnce);
|
|
587
631
|
if (seedMirror && options.clone && options.source?.kind === 'commit' && hostMirror && member?.sshHost) {
|
|
588
632
|
// Worst case added to a cold start: the push limit (GATE_MIRROR_SEED_LIMIT_MS), once per host·commit.
|
|
589
|
-
const seed = await seedMirror({ host: member.sshHost, commit: options.source.sha, cwd: options.mirrorSeedCwd ?? process.cwd() })
|
|
590
|
-
.catch((error: unknown) => ({ host: member!.sshHost!, ok: false, ms: 0, detail: String(error).slice(0, 300) }));
|
|
633
|
+
const seed = await awaitPodCommandAbort(seedMirror({ host: member.sshHost, commit: options.source.sha, cwd: options.mirrorSeedCwd ?? process.cwd() })
|
|
634
|
+
.catch((error: unknown) => ({ host: member!.sshHost!, ok: false, ms: 0, detail: String(error).slice(0, 300) })), options.signal);
|
|
591
635
|
log('pod.command-job', 'mirror-seed', { host: member.sshHost, commit: options.source.sha, ok: seed?.ok ?? false, ms: seed?.ms ?? 0, ...(seed?.detail ? { detail: seed.detail } : {}) });
|
|
592
636
|
}
|
|
593
637
|
// GATE-WARM-BOOT-NO-INIT (10-15): the hostPath dirs the uid-1000 child writes are handed over on the node itself, once per
|
|
@@ -600,14 +644,15 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
600
644
|
if (!member) log('pod.command-job', 'host-dirs-prep', { ok: false, reason: 'no-pool-member', paths: hostDirPaths });
|
|
601
645
|
else if (!prepareHostDirs) log('pod.command-job', 'host-dirs-prep', { ok: false, reason: 'prep-disabled', paths: hostDirPaths });
|
|
602
646
|
else {
|
|
603
|
-
const prep = await prepareHostDirs({ member, hostPaths: hostDirPaths })
|
|
604
|
-
.catch((error: unknown) => ({ host: member!.sshHost ?? 'local', ok: false, ms: 0, detail: String(error).slice(0, 300) }));
|
|
647
|
+
const prep = await awaitPodCommandAbort(prepareHostDirs({ member, hostPaths: hostDirPaths })
|
|
648
|
+
.catch((error: unknown) => ({ host: member!.sshHost ?? 'local', ok: false, ms: 0, detail: String(error).slice(0, 300) })), options.signal);
|
|
605
649
|
hostDirsPrepared = prep?.ok === true;
|
|
606
650
|
log('pod.command-job', 'host-dirs-prep', { host: prep?.host ?? member.sshHost ?? 'local', ok: prep?.ok ?? false, ms: prep?.ms ?? 0, paths: hostDirPaths, ...(prep?.detail ? { detail: prep.detail } : {}) });
|
|
607
651
|
}
|
|
608
652
|
}
|
|
609
653
|
// Any path where the node-side hand-over did not succeed keeps the old in-Pod hand-over (review mf: uid 1000 could not write).
|
|
610
654
|
const hostDirsInit = hostDirPaths.length > 0 && !hostDirsPrepared;
|
|
655
|
+
ensureLive();
|
|
611
656
|
const ghToken = options.clone ? (options.ghToken ?? defaultGhToken)() : undefined;
|
|
612
657
|
const secret = commandJobSecret({ name, namespace, launch, skills, skillEnvText, ...(grokAuth !== undefined ? { grokAuth } : {}), ...(ghToken !== undefined ? { ghToken } : {}) });
|
|
613
658
|
if (secret) {
|
|
@@ -623,6 +668,8 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
623
668
|
...(hostDirsInit ? { hostDirsInit: true } : {}),
|
|
624
669
|
});
|
|
625
670
|
kubectl(['-n', namespace, 'delete', 'job', '-l', own, '--ignore-not-found']);
|
|
671
|
+
// A wall deadline can elapse inside the synchronous apply; cleanup by this launch's name then remains safe.
|
|
672
|
+
jobApplied = true;
|
|
626
673
|
const applied = kubectl(['apply', '-f', '-'], JSON.stringify(manifest));
|
|
627
674
|
if (applied.status !== 0) {
|
|
628
675
|
cleanupSecret();
|
|
@@ -633,6 +680,7 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
633
680
|
let markerRc: number | null = null;
|
|
634
681
|
const appliedAt = Date.now();
|
|
635
682
|
for (;;) {
|
|
683
|
+
ensureLive();
|
|
636
684
|
const got = kubectl(['-n', namespace, 'get', 'job', name, '-o', 'jsonpath={.status.conditions[*].type}']);
|
|
637
685
|
const finished = jobFinished(got.stdout);
|
|
638
686
|
if (finished) { state = finished; break; }
|
|
@@ -655,8 +703,9 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
655
703
|
throw new Error(`pod command: Job 상태를 ${Math.round(options.statusUnreadableMs / 1000)}초 동안 못 읽었다(${context}) — ${(got.stderr ?? '').trim().split('\n').pop()?.slice(0, 200) ?? ''}`);
|
|
656
704
|
}
|
|
657
705
|
} else unreadableSince = null;
|
|
658
|
-
await sleep(options.pollMs ?? 15_000);
|
|
706
|
+
await awaitPodCommandAbort(sleep(options.pollMs ?? 15_000), options.signal);
|
|
659
707
|
}
|
|
708
|
+
ensureLive();
|
|
660
709
|
let logsResult = kubectl(['-n', namespace, 'logs', `job/${name}`, '-c', 'child']);
|
|
661
710
|
// Marker path returns before the Job condition — a full-log read can hit the same transient window the tail read
|
|
662
711
|
// already survived (container log rotation · API hiccup). Retry it a little before calling the artifacts lost.
|
|
@@ -721,6 +770,12 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
721
770
|
});
|
|
722
771
|
return { exitCode, artifactsDir, job: name, image: imageRef ?? image, artifacts };
|
|
723
772
|
} catch (err) {
|
|
773
|
+
if (jobApplied && options.signal) {
|
|
774
|
+
// Opt-in bounded callers remove their own failed/Pending Job, including status-unreadable exits.
|
|
775
|
+
// On an unreachable API this is best effort; the local lease is always released in finally.
|
|
776
|
+
try { kubectlRaw(['-n', namespace, 'delete', 'job', name, '--ignore-not-found', '--wait=false']); }
|
|
777
|
+
catch { /* preserve the cancellation reason */ }
|
|
778
|
+
}
|
|
724
779
|
cleanupSecret();
|
|
725
780
|
throw err;
|
|
726
781
|
} finally {
|
|
@@ -230,6 +230,13 @@ function runningLimit(spec: Record<string, unknown>): number | null {
|
|
|
230
230
|
|
|
231
231
|
/** A short-lived Pod proves cluster DNS from inside the same namespace as harness Jobs. Image pull failures are not DNS failures. */
|
|
232
232
|
export type PoolDnsProbe = 'ready' | 'dns' | 'image' | 'unknown';
|
|
233
|
+
/** Separate, opt-in observation. null means the probe could not measure that step. */
|
|
234
|
+
export interface ExternalGitHubProbe {
|
|
235
|
+
externalDns: boolean | null;
|
|
236
|
+
githubHttps: boolean | null;
|
|
237
|
+
measuredAt: string | null;
|
|
238
|
+
reason: string | null;
|
|
239
|
+
}
|
|
233
240
|
const DNS_CACHE_MS = 10 * 60_000;
|
|
234
241
|
const DNS_STALE_OK_MS = 30 * 60_000;
|
|
235
242
|
const DNS_LOCK_WAIT_MS = 6 * 60_000;
|
|
@@ -240,6 +247,97 @@ const dnsFlock = process.platform === 'linux' || process.platform === 'darwin'
|
|
|
240
247
|
flock: { args: ['int', 'int'], returns: 'int' },
|
|
241
248
|
}).symbols.flock : null;
|
|
242
249
|
|
|
250
|
+
/** A disposable Pod in the Job namespace measures GitHub reachability without changing admission. */
|
|
251
|
+
export function probePoolGitHub(context: string, kubectl: PoolKubectl = leaseKubectl, options: { dir?: string; now?: () => number } = {}): ExternalGitHubProbe {
|
|
252
|
+
const unknown = (reason: string): ExternalGitHubProbe => ({ externalDns: null, githubHttps: null, measuredAt: null, reason });
|
|
253
|
+
const now = options.now ?? Date.now;
|
|
254
|
+
const dir = options.dir ?? hostLeaseBaseDir();
|
|
255
|
+
const key = createHash('sha256').update(context).digest('hex');
|
|
256
|
+
const cache = join(dir, `github-egress-${key}.cache`);
|
|
257
|
+
const lock = join(dir, `github-egress-${key}.flock`);
|
|
258
|
+
const cached = (): ExternalGitHubProbe | null => {
|
|
259
|
+
try {
|
|
260
|
+
const record = object(JSON.parse(readFileSync(cache, 'utf8')));
|
|
261
|
+
if (typeof record?.at !== 'number' || now() < record.at || now() - record.at >= 60_000) return null;
|
|
262
|
+
if (typeof record.measuredAt !== 'string' || ![true, false].includes(record.externalDns as boolean) ||
|
|
263
|
+
![true, false, null].includes(record.githubHttps as boolean | null) ||
|
|
264
|
+
!(record.reason === null || typeof record.reason === 'string')) return null;
|
|
265
|
+
return { externalDns: record.externalDns as boolean, githubHttps: record.githubHttps as boolean | null,
|
|
266
|
+
measuredAt: record.measuredAt, reason: record.reason as string | null };
|
|
267
|
+
} catch { return null; }
|
|
268
|
+
};
|
|
269
|
+
const fresh = cached();
|
|
270
|
+
if (fresh) return fresh;
|
|
271
|
+
try { mkdirSync(dir, { recursive: true, mode: 0o700 }); } catch { return unknown('probe cache unavailable'); }
|
|
272
|
+
if (!dnsFlock) return unknown('probe lock unavailable');
|
|
273
|
+
let fd: number;
|
|
274
|
+
try { fd = openSync(lock, 'a', 0o600); } catch { return unknown('probe lock unavailable'); }
|
|
275
|
+
let held = false;
|
|
276
|
+
try {
|
|
277
|
+
const deadline = Date.now() + 2_000;
|
|
278
|
+
while (!held) {
|
|
279
|
+
const shared = cached();
|
|
280
|
+
if (shared) return shared;
|
|
281
|
+
if (dnsFlock(fd, 2 | 4) === 0) { held = true; break; }
|
|
282
|
+
if (Date.now() >= deadline) return unknown('probe busy');
|
|
283
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 100);
|
|
284
|
+
}
|
|
285
|
+
const shared = cached();
|
|
286
|
+
if (shared) return shared;
|
|
287
|
+
const result = runPoolGitHubProbe(context, kubectl, new Date(now()).toISOString());
|
|
288
|
+
if (result.measuredAt !== null) {
|
|
289
|
+
const temp = `${cache}.${randomUUID()}.tmp`;
|
|
290
|
+
try { writeFileSync(temp, JSON.stringify({ ...result, at: now() }), { mode: 0o600 }); renameSync(temp, cache); }
|
|
291
|
+
catch { try { rmSync(temp, { force: true }); } catch { /* observation remains valid without cache */ } }
|
|
292
|
+
}
|
|
293
|
+
return result;
|
|
294
|
+
} finally {
|
|
295
|
+
if (held) dnsFlock(fd, 8);
|
|
296
|
+
closeSync(fd);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function runPoolGitHubProbe(context: string, kubectl: PoolKubectl, measuredAt: string): ExternalGitHubProbe {
|
|
301
|
+
const name = `elanous-egress-${randomUUID().slice(0, 12)}`;
|
|
302
|
+
const base = ['--context', context, '--request-timeout=15s'];
|
|
303
|
+
const unknown = (reason: string): ExternalGitHubProbe => ({ externalDns: null, githubHttps: null, measuredAt: null, reason });
|
|
304
|
+
let created = false;
|
|
305
|
+
try {
|
|
306
|
+
const manifest = JSON.stringify({ apiVersion: 'v1', kind: 'Pod', metadata: { name, namespace: 'elanous-test', labels: { 'elanous.probe': 'github-egress' } }, spec: {
|
|
307
|
+
restartPolicy: 'Never', activeDeadlineSeconds: 35, automountServiceAccountToken: false,
|
|
308
|
+
containers: [{ name: 'probe', image: 'busybox:1.36', command: ['sh', '-c',
|
|
309
|
+
'if nslookup github.com >/dev/null 2>&1; then echo EXTERNAL_DNS_OK; if wget -q -T 8 -O /dev/null https://github.com/; then echo GITHUB_HTTPS_OK; else echo GITHUB_HTTPS_FAILED; fi; else echo EXTERNAL_DNS_FAILED; fi'],
|
|
310
|
+
resources: { requests: { cpu: '0', memory: '16Mi' }, limits: { cpu: '100m', memory: '64Mi' } } }],
|
|
311
|
+
} });
|
|
312
|
+
if (kubectl([...base, 'create', '-f', '-'], manifest).status !== 0) return unknown('probe create failed');
|
|
313
|
+
created = true;
|
|
314
|
+
const waited = kubectl([...base, '-n', 'elanous-test', 'wait', '--for=jsonpath={.status.phase}=Succeeded', `pod/${name}`, '--timeout=25s']);
|
|
315
|
+
const podResult = kubectl([...base, '-n', 'elanous-test', 'get', `pod/${name}`, '-o', 'json']);
|
|
316
|
+
if (podResult.status !== 0) return unknown('probe status unavailable');
|
|
317
|
+
const pod = object(JSON.parse(podResult.stdout));
|
|
318
|
+
const statuses = object(pod?.status)?.containerStatuses;
|
|
319
|
+
if (Array.isArray(statuses) && statuses.some((c) =>
|
|
320
|
+
['ErrImagePull', 'ImagePullBackOff', 'InvalidImageName'].includes(String(object(object(object(c)?.state)?.waiting)?.reason))))
|
|
321
|
+
return unknown('probe image unavailable');
|
|
322
|
+
const logs = kubectl([...base, '-n', 'elanous-test', 'logs', `pod/${name}`]);
|
|
323
|
+
if (logs.status !== 0) return unknown(waited.status === 0 ? 'probe output unavailable' : 'probe timeout');
|
|
324
|
+
const markers = logs.stdout.trim().split(/\r?\n/u);
|
|
325
|
+
const dnsOk = markers.includes('EXTERNAL_DNS_OK');
|
|
326
|
+
const dnsFail = markers.includes('EXTERNAL_DNS_FAILED');
|
|
327
|
+
const httpsOk = markers.includes('GITHUB_HTTPS_OK');
|
|
328
|
+
const httpsFail = markers.includes('GITHUB_HTTPS_FAILED');
|
|
329
|
+
if (dnsFail && !dnsOk && !httpsOk && !httpsFail)
|
|
330
|
+
return { externalDns: false, githubHttps: null, measuredAt, reason: 'external DNS failed' };
|
|
331
|
+
if (dnsOk && !dnsFail && httpsOk !== httpsFail)
|
|
332
|
+
return { externalDns: true, githubHttps: httpsOk, measuredAt, reason: httpsFail ? 'GitHub HTTPS failed' : null };
|
|
333
|
+
return unknown(waited.status === 0 ? 'probe output unavailable' : 'probe timeout');
|
|
334
|
+
} catch { return unknown('probe failed'); }
|
|
335
|
+
finally {
|
|
336
|
+
if (created) try { kubectl([...base, '-n', 'elanous-test', 'delete', `pod/${name}`, '--ignore-not-found=true', '--wait=false']); }
|
|
337
|
+
catch { /* best effort; Kubernetes activeDeadlineSeconds also bounds the Pod */ }
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
243
341
|
/** The cache and lock are shared by CLI processes, keyed by context rather than pool composition. */
|
|
244
342
|
export function probePoolDns(context: string, kubectl: PoolKubectl = leaseKubectl, options: { dir?: string; now?: () => number } = {}): PoolDnsProbe {
|
|
245
343
|
const dir = options.dir ?? hostLeaseBaseDir();
|
|
@@ -41,7 +41,7 @@ export function ledgerLineToLogEvent(line: string, runId: string): {
|
|
|
41
41
|
const sources = [entry, details].filter((source): source is Record<string, unknown> => source !== undefined);
|
|
42
42
|
const knownSecrets = secretValues(entry);
|
|
43
43
|
const containsCredential = (value: string) => SECRET_VALUE.test(value) || knownSecrets.some((secret) => value.includes(secret));
|
|
44
|
-
if (containsCredential(entry.event) || !EVENT_ALLOWED.test(entry.event)) return undefined;
|
|
44
|
+
if (containsCredential(entry.event) || (!EVENT_ALLOWED.test(entry.event) && entry.event !== 'ask-auto-target-candidates' && entry.event !== 'ask-auto-reauthor')) return undefined;
|
|
45
45
|
|
|
46
46
|
const data: Record<string, unknown> = { runId };
|
|
47
47
|
let fields = 0;
|