elanous 0.2.29 → 0.2.32
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/{cIpv5nU9AycwYWZI9H589 → IVKr3AlRUVLKsw2fh7eXF}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{058a98ba.7eb28d5e6dc03565.js → 0bb0ff36.b8d418980951e5ba.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +27 -0
- package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +287 -0
- package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +62 -0
- package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6013-2f769370d8b4c2c6.js → 1335-6731f392c35216eb.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8332.6f0f49df772e163b.js → 1654.32de4b324981a188.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
- package/apps/pwa/out/_next/static/chunks/{8795.32573a185af18c7b.js → 1913.7cc6fb6055b1ed3f.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{419.736c0d6f426249a7.js → 2001.6c7e0fd02190886c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6767.1fcfc9b8be83975f.js → 2213.2ccbada92c33ea0f.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4759.1f76713aefb87db5.js → 2871.0bca6137343b3f76.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6776.06ff1e3b464cc607.js → 2898.fd781bc7cf01a7b7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1782-59db1b5aa06df38a.js → 2940-619bfd8ef337c611.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{8471.8d2a8c74f09c36ff.js → 2985.39ccdecd36848b12.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +115 -0
- package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +64 -0
- package/apps/pwa/out/_next/static/chunks/{bc324b7c.02a09dd93f6a399b.js → 3267c0e6.d34854e7b3984a6e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3278.2e5d15b53a4091c8.js +2 -0
- package/apps/pwa/out/_next/static/chunks/{7725-4f83d5541fbdb81b.js → 3541-ce3a5424ed5ad7f1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +34 -0
- package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{46bd8bea.2f4b4099172fcdb7.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1142.65d002789ab3af7d.js → 4174.92ed04922709ac9e.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +36 -0
- package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +286 -0
- package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +77 -0
- package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +226 -0
- package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +79 -0
- package/apps/pwa/out/_next/static/chunks/5173-233188df2f42c626.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +148 -0
- package/apps/pwa/out/_next/static/chunks/5307.60f2209e809bd627.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3396-97b97928c49190c9.js → 5458-16cd7a2b51b74c8c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3403.7199205e65124486.js → 5525.86debf231e181813.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9143.ff14585db1d275ff.js → 5543.a438b8ab5a13ea47.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +74 -0
- package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +94 -0
- package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8398.73a19b39715eda04.js → 6092.a7f99e68b188ca66.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5591.a35e7a217734a8b9.js → 6157.0c9af021de4fb31b.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7375.050ea0d72968e49f.js → 6433.fc573af22bbc9ab7.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +90 -0
- package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +32 -0
- package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +104 -0
- package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +24 -0
- package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
- package/apps/pwa/out/_next/static/chunks/69-0a2c8209c6d4a158.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1852.7f7b53991fcb99ef.js → 7502.ccd5b8065545edd0.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
- package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6534.1ab00f370db7b105.js → 7862.30a8d6482bb238eb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
- package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
- package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.js → 9221.7d22eaf353a2d4e7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8767-2f6a634f5abeaa01.js → 9279-d28c5b7754d010ae.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.js → 9989.3694300e5f000b14.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-a27b1e5a0d1b308f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-32866485913d6a04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/{page-29900ed0011b2c83.js → page-c219f2ed171131be.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-04d00ae9b0890349.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
- package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
- package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.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 +7 -3
- package/graphs/context/nightly-condense.yaml +1 -0
- package/graphs/implement-loop.yaml +5 -0
- package/graphs/intake/intake-daily.yaml +8 -1
- package/graphs/intake/recipes.yaml +5 -0
- package/graphs/lecture/lecture-note.yaml +2 -2
- package/graphs/ops/harness-gc.yaml +1 -0
- package/graphs/release/recipes.yaml +3 -0
- package/graphs/release/release-loop.yaml +9 -5
- package/graphs/units/recipes.yaml +3 -0
- package/graphs/units/release-gate-recheck.yaml +15 -0
- package/package.json +2 -1
- package/scripts/check-native-tool-wiring.ts +3 -2
- package/scripts/ci-android-unit-tests.ts +16 -0
- package/scripts/ci-typecheck-changed.ts +63 -10
- package/scripts/coord-channel-watch.sh +22 -16
- package/scripts/coord-role-pack.ts +81 -2
- package/scripts/cron-run.ts +96 -3
- package/scripts/detect-test-interference.ts +38 -5
- package/scripts/gate-pr-cache.ts +65 -0
- package/scripts/gh-surface/capture.ts +126 -0
- package/scripts/gh-surface/gh +40 -0
- package/scripts/import-graph-scc.ts +38 -0
- package/scripts/install.ps1 +19 -0
- package/scripts/intake-social.ts +181 -0
- package/scripts/lecture-note/node.ts +71 -4
- package/scripts/lib/android-toolchain.ts +32 -0
- package/scripts/lib/deterministic-env.ts +62 -0
- package/scripts/lib/gate-test-env.ts +19 -0
- package/scripts/measure-goal-grounding-corpus.ts +2 -1
- package/scripts/measure-si-task-cpu.ts +143 -0
- package/scripts/ratchets/test-interference-patterns.allowlist.txt +255 -0
- package/scripts/ratchets/test-interference-patterns.ts +367 -0
- package/scripts/release-loop/cut-branch.ts +4 -3
- package/scripts/release-loop/export-check-node.ts +0 -1
- package/scripts/release-loop/fixtures/warm-failure-assertion/sample.junit.xml +8 -0
- package/scripts/release-loop/fixtures/warm-job-029/sample.json +1 -0
- package/scripts/release-loop/fixtures/warm-job-029/sample.junit.xml +10 -0
- package/scripts/release-loop/gate-closure.ts +12 -8
- package/scripts/release-loop/gate-diff.ts +1 -1
- package/scripts/release-loop/gate-host-mirror.ts +66 -0
- package/scripts/release-loop/gate-node.ts +523 -75
- package/scripts/release-loop/gate-partial.ts +106 -9
- package/scripts/release-loop/gate-pr-cache.ts +66 -0
- package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
- package/scripts/release-loop/gate-r2-verdict.ts +189 -0
- package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
- package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
- package/scripts/release-loop/import-graph-scc-run.ts +54 -0
- package/scripts/release-loop/import-graph-scc.ts +215 -0
- package/scripts/release-loop/node-verdict.ts +2 -0
- package/scripts/release-loop/prepare-node.ts +102 -4
- package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
- package/scripts/release-loop/resume-release.ts +33 -4
- package/scripts/release-loop/resume.ts +13 -5
- package/scripts/release-loop/spawn-lane.ts +2 -19
- package/scripts/release-loop/tui-sim-node.ts +3 -2
- package/scripts/release-loop/unattended-release.ts +16 -0
- package/scripts/test-deterministic.ts +5 -61
- package/scripts/train-reach-grouping.ts +48 -0
- package/scripts/tsc-incremental-cache.ts +86 -0
- package/scripts/tsc-incremental-diagnostics.ts +76 -0
- package/scripts/tsc-main-safety-net.ts +2 -2
- package/src/acp/client.ts +4 -1
- package/src/acp/core-turn-bridge.ts +65 -8
- package/src/acp/elanous-extensions.ts +3 -0
- package/src/acp/server.ts +3 -0
- package/src/acp/tool-trace.ts +186 -11
- package/src/ad-pipeline/run.ts +4 -2
- package/src/agent/runner.ts +169 -3
- package/src/agent/self-ambient-cache.ts +156 -0
- package/src/agent/self-ambient.ts +8 -1
- package/src/agent/subagent-callable.ts +3 -2
- package/src/agent/task-notification.ts +5 -0
- package/src/agent-mission/review-loop.ts +6 -3
- package/src/agent-substrate/acp-implementer.ts +14 -2
- package/src/agent-substrate/pr-reviewer.ts +14 -0
- package/src/agent-substrate/self-review-cli.ts +30 -4
- 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 +80 -7
- package/src/briefing/brief-items.ts +24 -22
- package/src/capture/frame-state-detect.ts +39 -0
- package/src/capture/tui-self-report.ts +149 -6
- package/src/chat/chat-cli.ts +10 -2
- package/src/chat/index.ts +138 -26
- package/src/chat/input-control-key.ts +5 -3
- package/src/chat/pickers/modal-runtime.ts +6 -0
- package/src/chat/pickers/modals.ts +8 -2
- package/src/chat/tool-interrupt-behavior.ts +38 -0
- package/src/chat/tool-render/dispatch.ts +5 -1
- package/src/chat/turn-typeahead.ts +75 -20
- package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
- package/src/cli/agent-cli.ts +41 -13
- package/src/cli/ask-bare.ts +1 -0
- package/src/cli/config-audit.ts +123 -0
- package/src/cli/decisions-cli.ts +80 -6
- package/src/cli/import-cli.ts +12 -0
- package/src/cli/log-event-names.ts +17 -0
- package/src/cli/mcp-login.ts +21 -5
- package/src/cli/msg-cli.ts +89 -0
- package/src/cli/pod-cli.ts +14 -3
- package/src/cli/pr-cli.ts +273 -81
- package/src/cli/pr-land-base-read.ts +34 -0
- package/src/cli/pr-land-heavy-remote.ts +82 -26
- package/src/cli/pr-land-overlap-evidence.ts +109 -11
- package/src/cli/pr-land-pod-shadow-job.ts +106 -0
- package/src/cli/pr-land-pod-shadow.ts +16 -3
- package/src/cli/pr-land-refusal.ts +20 -5
- package/src/cli/pr-land-virtual-rebase.ts +108 -0
- package/src/cli/pty-takeover-cli.ts +88 -14
- package/src/cli/release-cli.ts +80 -14
- package/src/cli/seat-cli.ts +138 -3
- package/src/cli/self-update.ts +5 -2
- package/src/cli/sim-cli.ts +18 -0
- package/src/cli/tasks-cli.ts +97 -19
- package/src/context-bus/context-first.ts +13 -0
- package/src/context-bus/context-now.ts +13 -2
- package/src/context-bus/ops-events.ts +79 -0
- package/src/control-plane/lease-holder.ts +12 -8
- package/src/control-plane/ledger.ts +163 -4
- package/src/control-plane/server.ts +91 -11
- package/src/core-turn/run-core-turn.ts +2 -0
- package/src/core-turn/run-goal-loop.ts +243 -3
- package/src/core-turn/seat-turn-cap.ts +79 -0
- package/src/core-turn/short-question.ts +38 -6
- package/src/core-turn/types.ts +6 -0
- package/src/dashboard/acp-active-model.ts +42 -1
- package/src/dashboard/acp-boot.ts +3 -0
- package/src/dashboard/background-jobs-status.ts +66 -0
- package/src/dashboard/index.ts +339 -657
- package/src/dashboard/input/agent-wake.ts +242 -0
- package/src/dashboard/input/chat-main-entry-runtime.ts +6 -1
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
- package/src/dashboard/input/chat-main-session.ts +8 -1
- package/src/dashboard/input/chat-main-turn.ts +12 -3
- package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
- package/src/dashboard/input/external-input-host.ts +49 -9
- package/src/dashboard/input/internal-turn.ts +261 -0
- package/src/dashboard/input/mouse-wiring.ts +108 -11
- package/src/dashboard/input/seat-autowake.ts +318 -0
- package/src/dashboard/input/turn-steer-bridge.ts +70 -0
- package/src/dashboard/log-click-runtime.ts +118 -2
- package/src/dashboard/loop-scheduler.ts +72 -0
- package/src/dashboard/seat-boot-preamble.ts +18 -0
- package/src/dashboard/skill-runtime.ts +2 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
- package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
- package/src/dashboard/slash-runtime/index.ts +13 -0
- package/src/dashboard/turn-busy-teardown.ts +50 -0
- package/src/dashboard/turn-preamble.ts +116 -40
- package/src/dashboard/turn-session-layers.ts +4 -2
- package/src/dashboard/turn-start-segments.ts +222 -0
- package/src/decisions/decision-ledger.ts +45 -4
- package/src/discord-self-message.ts +4 -4
- package/src/display/prompt-row-owner.ts +146 -0
- package/src/display/resize-listener.ts +33 -2
- package/src/domains/release-tool.ts +18 -1
- package/src/field-note/transcribe.ts +17 -0
- package/src/fold-stack.ts +4 -2
- package/src/git-fs/index.ts +263 -36
- package/src/github/remote-call.ts +81 -0
- package/src/goals/registry.ts +46 -6
- package/src/goals/types.ts +7 -1
- package/src/graph-runner/runner.ts +1 -0
- package/src/grok/credential.ts +26 -0
- package/src/harness/gate-reserve.ts +87 -0
- package/src/harness/harness-clean.ts +2 -1
- package/src/harness/harness-cli-command.ts +52 -5
- package/src/harness/harness-gc.ts +2 -1
- package/src/harness/harness-incidents.ts +70 -20
- package/src/harness/harness-pod-dispatch.ts +87 -10
- package/src/harness/harness-queue.ts +68 -4
- package/src/harness/harness-stop.ts +4 -3
- package/src/harness/harness-substrate-default.ts +78 -7
- package/src/harness/harness-worktree-auto.ts +2 -1
- package/src/harness/harness-worktrees.ts +3 -2
- package/src/hooks/dispatch.ts +2 -1
- package/src/index.ts +156 -27
- package/src/input/external-input-queue.ts +64 -7
- package/src/intake-plane/slash.ts +14 -3
- package/src/keybindings.ts +4 -1
- package/src/llm/route-decision.ts +36 -0
- package/src/llm/tool-loop-steered-rejection.ts +41 -0
- package/src/llm-request-shape.ts +209 -0
- package/src/llm.ts +301 -283
- package/src/loops/consensus.ts +348 -0
- package/src/loops/msg-wake.ts +206 -4
- package/src/loops/observe.ts +19 -3
- package/src/loops/orchestrator/tick.ts +88 -12
- package/src/loops/orchestrator/traffic.ts +64 -1
- package/src/loops/registry.ts +30 -0
- package/src/market/signed-index.ts +14 -0
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/mcp/mcp-oauth.ts +54 -5
- package/src/models/prompts.ts +28 -0
- package/src/msg/msg-sse-client.ts +223 -0
- package/src/msg/msg-store.ts +86 -2
- package/src/mss/logging/log-store.ts +225 -1
- package/src/mss/logging/render-categories.ts +5 -0
- package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
- package/src/nexus/api/http-server.ts +54 -15
- package/src/nexus/api/loop-resources.ts +19 -3
- package/src/nexus/api/ops-api.ts +11 -0
- package/src/nexus/daemon-thin-inventory.md +37 -0
- package/src/nexus/index.ts +70 -0
- package/src/nexus/state/state.ts +1 -0
- package/src/oauth/store.ts +32 -7
- package/src/onboarding/first-run.ts +28 -3
- package/src/ops/overview-cache.ts +16 -4
- package/src/ops/overview.ts +59 -2
- package/src/ops/resources.ts +82 -0
- package/src/plugins/maker/connector-maker.ts +41 -0
- package/src/plugins/maker/skill-maker.ts +42 -0
- package/src/pr-tool/census.ts +303 -0
- package/src/pr-tool/inflight-registry.ts +143 -0
- package/src/prompt-library/chat-conciseness.ts +13 -0
- package/src/prompt-library/universal-preamble.ts +10 -5
- package/src/pty-shell/pty-manifest.ts +12 -3
- package/src/pty-shell/tui-run-state.ts +34 -3
- package/src/release-loop/gate-host-reservation.ts +97 -0
- package/src/release-loop/landing-freeze.ts +5 -0
- package/src/release-loop/light-rc.ts +5 -2
- package/src/release-loop/placement.ts +92 -1
- package/src/release-loop/rehearsal-shard-plan.ts +149 -0
- package/src/release-loop/rehearsal.ts +73 -17
- package/src/repl/index.ts +20 -2
- package/src/seat-loop/seat-knowhow.ts +282 -0
- package/src/seat-loop/seat-loop.ts +41 -2
- package/src/seat-loop/traffic-signal.ts +5 -1
- package/src/self-dev/ask-launch-flow.ts +37 -3
- package/src/self-dev/decompose-compose-graph.ts +28 -27
- package/src/self-dev/decompose-proposal.ts +53 -38
- package/src/self-dev/decompose.ts +17 -0
- package/src/self-dev/dev-pipeline.ts +31 -2
- package/src/self-dev/draft-residue.ts +267 -33
- package/src/self-dev/draft-sweep.ts +59 -4
- package/src/self-dev/external-call-zero.ts +77 -0
- package/src/self-dev/launch-preflight-text.ts +6 -0
- package/src/self-dev/launch-preflight.ts +25 -3
- package/src/self-dev/local-supervisor-judge.ts +185 -0
- package/src/self-dev/run-supervisor.ts +229 -19
- package/src/self-dev/run-types.ts +20 -0
- package/src/self-dev/shard-aggregate.ts +13 -2
- package/src/self-dev/shard-plan.ts +56 -1
- package/src/self-dev/shard-run.ts +207 -12
- package/src/self-dev/spawn-lane-files.ts +19 -0
- package/src/self-implement/app-api-budget.ts +51 -11
- package/src/self-implement/config-gate.ts +2 -1
- package/src/self-implement/elanous-tui-spawn.ts +14 -0
- package/src/self-implement/expose-gate.ts +2 -1
- package/src/self-implement/follow-up-placement.ts +79 -0
- package/src/self-implement/gate-artifacts.ts +416 -0
- package/src/self-implement/gate-baseline.ts +96 -5
- package/src/self-implement/gate-cli.ts +207 -17
- package/src/self-implement/gate-remote.ts +136 -26
- package/src/self-implement/gate-scenario.ts +85 -0
- package/src/self-implement/goal-author.ts +160 -8
- package/src/self-implement/graph-authority.ts +38 -6
- package/src/self-implement/graph-overlay-condition.ts +92 -1
- package/src/self-implement/heal-triage.ts +79 -0
- package/src/self-implement/host-regate.ts +97 -7
- package/src/self-implement/orchestrator.ts +115 -134
- package/src/self-implement/pr-title.ts +123 -0
- package/src/self-implement/run-checkpoint.ts +235 -0
- package/src/self-implement/run-ledger.ts +162 -15
- package/src/self-implement/run-stop.ts +4 -3
- package/src/self-implement/run-ttl.ts +28 -4
- package/src/self-implement/seams.ts +2 -0
- package/src/self-implement/shadow-stage.ts +7 -6
- package/src/self-implement/stop-autoheal.ts +2 -1
- package/src/self-implement/train-gate-remote.ts +37 -8
- package/src/self-implement/train-reach-grouping.ts +157 -0
- package/src/self-implement/train-scenario-layers.ts +133 -0
- package/src/self-implement/uncommitted-work.ts +2 -0
- package/src/session/pending-input.ts +19 -0
- package/src/session/session-start.ts +224 -0
- package/src/session-runtime/index.ts +22 -267
- package/src/session-runtime/parallel-dispatch.ts +22 -5
- package/src/shell-runner/background-surface.ts +15 -5
- package/src/skills/tools/agent.ts +39 -6
- package/src/skills/tools/dev-harness.ts +6 -4
- package/src/skills/tools/list-dir.ts +11 -0
- package/src/skills/tools/schedule-wakeup.ts +408 -0
- package/src/skills/tools/shell.ts +246 -4
- 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/resync-tick.ts +114 -23
- package/src/steward/ta-repair-event-collect.ts +158 -0
- package/src/steward/triage.ts +10 -0
- package/src/surface/shell-runner-boot.ts +5 -2
- package/src/task-agent/card-evidence.ts +25 -1
- package/src/task-agent/green-sweep.ts +8 -3
- package/src/task-agent/judge.ts +76 -0
- package/src/task-agent/land-queue.ts +79 -0
- package/src/task-agent/live-moves.ts +30 -9
- package/src/task-agent/postland-card.ts +5 -0
- package/src/task-agent/prelaunch-already-done.ts +98 -0
- package/src/task-agent/real-launch-guard.ts +37 -0
- package/src/task-agent/rejudge-on-head.ts +89 -12
- package/src/task-agent/remote-rejudge-bind.ts +28 -8
- package/src/task-agent/repair-cycle.ts +45 -7
- package/src/task-agent/repair-worker.ts +7 -0
- package/src/task-agent/run-identity.ts +200 -0
- package/src/task-agent/shadow.ts +50 -3
- package/src/task-agent/task-hand.ts +182 -5
- package/src/task-agent/train-landing.ts +77 -0
- package/src/task-agent/work-order.ts +104 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +151 -37
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
- package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
- package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
- package/src/task-orchestrator/surfaces/pod-install-slots.ts +121 -9
- package/src/task-orchestrator/surfaces/pod-lease.ts +118 -6
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
- package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +27 -0
- package/src/task-orchestrator/surfaces/pod-pool.ts +3 -1
- package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
- package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +67 -0
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
- package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
- package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +525 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runner.ts +90 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +362 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +138 -19
- package/src/telegram.ts +2 -4
- package/src/tui/chat/execution-badge.ts +5 -1
- package/src/tui/input/pickers.ts +732 -0
- package/src/tui/input-lag-probe.ts +230 -0
- package/src/tui/slash/mission.ts +492 -0
- package/src/tui/slash/term.ts +877 -0
- package/src/tui-client/dashboard-session.ts +9 -0
- package/src/tui.ts +52 -0
- package/src/user-config/gemini-server-tools.ts +9 -0
- package/src/user-config.ts +53 -16
- package/src/util/spawn-sync-output.ts +7 -0
- package/src/ux-sim/fake-bin.ts +154 -0
- package/src/ux-sim/fake-clock.ts +36 -0
- package/src/ux-sim/headless-tui.ts +72 -0
- package/src/ux-sim/in-process-cli.ts +2 -1
- package/src/ux-sim/scenario.ts +255 -0
- package/src/ux-sim/temp-git-remote.ts +82 -0
- package/src/version/packed-revision.json +1 -1
- package/src/video-pipeline/recipes/vlog.ts +25 -7
- package/apps/pwa/out/_next/static/chunks/1015-9cba22a5a4554797.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
- package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
- package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
- package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
- package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
- package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
- package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
- package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
- package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
- package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
- package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
- package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
- package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
- package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
- package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
- package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
- package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
- package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
- package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
- package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
- package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
- package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
- package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
- package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
- package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-a5635eba0d73b84e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9f92737b8766009a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
- package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
- package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
- package/apps/pwa/out/_next/static/css/72becfd42807b50d.css +0 -1
- /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → IVKr3AlRUVLKsw2fh7eXF}/_ssgManifest.js +0 -0
|
@@ -16,7 +16,7 @@ import { collectPodArtifacts } from './pod-artifact-return.js';
|
|
|
16
16
|
import { getDefaultLogStore, type LogStore } from '../../mss/logging/log-store.js';
|
|
17
17
|
import { podBunCacheVolume } from './pod-bun-cache.js';
|
|
18
18
|
import { POD_JOB_TTL_AFTER_FINISHED_SECONDS } from './pod-lease.js';
|
|
19
|
-
import {
|
|
19
|
+
import { podHostDirsCheckScript, podInstallSlotsVolume, prepareHostDirsOnce, type HostDirsPrepResult, podHostDirsScript } from './pod-install-slots.js';
|
|
20
20
|
import { type PodPoolMember, PodPoolScheduler, resolvePodPoolSpec, parsePodPool, checkPodPool, syncPoolImages, type PoolKubectl } from './pod-pool.js';
|
|
21
21
|
import { podSkillsDigest, readSkillEnvFiles, resolvePodSkills } from './pod-skills.js';
|
|
22
22
|
import { podSourceScript, type PodSource } from './pod-source-receive.js';
|
|
@@ -34,17 +34,26 @@ 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';
|
|
40
42
|
|
|
41
43
|
export const POD_LITE_MEMORY_LIMIT = '2Gi';
|
|
42
44
|
|
|
45
|
+
/** W5 (10-15 #27801): where a memory-backed TMPDIR is mounted for release gate shards — the overlayfs `/tmp` made SQLite
|
|
46
|
+
* tests take 0.4~5s per turn (once 124s). tmpfs pages count against the container memory limit, so the caller's cap
|
|
47
|
+
* (`tmpfsSizeLimit`) stays small next to the 16Gi shard limit (request 6Gi). */
|
|
48
|
+
export const POD_TMPFS_MOUNT_PATH = '/tmp-mem';
|
|
49
|
+
|
|
43
50
|
/** 요청은 한도를 넘을 수 없다(쿠버네티스가 Job 을 거부한다) — lite 2Gi 처럼 한도가 기본 요청보다 작으면 한도로 맞춘다. */
|
|
44
51
|
/** The command Job container's CPU limit when the caller names none (GATE-SPEED A3①: unchanged default). */
|
|
45
52
|
export const POD_COMMAND_CPU_LIMIT_DEFAULT = '4';
|
|
46
53
|
/** 게이트 조각·pod-command 의 CPU 요청 기본 — 하니스 Pod(POD_CHILD_REQUESTS.cpu)와 따로 둔다(조각은 bun test 로 CPU 를 실제로 쓴다). */
|
|
47
54
|
export const POD_COMMAND_CPU_REQUEST_DEFAULT = '1';
|
|
55
|
+
/** Gate and command Pods retain their measured 6Gi scheduler request; si-task admission uses its own size. */
|
|
56
|
+
export const POD_COMMAND_MEMORY_REQUEST_DEFAULT = '6Gi';
|
|
48
57
|
|
|
49
58
|
/** Container CPU request/limit override. Omitted fields keep the defaults (request `POD_COMMAND_CPU_REQUEST_DEFAULT` · limit 4). */
|
|
50
59
|
export interface PodCpu { request?: string; limit?: string }
|
|
@@ -93,9 +102,9 @@ export function parsePodCpu(value: unknown, label = 'cpu'): PodCpu | undefined {
|
|
|
93
102
|
|
|
94
103
|
export function memoryRequestWithin(limit: string | undefined): string {
|
|
95
104
|
const gi = (value: string | undefined) => { const m = /^(\d+)Gi$/.exec(value ?? ''); return m ? Number(m[1]) : null; };
|
|
96
|
-
const request = gi(
|
|
105
|
+
const request = gi(POD_COMMAND_MEMORY_REQUEST_DEFAULT);
|
|
97
106
|
const max = gi(limit);
|
|
98
|
-
return request !== null && max !== null && request > max ? limit! :
|
|
107
|
+
return request !== null && max !== null && request > max ? limit! : POD_COMMAND_MEMORY_REQUEST_DEFAULT;
|
|
99
108
|
}
|
|
100
109
|
|
|
101
110
|
/** POD7 must-fix: the skill list alone can't tell a network-only job from one that needs ffmpeg/browser — so lite is
|
|
@@ -133,18 +142,24 @@ export function tailBytes(text: string, maxBytes: number): string {
|
|
|
133
142
|
return `…[앞 ${bytes.length - maxBytes}바이트 생략]\n${cut.subarray(start).toString('utf8')}`;
|
|
134
143
|
}
|
|
135
144
|
|
|
136
|
-
/**
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
+
/**
|
|
146
|
+
* The isolation probe: wait until the NetworkPolicy blocks the host/prod daemons, then go on with the child shell.
|
|
147
|
+
* GATE-WARM-BOOT-NO-INIT (10-15) — this used to be the `isolation-gate` init container; it is now the child shell's first
|
|
148
|
+
* lines, before any credential is read. Same probes, same log lines, same exit 1 when isolation is not enforced in 30 s.
|
|
149
|
+
* Measured on node-b k3d (#27805): init 2 → 354 s · init 1 → 41 s · none → 1 s from Pod creation to the child start.
|
|
150
|
+
*/
|
|
151
|
+
export function isolationGateLines(): string {
|
|
152
|
+
return `elanous_isolation_gate() {
|
|
153
|
+
local ok=0 i
|
|
154
|
+
for i in $(seq 1 60); do
|
|
155
|
+
if curl -s -m 1 -o /dev/null http://host.orb.internal:31415/health || curl -s -m 1 -o /dev/null http://core.elanous-prod:8080/; then ok=0; else ok=$((ok+1)); fi
|
|
156
|
+
[ "$ok" -ge 3 ] && { echo "[gate] isolation enforced after \${i} probes"; return 0; }
|
|
157
|
+
sleep 0.5
|
|
158
|
+
done
|
|
159
|
+
echo "[gate] ISOLATION NOT ENFORCED within 30s"; exit 1
|
|
160
|
+
}
|
|
161
|
+
elanous_isolation_gate || exit 1`;
|
|
145
162
|
}
|
|
146
|
-
|
|
147
|
-
const GATE = isolationGateScript();
|
|
148
163
|
|
|
149
164
|
/** Export the command's log store into the existing outbox return channel without changing the command exit status. */
|
|
150
165
|
const COMMAND_LOG_EXPORT = `if mkdir -p "$HOME/outbox/pod-logs" && elanous --test="$HOME/.elanous-test" logs --instance prod --since 12h --limit 20000 --json --json-data > "$HOME/outbox/pod-logs/logs.jsonl"; then
|
|
@@ -182,7 +197,7 @@ if [ -d "$HOME/outbox" ]; then
|
|
|
182
197
|
else
|
|
183
198
|
printf 'ELANOUS_POD_ARTIFACT_SKIPPED %s %s\\n' "$relative" "$size"
|
|
184
199
|
fi
|
|
185
|
-
done < <(find "$HOME/outbox" -type f -print0)
|
|
200
|
+
done < <(find "$HOME/outbox" -type f -print0 | while IFS= read -r -d '' f; do printf '%s\\t%s\\0' "$(( $(wc -c < "$f") ))" "$f"; done | LC_ALL=C sort -z -t $'\\t' -k1,1n -k2 | while IFS= read -r -d '' row; do printf '%s\\0' "\${row#*$'\\t'}"; done)
|
|
186
201
|
fi`;
|
|
187
202
|
|
|
188
203
|
export interface PodCommandJobInput {
|
|
@@ -208,9 +223,13 @@ export interface PodCommandJobInput {
|
|
|
208
223
|
memoryLimit?: string;
|
|
209
224
|
/** GATE-SPEED A3①: CPU request/limit override (release gate shards only). Omitted = request 1 / limit 4. */
|
|
210
225
|
cpu?: PodCpu;
|
|
226
|
+
/** W5 — emptyDir{medium: Memory} sizeLimit mounted at {@link POD_TMPFS_MOUNT_PATH} ⊕ `TMPDIR` (release gate shards only). Omitted = image `/tmp`. */
|
|
227
|
+
tmpfsSizeLimit?: string;
|
|
211
228
|
source?: PodSource;
|
|
212
229
|
deadlineSeconds: number;
|
|
213
230
|
runId?: string;
|
|
231
|
+
/** GATE-WARM-BOOT-NO-INIT fallback: the node-side hand-over did not run, so a root init container hands the hostPath dirs to uid 1000. */
|
|
232
|
+
hostDirsInit?: boolean;
|
|
214
233
|
}
|
|
215
234
|
|
|
216
235
|
function bashSingleQuote(value: string): string {
|
|
@@ -226,8 +245,11 @@ export function podCommandJobManifest(o: PodCommandJobInput): Record<string, unk
|
|
|
226
245
|
const grok = o.llm === 'grok';
|
|
227
246
|
const bunCache = o.bunCache ? podBunCacheVolume(o.bunCache) : undefined;
|
|
228
247
|
const installSlots = o.installSlots ? podInstallSlotsVolume(o.installSlots) : undefined;
|
|
229
|
-
// hostPath directories the uid-1000 child writes
|
|
248
|
+
// hostPath directories the uid-1000 child writes. DirectoryOrCreate makes them root 0755, so runPodCommand hands them to
|
|
249
|
+
// uid 1000 once per node (prepareHostDirsOnce); the child only reports a directory it still cannot write.
|
|
230
250
|
const hostDirMounts = [...(bunCache ? [bunCache.volumeMount] : []), ...(installSlots ? [installSlots.volumeMount] : [])];
|
|
251
|
+
const tmpfs = o.tmpfsSizeLimit?.trim() || undefined;
|
|
252
|
+
const tmpfsMounts = tmpfs ? [{ name: 'tmp-mem', mountPath: POD_TMPFS_MOUNT_PATH }] : [];
|
|
231
253
|
const cpu = resolvePodCpu(o.cpu);
|
|
232
254
|
const quotedArgs = o.command.map(bashSingleQuote).join(' ');
|
|
233
255
|
const credLines = [
|
|
@@ -237,12 +259,14 @@ export function podCommandJobManifest(o: PodCommandJobInput): Record<string, unk
|
|
|
237
259
|
: []),
|
|
238
260
|
];
|
|
239
261
|
const script = [
|
|
262
|
+
isolationGateLines(),
|
|
240
263
|
'set -u',
|
|
241
264
|
...credLines,
|
|
242
265
|
'curl -s -m 3 -o /dev/null http://host.orb.internal:31415/health && { echo "[pod] ISOLATION FAIL"; exit 3; }',
|
|
243
266
|
...(o.clone
|
|
244
267
|
? ['export GH_TOKEN="$(cat /creds/gh-token)" && gh auth setup-git', podSourceScript(o.source ?? { kind: 'default' }, o.repoUrl)]
|
|
245
268
|
: ['mkdir -p ~/work && cd ~/work']),
|
|
269
|
+
...(hostDirMounts.length ? [podHostDirsCheckScript(hostDirMounts)] : []),
|
|
246
270
|
...(bunCache ? [bunCache.shellPrefix] : []),
|
|
247
271
|
`set -- ${quotedArgs}`,
|
|
248
272
|
'"$@"',
|
|
@@ -270,14 +294,10 @@ export function podCommandJobManifest(o: PodCommandJobInput): Record<string, unk
|
|
|
270
294
|
spec: {
|
|
271
295
|
restartPolicy: 'Never',
|
|
272
296
|
securityContext: { runAsUser: 1000, fsGroup: 1000 },
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
hostDirMounts.length
|
|
278
|
-
? { name: 'isolation-gate', image: o.image, imagePullPolicy: o.imagePullPolicy ?? 'Never', securityContext: { runAsUser: 0 }, command: ['bash', '-c'], args: [isolationGateScript(podHostDirsScript(hostDirMounts))], volumeMounts: hostDirMounts.map((mount) => ({ ...mount })) }
|
|
279
|
-
: { name: 'isolation-gate', image: o.image, imagePullPolicy: o.imagePullPolicy ?? 'Never', command: ['bash', '-c'], args: [GATE] },
|
|
280
|
-
],
|
|
297
|
+
// Normal path: no init container. Fallback only when the node-side hand-over did not run (no member · prep failed).
|
|
298
|
+
...(o.hostDirsInit && hostDirMounts.length ? { initContainers: [
|
|
299
|
+
{ name: 'host-dirs', image: o.image, imagePullPolicy: o.imagePullPolicy ?? 'Never', securityContext: { runAsUser: 0 }, command: ['bash', '-c'], args: [podHostDirsScript(hostDirMounts)], volumeMounts: hostDirMounts.map((mount) => ({ ...mount })) },
|
|
300
|
+
] } : {}),
|
|
281
301
|
containers: [{
|
|
282
302
|
name: 'child', image: o.image, imagePullPolicy: o.imagePullPolicy ?? 'Never',
|
|
283
303
|
resources: { requests: { ...POD_CHILD_REQUESTS, cpu: cpu.request, memory: memoryRequestWithin(o.memoryLimit) }, limits: { memory: o.memoryLimit ?? '16Gi', cpu: cpu.limit } },
|
|
@@ -286,18 +306,21 @@ export function podCommandJobManifest(o: PodCommandJobInput): Record<string, unk
|
|
|
286
306
|
...(o.runId ? [{ name: 'ELANOUS_RUN_ID', value: o.runId }] : []),
|
|
287
307
|
{ name: 'ELANOUS_SUBSTRATE', value: 'pod' },
|
|
288
308
|
{ name: 'ELANOUS_POD_NAME', valueFrom: { fieldRef: { fieldPath: 'metadata.name' } } },
|
|
309
|
+
...(tmpfs ? [{ name: 'TMPDIR', value: POD_TMPFS_MOUNT_PATH }] : []),
|
|
289
310
|
],
|
|
290
|
-
...(secretKeys || o.hostMirror || hostDirMounts.length ? { volumeMounts: [
|
|
311
|
+
...(secretKeys || o.hostMirror || hostDirMounts.length || tmpfs ? { volumeMounts: [
|
|
291
312
|
...(secretKeys ? [{ name: 'creds', mountPath: '/creds', readOnly: true }] : []),
|
|
292
313
|
...(o.hostMirror ? [{ name: 'host-mirror', mountPath: '/host-mirror', readOnly: true }] : []),
|
|
293
314
|
...hostDirMounts,
|
|
315
|
+
...tmpfsMounts,
|
|
294
316
|
] } : {}),
|
|
295
317
|
}],
|
|
296
|
-
...(secretKeys || o.hostMirror || hostDirMounts.length ? { volumes: [
|
|
318
|
+
...(secretKeys || o.hostMirror || hostDirMounts.length || tmpfs ? { volumes: [
|
|
297
319
|
...(secretKeys ? [{ name: 'creds', secret: { secretName: `${o.name}-creds`, defaultMode: 0o400 } }] : []),
|
|
298
320
|
...(o.hostMirror ? [{ name: 'host-mirror', hostPath: { path: o.hostMirror, type: 'Directory' } }] : []),
|
|
299
321
|
...(bunCache ? [bunCache.volume] : []),
|
|
300
322
|
...(installSlots ? [installSlots.volume] : []),
|
|
323
|
+
...(tmpfs ? [{ name: 'tmp-mem', emptyDir: { medium: 'Memory', sizeLimit: tmpfs } }] : []),
|
|
301
324
|
] } : {}),
|
|
302
325
|
},
|
|
303
326
|
},
|
|
@@ -374,6 +397,8 @@ export interface RunPodCommandOptions {
|
|
|
374
397
|
memoryLimit?: string;
|
|
375
398
|
/** GATE-SPEED A3①: CPU request/limit override — only the release gate passes it. Omitted = request 1 / limit 4. */
|
|
376
399
|
cpu?: PodCpu;
|
|
400
|
+
/** W5 — memory-backed TMPDIR sizeLimit mounted at {@link POD_TMPFS_MOUNT_PATH}; only the release gate passes it. Omitted = image `/tmp`. */
|
|
401
|
+
tmpfsSizeLimit?: string;
|
|
377
402
|
/** POD7: 호출부가 «네트워크 스킬만 쓰는 명령»이라고 말할 때만 lite 이미지 ⊕ 2Gi. */
|
|
378
403
|
lite?: boolean;
|
|
379
404
|
source?: PodSource;
|
|
@@ -391,6 +416,12 @@ export interface RunPodCommandOptions {
|
|
|
391
416
|
* elsewhere. Omitted = poll without a bound (unchanged for every caller but the release gate).
|
|
392
417
|
*/
|
|
393
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;
|
|
394
425
|
kubectl?: Kubectl;
|
|
395
426
|
/** A caller-owned scheduler is self-capped: acquires count only its own Jobs, never cluster occupancy (POOLGLOBAL-REG). */
|
|
396
427
|
poolScheduler?: PodPoolScheduler;
|
|
@@ -398,6 +429,8 @@ export interface RunPodCommandOptions {
|
|
|
398
429
|
seedMirror?: (o: { host: string; commit: string; cwd: string }) => Promise<MirrorSeedResult | undefined>;
|
|
399
430
|
/** GATE-WARM-BOOT — the git tree the seed pushes from (default: the process cwd — the gate runs in the repo tree). */
|
|
400
431
|
mirrorSeedCwd?: string;
|
|
432
|
+
/** GATE-WARM-BOOT-NO-INIT — hands the hostPath dirs to uid 1000 on the member's nodes (test seam · default {@link prepareHostDirsOnce}). */
|
|
433
|
+
prepareHostDirs?: (o: { member: PodPoolMember; hostPaths: readonly string[] }) => Promise<HostDirsPrepResult | undefined>;
|
|
401
434
|
checkPool?: typeof checkPodPool;
|
|
402
435
|
syncImages?: typeof syncPoolImages;
|
|
403
436
|
imageCommit?: string | null;
|
|
@@ -417,6 +450,8 @@ export interface RunPodCommandOptions {
|
|
|
417
450
|
/** GATE-POD-RESULT-MARKER — the child script's final line (`\n<marker> <token> rc=<n>\n`), printed after the artifact emit. */
|
|
418
451
|
export const POD_RESULT_MARKER = '__ELANOUS_POD_DONE__';
|
|
419
452
|
/** The marker bound to one launch (`token` = the launch's random id · the Job name when the manifest has no launch). */
|
|
453
|
+
/** Full-log re-reads after an early marker return before the artifacts count as lost (GATE-POD-RESULT-MARKER follow-up). */
|
|
454
|
+
export const POD_MARKER_LOG_RETRIES = 2;
|
|
420
455
|
export function podResultMarker(token: string): string { return `${POD_RESULT_MARKER} ${token}`; }
|
|
421
456
|
|
|
422
457
|
/** Split the child's logs into the command output (marker tail removed, bytes otherwise unchanged) and the marker rc (null = no marker for this token). */
|
|
@@ -459,14 +494,35 @@ export function podCommandTargetCommit(o: { remote: boolean; gitHead: () => stri
|
|
|
459
494
|
return o.localImageCommit();
|
|
460
495
|
}
|
|
461
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
|
+
|
|
462
511
|
/** 풀 자리 · 이미지 판 · Job 적용 · 완료 대기 · 산출 회수 · Secret 정리. */
|
|
463
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();
|
|
464
519
|
const command = [...options.command];
|
|
465
520
|
if (command.length === 0) throw new Error('pod command: 명령이 비었다');
|
|
466
521
|
const skills = [...new Set((options.skills ?? []).map((s) => s.trim()).filter(Boolean))];
|
|
467
522
|
const llm = options.llm;
|
|
468
523
|
const log = options.log ?? ((c, e, d) => debug.log(c, e, d));
|
|
469
|
-
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));
|
|
470
526
|
const sleep = options.sleep ?? ((ms: number) => new Promise<void>((r) => setTimeout(r, ms)));
|
|
471
527
|
const namespace = options.namespace ?? 'elanous-test';
|
|
472
528
|
const image = options.image ?? podCommandImageFor(skills, options.clone === true, options.lite === true);
|
|
@@ -507,18 +563,32 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
507
563
|
// concurrency cap — its Jobs count against the spec caps, not the cluster's goal Pods (#24253 → 0.2.15 gate ran 1 shard).
|
|
508
564
|
const selfCapped = options.poolScheduler !== undefined;
|
|
509
565
|
for (;;) {
|
|
510
|
-
|
|
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
|
+
}
|
|
511
574
|
if (member) break;
|
|
512
|
-
await sleep(options.pollMs ?? 15_000);
|
|
575
|
+
await awaitPodCommandAbort(sleep(options.pollMs ?? 15_000), options.signal);
|
|
513
576
|
}
|
|
514
577
|
}
|
|
578
|
+
if (options.signal?.aborted) {
|
|
579
|
+
if (member && pool) pool.release(member);
|
|
580
|
+
ensureLive();
|
|
581
|
+
}
|
|
515
582
|
const currentContext = member || options.kubectl ? null : baseKubectl(['config', 'current-context']);
|
|
516
583
|
const context = member?.context ?? (currentContext?.status === 0 ? currentContext.stdout.trim() : '');
|
|
517
|
-
const
|
|
518
|
-
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']); };
|
|
519
587
|
const artifactRoot = options.artifactsRoot ?? `${effectiveInstanceRoot()}/pod-artifacts`;
|
|
520
588
|
const artifactsDir = `${artifactRoot}/${name}`;
|
|
589
|
+
let jobApplied = false;
|
|
521
590
|
try {
|
|
591
|
+
ensureLive();
|
|
522
592
|
if (!context && !options.kubectl) throw new Error('pod command: kubectl context 를 확인할 수 없다');
|
|
523
593
|
let grokAuth: string | undefined;
|
|
524
594
|
if (llm === 'grok') {
|
|
@@ -546,7 +616,7 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
546
616
|
const localSkillsDigest = options.kubectl ? null : image === POD_LITE_IMAGE
|
|
547
617
|
? podSkillsDigest(POD_NETWORK_SKILLS, resolve(import.meta.dir, '../../../skills')).digest
|
|
548
618
|
: podSkillsDigest(resolvePodSkills(env).skills).digest;
|
|
549
|
-
const syncs = await (options.syncImages ?? syncPoolImages)([member], image, imageCommit, { localSkillsDigest });
|
|
619
|
+
const syncs = await awaitPodCommandAbort((options.syncImages ?? syncPoolImages)([member], image, imageCommit, { localSkillsDigest }), options.signal);
|
|
550
620
|
const synced = syncs.get(member.context);
|
|
551
621
|
if (synced && !synced.ok) throw new Error(`pod command: 이미지 판을 못 맞췄다: ${synced.detail}`);
|
|
552
622
|
if (synced?.imageRef) member = { ...member, imageRef: synced.imageRef };
|
|
@@ -559,10 +629,29 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
559
629
|
const seedMirror = options.seedMirror ?? (options.kubectl ? undefined : seedMirrorOnce);
|
|
560
630
|
if (seedMirror && options.clone && options.source?.kind === 'commit' && hostMirror && member?.sshHost) {
|
|
561
631
|
// Worst case added to a cold start: the push limit (GATE_MIRROR_SEED_LIMIT_MS), once per host·commit.
|
|
562
|
-
const seed = await seedMirror({ host: member.sshHost, commit: options.source.sha, cwd: options.mirrorSeedCwd ?? process.cwd() })
|
|
563
|
-
.catch((error: unknown) => ({ host: member!.sshHost!, ok: false, ms: 0, detail: String(error).slice(0, 300) }));
|
|
632
|
+
const seed = await awaitPodCommandAbort(seedMirror({ host: member.sshHost, commit: options.source.sha, cwd: options.mirrorSeedCwd ?? process.cwd() })
|
|
633
|
+
.catch((error: unknown) => ({ host: member!.sshHost!, ok: false, ms: 0, detail: String(error).slice(0, 300) })), options.signal);
|
|
564
634
|
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 } : {}) });
|
|
565
635
|
}
|
|
636
|
+
// GATE-WARM-BOOT-NO-INIT (10-15): the hostPath dirs the uid-1000 child writes are handed over on the node itself, once per
|
|
637
|
+
// member·paths in this process (no init container). Best effort: a failure only logs; the child then falls back.
|
|
638
|
+
const hostDirPaths = [...(bunCache ? [bunCache] : []), ...(installSlots ? [installSlots] : [])];
|
|
639
|
+
const prepareHostDirs = options.prepareHostDirs ?? (options.kubectl ? undefined : prepareHostDirsOnce);
|
|
640
|
+
let hostDirsPrepared = false;
|
|
641
|
+
if (hostDirPaths.length) {
|
|
642
|
+
// Observed whether or not a hand-over runs: no member (nothing to reach) and an injected kubectl without a seam are skips.
|
|
643
|
+
if (!member) log('pod.command-job', 'host-dirs-prep', { ok: false, reason: 'no-pool-member', paths: hostDirPaths });
|
|
644
|
+
else if (!prepareHostDirs) log('pod.command-job', 'host-dirs-prep', { ok: false, reason: 'prep-disabled', paths: hostDirPaths });
|
|
645
|
+
else {
|
|
646
|
+
const prep = await awaitPodCommandAbort(prepareHostDirs({ member, hostPaths: hostDirPaths })
|
|
647
|
+
.catch((error: unknown) => ({ host: member!.sshHost ?? 'local', ok: false, ms: 0, detail: String(error).slice(0, 300) })), options.signal);
|
|
648
|
+
hostDirsPrepared = prep?.ok === true;
|
|
649
|
+
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 } : {}) });
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
// 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).
|
|
653
|
+
const hostDirsInit = hostDirPaths.length > 0 && !hostDirsPrepared;
|
|
654
|
+
ensureLive();
|
|
566
655
|
const ghToken = options.clone ? (options.ghToken ?? defaultGhToken)() : undefined;
|
|
567
656
|
const secret = commandJobSecret({ name, namespace, launch, skills, skillEnvText, ...(grokAuth !== undefined ? { grokAuth } : {}), ...(ghToken !== undefined ? { ghToken } : {}) });
|
|
568
657
|
if (secret) {
|
|
@@ -573,10 +662,13 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
573
662
|
name, namespace, launch, image: imageRef ?? image,
|
|
574
663
|
...(imageRef ? { imagePullPolicy: 'IfNotPresent' as const } : {}),
|
|
575
664
|
repoUrl, command, skills, ...(options.returnLogs ? { returnLogs: true } : {}), ...(llm ? { llm } : {}), ...(options.clone ? { clone: true } : {}),
|
|
576
|
-
...(options.source ? { source: options.source } : {}), ...(hostMirror ? { hostMirror } : {}), ...(bunCache ? { bunCache } : {}), ...(installSlots ? { installSlots } : {}), ...(memoryLimit ? { memoryLimit } : {}), ...(options.cpu ? { cpu: options.cpu } : {}), deadlineSeconds,
|
|
665
|
+
...(options.source ? { source: options.source } : {}), ...(hostMirror ? { hostMirror } : {}), ...(bunCache ? { bunCache } : {}), ...(installSlots ? { installSlots } : {}), ...(memoryLimit ? { memoryLimit } : {}), ...(options.cpu ? { cpu: options.cpu } : {}), ...(options.tmpfsSizeLimit ? { tmpfsSizeLimit: options.tmpfsSizeLimit } : {}), deadlineSeconds,
|
|
577
666
|
...(options.runId ? { runId: options.runId } : {}),
|
|
667
|
+
...(hostDirsInit ? { hostDirsInit: true } : {}),
|
|
578
668
|
});
|
|
579
669
|
kubectl(['-n', namespace, 'delete', 'job', '-l', own, '--ignore-not-found']);
|
|
670
|
+
// A wall deadline can elapse inside the synchronous apply; cleanup by this launch's name then remains safe.
|
|
671
|
+
jobApplied = true;
|
|
580
672
|
const applied = kubectl(['apply', '-f', '-'], JSON.stringify(manifest));
|
|
581
673
|
if (applied.status !== 0) {
|
|
582
674
|
cleanupSecret();
|
|
@@ -587,6 +679,7 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
587
679
|
let markerRc: number | null = null;
|
|
588
680
|
const appliedAt = Date.now();
|
|
589
681
|
for (;;) {
|
|
682
|
+
ensureLive();
|
|
590
683
|
const got = kubectl(['-n', namespace, 'get', 'job', name, '-o', 'jsonpath={.status.conditions[*].type}']);
|
|
591
684
|
const finished = jobFinished(got.stdout);
|
|
592
685
|
if (finished) { state = finished; break; }
|
|
@@ -609,9 +702,24 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
609
702
|
throw new Error(`pod command: Job 상태를 ${Math.round(options.statusUnreadableMs / 1000)}초 동안 못 읽었다(${context}) — ${(got.stderr ?? '').trim().split('\n').pop()?.slice(0, 200) ?? ''}`);
|
|
610
703
|
}
|
|
611
704
|
} else unreadableSince = null;
|
|
612
|
-
await sleep(options.pollMs ?? 15_000);
|
|
705
|
+
await awaitPodCommandAbort(sleep(options.pollMs ?? 15_000), options.signal);
|
|
706
|
+
}
|
|
707
|
+
ensureLive();
|
|
708
|
+
let logsResult = kubectl(['-n', namespace, 'logs', `job/${name}`, '-c', 'child']);
|
|
709
|
+
// Marker path returns before the Job condition — a full-log read can hit the same transient window the tail read
|
|
710
|
+
// already survived (container log rotation · API hiccup). Retry it a little before calling the artifacts lost.
|
|
711
|
+
// A read that «succeeds» but stops before this launch's marker (empty · cut off) is incomplete too (review mf · #27842).
|
|
712
|
+
const fullLogIncomplete = (r: { status: number | null; stdout: string }) =>
|
|
713
|
+
r.status !== 0 || splitPodResultMarker(r.stdout.startsWith('\n') ? r.stdout : `\n${r.stdout}`, launch).rc === null;
|
|
714
|
+
for (let attempt = 1; markerRc !== null && fullLogIncomplete(logsResult) && attempt <= POD_MARKER_LOG_RETRIES; attempt++) {
|
|
715
|
+
log('pod.command-job', 'result-marker-log-retry', { job: name, attempt, ...(logsResult.status !== 0 ? { error: (logsResult.stderr ?? '').trim().slice(0, 200) } : { reason: 'marker-missing-in-full-log' }) });
|
|
716
|
+
await sleep(options.pollMs === undefined ? 1_000 : Math.min(options.pollMs, 1_000)); // ≤2 re-reads within ≈2s total
|
|
717
|
+
logsResult = kubectl(['-n', namespace, 'logs', `job/${name}`, '-c', 'child']);
|
|
718
|
+
}
|
|
719
|
+
// Still without this launch's marker after the retries: the artifacts are not trusted as complete (explicit failure).
|
|
720
|
+
if (markerRc !== null && logsResult.status === 0 && fullLogIncomplete(logsResult)) {
|
|
721
|
+
logsResult = { ...logsResult, status: 1, stderr: 'full log ended before this launch\'s result marker (incomplete after retries)' };
|
|
613
722
|
}
|
|
614
|
-
const logsResult = kubectl(['-n', namespace, 'logs', `job/${name}`, '-c', 'child']);
|
|
615
723
|
const logsFailed = logsResult.status !== 0;
|
|
616
724
|
const logs = logsFailed ? '' : splitPodResultMarker(logsResult.stdout, launch).logs;
|
|
617
725
|
const artifactDir = artifactRoot;
|
|
@@ -661,6 +769,12 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
661
769
|
});
|
|
662
770
|
return { exitCode, artifactsDir, job: name, image: imageRef ?? image, artifacts };
|
|
663
771
|
} catch (err) {
|
|
772
|
+
if (jobApplied && options.signal) {
|
|
773
|
+
// Opt-in bounded callers remove their own failed/Pending Job, including status-unreadable exits.
|
|
774
|
+
// On an unreachable API this is best effort; the local lease is always released in finally.
|
|
775
|
+
try { kubectlRaw(['-n', namespace, 'delete', 'job', name, '--ignore-not-found', '--wait=false']); }
|
|
776
|
+
catch { /* preserve the cancellation reason */ }
|
|
777
|
+
}
|
|
664
778
|
cleanupSecret();
|
|
665
779
|
throw err;
|
|
666
780
|
} finally {
|
|
@@ -6,7 +6,15 @@ export const STOP_CLASS_NO_LAUNCH = 'no-launch' as const;
|
|
|
6
6
|
const CHILD_RESULT_KINDS = new Set(['self', 'external']);
|
|
7
7
|
|
|
8
8
|
/** The dev child's terminal line nests the stage: {ok, kind, result:{stage, ok, node, outcome, …}}. Other JSON rows are not results. */
|
|
9
|
-
export function nestedPodResult(row: Record<string, unknown>): {
|
|
9
|
+
export function nestedPodResult(row: Record<string, unknown>): {
|
|
10
|
+
stage: string;
|
|
11
|
+
ok: boolean;
|
|
12
|
+
error?: string;
|
|
13
|
+
reasonCode?: string;
|
|
14
|
+
checkName?: string;
|
|
15
|
+
targetPath?: string;
|
|
16
|
+
preflightChecks?: PreflightCheck[];
|
|
17
|
+
} | null {
|
|
10
18
|
if (typeof row.kind !== 'string' || !CHILD_RESULT_KINDS.has(row.kind) || typeof row.ok !== 'boolean') return null;
|
|
11
19
|
if (!row.result || typeof row.result !== 'object' || Array.isArray(row.result)) return null;
|
|
12
20
|
const result = row.result as Record<string, unknown>;
|
|
@@ -18,28 +26,72 @@ export function nestedPodResult(row: Record<string, unknown>): { stage: string;
|
|
|
18
26
|
? (classification as Record<string, unknown>).classification : undefined;
|
|
19
27
|
const reason = [result.node, result.outcome].filter((part): part is string => typeof part === 'string' && part.length > 0).join(' ');
|
|
20
28
|
const error = [reason || (typeof result.error === 'string' ? result.error : ''), typeof detail === 'string' && detail ? detail : ''].filter(Boolean).join(' · ');
|
|
21
|
-
|
|
29
|
+
// PREFLIGHT-RESULT-LINE: a nested preflight rejection carries its blockers under result.blockers — the same ledger fields as the flat row.
|
|
30
|
+
const blockers = result.stage === 'preflight-blocked' ? preflightBlockerText(result.blockers)
|
|
31
|
+
: { error: '', preflightChecks: [] as PreflightCheck[] };
|
|
32
|
+
return {
|
|
33
|
+
stage: result.stage,
|
|
34
|
+
ok: false,
|
|
35
|
+
...(error || blockers.error ? { error: error || blockers.error } : {}),
|
|
36
|
+
...(blockers.preflightChecks.length === 1 ? blockers.preflightChecks[0] : {}),
|
|
37
|
+
...(blockers.preflightChecks.length > 1 ? { preflightChecks: blockers.preflightChecks } : {}),
|
|
38
|
+
};
|
|
22
39
|
}
|
|
23
40
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
function ledgerString(value: unknown): string {
|
|
42
|
+
return typeof value === 'string' && value.trim().length > 0 ? value : '';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
type PreflightCheck = { reasonCode: string; checkName: string; targetPath?: string };
|
|
46
|
+
|
|
47
|
+
/** Keep each structured check paired with its own path; legacy blockers retain their name/detail diagnostic. */
|
|
48
|
+
function preflightBlockerText(blockers: unknown): { error: string; preflightChecks: PreflightCheck[] } {
|
|
49
|
+
if (!Array.isArray(blockers)) return { error: '', preflightChecks: [] };
|
|
50
|
+
const errors: string[] = [];
|
|
51
|
+
const preflightChecks: PreflightCheck[] = [];
|
|
52
|
+
for (const blocker of blockers) {
|
|
53
|
+
if (!blocker || typeof blocker !== 'object' || Array.isArray(blocker)) continue;
|
|
54
|
+
const record = blocker as Record<string, unknown>;
|
|
55
|
+
const reasonCode = ledgerString(record.reasonCode);
|
|
56
|
+
const checkName = ledgerString(record.checkName);
|
|
57
|
+
if (reasonCode && checkName) {
|
|
58
|
+
const targetPath = ledgerString(record.targetPath);
|
|
59
|
+
preflightChecks.push({ reasonCode, checkName, ...(targetPath ? { targetPath } : {}) });
|
|
60
|
+
errors.push(`${reasonCode} · ${checkName}`);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const parts = [record.name, record.detail]
|
|
64
|
+
.filter((part): part is string => typeof part === 'string' && part.trim().length > 0)
|
|
65
|
+
.map((part) => part.trim().replace(/\s+/gu, ' '));
|
|
66
|
+
if (parts.length) errors.push(parts.join(' — '));
|
|
67
|
+
}
|
|
68
|
+
return { error: errors.join(' · '), preflightChecks };
|
|
33
69
|
}
|
|
34
70
|
|
|
35
71
|
/** A child terminal row: the legacy flat form {stage, ok, error?} (no kind, or a child kind) or the nested dev result. Any other kind is not a result. */
|
|
36
|
-
export function podTerminalRow(row: Record<string, unknown>): {
|
|
72
|
+
export function podTerminalRow(row: Record<string, unknown>): {
|
|
73
|
+
stage: string;
|
|
74
|
+
ok: boolean;
|
|
75
|
+
error?: string;
|
|
76
|
+
reasonCode?: string;
|
|
77
|
+
checkName?: string;
|
|
78
|
+
targetPath?: string;
|
|
79
|
+
preflightChecks?: PreflightCheck[];
|
|
80
|
+
} | null {
|
|
37
81
|
if (typeof row.kind === 'string' && !CHILD_RESULT_KINDS.has(row.kind)) return null;
|
|
38
82
|
if (typeof row.stage === 'string' && typeof row.ok === 'boolean') {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
83
|
+
// PREFLIGHT-RESULT-LINE: preserve structured blockers even when an explicit error supplies the human-readable reason.
|
|
84
|
+
if (row.ok === false && row.stage === 'preflight-blocked') {
|
|
85
|
+
const blockers = preflightBlockerText(row.blockers);
|
|
86
|
+
return {
|
|
87
|
+
stage: row.stage,
|
|
88
|
+
ok: row.ok,
|
|
89
|
+
...(typeof row.error === 'string' ? { error: row.error } : blockers.error ? { error: blockers.error } : {}),
|
|
90
|
+
...(blockers.preflightChecks.length === 1 ? blockers.preflightChecks[0] : {}),
|
|
91
|
+
...(blockers.preflightChecks.length > 1 ? { preflightChecks: blockers.preflightChecks } : {}),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return { stage: row.stage, ok: row.ok, ...(typeof row.error === 'string' ? { error: row.error } : {}) };
|
|
43
95
|
}
|
|
44
96
|
return nestedPodResult(row);
|
|
45
97
|
}
|
|
@@ -64,9 +116,21 @@ export function classifyPodExit(input: {
|
|
|
64
116
|
jobReason?: string | null;
|
|
65
117
|
logs: string;
|
|
66
118
|
result?: Record<string, unknown> | null;
|
|
67
|
-
}): {
|
|
119
|
+
}): {
|
|
120
|
+
class: PodExitClass;
|
|
121
|
+
errorCode: string | null;
|
|
122
|
+
containerReason: string | null;
|
|
123
|
+
exitCode: number | null;
|
|
124
|
+
jobReason: string | null;
|
|
125
|
+
tail: string[];
|
|
126
|
+
reasonCode?: string;
|
|
127
|
+
checkName?: string;
|
|
128
|
+
targetPath?: string;
|
|
129
|
+
preflightChecks?: PreflightCheck[];
|
|
130
|
+
noResultLine?: true;
|
|
131
|
+
} {
|
|
68
132
|
const logLines = input.logs.split(/\r\n|\n|\r/u).map((line) => line.trim()).filter(Boolean);
|
|
69
|
-
let terminalResult:
|
|
133
|
+
let terminalResult: ReturnType<typeof podTerminalRow> = null;
|
|
70
134
|
for (const line of logLines) {
|
|
71
135
|
if (!line.startsWith('{')) continue;
|
|
72
136
|
let parsed: unknown;
|
|
@@ -74,8 +138,8 @@ export function classifyPodExit(input: {
|
|
|
74
138
|
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) continue;
|
|
75
139
|
terminalResult = podTerminalRow(parsed as Record<string, unknown>) ?? terminalResult;
|
|
76
140
|
}
|
|
77
|
-
if (!terminalResult && input.result) terminalResult = podTerminalRow(input.result);
|
|
78
141
|
const hasResultLine = terminalResult !== null;
|
|
142
|
+
if (!terminalResult && input.result) terminalResult = podTerminalRow(input.result);
|
|
79
143
|
const askReprompt = logLines.some((line) =>
|
|
80
144
|
/^\[ask\](?!\s+\d+\)\s).*(?:implementation[_ -]?target|reprompt|re-prompt|되묻)/iu.test(line));
|
|
81
145
|
// 파싱되는 JSON 줄(진행·결과 행)은 오류 «줄»로 세지 않는다 — tail 과 같은 기준.
|
|
@@ -116,6 +180,11 @@ export function classifyPodExit(input: {
|
|
|
116
180
|
exitCode: input.containerExitCode ?? null,
|
|
117
181
|
jobReason: input.jobReason ?? null,
|
|
118
182
|
tail,
|
|
183
|
+
...(terminalResult?.reasonCode ? { reasonCode: terminalResult.reasonCode } : {}),
|
|
184
|
+
...(terminalResult?.checkName ? { checkName: terminalResult.checkName } : {}),
|
|
185
|
+
...(terminalResult?.targetPath ? { targetPath: terminalResult.targetPath } : {}),
|
|
186
|
+
...(terminalResult?.preflightChecks ? { preflightChecks: terminalResult.preflightChecks } : {}),
|
|
187
|
+
...(!hasResultLine ? { noResultLine: true as const } : {}),
|
|
119
188
|
};
|
|
120
189
|
}
|
|
121
190
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// ⛔ 기본 꺼짐(opt-in): 옵션 → env `ELANOUS_POD_HOST_ACP_REVIEW` → config `llm.podHostAcpReview` 순.
|
|
12
12
|
// 📌 남은 조각(②-b): 이 문이 켜진 런에서 Pod 안 api 리뷰를 «끄는» 것은 Pod 이미지 쪽 변경이라 따로 간다.
|
|
13
13
|
import { spawnSync } from 'node:child_process';
|
|
14
|
+
import { SPAWN_SYNC_MAX_BUFFER } from '../../util/spawn-sync-output.js';
|
|
14
15
|
import { debug } from '../../debug/log.js';
|
|
15
16
|
import type { ReviewResult } from '../../agent-substrate/pr-reviewer.js';
|
|
16
17
|
import type { SubscriptionReviewerSpec } from '../../user-config.js';
|
|
@@ -57,7 +58,7 @@ export interface PodHostAcpReviewDeps {
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
function defaultReadPr(prNumber: number, repoRoot: string): { headRefOid: string; title: string; body: string; diff: string } | undefined {
|
|
60
|
-
const view = spawnSync('gh', ['pr', 'view', String(prNumber), '--json', 'headRefOid,title,body'], { cwd: repoRoot, encoding: 'utf8', timeout: 60_000 });
|
|
61
|
+
const view = spawnSync('gh', ['pr', 'view', String(prNumber), '--json', 'headRefOid,title,body'], { cwd: repoRoot, encoding: 'utf8', timeout: 60_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
|
|
61
62
|
if (view.status !== 0) return undefined;
|
|
62
63
|
const diff = spawnSync('gh', ['pr', 'diff', String(prNumber)], { cwd: repoRoot, encoding: 'utf8', timeout: 120_000, maxBuffer: 64 * 1024 * 1024 });
|
|
63
64
|
if (diff.status !== 0) return undefined;
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* 이미지는 표준판(elanous-harness)만 — 이 발사 경로는 lite 를 쓰지 않는다.
|
|
15
15
|
*/
|
|
16
16
|
import { spawnSync } from 'node:child_process';
|
|
17
|
+
import { SPAWN_SYNC_MAX_BUFFER } from '../../util/spawn-sync-output.js';
|
|
17
18
|
import { debug } from '../../debug/log.js';
|
|
18
19
|
import { memberHasRegistry, registryImageRef, type RemoteRun } from './pod-pool.js';
|
|
19
20
|
|
|
@@ -71,7 +72,7 @@ export function memberPinRegistry(member: PodImageMember, source: Extract<PodIma
|
|
|
71
72
|
|
|
72
73
|
/** 실제 조회 — 원격은 pod-pool 의 SSH 판정, 로컬은 이 기계의 docker/curl 로 조회한다. */
|
|
73
74
|
export function podPoolImageLookup(run?: RemoteRun, localRun: (cmd: string, args: readonly string[]) => { status: number | null; stdout: string } = (cmd, args) => {
|
|
74
|
-
const r = spawnSync(cmd, [...args], { encoding: 'utf8', timeout: 10_000 });
|
|
75
|
+
const r = spawnSync(cmd, [...args], { encoding: 'utf8', timeout: 10_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
|
|
75
76
|
return { status: r.status, stdout: r.stdout ?? '' };
|
|
76
77
|
}): {
|
|
77
78
|
hasRegistry: (member: PodImageMember & { context: string }, registry: string) => boolean;
|