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
|
@@ -1,29 +1,47 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
|
-
import { existsSync, linkSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { appendFileSync, closeSync, existsSync, linkSync, mkdirSync, mkdtempSync, openSync, readFileSync, readdirSync, renameSync, rmSync, realpathSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
|
-
import { dirname, join } from 'node:path';
|
|
5
|
+
import { dirname, join, resolve } from 'node:path';
|
|
6
6
|
import { debug } from '../debug/log.js';
|
|
7
|
+
import { stateDirSourceForChild } from '../agent/identity-env.js';
|
|
7
8
|
import { sendOutbound } from '../domains/outbound-alert.js';
|
|
8
9
|
import { releaseLedgerRoot } from '../instance/resolve.js';
|
|
9
10
|
import { isValidGateHost } from '../self-implement/gate-remote.js';
|
|
11
|
+
import { parsePodPool } from '../task-orchestrator/surfaces/pod-pool.js';
|
|
12
|
+
import { latestPublishedPreviousVersion, releaseLoopConfig } from '../../scripts/release-loop/unattended-release.js';
|
|
13
|
+
import { LEAK_MARKERS, loadExportConfig, selectExportFiles } from '../../scripts/public-export.js';
|
|
10
14
|
import { LIGHT_RC_UNKNOWN_HOST, runLightRc, type LightRcResult } from './light-rc.js';
|
|
11
15
|
import { planRehearsalShards, type RehearsalShardPlan, type RehearsalShardPlanDeps } from './rehearsal-shard-plan.js';
|
|
12
16
|
import { listSchedules, type ReleaseSchedule } from './release-schedule.js';
|
|
17
|
+
import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
|
|
13
18
|
|
|
14
|
-
export type StepId = 'rc-7h' | 'rc-150m';
|
|
19
|
+
export type StepId = 'hard-mid' | 'rc-7h' | 'hard-5h' | 'rc-150m';
|
|
15
20
|
export type RehearsalOutcome = 'ok' | 'regression' | 'unmeasured' | 'error' | 'no-checkout' | 'checkout-dirty' | 'superseded' | 'interrupted';
|
|
21
|
+
export interface HardGateResult {
|
|
22
|
+
outcome: 'ok' | 'regression' | 'error';
|
|
23
|
+
commit: string;
|
|
24
|
+
executor: 'pod' | 'host' | null;
|
|
25
|
+
introduced: string[];
|
|
26
|
+
preexisting: number;
|
|
27
|
+
error?: string;
|
|
28
|
+
}
|
|
16
29
|
export type RehearsalPlan =
|
|
17
30
|
| { status: 'no-schedule' }
|
|
18
31
|
| { status: 'not-yet'; version: string; cutAt: string; nextStepAt: string }
|
|
19
32
|
| { status: 'due'; version: string; cutAt: string; run: StepId | null; supersede: StepId[] }
|
|
20
33
|
| { status: 'nothing-due'; version: string; cutAt: string };
|
|
21
34
|
|
|
22
|
-
const
|
|
35
|
+
const fixedSteps = [{ id: 'rc-7h', minutes: 420 }, { id: 'hard-5h', minutes: 300 }, { id: 'rc-150m', minutes: 150 }] as const;
|
|
23
36
|
const minute = 60_000;
|
|
37
|
+
function rehearsalSteps(intervalHours = 12): Array<{ id: StepId; minutes: number }> {
|
|
38
|
+
if (!Number.isSafeInteger(intervalHours) || intervalHours < 8 || intervalHours > 72)
|
|
39
|
+
throw new Error('release.loop.rehearsalHardIntervalHours must be an integer from 8 to 72');
|
|
40
|
+
return [{ id: 'hard-mid', minutes: intervalHours * 60 }, ...fixedSteps];
|
|
41
|
+
}
|
|
24
42
|
|
|
25
|
-
/** Only the earliest future cut is eligible. A missed
|
|
26
|
-
export function planRehearsal(schedules: readonly ReleaseSchedule[], now: Date, stamps: Readonly<Partial<Record<StepId, boolean
|
|
43
|
+
/** Only the earliest future cut is eligible. A missed step is superseded rather than run beside a later one. */
|
|
44
|
+
export function planRehearsal(schedules: readonly ReleaseSchedule[], now: Date, stamps: Readonly<Partial<Record<StepId, boolean>>>, intervalHours = 12): RehearsalPlan {
|
|
27
45
|
const current = now.getTime();
|
|
28
46
|
if (!Number.isFinite(current)) throw new Error('now must be a valid date');
|
|
29
47
|
const schedule = schedules.filter(row => Number.isFinite(Date.parse(row.cutAt)) && Date.parse(row.cutAt) > current)
|
|
@@ -31,14 +49,20 @@ export function planRehearsal(schedules: readonly ReleaseSchedule[], now: Date,
|
|
|
31
49
|
if (!schedule) return { status: 'no-schedule' };
|
|
32
50
|
const { version, cutAt } = schedule;
|
|
33
51
|
const cut = Date.parse(cutAt);
|
|
52
|
+
const steps = rehearsalSteps(intervalHours);
|
|
34
53
|
const open = steps.filter(step => !stamps[step.id]);
|
|
35
54
|
if (!open.length) return { status: 'nothing-due', version, cutAt };
|
|
36
55
|
if (current >= cut - 45 * minute) return { status: 'due', version, cutAt, run: null, supersede: open.map(step => step.id) };
|
|
37
|
-
|
|
38
|
-
|
|
56
|
+
const latestDue = [...steps].reverse().find(step => current >= cut - step.minutes * minute);
|
|
57
|
+
if (latestDue) {
|
|
58
|
+
const run = stamps[latestDue.id] ? null : latestDue.id;
|
|
59
|
+
const supersede = steps.filter(step => step.minutes > latestDue.minutes && !stamps[step.id]).map(step => step.id);
|
|
60
|
+
if (!run && supersede.length === 0) {
|
|
61
|
+
const next = open.find(step => current < cut - step.minutes * minute);
|
|
62
|
+
if (next) return { status: 'not-yet', version, cutAt, nextStepAt: new Date(cut - next.minutes * minute).toISOString() };
|
|
63
|
+
}
|
|
64
|
+
return { status: 'due', version, cutAt, run, supersede };
|
|
39
65
|
}
|
|
40
|
-
const due = open.filter(step => current >= cut - step.minutes * minute);
|
|
41
|
-
if (due.length) return { status: 'due', version, cutAt, run: due[0]!.id, supersede: [] };
|
|
42
66
|
return { status: 'not-yet', version, cutAt, nextStepAt: new Date(cut - open[0]!.minutes * minute).toISOString() };
|
|
43
67
|
}
|
|
44
68
|
|
|
@@ -53,8 +77,13 @@ export interface RehearsalStamp {
|
|
|
53
77
|
summary?: string;
|
|
54
78
|
regressionFiles?: string[];
|
|
55
79
|
result?: LightRcResult;
|
|
80
|
+
hardGate?: HardGateResult;
|
|
81
|
+
hardGateRunId?: string;
|
|
82
|
+
hardGateLog?: string;
|
|
83
|
+
/** B6: an unmeasured hard gate always retains a cause, run id and durable local evidence path. */
|
|
84
|
+
measurementGap?: { cause: string; runId: string; evidence: string };
|
|
56
85
|
shardPlan?: RehearsalShardPlan;
|
|
57
|
-
leakCheck?: { outcome: 'ok' | 'fail'; sha: string; exitCode: number | null };
|
|
86
|
+
leakCheck?: { outcome: 'ok' | 'fail'; sha: string; exitCode: number | null; detail?: string };
|
|
58
87
|
selection?: { shards?: number; remote?: string };
|
|
59
88
|
notifiedAt?: string;
|
|
60
89
|
ownerPid?: number;
|
|
@@ -69,14 +98,16 @@ export interface RehearsalOptions {
|
|
|
69
98
|
}
|
|
70
99
|
|
|
71
100
|
export interface RehearsalDeps {
|
|
101
|
+
hardIntervalHours?: number;
|
|
72
102
|
now?: () => Date;
|
|
73
103
|
schedules?: (root: string) => ReleaseSchedule[];
|
|
74
104
|
lightRc?: (version: string, checkout: string, selection: { shards?: number; remote?: string }) => Promise<LightRcResult>;
|
|
105
|
+
hardGate?: (version: string, checkout: string, sha: string, ledgerRoot: string, runId: string) => Promise<HardGateResult>;
|
|
75
106
|
shardPlan?: typeof planRehearsalShards;
|
|
76
107
|
shardPlanDeps?: RehearsalShardPlanDeps;
|
|
77
108
|
notify?: (text: string) => void | boolean | Promise<void | boolean>;
|
|
78
109
|
git?: (args: string[], cwd: string) => { rc: number | null; stdout: string; stderr?: string };
|
|
79
|
-
leakCheck?: (checkout: string) => { status: number | null };
|
|
110
|
+
leakCheck?: (checkout: string) => { status: number | null; detail?: string };
|
|
80
111
|
}
|
|
81
112
|
|
|
82
113
|
export type RehearsalTickResult = RehearsalPlan & { applied?: boolean; stamps?: RehearsalStamp[]; notificationFailures?: number };
|
|
@@ -97,17 +128,103 @@ function gitResult(git: NonNullable<RehearsalDeps['git']>, args: string[], check
|
|
|
97
128
|
return result.stdout.trim();
|
|
98
129
|
}
|
|
99
130
|
|
|
131
|
+
export function rehearsalLeakFailureDetail(stdout: string, stderr: string, spawnError?: string): string {
|
|
132
|
+
try {
|
|
133
|
+
const report = JSON.parse(stdout.trim()) as {
|
|
134
|
+
leaks?: number; hits?: Array<{ marker?: string; file?: string; line?: number; text?: string }>;
|
|
135
|
+
};
|
|
136
|
+
const first = report.hits?.[0];
|
|
137
|
+
if (Number.isSafeInteger(report.leaks) && report.leaks! >= 0) {
|
|
138
|
+
if (!first) return `${report.leaks} hit(s)`;
|
|
139
|
+
return sanitizeRehearsalLeakDetail(`${report.leaks} hit(s) · ${first.marker ?? ''} ${first.file ?? ''}:${first.line ?? ''}`);
|
|
140
|
+
}
|
|
141
|
+
} catch { /* fall through to the process diagnostic */ }
|
|
142
|
+
return 'leak-check produced no structured diagnostic';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Validate before evidence persistence: JSON and injected checkers are both untrusted diagnostic inputs. */
|
|
146
|
+
export function sanitizeRehearsalLeakDetail(detail: string, checkout?: string): string {
|
|
147
|
+
if (detail === 'leak-check produced no structured diagnostic') return detail;
|
|
148
|
+
const parsed = /^(?<count>\d+) hit\(s\) · (?<marker>[a-z][a-z0-9-]{0,63}) (?<file>.+):(?<line>[1-9]\d*)$/.exec(detail);
|
|
149
|
+
if (!parsed?.groups) return 'leak-check produced no structured diagnostic';
|
|
150
|
+
const { count, marker, file, line } = parsed.groups;
|
|
151
|
+
const countValue = Number(count), lineValue = Number(line);
|
|
152
|
+
if (!Number.isSafeInteger(countValue) || countValue < 1 || !Number.isSafeInteger(lineValue) || lineValue < 1)
|
|
153
|
+
return 'leak-check produced no structured diagnostic';
|
|
154
|
+
const parts = file!.split('/');
|
|
155
|
+
if (!LEAK_MARKERS.some(item => item.marker === marker) || file!.startsWith('/')
|
|
156
|
+
|| /[\p{Cc}]/u.test(file!) || parts.some(part => !part || part === '.' || part === '..'))
|
|
157
|
+
return 'leak-check produced no structured diagnostic';
|
|
158
|
+
if (checkout) {
|
|
159
|
+
try {
|
|
160
|
+
const tracked = spawnSync('git', ['ls-files', '-z'], { cwd: checkout, encoding: 'utf8', maxBuffer: SPAWN_SYNC_MAX_BUFFER });
|
|
161
|
+
if (tracked.status !== 0 || tracked.error) return 'leak-check produced no structured diagnostic';
|
|
162
|
+
const publicFiles = selectExportFiles((tracked.stdout ?? '').split('\0').filter(Boolean), loadExportConfig(checkout));
|
|
163
|
+
if (!publicFiles.includes(file!)) return 'leak-check produced no structured diagnostic';
|
|
164
|
+
const checkoutRoot = realpathSync(checkout);
|
|
165
|
+
const realFile = realpathSync(resolve(checkoutRoot, file!));
|
|
166
|
+
if (!realFile.startsWith(`${checkoutRoot}/`))
|
|
167
|
+
return 'leak-check produced no structured diagnostic';
|
|
168
|
+
const sourceLine = readFileSync(realFile, 'utf8').split(/\r?\n/)[lineValue - 1];
|
|
169
|
+
const markerPattern = LEAK_MARKERS.find(item => item.marker === marker)?.pattern;
|
|
170
|
+
if (!sourceLine || !markerPattern?.test(sourceLine)) return 'leak-check produced no structured diagnostic';
|
|
171
|
+
} catch { return 'leak-check produced no structured diagnostic'; }
|
|
172
|
+
}
|
|
173
|
+
return `${countValue} hit(s) · ${marker} ${file}:${lineValue}`;
|
|
174
|
+
}
|
|
175
|
+
|
|
100
176
|
/** Public export checks the pinned rehearsal checkout before any remote RC work. Its output is private and ephemeral. */
|
|
101
|
-
function runRehearsalLeakCheck(checkout: string): { status: number | null } {
|
|
177
|
+
export function runRehearsalLeakCheck(checkout: string): { status: number | null; detail?: string } {
|
|
102
178
|
const out = mkdtempSync(join(tmpdir(), 'elanous-rehearsal-export-'));
|
|
103
179
|
try {
|
|
104
|
-
const result = spawnSync('bun', ['scripts/public-export.ts', '--out', join(out, 'export')], {
|
|
180
|
+
const result = spawnSync('bun', ['scripts/public-export.ts', '--out', join(out, 'export'), '--json', '--all'], {
|
|
105
181
|
cwd: checkout, encoding: 'utf8', timeout: 1_800_000, maxBuffer: 64 * 1024 * 1024,
|
|
106
182
|
});
|
|
107
|
-
return { status:
|
|
183
|
+
if (result.status === 0) return { status: 0 };
|
|
184
|
+
return { status: result.status, detail: rehearsalLeakFailureDetail(result.stdout ?? '', result.stderr ?? '', result.error?.message) };
|
|
108
185
|
} finally { rmSync(out, { recursive: true, force: true }); }
|
|
109
186
|
}
|
|
110
187
|
|
|
188
|
+
/** The hard rehearsal uses the release gate itself, pinned to the fetched main SHA and node-b Pod member. */
|
|
189
|
+
async function runHardGate(version: string, checkout: string, sha: string, ledgerRoot: string, runId: string): Promise<HardGateResult> {
|
|
190
|
+
const configuredPool = releaseLoopConfig().gatePodPool;
|
|
191
|
+
if (!configuredPool) throw new Error('hard rehearsal requires release.loop.gatePodPool');
|
|
192
|
+
const members = parsePodPool(configuredPool);
|
|
193
|
+
const gateMember = members.find(member => member.sshHost === 'node-b');
|
|
194
|
+
if (!gateMember) throw new Error('hard rehearsal requires a live node-b Pod member');
|
|
195
|
+
const pool = configuredPool.split(',').map(part => part.trim())
|
|
196
|
+
.find(part => part.split(/[#:]/, 1)[0] === `${gateMember.context}@${gateMember.sshHost}`);
|
|
197
|
+
if (!pool) throw new Error('hard rehearsal cannot isolate the node-b Pod member');
|
|
198
|
+
const previous = latestPublishedPreviousVersion(version, ledgerRoot);
|
|
199
|
+
const logPath = join(ledgerRoot, 'release', version, 'rehearsal', `${runId}.log`);
|
|
200
|
+
mkdirSync(dirname(logPath), { recursive: true });
|
|
201
|
+
const run = (() => {
|
|
202
|
+
const log = openSync(logPath, 'wx', 0o600);
|
|
203
|
+
try { return spawnSync('bun', ['scripts/release-loop/gate-node.ts', '--commit', sha, '--version', version,
|
|
204
|
+
'--baseline-version', previous, '--executor', 'pod', '--pod-pool', pool, '--pod-shards', '12', '--json'], {
|
|
205
|
+
cwd: checkout, encoding: 'utf8', stdio: ['ignore', log, log], timeout: 4 * 60 * 60_000,
|
|
206
|
+
env: { ...process.env, ELANOUS_STATE_DIR: ledgerRoot, ELANOUS_STATE_DIR_SOURCE: stateDirSourceForChild(ledgerRoot) },
|
|
207
|
+
}); } finally { closeSync(log); }
|
|
208
|
+
})();
|
|
209
|
+
// stdout and stderr stream to the claim's durable evidence while the child is still running.
|
|
210
|
+
const output = readFileSync(logPath, 'utf8');
|
|
211
|
+
const line = output.split(/\r?\n/).reverse().find(value => value.trim().startsWith('{'));
|
|
212
|
+
if (!line) throw new Error(`hard rehearsal gate produced no JSON (rc=${run.status ?? 'spawn'}${run.error ? `: ${run.error.message}` : ''}; log ${logPath})`);
|
|
213
|
+
const result = JSON.parse(line) as HardGateResult;
|
|
214
|
+
if (!['ok', 'regression', 'error'].includes(result.outcome) || !Array.isArray(result.introduced)
|
|
215
|
+
|| result.introduced.some(item => typeof item !== 'string')) {
|
|
216
|
+
throw new Error('hard rehearsal gate result lacks a valid verdict');
|
|
217
|
+
}
|
|
218
|
+
if (result.outcome !== 'error' && (result.commit !== sha || result.executor !== 'pod')) {
|
|
219
|
+
throw new Error('hard rehearsal gate result lacks pinned commit, Pod executor or verdict evidence');
|
|
220
|
+
}
|
|
221
|
+
if (result.outcome === 'ok' && result.introduced.length) throw new Error('hard rehearsal gate ok verdict contains introduced failures');
|
|
222
|
+
if (run.status === 0 && result.outcome === 'ok') return result;
|
|
223
|
+
if (run.status === 1 && result.outcome === 'regression') return result;
|
|
224
|
+
if (run.status === 2 && result.outcome === 'error') return result;
|
|
225
|
+
throw new Error(`hard rehearsal gate rc=${run.status ?? 'spawn'} disagrees with outcome=${result.outcome}`);
|
|
226
|
+
}
|
|
227
|
+
|
|
111
228
|
function oneLine(text: string): string { return text.replace(/\s+/g, ' ').trim(); }
|
|
112
229
|
|
|
113
230
|
function outcomeLine(stamp: RehearsalStamp): string {
|
|
@@ -121,7 +238,7 @@ function outcomeLine(stamp: RehearsalStamp): string {
|
|
|
121
238
|
|| (stamp.selection?.shards !== undefined && result.shards !== stamp.selection.shards)
|
|
122
239
|
|| (stamp.selection?.remote !== undefined && result.remote !== stamp.selection.remote);
|
|
123
240
|
const detail = stamp.summary && (stamp.outcome === 'unmeasured' || stamp.outcome === 'error' && planningGap) ? ` · ${stamp.summary}` : '';
|
|
124
|
-
return `${head} · 새 회귀 ${result.introduced ?? '
|
|
241
|
+
return `${head} · 새 회귀 ${result.introduced ?? 'UNKNOWN'} · 기존 ${result.preexisting ?? 'UNKNOWN'} · 미분류 ${result.unclassified ?? 'UNKNOWN'} · ${result.remote ?? 'local'} · ${duration}분${stamp.outcome === 'error' ? ` · gate rc ${result.gateExitCode}${!result.ok ? ' · RC 실패' : ''}` : ''}${stamp.regressionFiles?.length ? ` · 파일 ${stamp.regressionFiles.slice(0, 3).join(', ')}` : ''}${detail}`;
|
|
125
242
|
}
|
|
126
243
|
|
|
127
244
|
function persistStamp(path: string, stamp: RehearsalStamp): void {
|
|
@@ -221,9 +338,19 @@ function interruptStamp(path: string, saved: RehearsalStamp, now: Date): Rehears
|
|
|
221
338
|
try {
|
|
222
339
|
const latest = JSON.parse(readFileSync(path, 'utf8')) as RehearsalStamp;
|
|
223
340
|
if (latest.outcome !== 'running' || latest.endedAt || latest.startedAt !== saved.startedAt || latest.ownerPid !== saved.ownerPid || !ownerIsDead(latest.ownerPid)) return null;
|
|
341
|
+
if (latest.step === 'hard-mid' || latest.step === 'hard-5h') {
|
|
342
|
+
// The claim stores this identity atomically. Older running stamps may lack it, so recovery mints one.
|
|
343
|
+
const runId = latest.hardGateRunId || `hard-${randomUUID()}`;
|
|
344
|
+
const evidence = join(dirname(path), `${runId}.log`);
|
|
345
|
+
const cause = `hard rehearsal process ended before a gate verdict (pid ${latest.ownerPid})`;
|
|
346
|
+
appendFileSync(evidence, `${cause}\n`, { mode: 0o600 });
|
|
347
|
+
latest.hardGateRunId = runId;
|
|
348
|
+
latest.hardGateLog = evidence;
|
|
349
|
+
latest.measurementGap = { cause, runId, evidence };
|
|
350
|
+
latest.summary = `${cause} · runId ${runId} · evidence ${evidence}`;
|
|
351
|
+
} else latest.summary = '실행 프로세스 종료 · RC 재실행 안 함';
|
|
224
352
|
latest.outcome = 'interrupted';
|
|
225
353
|
latest.endedAt = now.toISOString();
|
|
226
|
-
latest.summary = '실행 프로세스 종료 · RC 재실행 안 함';
|
|
227
354
|
persistStamp(path, latest);
|
|
228
355
|
return latest;
|
|
229
356
|
} finally {
|
|
@@ -231,7 +358,7 @@ function interruptStamp(path: string, saved: RehearsalStamp, now: Date): Rehears
|
|
|
231
358
|
}
|
|
232
359
|
}
|
|
233
360
|
|
|
234
|
-
/**
|
|
361
|
+
/** A started RC claim is permanent; a preflight with no runnable shards releases its claim for the next tick. */
|
|
235
362
|
export async function runRehearsalTick(opts: RehearsalOptions = {}, deps: RehearsalDeps = {}): Promise<RehearsalTickResult> {
|
|
236
363
|
if (opts.shards !== undefined && (!Number.isSafeInteger(opts.shards) || opts.shards < 1)) {
|
|
237
364
|
throw new Error(`release rehearsal tick: invalid --shards count: ${opts.shards}`);
|
|
@@ -242,11 +369,13 @@ export async function runRehearsalTick(opts: RehearsalOptions = {}, deps: Rehear
|
|
|
242
369
|
const root = opts.ledgerRoot ?? releaseLedgerRoot();
|
|
243
370
|
const now = (deps.now ?? (() => new Date()))();
|
|
244
371
|
const schedules = (deps.schedules ?? listSchedules)(root);
|
|
372
|
+
const intervalHours = deps.hardIntervalHours ?? releaseLoopConfig().rehearsalHardIntervalHours ?? 12;
|
|
373
|
+
const steps = rehearsalSteps(intervalHours);
|
|
245
374
|
if (!Number.isFinite(now.getTime())) throw new Error('now must be a valid date');
|
|
246
|
-
const candidate = planRehearsal(schedules, now, {});
|
|
375
|
+
const candidate = planRehearsal(schedules, now, {}, intervalHours);
|
|
247
376
|
const stamps = candidate.status !== 'no-schedule'
|
|
248
377
|
? Object.fromEntries(steps.map(step => [step.id, existsSync(stampPath(root, candidate.version, step.id))])) as Partial<Record<StepId, boolean>> : {};
|
|
249
|
-
const plan = planRehearsal(schedules, now, stamps);
|
|
378
|
+
const plan = planRehearsal(schedules, now, stamps, intervalHours);
|
|
250
379
|
debug.log('release.rehearsal', 'tick', { ...plan, apply: !!opts.apply });
|
|
251
380
|
if (!opts.apply) return plan;
|
|
252
381
|
const written: RehearsalStamp[] = [];
|
|
@@ -278,6 +407,10 @@ export async function runRehearsalTick(opts: RehearsalOptions = {}, deps: Rehear
|
|
|
278
407
|
const path = stampPath(root, plan.version, step);
|
|
279
408
|
mkdirSync(dirname(path), { recursive: true });
|
|
280
409
|
const stamp: RehearsalStamp = { version: plan.version, cutAt: plan.cutAt, step, outcome: 'running', startedAt: now.toISOString(), ownerPid: process.pid };
|
|
410
|
+
if (step === 'hard-mid' || step === 'hard-5h') {
|
|
411
|
+
stamp.hardGateRunId = `hard-${randomUUID()}`;
|
|
412
|
+
stamp.hardGateLog = join(dirname(path), `${stamp.hardGateRunId}.log`);
|
|
413
|
+
}
|
|
281
414
|
// Crash-safe exclusive create: the complete JSON is written to a private temp file, then hard-linked into
|
|
282
415
|
// place. link(2) fails with EEXIST like wx, but the stamp can never be observed empty or half-written.
|
|
283
416
|
const temp = `${path}.${process.pid}.${randomUUID()}.claim.tmp`;
|
|
@@ -322,13 +455,47 @@ export async function runRehearsalTick(opts: RehearsalOptions = {}, deps: Rehear
|
|
|
322
455
|
stamp.sha = gitResult(git, ['rev-parse', 'HEAD'], checkout);
|
|
323
456
|
if (!stamp.sha) throw new Error('git rev-parse HEAD returned no sha');
|
|
324
457
|
const leak = (deps.leakCheck ?? runRehearsalLeakCheck)(checkout);
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const
|
|
458
|
+
const statusIsValid = leak.status === null || (Number.isSafeInteger(leak.status) && leak.status >= 0 && leak.status <= 255);
|
|
459
|
+
const leakStatus = statusIsValid ? leak.status : null;
|
|
460
|
+
const leakDetail = leakStatus === 0 ? undefined : sanitizeRehearsalLeakDetail(leak.detail ?? '', checkout);
|
|
461
|
+
stamp.leakCheck = { outcome: leakStatus === 0 ? 'ok' : 'fail', sha: stamp.sha, exitCode: leakStatus,
|
|
462
|
+
...(leakDetail ? { detail: leakDetail } : {}) };
|
|
463
|
+
if (leakStatus !== 0) throw new Error(`public export leak-check failed (rc=${leakStatus ?? 'spawn'})${leakDetail ? ` · ${leakDetail}` : ''}`);
|
|
464
|
+
if (plan.run === 'hard-5h' || plan.run === 'hard-mid') {
|
|
465
|
+
stamp.selection = { shards: 12, remote: 'node-b' };
|
|
466
|
+
const hardGateRunId = stamp.hardGateRunId;
|
|
467
|
+
const hardGateLog = stamp.hardGateLog;
|
|
468
|
+
if (!hardGateRunId || !hardGateLog) throw new Error('hard rehearsal claim has no evidence identity');
|
|
469
|
+
const hard = await (deps.hardGate ?? runHardGate)(plan.version, checkout, stamp.sha, root, hardGateRunId);
|
|
470
|
+
stamp.hardGate = hard;
|
|
471
|
+
if (!existsSync(hardGateLog)) writeFileSync(hardGateLog, `${JSON.stringify(hard)}\n`, { flag: 'wx', mode: 0o600 });
|
|
472
|
+
if (hard.outcome !== 'error' && (hard.commit !== stamp.sha || hard.executor !== 'pod' || !Array.isArray(hard.introduced)))
|
|
473
|
+
throw new Error('hard rehearsal result did not measure pinned SHA on a Pod');
|
|
474
|
+
if (hard.outcome === 'ok' && hard.introduced.length) throw new Error('hard rehearsal gate ok verdict contains introduced failures');
|
|
475
|
+
stamp.outcome = hard.outcome === 'regression' && hard.introduced.length === 0 ? 'unmeasured' : hard.outcome;
|
|
476
|
+
const cause = stamp.outcome === 'unmeasured' ? 'regression verdict has no introduced IDs'
|
|
477
|
+
: hard.outcome === 'error' ? hard.error?.trim() || 'gate returned error without a cause' : undefined;
|
|
478
|
+
if (cause) stamp.measurementGap = { cause, runId: hardGateRunId, evidence: hardGateLog };
|
|
479
|
+
const introducedCount: number | null = stamp.outcome === 'unmeasured' || stamp.outcome === 'error' ? null : hard.introduced.length;
|
|
480
|
+
const preexistingCount: number | null = introducedCount === null ? null : hard.preexisting;
|
|
481
|
+
const totalFailures: number | null = introducedCount === null || preexistingCount === null ? null : introducedCount + preexistingCount;
|
|
482
|
+
stamp.summary = oneLine(`hard gate ${hard.outcome} · introduced ${introducedCount ?? 'UNKNOWN'} · preexisting ${preexistingCount ?? 'UNKNOWN'} · total failures ${totalFailures ?? 'UNKNOWN'} · node-b Pod · 12 shards · runId ${hardGateRunId} · evidence ${hardGateLog}${cause ? ` · ${cause}` : ''}`);
|
|
483
|
+
} else {
|
|
328
484
|
const shardPlan = opts.shards === undefined ? (deps.shardPlan ?? planRehearsalShards)(plan.version, root, checkout, { ...deps.shardPlanDeps, remoteGate: true }) : undefined;
|
|
329
485
|
if (shardPlan) stamp.shardPlan = shardPlan;
|
|
330
486
|
const selection = { shards: opts.shards ?? shardPlan?.shards, remote: opts.remote };
|
|
331
487
|
stamp.selection = selection;
|
|
488
|
+
if (shardPlan && (shardPlan.testFiles === 0 || shardPlan.gatePlanShards === null)) {
|
|
489
|
+
stamp.outcome = 'unmeasured';
|
|
490
|
+
stamp.summary = oneLine(`${shardPlan.testFiles === 0 ? 'no runnable rehearsal shards' : 'rehearsal shard plan unavailable'} · ${shardPlan.unmeasured ?? 'selected test files empty'}`);
|
|
491
|
+
stamp.endedAt = clock().toISOString();
|
|
492
|
+
// No RC was launched: this claim is not a completed stage. Leave the ledger free for the next tick.
|
|
493
|
+
unlinkSync(path);
|
|
494
|
+
written.push(stamp);
|
|
495
|
+
debug.log('release.rehearsal', 'step-shortage-retry', { version: stamp.version, step: stamp.step, summary: stamp.summary });
|
|
496
|
+
return { ...plan, applied: true, stamps: written, notificationFailures };
|
|
497
|
+
}
|
|
498
|
+
const regressionFiles: string[] = [];
|
|
332
499
|
const result = await (deps.lightRc ?? ((version, cwd) => runLightRc(version, { ledgerRoot: root, head: stamp.sha, ...selection, rehearsalTui: true, log: (line) => {
|
|
333
500
|
for (const entry of line.split(/\r?\n/)) {
|
|
334
501
|
const file = /^- introduced: (.+?)(?: > |$)/.exec(entry)?.[1];
|
|
@@ -359,12 +526,25 @@ export async function runRehearsalTick(opts: RehearsalOptions = {}, deps: Rehear
|
|
|
359
526
|
: result.introduced === null || result.unclassified === null || result.unmeasured !== null || result.unclassified > 0 ? 'unmeasured'
|
|
360
527
|
: result.unmeasured === null && (!result.ok || result.gateExitCode !== 0) ? 'error'
|
|
361
528
|
: planningGap ? 'unmeasured' : 'ok';
|
|
362
|
-
stamp.summary = oneLine(`introduced ${result.introduced} · preexisting ${result.preexisting ?? '
|
|
529
|
+
stamp.summary = oneLine(`introduced ${result.introduced ?? 'UNKNOWN'} · preexisting ${result.preexisting ?? 'UNKNOWN'} · unclassified ${result.unclassified ?? 'UNKNOWN'} · ${result.remote ?? 'local'} · gate rc ${result.gateExitCode}${!result.ok ? ' · RC 실패' : ''}${result.unmeasured !== null ? ` · unmeasured: ${result.unmeasured || 'RC reason empty'}` : ''}${stamp.shardPlan?.unmeasured ? ` · unmeasured: ${stamp.shardPlan.unmeasured}` : ''}${shardMismatch ? ` · unmeasured: ${shardMismatch}` : ''}${remoteMismatch ? ` · unmeasured: ${remoteMismatch}` : ''}`);
|
|
530
|
+
}
|
|
363
531
|
}
|
|
364
532
|
}
|
|
365
533
|
} catch (error) {
|
|
366
534
|
stamp.outcome = 'error';
|
|
367
|
-
|
|
535
|
+
const cause = String(error instanceof Error ? error.message : error).split(/\r?\n/, 1)[0] ?? 'unknown error';
|
|
536
|
+
if (stamp.hardGateRunId && stamp.hardGateLog) {
|
|
537
|
+
// The runner opens stderr before launch, so a failed launch or missing JSON may leave an empty file.
|
|
538
|
+
appendFileSync(stamp.hardGateLog, `${cause}\n`, { mode: 0o600 });
|
|
539
|
+
stamp.measurementGap = { cause, runId: stamp.hardGateRunId, evidence: stamp.hardGateLog };
|
|
540
|
+
}
|
|
541
|
+
stamp.summary = oneLine(`${cause}${stamp.hardGateRunId ? ` · runId ${stamp.hardGateRunId} · evidence ${stamp.hardGateLog}` : ''}${stamp.shardPlan?.unmeasured ? ` · unmeasured: ${stamp.shardPlan.unmeasured}` : ''}`);
|
|
542
|
+
}
|
|
543
|
+
if (stamp.hardGateRunId && stamp.hardGateLog && !stamp.measurementGap
|
|
544
|
+
&& (stamp.outcome === 'no-checkout' || stamp.outcome === 'checkout-dirty')) {
|
|
545
|
+
const cause = stamp.outcome === 'no-checkout' ? 'hard gate checkout unavailable' : 'hard gate checkout dirty';
|
|
546
|
+
appendFileSync(stamp.hardGateLog, `${cause}\n`, { mode: 0o600 });
|
|
547
|
+
stamp.measurementGap = { cause, runId: stamp.hardGateRunId, evidence: stamp.hardGateLog };
|
|
368
548
|
}
|
|
369
549
|
await finish(path, stamp);
|
|
370
550
|
}
|
|
@@ -66,8 +66,7 @@ export interface Rubric {
|
|
|
66
66
|
|
|
67
67
|
const AXES = ['A', 'E', 'R', 'D', 'M', 'B', 'S', 'X'] as const;
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
export function parseRubric(text: string): Rubric | null {
|
|
69
|
+
function* rubricLines(text: string): Generator<Partial<Rubric>> {
|
|
71
70
|
for (const line of text.split(/\r?\n/)) {
|
|
72
71
|
const match = /(?:^|\s)루브릭:\s*([^\r\n]*)/.exec(line);
|
|
73
72
|
if (!match) continue;
|
|
@@ -77,11 +76,26 @@ export function parseRubric(text: string): Rubric | null {
|
|
|
77
76
|
const axis = /^([AERDMBSX])([0-3])$/.exec(token);
|
|
78
77
|
if (axis) values[axis[1] as keyof Rubric] = Number(axis[2]);
|
|
79
78
|
}
|
|
79
|
+
yield values;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Read one explicit rubric line; an old score in parentheses is not an axis. */
|
|
84
|
+
export function parseRubric(text: string): Rubric | null {
|
|
85
|
+
for (const values of rubricLines(text)) {
|
|
80
86
|
if (AXES.every((axis) => values[axis] !== undefined)) return values as Rubric;
|
|
81
87
|
}
|
|
82
88
|
return null;
|
|
83
89
|
}
|
|
84
90
|
|
|
91
|
+
/** Read an explicitly entered S axis even when the other rubric axes are incomplete. */
|
|
92
|
+
export function parseRubricS(text: string): number | null {
|
|
93
|
+
for (const values of rubricLines(text)) {
|
|
94
|
+
if (values.S !== undefined) return values.S;
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
85
99
|
export function rubricScore(r: Rubric): number {
|
|
86
100
|
return rubricScoreWith(INTERNAL_AXES, r);
|
|
87
101
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CLAIM_IDLE_HOURS, PR_LABELS, STALLED_DRAFT_HOURS } from '../github/pr-labels.js';
|
|
2
2
|
import { debug } from '../debug/log.js';
|
|
3
|
-
import { decideDraft, draftClaimComment, draftClaimState, draftReleaseComment, laterMergedTwins, sameGoalPr, type DraftTriagePr } from './draft-triage-rules.js';
|
|
3
|
+
import { decideDraft, draftClaimComment, draftClaimState, draftReleaseComment, laterMergedTwins, sameGoalPr, PROTECTED_LABELS, type DraftTriagePr } from './draft-triage-rules.js';
|
|
4
|
+
import { cellIdFromBody } from '../pr-tool/census.js';
|
|
4
5
|
import { cardPrNumber, draftTaskOwner, type TaskCard } from '../task-agent/task-hand.js';
|
|
5
6
|
import type { PrTerminalRecord } from './draft-residue.js';
|
|
6
7
|
import { branchLineageSlug } from '../cli/pr-lineage.js';
|
|
@@ -47,6 +48,8 @@ export interface DraftSweepAdapters {
|
|
|
47
48
|
/** Host ledger terminal records; undefined means the ledger could not be read. */
|
|
48
49
|
listPrTerminals?(): Promise<readonly PrTerminalRecord[] | undefined>;
|
|
49
50
|
commentDraft?(repository: string, number: number, body: string): Promise<void>;
|
|
51
|
+
/** Complete issue-comment inventory for idempotent merge-time same-cell cleanup. */
|
|
52
|
+
listIssueComments?(repository: string, number: number): Promise<readonly string[]>;
|
|
50
53
|
removeLabel?(repository: string, number: number, label: string): Promise<void>;
|
|
51
54
|
/** Whether the current owned run has a self-implement.result final observation, even if its worktree remains. */
|
|
52
55
|
hasFinalRunResult?(draft: SweepDraft, repository: string): Promise<boolean | undefined>;
|
|
@@ -587,12 +590,14 @@ export function resolveDraftSweepCloseCap(input: { flag?: unknown; config?: unkn
|
|
|
587
590
|
return { closeCap: DRAFT_SWEEP_CLOSE_CAP, closeCapSource: 'default', warnings };
|
|
588
591
|
}
|
|
589
592
|
|
|
590
|
-
/** Post-merge
|
|
593
|
+
/** Post-merge cleanup: an explicit same-cell successor or the existing verified-goal decision can authorize a close. */
|
|
591
594
|
export async function supersedeDraftsOnMerge(input: {
|
|
592
595
|
repository: string;
|
|
593
596
|
merged: SweepMergedPr & { createdAt: string; mergedAt: string };
|
|
597
|
+
/** `pr land` and HQ train invoke only the explicit same-cell successor path. */
|
|
598
|
+
onlyExplicitSameCell?: boolean;
|
|
594
599
|
adapters: Pick<DraftSweepAdapters, 'listDrafts' | 'listLiveBranches' | 'getRunStatus' | 'setLabels' | 'closeDraft'>
|
|
595
|
-
& Pick<Partial<DraftSweepAdapters>, 'getLatestFileChanges' | 'getPrFiles'>;
|
|
600
|
+
& Pick<Partial<DraftSweepAdapters>, 'getLatestFileChanges' | 'getPrFiles' | 'commentDraft' | 'listIssueComments'>;
|
|
596
601
|
}): Promise<{ closed: number[]; kept: number[] }> {
|
|
597
602
|
const { repository, merged, adapters } = input;
|
|
598
603
|
const closed: number[] = [];
|
|
@@ -611,6 +616,43 @@ export async function supersedeDraftsOnMerge(input: {
|
|
|
611
616
|
|| !Number.isFinite(Date.parse(merged.createdAt)) || !Number.isFinite(Date.parse(merged.mergedAt))
|
|
612
617
|
|| drafts.some((pr) => !Number.isInteger(pr.number) || !pr.branch || !Array.isArray(pr.labels)
|
|
613
618
|
|| !Number.isFinite(Date.parse(pr.createdAt)))) throw new Error('Incomplete merge draft inventory');
|
|
619
|
+
// The conflicting-PR path writes this exact marker. A marker by itself is not authority:
|
|
620
|
+
// both PR bodies must identify the same cell, and the old PR must still be an open draft.
|
|
621
|
+
const markers = [...(merged.body ?? '').matchAll(/^Supersedes:\s*#(\d+)\s*$/gm)];
|
|
622
|
+
const markedNumber = markers.length === 1 ? Number(markers[0]![1]) : null;
|
|
623
|
+
const explicitOld = Number.isSafeInteger(markedNumber) && markedNumber! > 0 ? markedNumber : null;
|
|
624
|
+
const mergedCell = cellIdFromBody(merged.body ?? '');
|
|
625
|
+
if (explicitOld && explicitOld !== merged.number && mergedCell) {
|
|
626
|
+
const old = drafts.find((draft) => draft.number === explicitOld);
|
|
627
|
+
if (old && cellIdFromBody(old.body ?? '') === mergedCell
|
|
628
|
+
&& Date.parse(old.createdAt) < Date.parse(merged.mergedAt)
|
|
629
|
+
&& !old.labels.some((label) => PROTECTED_LABELS.has(label))
|
|
630
|
+
&& PR_LABELS.filter((label) => label.axis === 'state' && old.labels.includes(label.name)).length <= 1) {
|
|
631
|
+
const marker = `<!-- elanous:same-cell-superseded #${old.number} -> #${merged.number} -->`;
|
|
632
|
+
const comment = `${marker}\nSame-cell draft superseded by merged PR #${merged.number} (https://github.com/${repository}/pull/${merged.number}). Branch preserved.`;
|
|
633
|
+
try {
|
|
634
|
+
if (!adapters.listIssueComments || !adapters.commentDraft) throw new Error('same-cell comment inventory unavailable');
|
|
635
|
+
const comments = await adapters.listIssueComments(repository, old.number);
|
|
636
|
+
if (!Array.isArray(comments)) throw new Error('same-cell comment inventory incomplete');
|
|
637
|
+
const remove = stateLabels.filter((label) => old.labels.includes(label.name) && label.name !== supersededLabel).map((label) => label.name);
|
|
638
|
+
if (!old.labels.includes(supersededLabel)) await adapters.setLabels(repository, old.number, { add: supersededLabel, remove });
|
|
639
|
+
if (!comments.some((body) => body.includes(marker))) await adapters.commentDraft(repository, old.number, comment);
|
|
640
|
+
await adapters.closeDraft(repository, old.number);
|
|
641
|
+
closed.push(old.number);
|
|
642
|
+
closeAttempts += 1;
|
|
643
|
+
} catch (failure) {
|
|
644
|
+
failed.push(old.number);
|
|
645
|
+
error = String(failure);
|
|
646
|
+
debug.log('drafts.cleanup', 'same-cell-supersede-failed', { merged: merged.number, old: old.number, error });
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
if (input.onlyExplicitSameCell) {
|
|
651
|
+
kept.push(...drafts.map((draft) => draft.number).filter((number) => !closed.includes(number)));
|
|
652
|
+
debug.log('drafts.cleanup', 'superseded-on-merge', { merged: merged.number, closed, kept,
|
|
653
|
+
...(failed.length ? { failed } : {}), ...(error ? { error } : {}) });
|
|
654
|
+
return { closed, kept };
|
|
655
|
+
}
|
|
614
656
|
const statuses = new Map<number, string | undefined>();
|
|
615
657
|
const latestChanges = new Map<number, Readonly<Record<string, string>> | undefined>();
|
|
616
658
|
const mergedFiles = await adapters.getPrFiles?.(repository, merged.number);
|
|
@@ -625,7 +667,14 @@ export async function supersedeDraftsOnMerge(input: {
|
|
|
625
667
|
}
|
|
626
668
|
}
|
|
627
669
|
for (const listedDraft of drafts) {
|
|
670
|
+
if (closed.includes(listedDraft.number)) continue;
|
|
628
671
|
const draft = { ...listedDraft, latestFileChanges: latestChanges.get(listedDraft.number) };
|
|
672
|
+
// The same-cell route is never inferred from a title, goal, or file overlap.
|
|
673
|
+
// A failed explicit cleanup also stays open for a later retry instead of falling through to generic triage.
|
|
674
|
+
if (draft.number === explicitOld || (mergedCell && cellIdFromBody(draft.body ?? '') === mergedCell)) {
|
|
675
|
+
kept.push(draft.number);
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
629
678
|
if (draft.number === merged.number || !draft.branch.startsWith('self-impl/') || liveBranches.has(draft.branch)
|
|
630
679
|
|| Date.parse(draft.createdAt) >= Date.parse(merged.mergedAt)) {
|
|
631
680
|
kept.push(draft.number);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { debug } from '../debug/log.js';
|
|
3
|
+
import type { FrontNodeId } from './graph-front-nodes.js';
|
|
4
|
+
import type { PipelineNodeId } from '../self-implement/pipeline-shape.js';
|
|
3
5
|
import { GRAPH_SPECS, GRAPH_TEMPLATES, GRAPH_TEMPLATES_SOURCE, pipelineNodeEntryPayload, templateForGoalType, type GraphTemplate } from '../self-implement/graph-templates.js';
|
|
4
6
|
import type { GoalType } from '../self-implement/goal-author.js';
|
|
5
7
|
|
|
@@ -42,6 +44,8 @@ export const JOURNEY_NODE_IDS = [
|
|
|
42
44
|
'stopped',
|
|
43
45
|
] as const;
|
|
44
46
|
export type JourneyNodeId = typeof JOURNEY_NODE_IDS[number];
|
|
47
|
+
/** Existing author/front and self-implement pipeline nodes may use the same observation helpers. */
|
|
48
|
+
export type JourneyObservationNodeId = JourneyNodeId | FrontNodeId | PipelineNodeId;
|
|
45
49
|
|
|
46
50
|
export const JOURNEY_KEY_ENV = 'ELANOUS_JOURNEY_KEY';
|
|
47
51
|
const QUEUE_LAUNCH_ENV = 'ELANOUS_HARNESS_QUEUE_LAUNCH';
|
|
@@ -81,7 +85,7 @@ export interface JourneyObservation {
|
|
|
81
85
|
readonly data?: Readonly<Record<string, unknown>>;
|
|
82
86
|
}
|
|
83
87
|
|
|
84
|
-
function emit(entry: boolean, node:
|
|
88
|
+
function emit(entry: boolean, node: JourneyObservationNodeId, o: JourneyObservation): void {
|
|
85
89
|
try {
|
|
86
90
|
const template = journeyTemplate(node, o.goalType);
|
|
87
91
|
const runId = o.runId ?? process.env[RUN_ID_ENV]?.trim();
|
|
@@ -104,14 +108,14 @@ function emit(entry: boolean, node: JourneyNodeId, o: JourneyObservation): void
|
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
/** 노드 진입. */
|
|
107
|
-
export function enterJourneyNode(node:
|
|
111
|
+
export function enterJourneyNode(node: JourneyObservationNodeId, o: JourneyObservation): void {
|
|
108
112
|
emit(true, node, o);
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
/** 노드 출구 — `outcome` 이 그 노드에서 나간 간선의 라벨(YAML `map` 키)이다.
|
|
112
116
|
* ⭐ 그 라벨이 선언에서 종결 노드 `stopped` 로 가면 `stopped` 진입도 남긴다 — 거절·포기 런이 «선언된 종결점»에서 끝난다.
|
|
113
117
|
* `outcome: 'error'` = 노드 안 작업이 예외를 던졌다(예외는 호출자에게 그대로 간다). */
|
|
114
|
-
export function exitJourneyNode(node:
|
|
118
|
+
export function exitJourneyNode(node: JourneyObservationNodeId, o: JourneyObservation & { readonly outcome: string }): void {
|
|
115
119
|
emit(false, node, o);
|
|
116
120
|
if (node !== 'stopped' && journeyEdgeTarget(node, o.outcome) === 'stopped') {
|
|
117
121
|
const { outcome: _outcome, ...rest } = o;
|
|
@@ -130,7 +134,7 @@ export function journeyEdgeTarget(from: string, label: string): string | undefin
|
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
/** 노드 안 작업을 감싼다 — 예외면 출구 `error` 를 남기고 다시 던진다(진입 뒤 출구가 빠지지 않게). */
|
|
133
|
-
export function withJourneyNode<T>(node:
|
|
137
|
+
export function withJourneyNode<T>(node: JourneyObservationNodeId, o: JourneyObservation, work: () => Promise<T>): Promise<T> {
|
|
134
138
|
const onError = (error: unknown): void => {
|
|
135
139
|
exitJourneyNode(node, { ...o, outcome: 'error', data: { ...o.data, error: error instanceof Error ? error.message : String(error) } });
|
|
136
140
|
};
|
|
@@ -144,7 +148,7 @@ export function withJourneyNode<T>(node: JourneyNodeId, o: JourneyObservation, w
|
|
|
144
148
|
}
|
|
145
149
|
|
|
146
150
|
/** 동기 판. */
|
|
147
|
-
export function withJourneyNodeSync<T>(node:
|
|
151
|
+
export function withJourneyNodeSync<T>(node: JourneyObservationNodeId, o: JourneyObservation, work: () => T): T {
|
|
148
152
|
try { return work(); }
|
|
149
153
|
catch (error) {
|
|
150
154
|
exitJourneyNode(node, { ...o, outcome: 'error', data: { ...o.data, error: error instanceof Error ? error.message : String(error) } });
|
|
@@ -153,7 +157,7 @@ export function withJourneyNodeSync<T>(node: JourneyNodeId, o: JourneyObservatio
|
|
|
153
157
|
}
|
|
154
158
|
|
|
155
159
|
/** 진입·출구를 한 번에 — 판정만 하는 노드(대기 없는 관문)용. */
|
|
156
|
-
export function passJourneyNode(node:
|
|
160
|
+
export function passJourneyNode(node: JourneyObservationNodeId, o: JourneyObservation & { readonly outcome: string }): void {
|
|
157
161
|
enterJourneyNode(node, o);
|
|
158
162
|
exitJourneyNode(node, o);
|
|
159
163
|
}
|