elanous 0.2.28 → 0.2.31
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/{y1ltt7oCZxVpC6zVPhZ2O → LSXfY0u9QtfDbejY0Ukf_}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{ab4d57c2.e90bc2cb31949045.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/{5492-e05e26a033ba80d2.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/1654.32de4b324981a188.js +23 -0
- package/apps/pwa/out/_next/static/chunks/1834-50625904996a8fa8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
- package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +41 -0
- package/apps/pwa/out/_next/static/chunks/2001.6c7e0fd02190886c.js +1 -0
- 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/{8578.dff22d988cc2b106.js → 2213.2ccbada92c33ea0f.js} +3 -3
- 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/{5081.a240b63fad28663a.js → 2871.0bca6137343b3f76.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2940-619bfd8ef337c611.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2846.d6a433b8663819a5.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/{f4dfbfc0.a69fb12f854882aa.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/3541-ce3a5424ed5ad7f1.js +1 -0
- 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/{3143.257997a5f1ed79df.js → 3902.e1e71aaac850a045.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{16e57f67.3ea19e893461e611.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1146.80d15ea7c6e6ee95.js → 4111.2bfedbb233ad206b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1516.83dd2c1b86b4e507.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/{9938.b23e4d4dfa0114cd.js → 4999.c064a4000c2a9e94.js} +2 -2
- 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/{1157.f08bf2b70915e176.js → 5304.04d24756f242a094.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{7752.5cbdd0b433c54af9.js → 5307.60f2209e809bd627.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9917-9e26abc5f7772735.js → 5458-16cd7a2b51b74c8c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6196.34d6b229079e9e28.js → 5525.86debf231e181813.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4593.10f5b9bd702d4a6c.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/{7483.ba01c6c209b81bba.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/{9974.e77b4ff4884557b3.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/{3309.364573ceedbdfd5f.js → 6323.8672b4817a306928.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{94.4cfed21c0b781a06.js → 6433.fc573af22bbc9ab7.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{949.1e7d45ccb71580aa.js → 6517.4147878ac06d584d.js} +2 -2
- 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/{2528.3868070ef1be69f9.js → 6767.ea607cf0c20a25af.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -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/{1743.563d3168e95825ef.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/{5408.377c8c543635b81f.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/{65ebff95.081daeff622d238e.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2697.76ca2ac3efef6f3b.js → 8018.a32663f04a6fc5f9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8097-92f87bd108322f66.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/9138.b6e80031afb1d973.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4204.a409ab6250c0f6a8.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/{5785-ea8d2c633b6688e3.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/9398-6aed28f0a96d0d6f.js +1 -0
- 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/997ce8a5-2ad501927003b41b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9311.24c8f5ea793253dd.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-bf3634a117322df7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-3535a4a69f1fafaa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-b9f51447f757fbf2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-fa46d4588e8442c2.js → page-2ebb8fd59b9461f9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-a2fc4e49a4fa4ba8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-5a503541353e60a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-6025101384e361a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-f4b630cc8b5273cd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-a645f00a06483e9a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-61ac22cbab1ee4ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e9bab7413b028b28.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c992eafe028b642e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-e547e6ce55f1fb33.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-d27e1b9850fd54bf.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-805ac2e137b7a121.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-0fec29c7ba01894b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-339a07410cd6f36b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/{page-ced0bcfc6542b3fc.js → page-349f2752d8cd37ad.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-d5c6dcf31c25cecc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-2fd93ed8c9f16580.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-9b564dbff0fefc35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-62f4475d3c38fb9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-814ba51385225776.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-397d479626e5a459.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-af1bba4e3251b728.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ad3be5e7d3fdce9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-f219ccdbc0bf27df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4da93ad35d4a8d28.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-456666766e5ce6fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-7404e377e8adb8c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-14456240ed2a36ad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-3a658d5fa6d16a25.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-0157de6e85f8bb6b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-cb249e81ed339318.js → page-0a07363b130182a1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-841d73d4ac44ed49.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6f43a3d1146e6377.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-521ee23ac8c0abfa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-a9992ee285efaa83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-3d48e85fa89ec04f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-d2ced71132fac9b2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-f08358bdf251adb9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-233c71cd5f68f0d7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-70151d78de2f375e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-dcac33a3e2cb72c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-149dc1caba411bb9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0448145ccd5c45c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-9cb0c444903da65d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-17e504c396e0e389.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6def8a8e.c81f9ca41028eccf.js → b313b242.cb1265eea908db61.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{e87d89b9.2e71c0ae475d28a1.js → e5012ffe.f727e23c231f4342.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{e117f801.e92bf10242653497.js → ebc7d829.264a0bcb6c750b50.js} +1 -1
- 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/{72becfd42807b50d.css → 3f5fc6f96e2cf7b2.css} +1 -1
- 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 +23 -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/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 +15 -7
- package/graphs/units/recipes.yaml +3 -0
- package/graphs/units/release-gate-recheck.yaml +15 -0
- package/package.json +2 -1
- package/plugins/agent-team/agents/research.md +1 -0
- package/scripts/check-native-tool-wiring.ts +3 -2
- package/scripts/ci-android-unit-tests.ts +16 -0
- package/scripts/ci-typecheck-changed.ts +40 -11
- package/scripts/coord-channel-watch.sh +45 -19
- package/scripts/coord-role-pack.ts +222 -0
- 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/lib/morning-report-options.ts +41 -0
- package/scripts/measure-goal-grounding-corpus.ts +2 -1
- package/scripts/pr-land-extra-remote-gates.ts +49 -0
- package/scripts/ratchets/test-interference-patterns.allowlist.txt +257 -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-batch-safe.ts +23 -0
- package/scripts/release-loop/gate-closure.ts +12 -8
- package/scripts/release-loop/gate-diff.ts +1 -1
- package/scripts/release-loop/gate-history.ts +422 -0
- package/scripts/release-loop/gate-host-mirror.ts +66 -0
- package/scripts/release-loop/gate-node.ts +806 -94
- 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-triage-node.ts +190 -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/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 +51 -0
- package/scripts/release-loop/tui-node-checks.ts +23 -0
- package/scripts/release-loop/tui-sim-node.ts +3 -2
- package/scripts/release-loop/unattended-release.ts +16 -0
- package/scripts/release-loop/version-node.ts +62 -4
- package/scripts/test-deterministic.ts +46 -73
- 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/scripts/usage-rollup.ts +11 -3
- package/src/acp/client.ts +4 -1
- package/src/acp/core-turn-bridge.ts +145 -24
- package/src/acp/elanous-extensions.ts +2 -0
- package/src/acp/server.ts +2 -0
- package/src/ad-pipeline/run.ts +4 -2
- package/src/agent/ref-grounding.ts +18 -0
- package/src/agent/runner.ts +169 -3
- package/src/agent/subagent-callable.ts +3 -2
- 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 +41 -21
- package/src/agent-substrate/self-review-cli.ts +30 -4
- package/src/autopilot/pr-manager.ts +62 -7
- package/src/briefing/brief-items.ts +24 -22
- package/src/budget/pty-usage-reemit.ts +7 -0
- package/src/budget/run-usage-rollup.ts +9 -0
- package/src/budget/usage-daily-store.ts +98 -0
- package/src/capture/tui-self-report.ts +37 -4
- package/src/chat/chat-cli.ts +10 -2
- package/src/chat/index.ts +107 -20
- package/src/chat/input-control-key.ts +5 -3
- package/src/chat/pickers/modal-runtime.ts +1 -0
- package/src/chat/pickers/modals.ts +3 -1
- package/src/chat/tool-interrupt-behavior.ts +38 -0
- package/src/chat/tool-render/dispatch.ts +5 -1
- package/src/chat/turn-typeahead.ts +191 -29
- package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
- package/src/cli/agent-cli.ts +41 -13
- package/src/cli/config-audit.ts +123 -0
- package/src/cli/dashboard-name-flag.ts +48 -0
- package/src/cli/decisions-cli.ts +80 -6
- package/src/cli/doctor-cli.ts +80 -0
- package/src/cli/log-event-names.ts +19 -0
- package/src/cli/mcp-login.ts +21 -5
- package/src/cli/msg-cli.ts +133 -2
- package/src/cli/pr-cli.ts +546 -112
- package/src/cli/pr-land-heavy-remote.ts +233 -0
- package/src/cli/pr-land-overlap-evidence.ts +167 -14
- package/src/cli/pr-land-pod-shadow-job.ts +83 -0
- package/src/cli/pr-land-pod-shadow.ts +16 -3
- package/src/cli/pr-land-virtual-rebase.ts +108 -0
- package/src/cli/pty-takeover-cli.ts +125 -16
- package/src/cli/release-cli.ts +122 -14
- package/src/cli/remote-resolve.ts +2 -1
- package/src/cli/seat-cli.ts +164 -19
- package/src/cli/self-update.ts +5 -2
- package/src/cli/tasks-cli.ts +105 -21
- package/src/cli/usage-cli.ts +146 -12
- package/src/cli/usage-daily-cli.ts +84 -0
- package/src/context-bus/context-first.ts +13 -0
- package/src/context-bus/context-now.ts +95 -7
- package/src/context-bus/ops-events.ts +75 -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/auth-rejected-notice.ts +41 -0
- package/src/core-turn/run-core-turn.ts +14 -2
- package/src/core-turn/run-goal-loop.ts +239 -4
- package/src/core-turn/seat-turn-cap.ts +79 -0
- package/src/core-turn/short-question.ts +78 -13
- package/src/core-turn/types.ts +10 -0
- package/src/dashboard/acp-active-model.ts +40 -0
- package/src/dashboard/acp-boot.ts +3 -0
- package/src/dashboard/auto-compact-runtime.ts +2 -0
- package/src/dashboard/boot-banner.ts +80 -0
- package/src/dashboard/dashboard-status-lines.ts +11 -0
- package/src/dashboard/detail-viewer-runtime.ts +15 -2
- package/src/dashboard/event-loop-stall-monitor.ts +4 -0
- package/src/dashboard/goal-loop-thinking.ts +16 -0
- package/src/dashboard/hitl-boot.ts +9 -4
- package/src/dashboard/index.ts +448 -998
- package/src/dashboard/input/chat-main-entry-runtime.ts +2 -0
- package/src/dashboard/input/chat-main-log-actions.ts +4 -0
- package/src/dashboard/input/chat-main-log-command.ts +12 -1
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +176 -4
- package/src/dashboard/input/chat-main-session.ts +14 -3
- package/src/dashboard/input/chat-main-slash-command.ts +7 -0
- package/src/dashboard/input/chat-main-turn.ts +14 -4
- package/src/dashboard/input/compact-prepass-recovery.ts +130 -0
- package/src/dashboard/input/dashboard-chord-actions.ts +10 -1
- package/src/dashboard/input/dashboard-chord-runtime.ts +2 -0
- package/src/dashboard/input/external-input-host.ts +71 -0
- package/src/dashboard/input/internal-turn.ts +261 -0
- package/src/dashboard/input/log-fold-binding.ts +18 -0
- package/src/dashboard/input/mouse-wiring.ts +17 -4
- package/src/dashboard/input/seat-autowake.ts +318 -0
- package/src/dashboard/input/turn-steer-bridge.ts +164 -0
- package/src/dashboard/log-click-runtime.ts +5 -3
- package/src/dashboard/loop-scheduler.ts +72 -0
- package/src/dashboard/running-build-status.ts +74 -0
- package/src/dashboard/seat-boot-preamble.ts +131 -0
- package/src/dashboard/seat-local-instructions.ts +305 -0
- package/src/dashboard/skill-runtime.ts +2 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +220 -1203
- package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
- package/src/dashboard/slash-runtime/index.ts +13 -0
- package/src/dashboard/slash-runtime/model-choices.ts +35 -0
- package/src/dashboard/term-slash-runtime.ts +15 -0
- package/src/dashboard/turn-busy-teardown.ts +50 -0
- package/src/dashboard/turn-preamble.ts +30 -2
- package/src/dashboard/turn-session-layers.ts +176 -0
- package/src/dashboard/turn-stream-formatter.ts +14 -6
- package/src/dashboard/turn-stream-presentation-applier.ts +8 -0
- package/src/decisions/decision-ledger.ts +45 -4
- package/src/discord-self-message.ts +4 -4
- package/src/domains/release-tool.ts +26 -10
- package/src/domains/surface-events.ts +4 -1
- package/src/domains/watch-default-scheduler.ts +8 -9
- package/src/field-note/transcribe.ts +17 -0
- package/src/fold-stack.ts +24 -1
- package/src/git-fs/dirty.ts +32 -4
- package/src/git-fs/index.ts +43 -1
- 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 +2 -0
- package/src/grok/credential.ts +26 -0
- package/src/harness/harness-clean.ts +2 -1
- package/src/harness/harness-cli-command.ts +52 -5
- package/src/harness/harness-gc.ts +34 -6
- package/src/harness/harness-incidents.ts +57 -20
- package/src/harness/harness-pod-dispatch.ts +87 -10
- package/src/harness/harness-queue.ts +53 -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 +166 -26
- package/src/input/external-input-queue.ts +251 -0
- package/src/intake-plane/slash.ts +14 -3
- package/src/interactive-terminal-modal.ts +13 -0
- package/src/keybindings.ts +4 -1
- package/src/llm/route-decision.ts +25 -0
- package/src/llm/tool-loop-steered-rejection.ts +33 -0
- package/src/llm-stream-retry-display.ts +59 -0
- package/src/llm.ts +391 -74
- package/src/log-entry.ts +3 -3
- package/src/log-pane/search.ts +29 -4
- package/src/loops/agent-reply.ts +256 -0
- package/src/loops/budget.ts +37 -7
- package/src/loops/consensus.ts +348 -0
- package/src/loops/loop-cli.ts +3 -2
- package/src/loops/msg-address.ts +57 -0
- package/src/loops/msg-wake.ts +484 -0
- package/src/loops/observe.ts +19 -3
- package/src/loops/orchestrator/inbox.ts +60 -3
- package/src/loops/orchestrator/tick.ts +80 -6
- package/src/loops/orchestrator/traffic.ts +64 -1
- package/src/loops/registry.ts +72 -4
- package/src/market/signed-index.ts +14 -0
- package/src/mcp/mcp-oauth.ts +54 -5
- package/src/memory.ts +20 -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/native-tool-catalog.ts +125 -0
- package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
- package/src/nexus/api/http-server.ts +59 -15
- package/src/nexus/api/loop-resources.ts +19 -3
- package/src/nexus/api/ops-api.ts +13 -0
- package/src/nexus/api/project-autopsy.ts +127 -0
- package/src/nexus/api/terminals.ts +3 -0
- package/src/nexus/api/workflow-approvals.ts +2 -0
- package/src/nexus/daemon-thin-inventory.md +37 -0
- package/src/nexus/index.ts +70 -0
- package/src/nexus/onboarding/first-boot-wizard.ts +56 -2
- package/src/nexus/state/state.ts +1 -0
- package/src/oauth/codex-account-store.ts +15 -3
- package/src/oauth/codex-billing-route.ts +31 -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-collect.ts +19 -2
- package/src/ops/resources.ts +82 -0
- package/src/panes/log-pane.ts +67 -8
- package/src/persona/presets.ts +44 -0
- package/src/plugins/maker/connector-maker.ts +41 -0
- package/src/plugins/maker/skill-maker.ts +42 -0
- package/src/plugins/maker/wizard-generate.ts +6 -4
- package/src/pr-tool/census.ts +288 -0
- package/src/preview/terminal.ts +14 -1
- package/src/prompt-cache/types.ts +2 -0
- package/src/prompt-enhance/enhance.ts +24 -8
- package/src/prompt-library/chat-conciseness.ts +13 -0
- package/src/prompt-library/universal-preamble.ts +283 -61
- package/src/pty-shell/pty-control-ipc.ts +4 -1
- package/src/pty-shell/pty-manifest.ts +77 -5
- package/src/pty-shell/registry.ts +19 -2
- package/src/pty-shell/tui-run-state.ts +253 -0
- 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 +32 -4
- 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/render.ts +5 -1
- 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/seat-report.ts +42 -2
- package/src/seat-loop/traffic-signal.ts +3 -0
- package/src/self-dev/ask-launch-flow.ts +24 -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 +24 -9
- 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 +300 -24
- package/src/self-dev/run-types.ts +20 -0
- package/src/self-dev/shard-aggregate.ts +15 -2
- package/src/self-dev/shard-plan.ts +47 -0
- package/src/self-dev/shard-run.ts +135 -12
- package/src/self-dev/spawn-lane-files.ts +19 -0
- package/src/self-health/signatures.ts +132 -0
- package/src/self-implement/app-api-budget.ts +51 -11
- package/src/self-implement/config-gate.ts +2 -1
- package/src/self-implement/doctor-visit.ts +118 -0
- package/src/self-implement/expose-gate.ts +2 -1
- package/src/self-implement/gate-artifacts.ts +405 -0
- package/src/self-implement/gate-cli.ts +212 -18
- package/src/self-implement/gate-remote.ts +110 -25
- package/src/self-implement/gate-scenario.ts +85 -0
- package/src/self-implement/goal-author-decompose.ts +80 -16
- package/src/self-implement/goal-author.ts +270 -76
- package/src/self-implement/goal-authoring-grounding.ts +1 -1
- package/src/self-implement/goal-file-name.ts +65 -0
- package/src/self-implement/graph-authority.ts +38 -6
- package/src/self-implement/graph-overlay-condition.ts +92 -1
- package/src/self-implement/ground-goal.ts +2 -1
- package/src/self-implement/heal-triage.ts +79 -0
- package/src/self-implement/host-regate.ts +74 -2
- package/src/self-implement/orchestrator.ts +14 -123
- package/src/self-implement/pr-title.ts +123 -0
- package/src/self-implement/review-mustfix-class.ts +115 -0
- package/src/self-implement/run-checkpoint.ts +235 -0
- package/src/self-implement/run-ledger.ts +266 -17
- package/src/self-implement/run-stop.ts +4 -3
- package/src/self-implement/run-ttl.ts +28 -4
- package/src/self-implement/running-runs.ts +10 -6
- package/src/self-implement/seams.ts +2 -0
- package/src/self-implement/self-implement-runtime.ts +32 -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 +81 -11
- package/src/session/session-start.ts +224 -0
- package/src/session-runtime/index.ts +7 -1
- package/src/session-runtime/parallel-dispatch.ts +22 -5
- package/src/skills/tools/dev-harness.ts +6 -4
- package/src/skills/tools/ops-ledger.ts +707 -0
- package/src/skills/tools/persistent-grounding.ts +47 -7
- package/src/skills/tools/shell.ts +117 -1
- package/src/status/bar.ts +32 -2
- package/src/status/status-provider-info.ts +58 -0
- package/src/steward/resync-tick.ts +114 -23
- package/src/steward/ta-repair-event-collect.ts +158 -0
- 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 +93 -13
- package/src/task-agent/remote-rejudge-bind.ts +62 -13
- package/src/task-agent/repair-cycle.ts +58 -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 +158 -5
- package/src/task-agent/train-landing.ts +77 -0
- package/src/task-agent/work-order.ts +104 -0
- package/src/task-orchestrator/surfaces/kubectl-transient-retry.ts +51 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +138 -22
- 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 +122 -15
- package/src/task-orchestrator/surfaces/pod-lease.ts +20 -6
- package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
- package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +103 -0
- package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
- package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +63 -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-protocol.ts +153 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +208 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +237 -46
- package/src/telegram.ts +2 -4
- package/src/terminal/session-registry.ts +6 -0
- package/src/thinking-line.ts +12 -3
- package/src/tool-runtime/index.ts +4 -0
- package/src/tool-runtime/ops-ledger-runtimes.ts +84 -0
- package/src/tool-runtime/ref-consult-runtime.ts +17 -2
- package/src/tool-runtime/run-shell-runtime.ts +4 -1
- package/src/tool-runtime/self-cognition-runtimes.ts +5 -1
- package/src/tui/input/pickers.ts +732 -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 +53 -0
- package/src/user-config/gemini-server-tools.ts +9 -0
- package/src/user-config.ts +106 -21
- 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/fake-llm.ts +29 -0
- package/src/ux-sim/headless-tui.ts +72 -0
- package/src/ux-sim/in-process-cli.ts +176 -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/1027.a0f04663d24c2779.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +0 -1
- package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +0 -36
- package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1454-29d1d773d5996a49.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +0 -27
- package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +0 -1
- package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +0 -32
- package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3259-86f3be56e43eaf6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +0 -287
- package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4084.15ecaf4240bd9e77.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +0 -8
- package/apps/pwa/out/_next/static/chunks/4565-67e4c620597965c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +0 -104
- package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +0 -149
- package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +0 -1
- package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/599-56f2c0a5cc4a7295.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +0 -23
- package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +0 -77
- package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +0 -64
- package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +0 -2
- package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +0 -62
- package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8085-1e5fce59500a2cc2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +0 -226
- package/apps/pwa/out/_next/static/chunks/83a80514-b897b64df43ce108.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +0 -93
- package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +0 -24
- package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +0 -115
- package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +0 -41
- package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +0 -74
- package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +0 -94
- package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/973cbf1b.3bbcf2b41548eca7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-5ab1e47978577c5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-24453f6a302816b4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-6c131d30bb1cf871.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-dc0772b11861af51.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-66ad46ed0279feb9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-5159dc8752c6cd29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-c5a2478861c08b87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-f722a9dec084e08b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-256ffd365d32e100.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e0de78ae7b99f01c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-cfbdc44b708d9801.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-4c741eb760f2f77c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-e9ba98f5f1440a21.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-dafc901bb1b72b5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-2f6f303fa114ec24.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-1634081c5272006c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-bb1f05cd51c38944.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-646b50f63b6fe732.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-db069b48a59c8c00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-f736324afa2117c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-6f131b51193a36f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-435f5e2faf02bc01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-497e0eedf20e7890.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-a8d28fdf995e16ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-8966452228753c5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fd5d18656cb432b6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-5663779cb1a37609.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-66a67eb19ebd976b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-3b492aa78cf3c4a6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c71267e7681da982.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-a21d1e1797172692.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-781cfc5114e097da.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-478157214db6a023.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-86141f12cf090b7f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-7256c73bb1c36751.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-5c738ca7adef3de5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-0138c8091ec17224.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-cc2f24f16d85e735.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-979d318a534e92da.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-182d394f7e6e096b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-21050928a697ed7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-44b9d807005a9030.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-601fb77340e63c9a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-75d3fb5d47af0edf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-11bf9e5725a72c22.js +0 -1
- package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +0 -1
- package/src/dashboard/bench-slash-runtime.ts +0 -40
- package/src/dashboard/input/search-modal-router.ts +0 -9
- package/src/dashboard/modals/pane-key-router.ts +0 -27
- package/src/dashboard/view-slash-runtime.ts +0 -48
- /package/apps/pwa/out/_next/static/{y1ltt7oCZxVpC6zVPhZ2O → LSXfY0u9QtfDbejY0Ukf_}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
|
|
6
|
+
export interface TrainLanding {
|
|
7
|
+
componentPr: number;
|
|
8
|
+
integrationPr: number;
|
|
9
|
+
mergeSha: string;
|
|
10
|
+
train: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface TrainLedgerRow extends Omit<TrainLanding, 'mergeSha'> { mergePrefix: string }
|
|
14
|
+
|
|
15
|
+
/** HQ train ledger is advisory until the integration PR's exact merge commit is verified. */
|
|
16
|
+
export function trainLedgerPath(): string {
|
|
17
|
+
return process.env.ELANOUS_TRAIN_LEDGER_PATH || join(homedir(), 'elanous-hq', 'seat-state', 'OP', 'train-ledger.tsv');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function trainLedgerComponent(text: string, componentPr: number): TrainLedgerRow | null {
|
|
21
|
+
const lines = text.trim().split(/\r?\n/);
|
|
22
|
+
if (lines.shift() !== 'time\ttrain\tintegrationPr\tmergeSha\tcomponentPrs\tsideHost\tresult') return null;
|
|
23
|
+
let matched: TrainLedgerRow | null = null;
|
|
24
|
+
let matchedLine: string | null = null;
|
|
25
|
+
for (const line of lines) {
|
|
26
|
+
const fields = line.split('\t');
|
|
27
|
+
if (fields.length !== 7) return null;
|
|
28
|
+
const integrationPr = Number(fields[2]);
|
|
29
|
+
const mergePrefix = fields[3]?.toLowerCase() ?? '';
|
|
30
|
+
const componentPrs = (fields[4] ?? '').split(',').map(Number);
|
|
31
|
+
if (!componentPrs.every((pr) => Number.isSafeInteger(pr) && pr > 0)) return null;
|
|
32
|
+
if (!componentPrs.includes(componentPr)) continue;
|
|
33
|
+
if (fields[6] !== 'merged' || !Number.isSafeInteger(integrationPr) || integrationPr <= 0
|
|
34
|
+
|| !/^[a-f0-9]{12,40}$/.test(mergePrefix)) return null;
|
|
35
|
+
const row = { componentPr, integrationPr, mergePrefix, train: fields[1] ?? '' };
|
|
36
|
+
if (matchedLine !== null && matchedLine !== line) return null;
|
|
37
|
+
matched = row;
|
|
38
|
+
matchedLine = line;
|
|
39
|
+
}
|
|
40
|
+
return matched;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type TrainPrView = (pr: number, cwd: string) => { state: string; mergeSha?: string } | null;
|
|
44
|
+
|
|
45
|
+
export function defaultTrainPrView(pr: number, cwd: string): ReturnType<TrainPrView> {
|
|
46
|
+
const run = (env: NodeJS.ProcessEnv) => spawnSync('gh', ['pr', 'view', String(pr), '--json', 'state,mergeCommit'],
|
|
47
|
+
{ cwd, env, encoding: 'utf8', timeout: 20_000, maxBuffer: 512 * 1024 });
|
|
48
|
+
let result = run(process.env);
|
|
49
|
+
if (result.status !== 0) {
|
|
50
|
+
const noProxy = { ...process.env };
|
|
51
|
+
for (const key of ['HTTPS_PROXY', 'https_proxy', 'HTTP_PROXY', 'http_proxy']) delete noProxy[key];
|
|
52
|
+
result = run(noProxy);
|
|
53
|
+
}
|
|
54
|
+
if (result.status !== 0) return null;
|
|
55
|
+
try {
|
|
56
|
+
const parsed = JSON.parse(result.stdout) as { state?: unknown; mergeCommit?: { oid?: unknown } };
|
|
57
|
+
return typeof parsed.state === 'string' && typeof parsed.mergeCommit?.oid === 'string'
|
|
58
|
+
? { state: parsed.state, mergeSha: parsed.mergeCommit.oid } : null;
|
|
59
|
+
} catch { return null; }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function verifiedTrainLanding(componentPr: number, cwd: string, opts: {
|
|
63
|
+
ledgerText?: string;
|
|
64
|
+
readLedger?: () => string;
|
|
65
|
+
trainPrView?: TrainPrView;
|
|
66
|
+
} = {}): TrainLanding | null {
|
|
67
|
+
let ledger: string;
|
|
68
|
+
try { ledger = opts.ledgerText ?? (opts.readLedger ?? (() => readFileSync(trainLedgerPath(), 'utf8')))(); }
|
|
69
|
+
catch { return null; }
|
|
70
|
+
const row = trainLedgerComponent(ledger, componentPr);
|
|
71
|
+
if (!row) return null;
|
|
72
|
+
let view: ReturnType<TrainPrView>;
|
|
73
|
+
try { view = (opts.trainPrView ?? defaultTrainPrView)(row.integrationPr, cwd); } catch { return null; }
|
|
74
|
+
const mergeSha = view?.mergeSha?.toLowerCase();
|
|
75
|
+
return view?.state === 'MERGED' && mergeSha && /^[a-f0-9]{40}$/.test(mergeSha) && mergeSha.startsWith(row.mergePrefix)
|
|
76
|
+
? { componentPr, integrationPr: row.integrationPr, mergeSha, train: row.train } : null;
|
|
77
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TASK-AGENT 작업 지시서(work order) 스키마 — RFC-adaptive-graph-ops-2026-10-09 §9 «작업 지시서» 칸 아홉.
|
|
3
|
+
*
|
|
4
|
+
* 조율자 → TA 호출의 계약으로 칸 제목 한 줄을 대신한다. 이 첫 조각은 스키마와 검증(`parseWorkOrder`)·
|
|
5
|
+
* 골 문면 펼치기만 담는다 — 조율자가 칸·신호·선례에서 지시서를 «자동 작성»하는 일은 다음 조각이다.
|
|
6
|
+
*
|
|
7
|
+
* 칸 아홉(RFC 목록 그대로 — 칸 1·4는 여러 키로 펼친다):
|
|
8
|
+
* 1. `lifeId` · 칸 id(`cellId`) · 판(`version`) · 착지 마감(`landBy`) — cellId 만 필수다.
|
|
9
|
+
* 2. 신분 태그(`identityTags` — class·care·rights·origin·rework)
|
|
10
|
+
* 3. 우선순위(`priority` — 신호 order 순위 · 승수 등급 · 대표 표시)
|
|
11
|
+
* 4. 판정 신호(`verdictSignal` — 조건·관측·기대) ⊕ 현재 계약 한 줄(`contract`)
|
|
12
|
+
* 5. 경계(`boundary` — 대상 경로 · 건드리지 말 곳)
|
|
13
|
+
* 6. 예산(`budget` — 시간 · 모델 티어 · Pod 자리 · 재작업 상한)
|
|
14
|
+
* 7. 선행·짝 칸(`peers`)
|
|
15
|
+
* 8. 선례 묶음(`precedents` — 같은 칸 앞 생애 결말·must-fix 서명)
|
|
16
|
+
* 9. 올림 규칙(`escalation` — 무엇이면 누구에게 · 돈·보안은 대표)
|
|
17
|
+
*
|
|
18
|
+
* 빠진 칸은 거부하지 않고 «모름»(`WORK_ORDER_UNKNOWN`)으로 채워 그 키를 `unknownFields` 에 적는다
|
|
19
|
+
* (RFC: 비우면 TA 가 추측한다). 거부는 두 가지뿐 — JSON 이 깨졌거나 칸 id 가 없거나.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/** 빠진 칸을 채우는 값 — RFC «빠진 칸은 «모름»으로 적는다». */
|
|
23
|
+
export const WORK_ORDER_UNKNOWN = '모름';
|
|
24
|
+
/** 지시서 골 파일 이름 접미 — 이 이름으로 끝나는 파일만 지시서로 검증한다. */
|
|
25
|
+
export const WORK_ORDER_FILE_PATTERN = /\.work-order\.json$/i;
|
|
26
|
+
|
|
27
|
+
/** 칸 아홉 중 채울 수 있는 키(칸 id 제외) — unknownFields 는 이 순서로 적는다. */
|
|
28
|
+
export const WORK_ORDER_FIELDS = [
|
|
29
|
+
'lifeId', 'version', 'landBy',
|
|
30
|
+
'identityTags', 'priority', 'verdictSignal', 'contract',
|
|
31
|
+
'boundary', 'budget', 'peers', 'precedents', 'escalation',
|
|
32
|
+
] as const;
|
|
33
|
+
export type WorkOrderField = typeof WORK_ORDER_FIELDS[number];
|
|
34
|
+
|
|
35
|
+
/** 검증을 통과한 작업 지시서 — 모든 칸이 문자열로 채워져 있다(빠진 칸은 «모름»). */
|
|
36
|
+
export interface WorkOrder {
|
|
37
|
+
lifeId: string;
|
|
38
|
+
/** 필수 칸 — 이것만 없으면 거부한다. */
|
|
39
|
+
cellId: string;
|
|
40
|
+
version: string;
|
|
41
|
+
landBy: string;
|
|
42
|
+
identityTags: string;
|
|
43
|
+
priority: string;
|
|
44
|
+
verdictSignal: string;
|
|
45
|
+
contract: string;
|
|
46
|
+
boundary: string;
|
|
47
|
+
budget: string;
|
|
48
|
+
peers: string;
|
|
49
|
+
precedents: string;
|
|
50
|
+
escalation: string;
|
|
51
|
+
/** 입력에 없어 «모름»으로 채운 키. */
|
|
52
|
+
unknownFields: string[];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type ParseWorkOrderResult = { ok: true; order: WorkOrder } | { ok: false; reason: string };
|
|
56
|
+
|
|
57
|
+
/** 칸 하나를 사람이 읽는 문자열로 정규화한다 — 없거나 비면 «모름», 문자열이 아니면 JSON 표기로. */
|
|
58
|
+
function cellText(value: unknown): string {
|
|
59
|
+
if (value === undefined || value === null) return WORK_ORDER_UNKNOWN;
|
|
60
|
+
if (typeof value === 'string') { const carried = value.trim(); return carried || WORK_ORDER_UNKNOWN; }
|
|
61
|
+
if (typeof value === 'number' || typeof value === 'boolean') return String(value);
|
|
62
|
+
try { const carried = JSON.stringify(value); return carried === 'null' || carried === undefined ? WORK_ORDER_UNKNOWN : carried; }
|
|
63
|
+
catch { return WORK_ORDER_UNKNOWN; }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 지시서 JSON 원문을 검증한다. 깨진 JSON 은 `JSON 이 깨졌다: …`, 칸 id(문자열)가 없으면 `칸 id 가 없다`
|
|
68
|
+
* 하나로 거부하고, 그 밖의 빠진 칸은 «모름»으로 채운다(거부 아님).
|
|
69
|
+
*/
|
|
70
|
+
export function parseWorkOrder(source: string): ParseWorkOrderResult {
|
|
71
|
+
let parsed: unknown;
|
|
72
|
+
try { parsed = JSON.parse(source); }
|
|
73
|
+
catch (error) {
|
|
74
|
+
return { ok: false, reason: `JSON 이 깨졌다: ${error instanceof Error ? error.message : String(error)}` };
|
|
75
|
+
}
|
|
76
|
+
const record = parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed as Record<string, unknown> : {};
|
|
77
|
+
const rawCellId = record['cellId'];
|
|
78
|
+
if (typeof rawCellId !== 'string' || !rawCellId.trim()) return { ok: false, reason: '칸 id 가 없다' };
|
|
79
|
+
const unknownFields: string[] = [];
|
|
80
|
+
const cells = {} as Record<WorkOrderField, string>;
|
|
81
|
+
for (const field of WORK_ORDER_FIELDS) {
|
|
82
|
+
const text = cellText(record[field]);
|
|
83
|
+
if (text === WORK_ORDER_UNKNOWN) unknownFields.push(field);
|
|
84
|
+
cells[field] = text;
|
|
85
|
+
}
|
|
86
|
+
return { ok: true, order: { cellId: rawCellId.trim(), ...cells, unknownFields } };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** 검증된 지시서를 사람이 읽는 골 문면으로 펼친다 — 첫 줄 «대상 경로:»(경계), 둘째 줄 «현재 계약:». */
|
|
90
|
+
export function renderWorkOrderGoal(order: WorkOrder): string {
|
|
91
|
+
return [
|
|
92
|
+
`대상 경로: ${order.boundary}`,
|
|
93
|
+
`현재 계약: ${order.contract}`,
|
|
94
|
+
'',
|
|
95
|
+
`[${order.lifeId} · 칸 ${order.cellId} · 판 ${order.version} · 착지 마감 ${order.landBy}]`,
|
|
96
|
+
`신분 태그: ${order.identityTags}`,
|
|
97
|
+
`우선순위: ${order.priority}`,
|
|
98
|
+
`판정 신호: ${order.verdictSignal}`,
|
|
99
|
+
`예산: ${order.budget}`,
|
|
100
|
+
`선행·짝 칸: ${order.peers}`,
|
|
101
|
+
`선례: ${order.precedents}`,
|
|
102
|
+
`올림 규칙: ${order.escalation}`,
|
|
103
|
+
].join('\n');
|
|
104
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* K3S-SECRET-DB-LOCK-RETRY — kubectl 호출이 «일시 오류»로 거부되면 지수 백오프로 다시 친다.
|
|
3
|
+
*
|
|
4
|
+
* 근거: node-b k3d(k3s · sqlite 저장소)가 Pod Secret 생성 때
|
|
5
|
+
* `Error from server: error when creating "STDIN": rpc error: code = Unknown desc = database is locked`
|
|
6
|
+
* 로 거부했다(10-15 02:11 KST 전후 4건 · TC #4186). sqlite 쓰기 잠금 경합이라 잠시 뒤 같은 apply 는 선다.
|
|
7
|
+
*
|
|
8
|
+
* ⛔ 판정 문구는 «실측 근거가 있는 것»만 둔다 — 짐작으로 늘리면 진짜 거부(권한·스키마)를 백오프 동안 삼킨다.
|
|
9
|
+
* 재시도 소진 시에만 호출부의 기존 실패 경로로 마지막 결과를 그대로 돌려준다.
|
|
10
|
+
*/
|
|
11
|
+
import { debug } from '../../debug/log.js';
|
|
12
|
+
|
|
13
|
+
export type KubectlCallResult = { status: number | null; stdout: string; stderr: string };
|
|
14
|
+
|
|
15
|
+
/** 실측된 일시 오류 문구(stderr 만 · 부분 일치 · 대소문자 무시 — stdout 은 apply 결과라 판정에 안 쓴다). */
|
|
16
|
+
export const KUBECTL_TRANSIENT_PATTERNS: readonly RegExp[] = [/database is locked/i];
|
|
17
|
+
|
|
18
|
+
/** 재시도 사이 대기(ms) — 길이가 곧 재시도 상한(4회 · 합 7.5s). */
|
|
19
|
+
export const KUBECTL_TRANSIENT_BACKOFF_MS: readonly number[] = [500, 1_000, 2_000, 4_000];
|
|
20
|
+
|
|
21
|
+
export function kubectlTransientReason(result: KubectlCallResult): string | null {
|
|
22
|
+
if (result.status === 0) return null;
|
|
23
|
+
const hit = KUBECTL_TRANSIENT_PATTERNS.find((pattern) => pattern.test(result.stderr));
|
|
24
|
+
return hit ? hit.source : null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 첫 결과 `first` 가 일시 오류일 때만 부른다(성공 경로에 await 를 더하지 않으려고 — 호출부의 마이크로태스크 순서를 지킨다).
|
|
29
|
+
* 다시 친 결과가 성공이거나 일시 오류가 아니면 즉시 돌려주고, 백오프를 다 써도 일시 오류면 마지막 결과를 돌려준다.
|
|
30
|
+
*/
|
|
31
|
+
export async function retryKubectlTransient(
|
|
32
|
+
run: () => KubectlCallResult,
|
|
33
|
+
first: KubectlCallResult,
|
|
34
|
+
opts: { sleep: (ms: number) => Promise<void>; category: string; data?: Record<string, unknown>; backoffMs?: readonly number[] },
|
|
35
|
+
): Promise<KubectlCallResult> {
|
|
36
|
+
const backoff = opts.backoffMs ?? KUBECTL_TRANSIENT_BACKOFF_MS;
|
|
37
|
+
let last = first;
|
|
38
|
+
let reason = kubectlTransientReason(last);
|
|
39
|
+
for (let i = 0; i < backoff.length && reason; i++) {
|
|
40
|
+
debug.log(opts.category, 'retry', { ...opts.data, attempt: i + 1, maxAttempts: backoff.length, delayMs: backoff[i], reason });
|
|
41
|
+
await opts.sleep(backoff[i]!);
|
|
42
|
+
last = run();
|
|
43
|
+
reason = kubectlTransientReason(last);
|
|
44
|
+
if (last.status === 0) {
|
|
45
|
+
debug.log(opts.category, 'retry-recovered', { ...opts.data, attempt: i + 1 });
|
|
46
|
+
return last;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (reason) debug.log(opts.category, 'retry-exhausted', { ...opts.data, attempts: backoff.length, reason, stderr: last.stderr.trim().slice(0, 300) }, { level: 'warn' });
|
|
50
|
+
return last;
|
|
51
|
+
}
|
|
@@ -16,10 +16,11 @@ 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';
|
|
23
|
+
import { seedMirrorOnce, type MirrorSeedResult } from './pod-mirror-seed.js';
|
|
23
24
|
import {
|
|
24
25
|
POD_CHILD_REQUESTS,
|
|
25
26
|
POD_JOB_DEADLINE_SECONDS,
|
|
@@ -39,11 +40,18 @@ export const POD_LITE_IMAGE = 'elanous-harness-lite:local';
|
|
|
39
40
|
|
|
40
41
|
export const POD_LITE_MEMORY_LIMIT = '2Gi';
|
|
41
42
|
|
|
43
|
+
/** W5 (10-15 #27801): where a memory-backed TMPDIR is mounted for release gate shards — the overlayfs `/tmp` made SQLite
|
|
44
|
+
* tests take 0.4~5s per turn (once 124s). tmpfs pages count against the container memory limit, so the caller's cap
|
|
45
|
+
* (`tmpfsSizeLimit`) stays small next to the 16Gi shard limit (request 6Gi). */
|
|
46
|
+
export const POD_TMPFS_MOUNT_PATH = '/tmp-mem';
|
|
47
|
+
|
|
42
48
|
/** 요청은 한도를 넘을 수 없다(쿠버네티스가 Job 을 거부한다) — lite 2Gi 처럼 한도가 기본 요청보다 작으면 한도로 맞춘다. */
|
|
43
49
|
/** The command Job container's CPU limit when the caller names none (GATE-SPEED A3①: unchanged default). */
|
|
44
50
|
export const POD_COMMAND_CPU_LIMIT_DEFAULT = '4';
|
|
45
51
|
/** 게이트 조각·pod-command 의 CPU 요청 기본 — 하니스 Pod(POD_CHILD_REQUESTS.cpu)와 따로 둔다(조각은 bun test 로 CPU 를 실제로 쓴다). */
|
|
46
52
|
export const POD_COMMAND_CPU_REQUEST_DEFAULT = '1';
|
|
53
|
+
/** Gate and command Pods retain their measured 6Gi scheduler request; si-task admission uses its own size. */
|
|
54
|
+
export const POD_COMMAND_MEMORY_REQUEST_DEFAULT = '6Gi';
|
|
47
55
|
|
|
48
56
|
/** Container CPU request/limit override. Omitted fields keep the defaults (request `POD_COMMAND_CPU_REQUEST_DEFAULT` · limit 4). */
|
|
49
57
|
export interface PodCpu { request?: string; limit?: string }
|
|
@@ -92,9 +100,9 @@ export function parsePodCpu(value: unknown, label = 'cpu'): PodCpu | undefined {
|
|
|
92
100
|
|
|
93
101
|
export function memoryRequestWithin(limit: string | undefined): string {
|
|
94
102
|
const gi = (value: string | undefined) => { const m = /^(\d+)Gi$/.exec(value ?? ''); return m ? Number(m[1]) : null; };
|
|
95
|
-
const request = gi(
|
|
103
|
+
const request = gi(POD_COMMAND_MEMORY_REQUEST_DEFAULT);
|
|
96
104
|
const max = gi(limit);
|
|
97
|
-
return request !== null && max !== null && request > max ? limit! :
|
|
105
|
+
return request !== null && max !== null && request > max ? limit! : POD_COMMAND_MEMORY_REQUEST_DEFAULT;
|
|
98
106
|
}
|
|
99
107
|
|
|
100
108
|
/** POD7 must-fix: the skill list alone can't tell a network-only job from one that needs ffmpeg/browser — so lite is
|
|
@@ -132,13 +140,24 @@ export function tailBytes(text: string, maxBytes: number): string {
|
|
|
132
140
|
return `…[앞 ${bytes.length - maxBytes}바이트 생략]\n${cut.subarray(start).toString('utf8')}`;
|
|
133
141
|
}
|
|
134
142
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
143
|
+
/**
|
|
144
|
+
* The isolation probe: wait until the NetworkPolicy blocks the host/prod daemons, then go on with the child shell.
|
|
145
|
+
* GATE-WARM-BOOT-NO-INIT (10-15) — this used to be the `isolation-gate` init container; it is now the child shell's first
|
|
146
|
+
* lines, before any credential is read. Same probes, same log lines, same exit 1 when isolation is not enforced in 30 s.
|
|
147
|
+
* Measured on node-b k3d (#27805): init 2 → 354 s · init 1 → 41 s · none → 1 s from Pod creation to the child start.
|
|
148
|
+
*/
|
|
149
|
+
export function isolationGateLines(): string {
|
|
150
|
+
return `elanous_isolation_gate() {
|
|
151
|
+
local ok=0 i
|
|
152
|
+
for i in $(seq 1 60); do
|
|
153
|
+
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
|
|
154
|
+
[ "$ok" -ge 3 ] && { echo "[gate] isolation enforced after \${i} probes"; return 0; }
|
|
155
|
+
sleep 0.5
|
|
156
|
+
done
|
|
157
|
+
echo "[gate] ISOLATION NOT ENFORCED within 30s"; exit 1
|
|
158
|
+
}
|
|
159
|
+
elanous_isolation_gate || exit 1`;
|
|
160
|
+
}
|
|
142
161
|
|
|
143
162
|
/** Export the command's log store into the existing outbox return channel without changing the command exit status. */
|
|
144
163
|
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
|
|
@@ -176,7 +195,7 @@ if [ -d "$HOME/outbox" ]; then
|
|
|
176
195
|
else
|
|
177
196
|
printf 'ELANOUS_POD_ARTIFACT_SKIPPED %s %s\\n' "$relative" "$size"
|
|
178
197
|
fi
|
|
179
|
-
done < <(find "$HOME/outbox" -type f -print0)
|
|
198
|
+
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)
|
|
180
199
|
fi`;
|
|
181
200
|
|
|
182
201
|
export interface PodCommandJobInput {
|
|
@@ -202,9 +221,13 @@ export interface PodCommandJobInput {
|
|
|
202
221
|
memoryLimit?: string;
|
|
203
222
|
/** GATE-SPEED A3①: CPU request/limit override (release gate shards only). Omitted = request 1 / limit 4. */
|
|
204
223
|
cpu?: PodCpu;
|
|
224
|
+
/** W5 — emptyDir{medium: Memory} sizeLimit mounted at {@link POD_TMPFS_MOUNT_PATH} ⊕ `TMPDIR` (release gate shards only). Omitted = image `/tmp`. */
|
|
225
|
+
tmpfsSizeLimit?: string;
|
|
205
226
|
source?: PodSource;
|
|
206
227
|
deadlineSeconds: number;
|
|
207
228
|
runId?: string;
|
|
229
|
+
/** 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. */
|
|
230
|
+
hostDirsInit?: boolean;
|
|
208
231
|
}
|
|
209
232
|
|
|
210
233
|
function bashSingleQuote(value: string): string {
|
|
@@ -220,8 +243,11 @@ export function podCommandJobManifest(o: PodCommandJobInput): Record<string, unk
|
|
|
220
243
|
const grok = o.llm === 'grok';
|
|
221
244
|
const bunCache = o.bunCache ? podBunCacheVolume(o.bunCache) : undefined;
|
|
222
245
|
const installSlots = o.installSlots ? podInstallSlotsVolume(o.installSlots) : undefined;
|
|
223
|
-
// hostPath directories the uid-1000 child writes
|
|
246
|
+
// hostPath directories the uid-1000 child writes. DirectoryOrCreate makes them root 0755, so runPodCommand hands them to
|
|
247
|
+
// uid 1000 once per node (prepareHostDirsOnce); the child only reports a directory it still cannot write.
|
|
224
248
|
const hostDirMounts = [...(bunCache ? [bunCache.volumeMount] : []), ...(installSlots ? [installSlots.volumeMount] : [])];
|
|
249
|
+
const tmpfs = o.tmpfsSizeLimit?.trim() || undefined;
|
|
250
|
+
const tmpfsMounts = tmpfs ? [{ name: 'tmp-mem', mountPath: POD_TMPFS_MOUNT_PATH }] : [];
|
|
225
251
|
const cpu = resolvePodCpu(o.cpu);
|
|
226
252
|
const quotedArgs = o.command.map(bashSingleQuote).join(' ');
|
|
227
253
|
const credLines = [
|
|
@@ -231,12 +257,14 @@ export function podCommandJobManifest(o: PodCommandJobInput): Record<string, unk
|
|
|
231
257
|
: []),
|
|
232
258
|
];
|
|
233
259
|
const script = [
|
|
260
|
+
isolationGateLines(),
|
|
234
261
|
'set -u',
|
|
235
262
|
...credLines,
|
|
236
263
|
'curl -s -m 3 -o /dev/null http://host.orb.internal:31415/health && { echo "[pod] ISOLATION FAIL"; exit 3; }',
|
|
237
264
|
...(o.clone
|
|
238
265
|
? ['export GH_TOKEN="$(cat /creds/gh-token)" && gh auth setup-git', podSourceScript(o.source ?? { kind: 'default' }, o.repoUrl)]
|
|
239
266
|
: ['mkdir -p ~/work && cd ~/work']),
|
|
267
|
+
...(hostDirMounts.length ? [podHostDirsCheckScript(hostDirMounts)] : []),
|
|
240
268
|
...(bunCache ? [bunCache.shellPrefix] : []),
|
|
241
269
|
`set -- ${quotedArgs}`,
|
|
242
270
|
'"$@"',
|
|
@@ -244,6 +272,10 @@ export function podCommandJobManifest(o: PodCommandJobInput): Record<string, unk
|
|
|
244
272
|
// A command may not end in LF; keep artifact markers on their own line for the existing parser.
|
|
245
273
|
...(o.returnLogs ? ["printf '\\n'", COMMAND_LOG_EXPORT] : []),
|
|
246
274
|
ARTIFACT_EMIT,
|
|
275
|
+
// GATE-POD-RESULT-MARKER: the last line says «the child is done» so the host need not wait for the Job condition
|
|
276
|
+
// (k3d on node-b flips it 90~550s late). Leading LF keeps it on its own line; the host strips exactly this tail.
|
|
277
|
+
// The token is this launch's random id — a command that prints the bare marker word cannot end the wait early.
|
|
278
|
+
`printf '\\n${podResultMarker(o.launch ?? o.name)} rc=%s\\n' "$rc"`,
|
|
247
279
|
'exit $rc',
|
|
248
280
|
].join('\n');
|
|
249
281
|
const secretKeys = grok || skillNames.length || o.clone === true;
|
|
@@ -260,10 +292,10 @@ export function podCommandJobManifest(o: PodCommandJobInput): Record<string, unk
|
|
|
260
292
|
spec: {
|
|
261
293
|
restartPolicy: 'Never',
|
|
262
294
|
securityContext: { runAsUser: 1000, fsGroup: 1000 },
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
],
|
|
295
|
+
// Normal path: no init container. Fallback only when the node-side hand-over did not run (no member · prep failed).
|
|
296
|
+
...(o.hostDirsInit && hostDirMounts.length ? { initContainers: [
|
|
297
|
+
{ name: 'host-dirs', image: o.image, imagePullPolicy: o.imagePullPolicy ?? 'Never', securityContext: { runAsUser: 0 }, command: ['bash', '-c'], args: [podHostDirsScript(hostDirMounts)], volumeMounts: hostDirMounts.map((mount) => ({ ...mount })) },
|
|
298
|
+
] } : {}),
|
|
267
299
|
containers: [{
|
|
268
300
|
name: 'child', image: o.image, imagePullPolicy: o.imagePullPolicy ?? 'Never',
|
|
269
301
|
resources: { requests: { ...POD_CHILD_REQUESTS, cpu: cpu.request, memory: memoryRequestWithin(o.memoryLimit) }, limits: { memory: o.memoryLimit ?? '16Gi', cpu: cpu.limit } },
|
|
@@ -272,18 +304,21 @@ export function podCommandJobManifest(o: PodCommandJobInput): Record<string, unk
|
|
|
272
304
|
...(o.runId ? [{ name: 'ELANOUS_RUN_ID', value: o.runId }] : []),
|
|
273
305
|
{ name: 'ELANOUS_SUBSTRATE', value: 'pod' },
|
|
274
306
|
{ name: 'ELANOUS_POD_NAME', valueFrom: { fieldRef: { fieldPath: 'metadata.name' } } },
|
|
307
|
+
...(tmpfs ? [{ name: 'TMPDIR', value: POD_TMPFS_MOUNT_PATH }] : []),
|
|
275
308
|
],
|
|
276
|
-
...(secretKeys || o.hostMirror || hostDirMounts.length ? { volumeMounts: [
|
|
309
|
+
...(secretKeys || o.hostMirror || hostDirMounts.length || tmpfs ? { volumeMounts: [
|
|
277
310
|
...(secretKeys ? [{ name: 'creds', mountPath: '/creds', readOnly: true }] : []),
|
|
278
311
|
...(o.hostMirror ? [{ name: 'host-mirror', mountPath: '/host-mirror', readOnly: true }] : []),
|
|
279
312
|
...hostDirMounts,
|
|
313
|
+
...tmpfsMounts,
|
|
280
314
|
] } : {}),
|
|
281
315
|
}],
|
|
282
|
-
...(secretKeys || o.hostMirror || hostDirMounts.length ? { volumes: [
|
|
316
|
+
...(secretKeys || o.hostMirror || hostDirMounts.length || tmpfs ? { volumes: [
|
|
283
317
|
...(secretKeys ? [{ name: 'creds', secret: { secretName: `${o.name}-creds`, defaultMode: 0o400 } }] : []),
|
|
284
318
|
...(o.hostMirror ? [{ name: 'host-mirror', hostPath: { path: o.hostMirror, type: 'Directory' } }] : []),
|
|
285
319
|
...(bunCache ? [bunCache.volume] : []),
|
|
286
320
|
...(installSlots ? [installSlots.volume] : []),
|
|
321
|
+
...(tmpfs ? [{ name: 'tmp-mem', emptyDir: { medium: 'Memory', sizeLimit: tmpfs } }] : []),
|
|
287
322
|
] } : {}),
|
|
288
323
|
},
|
|
289
324
|
},
|
|
@@ -360,6 +395,8 @@ export interface RunPodCommandOptions {
|
|
|
360
395
|
memoryLimit?: string;
|
|
361
396
|
/** GATE-SPEED A3①: CPU request/limit override — only the release gate passes it. Omitted = request 1 / limit 4. */
|
|
362
397
|
cpu?: PodCpu;
|
|
398
|
+
/** W5 — memory-backed TMPDIR sizeLimit mounted at {@link POD_TMPFS_MOUNT_PATH}; only the release gate passes it. Omitted = image `/tmp`. */
|
|
399
|
+
tmpfsSizeLimit?: string;
|
|
363
400
|
/** POD7: 호출부가 «네트워크 스킬만 쓰는 명령»이라고 말할 때만 lite 이미지 ⊕ 2Gi. */
|
|
364
401
|
lite?: boolean;
|
|
365
402
|
source?: PodSource;
|
|
@@ -380,6 +417,12 @@ export interface RunPodCommandOptions {
|
|
|
380
417
|
kubectl?: Kubectl;
|
|
381
418
|
/** A caller-owned scheduler is self-capped: acquires count only its own Jobs, never cluster occupancy (POOLGLOBAL-REG). */
|
|
382
419
|
poolScheduler?: PodPoolScheduler;
|
|
420
|
+
/** GATE-WARM-BOOT — seeds a commit-pinned clone's commit into the pool host mirror (test seam · default {@link seedMirrorOnce}). */
|
|
421
|
+
seedMirror?: (o: { host: string; commit: string; cwd: string }) => Promise<MirrorSeedResult | undefined>;
|
|
422
|
+
/** GATE-WARM-BOOT — the git tree the seed pushes from (default: the process cwd — the gate runs in the repo tree). */
|
|
423
|
+
mirrorSeedCwd?: string;
|
|
424
|
+
/** GATE-WARM-BOOT-NO-INIT — hands the hostPath dirs to uid 1000 on the member's nodes (test seam · default {@link prepareHostDirsOnce}). */
|
|
425
|
+
prepareHostDirs?: (o: { member: PodPoolMember; hostPaths: readonly string[] }) => Promise<HostDirsPrepResult | undefined>;
|
|
383
426
|
checkPool?: typeof checkPodPool;
|
|
384
427
|
syncImages?: typeof syncPoolImages;
|
|
385
428
|
imageCommit?: string | null;
|
|
@@ -396,6 +439,21 @@ export interface RunPodCommandOptions {
|
|
|
396
439
|
childLogMaxBytes?: number;
|
|
397
440
|
}
|
|
398
441
|
|
|
442
|
+
/** GATE-POD-RESULT-MARKER — the child script's final line (`\n<marker> <token> rc=<n>\n`), printed after the artifact emit. */
|
|
443
|
+
export const POD_RESULT_MARKER = '__ELANOUS_POD_DONE__';
|
|
444
|
+
/** The marker bound to one launch (`token` = the launch's random id · the Job name when the manifest has no launch). */
|
|
445
|
+
/** Full-log re-reads after an early marker return before the artifacts count as lost (GATE-POD-RESULT-MARKER follow-up). */
|
|
446
|
+
export const POD_MARKER_LOG_RETRIES = 2;
|
|
447
|
+
export function podResultMarker(token: string): string { return `${POD_RESULT_MARKER} ${token}`; }
|
|
448
|
+
|
|
449
|
+
/** 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). */
|
|
450
|
+
export function splitPodResultMarker(logs: string, token: string): { logs: string; rc: number | null } {
|
|
451
|
+
const escaped = podResultMarker(token).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
452
|
+
const match = new RegExp(`\\n${escaped} rc=(\\d+)\\n?$`).exec(logs);
|
|
453
|
+
if (!match) return { logs, rc: null };
|
|
454
|
+
return { logs: logs.slice(0, match.index), rc: Number(match[1]) };
|
|
455
|
+
}
|
|
456
|
+
|
|
399
457
|
function jobFinished(types: string): 'complete' | 'failed' | null {
|
|
400
458
|
if (/Complete|SuccessCriteriaMet/.test(types)) return 'complete';
|
|
401
459
|
if (/Failed|FailureTarget/.test(types)) return 'failed';
|
|
@@ -522,6 +580,34 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
522
580
|
}
|
|
523
581
|
const imageRef = member?.imageRef;
|
|
524
582
|
if (!imageRef) log('pod.command-job', 'image-fallback-local', { reason: !member ? 'no-pool-member' : !imageCommit ? 'image-commit-unavailable' : 'registry-tag-unavailable' });
|
|
583
|
+
// GATE-WARM-BOOT (10-15): a commit-pinned clone on a pool host — put that commit into the host's mirror first (once per
|
|
584
|
+
// host·commit in this process), so the Pod's podSourceScript finds it (`cat-file -e`) instead of fetching from GitHub.
|
|
585
|
+
// Best effort: a failed seed only logs; the Pod keeps the old path. Never with an injected kubectl (tests) unless seeded.
|
|
586
|
+
const seedMirror = options.seedMirror ?? (options.kubectl ? undefined : seedMirrorOnce);
|
|
587
|
+
if (seedMirror && options.clone && options.source?.kind === 'commit' && hostMirror && member?.sshHost) {
|
|
588
|
+
// Worst case added to a cold start: the push limit (GATE_MIRROR_SEED_LIMIT_MS), once per host·commit.
|
|
589
|
+
const seed = await seedMirror({ host: member.sshHost, commit: options.source.sha, cwd: options.mirrorSeedCwd ?? process.cwd() })
|
|
590
|
+
.catch((error: unknown) => ({ host: member!.sshHost!, ok: false, ms: 0, detail: String(error).slice(0, 300) }));
|
|
591
|
+
log('pod.command-job', 'mirror-seed', { host: member.sshHost, commit: options.source.sha, ok: seed?.ok ?? false, ms: seed?.ms ?? 0, ...(seed?.detail ? { detail: seed.detail } : {}) });
|
|
592
|
+
}
|
|
593
|
+
// GATE-WARM-BOOT-NO-INIT (10-15): the hostPath dirs the uid-1000 child writes are handed over on the node itself, once per
|
|
594
|
+
// member·paths in this process (no init container). Best effort: a failure only logs; the child then falls back.
|
|
595
|
+
const hostDirPaths = [...(bunCache ? [bunCache] : []), ...(installSlots ? [installSlots] : [])];
|
|
596
|
+
const prepareHostDirs = options.prepareHostDirs ?? (options.kubectl ? undefined : prepareHostDirsOnce);
|
|
597
|
+
let hostDirsPrepared = false;
|
|
598
|
+
if (hostDirPaths.length) {
|
|
599
|
+
// Observed whether or not a hand-over runs: no member (nothing to reach) and an injected kubectl without a seam are skips.
|
|
600
|
+
if (!member) log('pod.command-job', 'host-dirs-prep', { ok: false, reason: 'no-pool-member', paths: hostDirPaths });
|
|
601
|
+
else if (!prepareHostDirs) log('pod.command-job', 'host-dirs-prep', { ok: false, reason: 'prep-disabled', paths: hostDirPaths });
|
|
602
|
+
else {
|
|
603
|
+
const prep = await prepareHostDirs({ member, hostPaths: hostDirPaths })
|
|
604
|
+
.catch((error: unknown) => ({ host: member!.sshHost ?? 'local', ok: false, ms: 0, detail: String(error).slice(0, 300) }));
|
|
605
|
+
hostDirsPrepared = prep?.ok === true;
|
|
606
|
+
log('pod.command-job', 'host-dirs-prep', { host: prep?.host ?? member.sshHost ?? 'local', ok: prep?.ok ?? false, ms: prep?.ms ?? 0, paths: hostDirPaths, ...(prep?.detail ? { detail: prep.detail } : {}) });
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
// Any path where the node-side hand-over did not succeed keeps the old in-Pod hand-over (review mf: uid 1000 could not write).
|
|
610
|
+
const hostDirsInit = hostDirPaths.length > 0 && !hostDirsPrepared;
|
|
525
611
|
const ghToken = options.clone ? (options.ghToken ?? defaultGhToken)() : undefined;
|
|
526
612
|
const secret = commandJobSecret({ name, namespace, launch, skills, skillEnvText, ...(grokAuth !== undefined ? { grokAuth } : {}), ...(ghToken !== undefined ? { ghToken } : {}) });
|
|
527
613
|
if (secret) {
|
|
@@ -532,8 +618,9 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
532
618
|
name, namespace, launch, image: imageRef ?? image,
|
|
533
619
|
...(imageRef ? { imagePullPolicy: 'IfNotPresent' as const } : {}),
|
|
534
620
|
repoUrl, command, skills, ...(options.returnLogs ? { returnLogs: true } : {}), ...(llm ? { llm } : {}), ...(options.clone ? { clone: true } : {}),
|
|
535
|
-
...(options.source ? { source: options.source } : {}), ...(hostMirror ? { hostMirror } : {}), ...(bunCache ? { bunCache } : {}), ...(installSlots ? { installSlots } : {}), ...(memoryLimit ? { memoryLimit } : {}), ...(options.cpu ? { cpu: options.cpu } : {}), deadlineSeconds,
|
|
621
|
+
...(options.source ? { source: options.source } : {}), ...(hostMirror ? { hostMirror } : {}), ...(bunCache ? { bunCache } : {}), ...(installSlots ? { installSlots } : {}), ...(memoryLimit ? { memoryLimit } : {}), ...(options.cpu ? { cpu: options.cpu } : {}), ...(options.tmpfsSizeLimit ? { tmpfsSizeLimit: options.tmpfsSizeLimit } : {}), deadlineSeconds,
|
|
536
622
|
...(options.runId ? { runId: options.runId } : {}),
|
|
623
|
+
...(hostDirsInit ? { hostDirsInit: true } : {}),
|
|
537
624
|
});
|
|
538
625
|
kubectl(['-n', namespace, 'delete', 'job', '-l', own, '--ignore-not-found']);
|
|
539
626
|
const applied = kubectl(['apply', '-f', '-'], JSON.stringify(manifest));
|
|
@@ -543,10 +630,24 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
543
630
|
}
|
|
544
631
|
let state: 'complete' | 'failed' = 'failed';
|
|
545
632
|
let unreadableSince: number | null = null;
|
|
633
|
+
let markerRc: number | null = null;
|
|
634
|
+
const appliedAt = Date.now();
|
|
546
635
|
for (;;) {
|
|
547
636
|
const got = kubectl(['-n', namespace, 'get', 'job', name, '-o', 'jsonpath={.status.conditions[*].type}']);
|
|
548
637
|
const finished = jobFinished(got.stdout);
|
|
549
638
|
if (finished) { state = finished; break; }
|
|
639
|
+
// GATE-POD-RESULT-MARKER: the condition is not there yet — the child may already be done (k3d condition lag).
|
|
640
|
+
// A tail read that fails (Pod still pending · init container) or lacks the marker changes nothing.
|
|
641
|
+
const tail = kubectl(['-n', namespace, 'logs', `job/${name}`, '-c', 'child', '--tail=2']);
|
|
642
|
+
if (tail.status === 0) {
|
|
643
|
+
const seen = splitPodResultMarker(tail.stdout.startsWith('\n') ? tail.stdout : `\n${tail.stdout}`, launch).rc;
|
|
644
|
+
if (seen !== null) {
|
|
645
|
+
markerRc = seen;
|
|
646
|
+
state = seen === 0 ? 'complete' : 'failed';
|
|
647
|
+
log('pod.command-job', 'result-marker-early', { job: name, waitedMs: Date.now() - appliedAt, rc: seen });
|
|
648
|
+
break;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
550
651
|
if (got.status !== 0 && options.statusUnreadableMs !== undefined) {
|
|
551
652
|
unreadableSince ??= Date.now();
|
|
552
653
|
if (Date.now() - unreadableSince >= options.statusUnreadableMs) {
|
|
@@ -556,9 +657,23 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
556
657
|
} else unreadableSince = null;
|
|
557
658
|
await sleep(options.pollMs ?? 15_000);
|
|
558
659
|
}
|
|
559
|
-
|
|
660
|
+
let logsResult = kubectl(['-n', namespace, 'logs', `job/${name}`, '-c', 'child']);
|
|
661
|
+
// Marker path returns before the Job condition — a full-log read can hit the same transient window the tail read
|
|
662
|
+
// already survived (container log rotation · API hiccup). Retry it a little before calling the artifacts lost.
|
|
663
|
+
// A read that «succeeds» but stops before this launch's marker (empty · cut off) is incomplete too (review mf · #27842).
|
|
664
|
+
const fullLogIncomplete = (r: { status: number | null; stdout: string }) =>
|
|
665
|
+
r.status !== 0 || splitPodResultMarker(r.stdout.startsWith('\n') ? r.stdout : `\n${r.stdout}`, launch).rc === null;
|
|
666
|
+
for (let attempt = 1; markerRc !== null && fullLogIncomplete(logsResult) && attempt <= POD_MARKER_LOG_RETRIES; attempt++) {
|
|
667
|
+
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' }) });
|
|
668
|
+
await sleep(options.pollMs === undefined ? 1_000 : Math.min(options.pollMs, 1_000)); // ≤2 re-reads within ≈2s total
|
|
669
|
+
logsResult = kubectl(['-n', namespace, 'logs', `job/${name}`, '-c', 'child']);
|
|
670
|
+
}
|
|
671
|
+
// Still without this launch's marker after the retries: the artifacts are not trusted as complete (explicit failure).
|
|
672
|
+
if (markerRc !== null && logsResult.status === 0 && fullLogIncomplete(logsResult)) {
|
|
673
|
+
logsResult = { ...logsResult, status: 1, stderr: 'full log ended before this launch\'s result marker (incomplete after retries)' };
|
|
674
|
+
}
|
|
560
675
|
const logsFailed = logsResult.status !== 0;
|
|
561
|
-
const logs = logsFailed ? '' : logsResult.stdout;
|
|
676
|
+
const logs = logsFailed ? '' : splitPodResultMarker(logsResult.stdout, launch).logs;
|
|
562
677
|
const artifactDir = artifactRoot;
|
|
563
678
|
let artifacts: PodArtifactCollection;
|
|
564
679
|
if (logsFailed) {
|
|
@@ -591,7 +706,8 @@ export async function runPodCommand(options: RunPodCommandOptions): Promise<PodC
|
|
|
591
706
|
const maxBytes = options.childLogMaxBytes ?? podChildLogMaxBytes();
|
|
592
707
|
const childLog = logsFailed ? `산출 회수 못 함: ${artifacts.error}` : tailBytes(logs, maxBytes);
|
|
593
708
|
writeFileSync(resolve(artifactsDir, 'child.log'), childLog);
|
|
594
|
-
|
|
709
|
+
// Marker path: the rc the child printed (the Pod's terminated state may lag like the condition). Condition path: unchanged.
|
|
710
|
+
const exitCode = markerRc ?? exitCodeFromPod(kubectl, namespace, name, state);
|
|
595
711
|
cleanupSecret();
|
|
596
712
|
log('pod.command', 'job-finished', {
|
|
597
713
|
job: name,
|