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,98 @@
|
|
|
1
|
+
/** TA-PRELAUNCH-ALREADY-DONE: bounded evidence against a pinned, detached main tree. */
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { realpathSync } from 'node:fs';
|
|
4
|
+
import { isAbsolute } from 'node:path';
|
|
5
|
+
import { inspectGoalDoneBoundary } from '../self-implement/goal-author.js';
|
|
6
|
+
|
|
7
|
+
export interface AlreadyDoneCandidate { mainSha: string; repository: string; command: string; exitCode: 0 }
|
|
8
|
+
export interface AlreadyDoneDecision { candidate?: AlreadyDoneCandidate; reason: string }
|
|
9
|
+
|
|
10
|
+
type SafeCommand = { argv: string[]; path: string };
|
|
11
|
+
const SHA = /^[0-9a-f]{40}$/i;
|
|
12
|
+
const SAFE_PATH = /^[A-Za-z0-9_./-]+$/;
|
|
13
|
+
|
|
14
|
+
/** A lexical command declaration is not authority to run shell or project scripts. */
|
|
15
|
+
export function parseAlreadyDoneCommand(command: string): SafeCommand | null {
|
|
16
|
+
let input = command.trim();
|
|
17
|
+
while (input.length >= 2 && ((input.startsWith('`') && input.endsWith('`'))
|
|
18
|
+
|| (input.startsWith('"') && input.endsWith('"')) || (input.startsWith("'") && input.endsWith("'"))))
|
|
19
|
+
input = input.slice(1, -1).trim();
|
|
20
|
+
if (!input || /[\n\r\t`$;&|<>\\'"*?()[\]{}!]/.test(input)) return null;
|
|
21
|
+
const argv = input.split(/ +/);
|
|
22
|
+
let path: string | undefined;
|
|
23
|
+
if (argv.length === 3 && argv[0] === 'test' && ['-f', '-e'].includes(argv[1]!)) path = argv[2];
|
|
24
|
+
else if (argv.length === 5 && argv[0] === 'git' && argv[1] === 'ls-files' && argv[2] === '--error-unmatch' && argv[3] === '--') path = argv[4];
|
|
25
|
+
else if (argv.length === 7 && argv[0] === 'git' && argv[1] === 'diff' && argv[2] === '--quiet'
|
|
26
|
+
&& SHA.test(argv[3]!) && argv[4] === 'HEAD' && argv[5] === '--') path = argv[6];
|
|
27
|
+
if (!path || !SAFE_PATH.test(path) || isAbsolute(path) || path.startsWith('-')
|
|
28
|
+
|| path.split('/').some((part) => part === '..' || part === '.' || !part)) return null;
|
|
29
|
+
return { argv, path };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type PinnedGitResult = { status: number | null; stdout: string; error: boolean };
|
|
33
|
+
export type PrelaunchGitRunnerForTest = (cwd: string, argv: string[], timeout?: number) => PinnedGitResult;
|
|
34
|
+
|
|
35
|
+
export function runPinnedGit(cwd: string, argv: string[], timeout = 4_000, input?: string): PinnedGitResult {
|
|
36
|
+
// Trust boundary: the operator's own repository and Git config. Drop inherited GIT_* overrides,
|
|
37
|
+
// disable replace refs, hooks, and credential helpers; remote transport uses the operator's SSH config.
|
|
38
|
+
const env = { ...process.env };
|
|
39
|
+
for (const key of Object.keys(env)) if (key.startsWith('GIT_')) delete env[key];
|
|
40
|
+
const result = spawnSync('git', ['--no-replace-objects', '-c', 'core.hooksPath=/dev/null', '-c', 'credential.helper=', ...argv],
|
|
41
|
+
{ cwd, env, encoding: 'utf8', timeout, maxBuffer: 64 * 1024, ...(input !== undefined ? { input } : {}) });
|
|
42
|
+
return { status: result.status, stdout: result.stdout ?? '', error: !!result.error };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function evaluatePinnedTree(root: string, sha: string, safe: SafeCommand, runGit: PrelaunchGitRunnerForTest): AlreadyDoneDecision {
|
|
46
|
+
const { argv, path } = safe;
|
|
47
|
+
// Every supported command names one tracked regular file in the pinned tree.
|
|
48
|
+
// A symlink's filesystem -e/-f meaning is not inferable from its Git object.
|
|
49
|
+
const entry = runGit(root, ['ls-tree', sha, '--', path]);
|
|
50
|
+
if (entry.status !== 0 || entry.error) return { reason: 'evidence-unmeasured' };
|
|
51
|
+
const match = /^(100644|100755|040000|120000) (blob|tree) [0-9a-f]{40}\t(.+)$/m.exec(entry.stdout);
|
|
52
|
+
if (!match || match[3] !== path) return { reason: 'evidence-not-passing' };
|
|
53
|
+
if (match[1] === '120000') return { reason: 'evidence-symlink-unmeasured' };
|
|
54
|
+
if (!['100644', '100755'].includes(match[1]!) || match[2] !== 'blob') return { reason: 'evidence-path-not-tracked-file' };
|
|
55
|
+
if (argv[0] === 'git' && argv[1] === 'diff') {
|
|
56
|
+
const base = argv[3]!;
|
|
57
|
+
if (base.toLowerCase() === sha.toLowerCase()) return { reason: 'diff-compares-main-to-itself' };
|
|
58
|
+
const ancestor = runGit(root, ['merge-base', '--is-ancestor', base, sha]);
|
|
59
|
+
if (ancestor.status !== 0) return { reason: 'diff-base-unverified' };
|
|
60
|
+
const diff = runGit(root, ['diff', '--no-ext-diff', '--no-textconv', '--quiet', base, sha, '--', path]);
|
|
61
|
+
return { reason: diff.status === 0 ? 'evidence-passed-on-main' : diff.status === 1 && !diff.error ? 'evidence-not-passing' : 'evidence-unmeasured' };
|
|
62
|
+
}
|
|
63
|
+
return { reason: 'evidence-passed-on-main' };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Only an explicit project repository qualifies. Unknown target means preserve the live launch. */
|
|
67
|
+
export function inspectPrelaunchAlreadyDone(text: string, projectTarget?: string,
|
|
68
|
+
deps: { runGit?: PrelaunchGitRunnerForTest; realpath?: (path: string) => string } = {}): AlreadyDoneDecision {
|
|
69
|
+
const boundary = inspectGoalDoneBoundary(text);
|
|
70
|
+
if (boundary.missing.length) return { reason: `boundary-missing:${boundary.missing.join(',')}` };
|
|
71
|
+
const command = boundary.values['완료 경계 증거 명령'] ?? '';
|
|
72
|
+
const safe = parseAlreadyDoneCommand(command);
|
|
73
|
+
if (!safe) return { reason: 'evidence-command-unsupported' };
|
|
74
|
+
const codeBoundary = boundary.values['완료 경계 코드'] ?? '';
|
|
75
|
+
const realBoundary = boundary.values['완료 경계 실물'] ?? '';
|
|
76
|
+
if (codeBoundary !== `기존 추적 파일 ${safe.path}` || realBoundary !== '원격 main의 일반 파일로 존재')
|
|
77
|
+
return { reason: 'evidence-boundary-not-file-existence' };
|
|
78
|
+
if (!projectTarget) return { reason: 'project-target-unverified' };
|
|
79
|
+
let root: string;
|
|
80
|
+
try { root = (deps.realpath ?? realpathSync)(projectTarget); } catch { return { reason: 'project-target-unreadable' }; }
|
|
81
|
+
const runGit = deps.runGit ?? runPinnedGit;
|
|
82
|
+
const top = runGit(root, ['rev-parse', '--show-toplevel']);
|
|
83
|
+
if (top.status !== 0 || top.stdout.trim() !== root) return { reason: 'project-root-unverified' };
|
|
84
|
+
const origin = runGit(root, ['remote', 'get-url', 'origin']);
|
|
85
|
+
const originUrl = origin.stdout.trim();
|
|
86
|
+
// Keep credentials and arbitrary transports out of both the verifier and its card evidence.
|
|
87
|
+
const repository = /^(?:https:\/\/github\.com\/|git@github\.com:)([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+?)(?:\.git)?$/.exec(originUrl)?.[1];
|
|
88
|
+
if (origin.status !== 0 || !repository) return { reason: 'origin-unverified' };
|
|
89
|
+
const local = runGit(root, ['rev-parse', 'refs/remotes/origin/main']).stdout.trim();
|
|
90
|
+
const remote = runGit(root, ['ls-remote', 'origin', 'refs/heads/main'], 7_000);
|
|
91
|
+
const sha = remote.stdout.trim().split(/\s+/)[0] ?? '';
|
|
92
|
+
if (remote.status !== 0 || !SHA.test(sha) || local !== sha) return { reason: 'main-unverified-or-stale' };
|
|
93
|
+
const evaluated = evaluatePinnedTree(root, sha, safe, runGit);
|
|
94
|
+
if (evaluated.reason !== 'evidence-passed-on-main') return evaluated;
|
|
95
|
+
const remoteAgain = runGit(root, ['ls-remote', 'origin', 'refs/heads/main'], 7_000);
|
|
96
|
+
if (remoteAgain.status !== 0 || remoteAgain.stdout.trim().split(/\s+/)[0] !== sha) return { reason: 'main-moved' };
|
|
97
|
+
return { candidate: { mainSha: sha, repository, command, exitCode: 0 }, reason: 'evidence-passed-on-main' };
|
|
98
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ⛔ 시험 안의 «실물 발사» 거부 — 2026-10-16 사고(R7 · OP #8751) 의 구조 방어.
|
|
3
|
+
*
|
|
4
|
+
* 무엇이 있었나: 호스트 재게이트가 시험을 운영 HOME 그대로 돌렸고, seam 이 빠진 시험 둘이 `defaultTaskLauncher` 의
|
|
5
|
+
* 원격 부모 경로(`tryRemoteParent`)로 진짜 ssh 를 쏴 원격 prod 런 25 · draft PR 11 을 만들었다.
|
|
6
|
+
* 격리 env(재게이트 러너)와 시험 seam 은 «잊음»을 줄일 뿐 «다음 시험이 seam 을 빠뜨리는 것»은 못 막는다 — 그래서
|
|
7
|
+
* 발사 지점이 bun test 안에서는 명시 허용 없이 실물 발사를 «거부»한다(fail-closed · 큰소리).
|
|
8
|
+
*
|
|
9
|
+
* - 시험 밖(제품 경로): 아무 영향 없다 — `isUnderTestRunner()` 가 거짓이면 즉시 돌아간다.
|
|
10
|
+
* - 시험 안: 주입(가짜 ssh·spawn)을 쓰면 이 가드에 닿지 않는다. 실물이 정말 필요한 시험만
|
|
11
|
+
* `ELANOUS_TEST_ALLOW_REAL_LAUNCH=1` 로 명시 허용한다.
|
|
12
|
+
*/
|
|
13
|
+
import { debug } from '../debug/log.js';
|
|
14
|
+
import { isUnderTestRunner } from '../oauth/store.js';
|
|
15
|
+
|
|
16
|
+
export const ALLOW_REAL_LAUNCH_UNDER_TEST_ENV = 'ELANOUS_TEST_ALLOW_REAL_LAUNCH';
|
|
17
|
+
|
|
18
|
+
export type RealLaunchKind = 'remote-parent-ssh' | 'local-harness-spawn';
|
|
19
|
+
|
|
20
|
+
export class RealLaunchRefusedUnderTestError extends Error {
|
|
21
|
+
constructor(readonly kind: RealLaunchKind, detail: string) {
|
|
22
|
+
super(`⛔ 시험 안에서 실물 발사를 거부했다(${kind}${detail ? ` · ${detail}` : ''}) — `
|
|
23
|
+
+ (kind === 'remote-parent-ssh'
|
|
24
|
+
? 'deps.parentHost: null(원격 끔) 또는 deps.ssh 가짜를 주입하라'
|
|
25
|
+
: 'deps.spawn 가짜(또는 handToTaskAgent:\'off\' · taskLauncher 가짜)를 주입하라')
|
|
26
|
+
+ ` · 실물이 정말 필요하면 ${ALLOW_REAL_LAUNCH_UNDER_TEST_ENV}=1 (2026-10-16 시험 누수 사고 R7)`);
|
|
27
|
+
this.name = 'RealLaunchRefusedUnderTestError';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** bun test 안이고 명시 허용이 없으면 던진다. 시험 밖에서는 아무것도 하지 않는다. */
|
|
32
|
+
export function refuseRealLaunchUnderTest(kind: RealLaunchKind, detail = '', env: NodeJS.ProcessEnv = process.env): void {
|
|
33
|
+
if (!isUnderTestRunner(env)) return;
|
|
34
|
+
if (env[ALLOW_REAL_LAUNCH_UNDER_TEST_ENV]?.trim() === '1') return;
|
|
35
|
+
try { debug.log('task-agent', 'real-launch-refused-under-test', { kind, detail }); } catch { /* fail-soft */ }
|
|
36
|
+
throw new RealLaunchRefusedUnderTestError(kind, detail);
|
|
37
|
+
}
|
|
@@ -35,6 +35,7 @@ import { tmpdir } from 'node:os';
|
|
|
35
35
|
import { dirname, join } from 'node:path';
|
|
36
36
|
import { debug } from '../debug/log.js';
|
|
37
37
|
import { prodInstanceRoot } from '../instance/resolve.js';
|
|
38
|
+
import { getUserConfig } from '../user-config.js';
|
|
38
39
|
import { loadRunLedger, type RunLedgerEntry } from '../self-implement/run-ledger.js';
|
|
39
40
|
import type { DetachedSpawn } from '../cli/tasks-cli.js';
|
|
40
41
|
import { remoteLedgerMirrorDir } from './parent-host.js';
|
|
@@ -46,6 +47,9 @@ import type { RepairCasOutcome, RepairCasRequest } from './repair-branch-cas.js'
|
|
|
46
47
|
import { defaultLandPrHead, defaultPrHead, defaultReviewRepoCandidates, executeLiveLand, executeLiveReview, landRetryPending, type LiveMoveDeps, type LiveMoveResult, type PrHeadView, type ReviewRepoCandidate, type TaskAgentLiveMove } from './live-moves.js';
|
|
47
48
|
import { capturedLandReview, captureReviewResults, parseReviewResultOutput, pendingReviewResults, reviewResultPath, type ParsedReviewResult } from './review-result-capture.js';
|
|
48
49
|
import { boundPrTerminal, cardPrNumber, LIVE_MOVE_RESULT_EVENT, readTaskCard, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
|
|
50
|
+
import { verifiedTrainLanding, type TrainLanding } from './train-landing.js';
|
|
51
|
+
import { isGoalOnlyPr } from './judge.js';
|
|
52
|
+
import { defaultPrFiles } from './shadow.js';
|
|
49
53
|
|
|
50
54
|
export const REJUDGE_ON_HEAD_EVENT = 'rejudge-on-head';
|
|
51
55
|
/** 카드·PR 당 재게이트하는 머리 수 상한(머리가 바뀔 때마다 하나) — 넘으면 멈추고 사람에게 넘긴다. */
|
|
@@ -60,6 +64,7 @@ export type CatchUpDecision = 'pushed' | 'conflict' | 'cap-reached' | 'failed';
|
|
|
60
64
|
export interface RejudgeOutcome {
|
|
61
65
|
card: string; pr: number | null; fromHead: string | null; toHead: string | null; step: RejudgeStep; decision: string; reason: string;
|
|
62
66
|
fromBase?: string; toBase?: string; newHead?: string;
|
|
67
|
+
repairRunId?: string; repairHead?: string;
|
|
63
68
|
}
|
|
64
69
|
|
|
65
70
|
export interface RegateRequest { card: string; pr: number; head: string; repoRoot: string; resultPath: string }
|
|
@@ -77,6 +82,8 @@ export type CatchUpGit = (cwd: string, args: string[]) => { status: number | nul
|
|
|
77
82
|
export interface RejudgeDeps {
|
|
78
83
|
live?: LiveMoveDeps;
|
|
79
84
|
liveMoves: ReadonlySet<TaskAgentLiveMove>;
|
|
85
|
+
/** Complete PR target paths; undefined means the PR diff could not be measured. */
|
|
86
|
+
prFiles?: (pr: number, prUrl: string) => Promise<readonly string[] | undefined>;
|
|
80
87
|
/** Only phase ① shadow callbacks may inspect a previously judged head without a regate. */
|
|
81
88
|
shadowSameHead?: boolean;
|
|
82
89
|
/** HQ mirror proof that the bound remote child has stopped. Test seam; absence fails closed. */
|
|
@@ -89,11 +96,15 @@ export interface RejudgeDeps {
|
|
|
89
96
|
requestRepair?: (request: RepairLaunchRequest) => Promise<void>;
|
|
90
97
|
applyRepair?: (request: RepairCasRequest) => RepairCasOutcome;
|
|
91
98
|
notifyRepair?: (seat: string, body: string) => void;
|
|
99
|
+
/** Shared new-launch budget for this `tasks rejudge --all` call. */
|
|
100
|
+
repairBudget?: import('./repair-cycle.js').RepairTickBudget;
|
|
92
101
|
/** TA-REJUDGE-REBASE-LOOP — origin/main 을 PR 가지에 3-way merge 하고 일반 push. 시험은 주입한다. */
|
|
93
102
|
catchUpMain?: (request: CatchUpRequest) => Promise<CatchUpResult>;
|
|
94
103
|
log?: (category: string, event: string, data: Record<string, unknown>) => void;
|
|
95
104
|
/** 시험 seam — 결과 파일 읽기(없으면 ENOENT). */
|
|
96
105
|
readFile?: (path: string) => string;
|
|
106
|
+
/** Verify a CLOSED component PR against the HQ train ledger and merged integration PR. */
|
|
107
|
+
trainLanding?: (pr: number, cwd: string) => TrainLanding | null;
|
|
97
108
|
}
|
|
98
109
|
|
|
99
110
|
/** PR binding alone does not mean a remote parent has stopped. Require its child edge and terminal ledger row. */
|
|
@@ -281,6 +292,15 @@ export function parseRegateResult(text: string, pr: number, head: string): Regat
|
|
|
281
292
|
const sameUrl = (a: string, b: string) => a.trim().replace(/\/+$/, '').toLowerCase() === b.trim().replace(/\/+$/, '').toLowerCase();
|
|
282
293
|
const sameHead = (a: string, b: string) => a.toLowerCase() === b.toLowerCase();
|
|
283
294
|
|
|
295
|
+
/**
|
|
296
|
+
* TA-REGATE-UNMEASURED — «못 잰» 재게이트(draft `pr-head` 거부·띄우기 실패 등 status=unmeasured)는 코드 판정이 아니다.
|
|
297
|
+
* 재게이트 상한(REJUDGE_HEAD_CAP)에 세지 않는다. 옛 결과 파일은 noMerge 에 status 가 없어서 draft 거부 문면으로도 가린다.
|
|
298
|
+
*/
|
|
299
|
+
export function regateUnmeasured(entry: { passed?: boolean; status?: string; detail?: string }): boolean {
|
|
300
|
+
return entry.passed === false && (entry.status === 'unmeasured' || /^pr-head:.*\bisDraft=true\b/.test(entry.detail ?? ''));
|
|
301
|
+
}
|
|
302
|
+
const cappedRegates = <T extends { passed?: boolean; status?: string; detail?: string }>(entries: readonly T[]): T[] => entries.filter((entry) => !regateUnmeasured(entry));
|
|
303
|
+
|
|
284
304
|
const defaultCatchUpGit: CatchUpGit = (cwd, args) => {
|
|
285
305
|
const r = spawnSync('git', args, { cwd, encoding: 'utf8', timeout: 120_000 });
|
|
286
306
|
return { status: r.status, stdout: String(r.stdout ?? ''), stderr: String(r.stderr ?? '') };
|
|
@@ -414,8 +434,6 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
|
|
|
414
434
|
// 원격 부모는 node-b 의 liveMoves 가 꺼져 리뷰 이력이 0일 수 있다. HQ 거울의 종결 증거가 있을 때만 시작한다.
|
|
415
435
|
const adopted = card.adoptedPr?.pr === pr && typeof card.pr === 'object'
|
|
416
436
|
&& !!card.pr.url && sameUrl(card.adoptedPr.url, card.pr.url) && /^[a-f0-9]{40}$/i.test(card.adoptedPr.head);
|
|
417
|
-
if (!reviews.length && !adopted && (!card.parentHost || !(deps.remoteRunTerminal ?? remoteBoundRunTerminal)(card)))
|
|
418
|
-
return target('not-started', 'no task-agent review on this PR yet (remote terminal unproven or run not stopped/judged)', pr);
|
|
419
437
|
// 떼어 띄운 재게이트 결과를 «머리와 무관하게» 먼저 회수한다 — 결과가 나오기 전에 머리가 또 바뀌어도 그 머리의 결과는 카드에 남는다.
|
|
420
438
|
for (const pending of (card.regates ?? []).filter((entry) => entry.pr === pr && entry.passed === undefined && entry.resultPath)) {
|
|
421
439
|
let text: string | null = null;
|
|
@@ -433,7 +451,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
|
|
|
433
451
|
wrote = true;
|
|
434
452
|
return { ...current, regates: current.regates.map((entry) => entry.pr === pr && entry.head === pending.head && entry.at === pending.at ? { ...entry, ...patch } : entry) };
|
|
435
453
|
});
|
|
436
|
-
if (wrote) emit({ card: card.id, pr, fromHead: null, toHead: pending.head, step: 'regate', decision: patch.passed ? 'regate-passed' : 'regate-failed',
|
|
454
|
+
if (wrote) emit({ card: card.id, pr, fromHead: null, toHead: pending.head, step: 'regate', decision: patch.passed ? 'regate-passed' : regateUnmeasured(patch) ? 'regate-unmeasured' : 'regate-failed',
|
|
437
455
|
reason: `head ${pending.head.slice(0, 12)} · base ${(patch as { baseCommit?: string }).baseCommit?.slice(0, 12) ?? '-'} · ${patch.detail}` }, true);
|
|
438
456
|
}
|
|
439
457
|
card = readTaskCard(card.id, statePath) ?? card;
|
|
@@ -451,15 +469,40 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
|
|
|
451
469
|
if ('reason' in found) return target('pr-unreadable', found.reason, pr, fromHead);
|
|
452
470
|
const { cwd, view } = found;
|
|
453
471
|
const toHead = view.head;
|
|
472
|
+
const eligible = !!reviews.length || adopted || (!!card.parentHost && (deps.remoteRunTerminal ?? remoteBoundRunTerminal)(card));
|
|
473
|
+
const trustedTrain = view.state === 'CLOSED' && card.status === 'launched'
|
|
474
|
+
? (() => { try { return (deps.trainLanding ?? verifiedTrainLanding)(pr, cwd); } catch { return null; } })() : null;
|
|
475
|
+
// An unreviewed or unproven remote card retains the old guard. Only verified train
|
|
476
|
+
// evidence may cross it; an arbitrary CLOSED PR must not disappear from rejudge.
|
|
477
|
+
if (!eligible && !trustedTrain)
|
|
478
|
+
return target('not-started', 'no task-agent review on this PR yet (remote terminal unproven or run not stopped/judged)', pr);
|
|
479
|
+
try {
|
|
480
|
+
const paths = await (deps.prFiles ?? defaultPrFiles)(pr, url);
|
|
481
|
+
if (isGoalOnlyPr(paths)) return target('goal-only-pr', `PR #${pr} target diff 0 (docs/goals/** only) — review·land·같은 골 재큐 중지`, pr, fromHead, toHead, true);
|
|
482
|
+
} catch (error) {
|
|
483
|
+
try { log('task-agent', 'pr-target-diff-unavailable', { card: card.id, pr,
|
|
484
|
+
reason: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
|
|
485
|
+
}
|
|
454
486
|
if (view.state === 'MERGED' || view.state === 'CLOSED') {
|
|
455
487
|
const at = now().toISOString();
|
|
488
|
+
const train = trustedTrain;
|
|
456
489
|
updateTaskCard(statePath, card.id, (current) => {
|
|
457
490
|
if (!current || cardPrNumber(current) !== pr || typeof current.pr !== 'object' || current.pr.url !== url) return undefined;
|
|
458
491
|
const previous = boundPrTerminal(current);
|
|
459
|
-
|
|
460
|
-
|
|
492
|
+
const alreadyLanded = train && current.trainLanding?.componentPr === pr
|
|
493
|
+
&& current.trainLanding.integrationPr === train.integrationPr && current.trainLanding.mergeSha === train.mergeSha;
|
|
494
|
+
if (previous?.state === view.state && previous.head === toHead && (!train || alreadyLanded) && (!train || current.status === 'done')) return undefined;
|
|
495
|
+
return {
|
|
496
|
+
...current,
|
|
497
|
+
...(train ? { status: 'done' as const, trainLanding: alreadyLanded ? current.trainLanding : { ...train, at }, history: alreadyLanded ? current.history : [...(current.history ?? []), {
|
|
498
|
+
at, event: 'landed-via-train', pr, head: toHead, detail: `train #${train.integrationPr} merged ${train.mergeSha}`,
|
|
499
|
+
}] } : {}),
|
|
500
|
+
prTerminal: previous?.state === view.state && previous.head === toHead ? previous
|
|
501
|
+
: { pr, url, head: toHead, state: view.state as 'MERGED' | 'CLOSED', at },
|
|
502
|
+
};
|
|
461
503
|
});
|
|
462
|
-
return target('
|
|
504
|
+
return train ? target('landed-via-train', `PR #${pr} via train #${train.integrationPr} merge ${train.mergeSha}`, pr, fromHead, toHead)
|
|
505
|
+
: target('pr-not-open', `PR #${pr} is ${view.state}`, pr, fromHead, toHead);
|
|
463
506
|
}
|
|
464
507
|
if (view.state !== 'OPEN') return target('pr-not-open', `PR #${pr} is ${view.state}`, pr, fromHead, toHead);
|
|
465
508
|
// An explicitly rejudged PR can be reopened. Clear the old marker before normal head judgement.
|
|
@@ -533,8 +576,10 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
|
|
|
533
576
|
mustFix: mustFix ?? [], liveMoves: deps.liveMoves, now: now(), readFile: read,
|
|
534
577
|
...(deps.requestRepair ? { request: deps.requestRepair } : {}),
|
|
535
578
|
...(deps.applyRepair ? { apply: deps.applyRepair } : {}),
|
|
536
|
-
...(deps.notifyRepair ? { notify: deps.notifyRepair } : {})
|
|
537
|
-
|
|
579
|
+
...(deps.notifyRepair ? { notify: deps.notifyRepair } : {}),
|
|
580
|
+
...(deps.repairBudget ? { repairBudget: deps.repairBudget } : {}) });
|
|
581
|
+
step('repair', result.decision, result.reason, true,
|
|
582
|
+
result.repairRunId && result.repairHead ? { repairRunId: result.repairRunId, repairHead: result.repairHead } : {});
|
|
538
583
|
return outcomes;
|
|
539
584
|
}
|
|
540
585
|
}
|
|
@@ -582,6 +627,40 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
|
|
|
582
627
|
return outcomes;
|
|
583
628
|
}
|
|
584
629
|
|
|
630
|
+
// TA-LAND-AFTER-REVIEW: configured queue mode owns its one remote changed gate inside
|
|
631
|
+
// the queue adapter. The older host regate below is the direct-merge path only.
|
|
632
|
+
const queueMode = live.landQueueConfig === undefined ? getUserConfig().taskAgent?.landQueue : live.landQueueConfig;
|
|
633
|
+
if (queueMode) {
|
|
634
|
+
const latest = readTaskCard(card.id, statePath) ?? card;
|
|
635
|
+
const priorQueue = (latest.landAttempts ?? []).filter((entry) => entry.pr === pr && sameHead(entry.head, toHead));
|
|
636
|
+
if (priorQueue.length && !landRetryPending(latest, pr, toHead)) {
|
|
637
|
+
step('land', 'queue-skipped', `PR #${pr} head ${toHead.slice(0, 12)} already claimed or queued`, false);
|
|
638
|
+
return outcomes;
|
|
639
|
+
}
|
|
640
|
+
const review = capturedLandReview(latest, pr, toHead);
|
|
641
|
+
if (!review || review.mustFixCount !== 0) {
|
|
642
|
+
if (pendingReviewResults(latest).some((entry) => entry.pr === pr && sameHead(entry.head, toHead))) {
|
|
643
|
+
step('review', 'awaiting-review-result', 'exact-head review result pending', false);
|
|
644
|
+
} else if (!latest.reviewRequests?.some((entry) => entry.pr === pr && sameHead(entry.head, toHead)) && deps.liveMoves.has('review')) {
|
|
645
|
+
const before = { reviewRequests: latest.reviewRequests, landAttempts: latest.landAttempts };
|
|
646
|
+
const result = await executeLiveReview(latest, pr, { runId: latest.runId ?? null, stopReason: 'queue-exact-head', cwd }, { ...live, ...(deps.log ? { log: deps.log } : {}) });
|
|
647
|
+
recordMove(statePath, latest.id, latest.runId, 'review', result, pr, before, now, deps.log);
|
|
648
|
+
step('review', result.executed ? 'review-requested' : 'review-request-failed', result.detail, true);
|
|
649
|
+
} else step('review', 'not-landing', 'exact-head PASS/WARN mf0 review not captured', true);
|
|
650
|
+
return outcomes;
|
|
651
|
+
}
|
|
652
|
+
if (!readyConfirmed) { step('ready', 'ready-unconfirmed', 'exact-head ready PR not confirmed', false); return outcomes; }
|
|
653
|
+
if (!deps.liveMoves.has('propose-land')) { step('land', 'would-land', 'propose-land not enabled — queue shadow', false); return outcomes; }
|
|
654
|
+
const reviewResult = latest.reviewRequests?.find((entry) => entry.pr === pr && sameHead(entry.head, toHead) && entry.resultPath)?.resultPath;
|
|
655
|
+
if (!reviewResult) { step('land', 'not-landing', 'exact-head review JSON path missing', true); return outcomes; }
|
|
656
|
+
const before = { reviewRequests: latest.reviewRequests, landAttempts: latest.landAttempts };
|
|
657
|
+
const queued = await executeLiveLand(latest, pr, { runId: latest.runId ?? null, cycleId: `queue:${latest.id}:${toHead}`, cwd,
|
|
658
|
+
review, reviewResultPath: reviewResult }, { ...live, landQueueConfig: queueMode, ...(deps.log ? { log: deps.log } : {}) });
|
|
659
|
+
recordMove(statePath, latest.id, latest.runId, 'propose-land', queued, pr, before, now, deps.log);
|
|
660
|
+
step('land', queued.queued ? 'queued' : queued.ok && !queued.executed ? 'queue-skipped' : 'queue-refused', queued.detail, true);
|
|
661
|
+
return outcomes;
|
|
662
|
+
}
|
|
663
|
+
|
|
585
664
|
const tryCatchUp = async (fromBase: string | undefined, why: string): Promise<boolean> => {
|
|
586
665
|
const prior = catchUpHistory(card!, pr);
|
|
587
666
|
// 상한은 «실제 push» 만 센다 — 충돌·실패 뒤 사람이 새 머리를 올리면 다시 시도할 수 있어야 한다.
|
|
@@ -650,8 +729,9 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
|
|
|
650
729
|
if (!regate || staleBase || retryDraft) {
|
|
651
730
|
const why = staleBase ? `base-stale-overlap — gate base ${staleBase.slice(0, 12)} went stale (${(stale!.reason ?? '').replace(/^base-stale-overlap:\s*/, '').slice(0, 160)})`
|
|
652
731
|
: retryDraft ? 'draft rejection became stale after PR ready' : '';
|
|
653
|
-
|
|
654
|
-
|
|
732
|
+
const counted = cappedRegates(regates).length;
|
|
733
|
+
if (counted >= REJUDGE_HEAD_CAP) {
|
|
734
|
+
step('regate', 'cap-reached', `${why ? `${why} · ` : ''}re-gated ${counted} times already (cap ${REJUDGE_HEAD_CAP} · unmeasured ${regates.length - counted} not counted) — no more rejudge; needs owner`, true);
|
|
655
735
|
return outcomes;
|
|
656
736
|
}
|
|
657
737
|
if (!deps.liveMoves.has('propose-land')) step('regate', 'would-regate', `${why ? `${why} · ` : ''}propose-land not enabled in taskAgent.liveMoves — shadow`, false);
|
|
@@ -667,7 +747,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
|
|
|
667
747
|
if (!current || held.some((entry) => sameHead(entry.head, toHead) && (staleBase ? entry.staleBase !== undefined && sameHead(entry.staleBase, staleBase)
|
|
668
748
|
: retryDraft ? entry.readyRetry === true : true))) return undefined;
|
|
669
749
|
// 상한은 잠금 안의 «지금» 카드로 다시 잰다 — 다른 머리를 본 두 틱이 겹쳐도 상한을 넘지 않게.
|
|
670
|
-
if (held.length >= REJUDGE_HEAD_CAP) { capped = true; return undefined; }
|
|
750
|
+
if (cappedRegates(held).length >= REJUDGE_HEAD_CAP) { capped = true; return undefined; }
|
|
671
751
|
claimed = true;
|
|
672
752
|
return { ...current, regates: [...(current.regates ?? []), { pr, head: toHead, at, resultPath, ...(staleBase ? { staleBase } : {}), ...(retryDraft ? { readyRetry: true as const } : {}) }] };
|
|
673
753
|
});
|
|
@@ -750,7 +830,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
|
|
|
750
830
|
const before = { reviewRequests: latest.reviewRequests, landAttempts: latest.landAttempts };
|
|
751
831
|
// 주기 id — base-stale 재게이트 뒤의 land 는 새 base 를 붙여 앞 land 의 주기 표시(모듈 전역)와 갈린다 · gateAt 이 앞 base-stale 시도를 소비한다.
|
|
752
832
|
const cycleId = `rejudge:${card.id}:${toHead}${regate.staleBase ? `:${regate.baseCommit.slice(0, 12)}` : ''}`;
|
|
753
|
-
const landed = await executeLiveLand(latest, pr, { runId: card.runId ?? null, cycleId, cwd, review, overlapEvidence, gateAt: regate.at },
|
|
833
|
+
const landed = await executeLiveLand(latest, pr, { runId: card.runId ?? null, cycleId, cwd, review, reviewResultPath: reviewResult, overlapEvidence, gateAt: regate.at },
|
|
754
834
|
{ ...live, ...(deps.log ? { log: deps.log } : {}) });
|
|
755
835
|
// LAND-ORDER-LEDGER — executeLiveLand 직후 원장 한 줄(같은 pr+head 는 한 줄만). 쓰기가 실패해도 land 결과는 그대로(삼킨다).
|
|
756
836
|
const landOrderLog = (event: 'appended' | 'append-failed') => { try { log('task-agent.land-order', event, { pr, head: toHead }); } catch { /* fail-soft */ } };
|
|
@@ -768,7 +848,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
|
|
|
768
848
|
const attempt = landed.landAttempt?.class
|
|
769
849
|
? ` · land-class ${landed.landAttempt.class} (${landed.landAttempt.reason}) · attempt ${landed.landAttempt.attempt} · ${landed.landAttempt.class === 'base-stale' ? 'base-stale → re-gate on a new base next tick (cap counts)' : landed.landAttempt.retryAllowed ? 'retry allowed on this head' : 'no retry on this head'}`
|
|
770
850
|
: '';
|
|
771
|
-
step('land', landed.executed && landed.ok ? 'landed'
|
|
851
|
+
step('land', landed.queued ? 'queued' : landed.executed && landed.ok ? 'landed'
|
|
772
852
|
: !landed.executed && landed.ok ? 'land-skipped' : 'land-rejected',
|
|
773
853
|
`${landed.detail}${attempt} · overlap-evidence ${overlapEvidence}`, true);
|
|
774
854
|
return outcomes;
|
|
@@ -1,30 +1,73 @@
|
|
|
1
1
|
/** Bind remote TA parents from the HQ ledger mirror before `rejudge --all` selects PR cards. */
|
|
2
|
-
import {
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
3
4
|
import { debug } from '../debug/log.js';
|
|
4
5
|
import { loadRunLedger } from '../self-implement/run-ledger.js';
|
|
5
|
-
import { bindCardEvidence, podChildRunIds, readCardRunSnapshot, refreshCardRunBinding } from './card-evidence.js';
|
|
6
|
-
import { remoteLedgerMirrorDir } from './parent-host.js';
|
|
6
|
+
import { bindCardEvidence, podChildRunIds, podTerminalPr, readCardRunSnapshot, refreshCardRunBinding } from './card-evidence.js';
|
|
7
|
+
import { mirrorRemoteRunLedgers, remoteLedgerMirrorDir } from './parent-host.js';
|
|
7
8
|
import { cardPrNumber, type TaskCard } from './task-hand.js';
|
|
8
9
|
|
|
10
|
+
const RECENT_LAUNCH_MS = 24 * 60 * 60 * 1000;
|
|
11
|
+
/**
|
|
12
|
+
* TA-BIND-PULL-ONCE — an older launch whose parent ledger was never mirrored at HQ gets one pull («묶기만»).
|
|
13
|
+
* Bounded per tick so the first tick after deploy does not run hundreds of sequential ssh reads (backlog ≈690
|
|
14
|
+
* cards on 10-15 drains over ticks); a pulled mirror is then read locally and never pulled again by this rule.
|
|
15
|
+
*/
|
|
16
|
+
export const UNMIRRORED_PULL_CAP_PER_TICK = 20;
|
|
17
|
+
|
|
18
|
+
type BindDeps = {
|
|
19
|
+
now?: () => number;
|
|
20
|
+
mirror?: typeof mirrorRemoteRunLedgers;
|
|
21
|
+
unmirroredPullCap?: number;
|
|
22
|
+
onFailure?: (failure: { card: string; runId: string; host: string; reason: string }) => void;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function recentlyLaunched(card: TaskCard, now: number): boolean {
|
|
26
|
+
const launch = [...card.history].reverse().find(event => event.event === 'launch');
|
|
27
|
+
const at = Date.parse(launch?.at ?? card.createdAt);
|
|
28
|
+
return Number.isFinite(at) && at <= now && now - at < RECENT_LAUNCH_MS;
|
|
29
|
+
}
|
|
30
|
+
|
|
9
31
|
/**
|
|
10
32
|
* A remote child PR can appear after the last HQ card refresh. A card without a PR is otherwise absent from
|
|
11
33
|
* `rejudgeCandidates`, so the normal rejudge tick never reaches `mirrorRemoteCardLedger` or the binding replay.
|
|
12
|
-
* Only an existing, launched TA-owned
|
|
34
|
+
* Only an existing, launched parent (TA-owned or not — TA-BIND-WIDEN) with a parent→child edge in its own host
|
|
35
|
+
* mirror is bound; rejudge/land selection keeps its own taLand gate. The
|
|
13
36
|
* launch registry (including foreign/test universes) and child-only ledgers are never scanned or adopted here.
|
|
14
37
|
*/
|
|
15
38
|
export async function bindMirroredRemoteRejudgeCards(
|
|
16
39
|
tasks: Readonly<Record<string, TaskCard>>, statePath: string,
|
|
17
|
-
|
|
40
|
+
deps: BindDeps = {},
|
|
41
|
+
): Promise<{ scanned: number; bound: number; skipped: number; pulledUnmirrored: number }> {
|
|
18
42
|
const root = dirname(statePath);
|
|
43
|
+
const now = (deps.now ?? Date.now)();
|
|
44
|
+
const mirror = deps.mirror ?? mirrorRemoteRunLedgers;
|
|
45
|
+
const reportFailure = (card: TaskCard, reason: string): void => {
|
|
46
|
+
const failure = { card: card.id, runId: card.runId!, host: card.parentHost!.host, reason: reason.slice(0, 300) };
|
|
47
|
+
try { (deps.onFailure ?? ((data) => debug.log('task-agent', 'remote-rejudge-bind-failed', data)))(failure); }
|
|
48
|
+
catch { /* observation must not stop the other cards */ }
|
|
49
|
+
};
|
|
19
50
|
let scanned = 0;
|
|
20
51
|
let bound = 0;
|
|
21
52
|
let skipped = 0;
|
|
53
|
+
let pulledUnmirrored = 0;
|
|
54
|
+
const unmirroredCap = deps.unmirroredPullCap ?? UNMIRRORED_PULL_CAP_PER_TICK;
|
|
22
55
|
for (const card of Object.values(tasks)) {
|
|
23
|
-
|
|
56
|
+
// TA-BIND-WIDEN — «묶기»는 taLand 와 무관하게 launched ⊕ runId 카드 전부. 묶여도 재판정(rejudge)·land 후보는
|
|
57
|
+
// `rejudgeCandidates`/`remoteBoundRunTerminal` 의 taLand 관문이 그대로 거른다 — 여기서 넓히는 것은 카드↔PR 연결뿐이다.
|
|
58
|
+
if (card.status !== 'launched' || !card.parentHost || !card.runId
|
|
24
59
|
|| cardPrNumber(card) !== undefined || card.refSource === 'manual') continue;
|
|
25
60
|
scanned++;
|
|
26
61
|
const dir = remoteLedgerMirrorDir(root, card.parentHost.host);
|
|
27
62
|
try {
|
|
63
|
+
// This prepass runs before PR-based candidate selection. Pulling here breaks the otherwise circular
|
|
64
|
+
// dependency: cards with a remote PR cannot be selected while their parent/child ledgers are absent locally.
|
|
65
|
+
// Limit fresh remote pulls to recent launches, but keep binding older ledgers already mirrored at HQ.
|
|
66
|
+
if (recentlyLaunched(card, now)) mirror(card.parentHost, card.runId, root);
|
|
67
|
+
else if (!existsSync(join(dir, `${card.runId}.jsonl`)) && pulledUnmirrored < unmirroredCap) {
|
|
68
|
+
pulledUnmirrored++;
|
|
69
|
+
mirror(card.parentHost, card.runId, root);
|
|
70
|
+
}
|
|
28
71
|
const snapshot = await readCardRunSnapshot(card, {
|
|
29
72
|
loadLedger: (id) => loadRunLedger(id, dir),
|
|
30
73
|
podFinishes: () => [],
|
|
@@ -34,12 +77,20 @@ export async function bindMirroredRemoteRejudgeCards(
|
|
|
34
77
|
const childRunId = evidence.childRunId;
|
|
35
78
|
const pr = evidence.pr;
|
|
36
79
|
const child = childRunId ? snapshot.children[childRunId] : null;
|
|
80
|
+
if (snapshot.readErrors?.length) {
|
|
81
|
+
reportFailure(card, snapshot.readErrors.join('; '));
|
|
82
|
+
skipped++;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
37
85
|
// A PR event alone is not a completed remote run. The rejudge candidate must have the same exact
|
|
38
86
|
// child PR and terminal status that remoteBoundRunTerminal will later require.
|
|
39
|
-
|
|
87
|
+
// TA-BIND-PR-TERMINAL — a blocked-draft child has no `pr-opened`; the parent's `pr-terminal` for that exact child,
|
|
88
|
+
// number and URL is the same PR evidence.
|
|
89
|
+
const terminal = parent ? podTerminalPr(parent, [childRunId ?? '']) : undefined;
|
|
90
|
+
if (!parent || !childRunId || !pr?.url || !child
|
|
40
91
|
|| !podChildRunIds(parent, card.runId).includes(childRunId)
|
|
41
|
-
|| !child.some((entry) => entry.event === 'pr-opened' && entry.data?.number === pr.number
|
|
42
|
-
&& entry.data?.url === pr.url)
|
|
92
|
+
|| !(child.some((entry) => entry.event === 'pr-opened' && entry.data?.number === pr.number
|
|
93
|
+
&& entry.data?.url === pr.url) || (terminal?.number === pr.number && terminal.url === pr.url))
|
|
43
94
|
|| !child.some((entry) => entry.event === 'run-status'
|
|
44
95
|
&& ['completed', 'failed', 'cancelled'].includes(String(entry.data?.runStatus)))) { skipped++; continue; }
|
|
45
96
|
const result = await refreshCardRunBinding(card.id, statePath, {
|
|
@@ -53,10 +104,8 @@ export async function bindMirroredRemoteRejudgeCards(
|
|
|
53
104
|
else skipped++;
|
|
54
105
|
} catch (error) {
|
|
55
106
|
skipped++;
|
|
56
|
-
|
|
57
|
-
card: card.id, runId: card.runId, host: card.parentHost.host, reason: error instanceof Error ? error.message : String(error),
|
|
58
|
-
}); } catch { /* observation must not stop the other cards */ }
|
|
107
|
+
reportFailure(card, error instanceof Error ? error.message : String(error));
|
|
59
108
|
}
|
|
60
109
|
}
|
|
61
|
-
return { scanned, bound, skipped };
|
|
110
|
+
return { scanned, bound, skipped, pulledUnmirrored };
|
|
62
111
|
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
3
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { dirname, join, resolve, sep } from 'node:path';
|
|
5
|
+
import { debug } from '../debug/log.js';
|
|
6
|
+
import { readBudgetInputsLive, type BudgetInputs } from '../self-implement/budget-gate.js';
|
|
5
7
|
import { mintRunId } from '../harness/harness-space.js';
|
|
6
8
|
import { spawnElanousSync } from '../instance/spawn-elanous.js';
|
|
7
9
|
import { passJourneyNode } from '../self-dev/graph-journey-nodes.js';
|
|
@@ -29,9 +31,19 @@ export interface RepairCycleInput {
|
|
|
29
31
|
notify?: (seat: string, body: string) => void;
|
|
30
32
|
observeLaunch?: (move: string, runId: string) => void;
|
|
31
33
|
resolveOwner?: (card: TaskCard) => RepairOwner;
|
|
34
|
+
/** Shared only by one `tasks rejudge --all` invocation; a single-card rejudge has no cap. */
|
|
35
|
+
repairBudget?: RepairTickBudget;
|
|
36
|
+
/** Test seam; production reads the existing subscription quota signals. */
|
|
37
|
+
modelAvailability?: RepairModelAvailability;
|
|
38
|
+
/** Test seam for the same live quota reader used when availability is not injected. */
|
|
39
|
+
readBudgetInputs?: () => Promise<Pick<BudgetInputs, 'codexCandidates' | 'grokUsedPercent' | 'maxUsedPercent'>>;
|
|
32
40
|
}
|
|
33
41
|
|
|
34
|
-
export
|
|
42
|
+
export interface RepairTickBudget { max: number; requested: number; capped: number }
|
|
43
|
+
|
|
44
|
+
export type RepairCycleOutcome = { decision: 'would-repair' | 'repair-requested' | 'repair-pending' | 'repair-applied' | 'repair-failed' | 'repair-stopped'; reason: string;
|
|
45
|
+
/** Present only when this tick actually consumed a bound worker result. */
|
|
46
|
+
repairRunId?: string; repairHead?: string };
|
|
35
47
|
export type RepairOwner = { seat?: TaskSeat; source: string; reason?: string };
|
|
36
48
|
|
|
37
49
|
/** A missing card seat may use only a uniquely identified checklist cell's valid seat. */
|
|
@@ -65,12 +77,39 @@ export function resolveRepairOwner(card: TaskCard, deps: {
|
|
|
65
77
|
} catch { return { source: 'none', reason: `checklist owner invalid: ${cell.version}/${card.checklistId}` }; }
|
|
66
78
|
}
|
|
67
79
|
|
|
68
|
-
export
|
|
80
|
+
export interface RepairModelAvailability { codexSubscription: boolean; grokSubscription: boolean }
|
|
81
|
+
|
|
82
|
+
export async function repairModelAvailability(readInputs: () => Promise<Pick<BudgetInputs, 'codexCandidates' | 'grokUsedPercent' | 'maxUsedPercent'>> = readBudgetInputsLive): Promise<RepairModelAvailability> {
|
|
83
|
+
try {
|
|
84
|
+
const input = await readInputs();
|
|
85
|
+
const codexCap = input.maxUsedPercent['openai-codex'] ?? 95;
|
|
86
|
+
const grokCap = input.maxUsedPercent.grok ?? 100;
|
|
87
|
+
return {
|
|
88
|
+
codexSubscription: input.codexCandidates.some((candidate) => candidate.reached !== true
|
|
89
|
+
&& typeof candidate.usedPercent === 'number' && candidate.usedPercent < codexCap),
|
|
90
|
+
grokSubscription: typeof input.grokUsedPercent === 'number' && input.grokUsedPercent < grokCap,
|
|
91
|
+
};
|
|
92
|
+
} catch { return { codexSubscription: false, grokSubscription: false }; }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Repair stays inside the dispatch tier. A missing legacy tier is high, with Sol allowed only on measured subscription quota. */
|
|
96
|
+
export function alternateRepairModel(card: TaskCard, availability: RepairModelAvailability = { codexSubscription: false, grokSubscription: false }): { from: string; to: TaskChildLlm } {
|
|
69
97
|
const last = card.repairs?.at(-1);
|
|
70
98
|
const from = last?.toModel ?? (card.childLlm ? `${card.childLlm.provider}/${card.childLlm.model}` : 'unknown');
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
99
|
+
const glm: TaskChildLlm = { provider: 'openrouter', model: 'openrouter/z-ai/glm-5.3' };
|
|
100
|
+
const sol: TaskChildLlm = { provider: 'openai-codex', model: 'gpt-6-sol' };
|
|
101
|
+
const grok: TaskChildLlm = { provider: 'grok', model: 'grok-4.6' };
|
|
102
|
+
const tier = card.tier ?? '상';
|
|
103
|
+
const pr = typeof card.pr === 'number' ? card.pr : card.pr?.number;
|
|
104
|
+
const mixEven = ((pr ?? [...card.id].reduce((sum, ch) => sum + ch.charCodeAt(0), 0)) % 2) === 0;
|
|
105
|
+
let to: TaskChildLlm;
|
|
106
|
+
if (tier === '특') to = sol;
|
|
107
|
+
else if (tier === '상' && availability.codexSubscription && mixEven && !from.includes('gpt-6-sol')) to = sol;
|
|
108
|
+
else if (tier === '상') to = availability.grokSubscription && from.includes('glm') ? grok
|
|
109
|
+
: from.includes('glm-5.3-flash') ? glm
|
|
110
|
+
: from.includes('glm-5.3') ? { provider: 'openrouter', model: 'openrouter/z-ai/glm-5.3-flash' } : glm;
|
|
111
|
+
else to = from.includes('glm-5.3-flash') ? glm : from.includes('glm-5.3')
|
|
112
|
+
? { provider: 'openrouter', model: 'openrouter/z-ai/glm-5.3-flash' } : glm;
|
|
74
113
|
return { from, to };
|
|
75
114
|
}
|
|
76
115
|
|
|
@@ -126,6 +165,7 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
|
|
|
126
165
|
runId: latest.runId, effect: status, detail: applied.ok ? applied.toHead : applied.reason }] } : undefined);
|
|
127
166
|
} catch (error) { return { decision: 'repair-pending', reason: `repair confirmation card write failed: ${String(error).slice(-200)}` }; }
|
|
128
167
|
const recorded = readTaskCard(card.id, statePath)?.repairs?.find((entry) => entry.runId === latest.runId)?.status === status;
|
|
168
|
+
// This confirms a result already claimed by another tick; it did not consume the worker result.
|
|
129
169
|
return recorded ? { decision: applied.ok ? 'repair-applied' : 'repair-failed', reason: applied.ok ? `same PR #${pr} fast-forward ${latest.head.slice(0, 12)} → ${applied.toHead.slice(0, 12)}` : applied.reason }
|
|
130
170
|
: { decision: 'repair-pending', reason: 'repair confirmation card changed concurrently' };
|
|
131
171
|
}
|
|
@@ -182,7 +222,8 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
|
|
|
182
222
|
runId: latest.runId, effect: status, detail }] } : undefined);
|
|
183
223
|
} catch (error) { return { decision: 'repair-pending', reason: `repair card write failed after CAS: ${String(error).slice(-200)}` }; }
|
|
184
224
|
const recorded = readTaskCard(card.id, statePath)?.repairs?.find((entry) => entry.runId === latest.runId)?.status === status;
|
|
185
|
-
return recorded ? { decision: applied?.ok ? 'repair-applied' : applied?.unconfirmed ? 'repair-pending' : 'repair-failed', reason: detail
|
|
225
|
+
return recorded ? { decision: applied?.ok ? 'repair-applied' : applied?.unconfirmed ? 'repair-pending' : 'repair-failed', reason: detail,
|
|
226
|
+
repairRunId: latest.runId, repairHead: latest.head }
|
|
186
227
|
: { decision: 'repair-pending', reason: 'repair result card changed concurrently' };
|
|
187
228
|
}
|
|
188
229
|
if (latest?.status === 'applied' && latest.head.toLowerCase() === head.toLowerCase())
|
|
@@ -230,9 +271,18 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
|
|
|
230
271
|
? { ...current, status: 'failed', history: [...(current.history ?? []), { at: now.toISOString(), event: 'repair-owner-missing', pr, head, detail: reason }] } : undefined);
|
|
231
272
|
return { decision: 'repair-stopped', reason };
|
|
232
273
|
}
|
|
274
|
+
if (input.repairBudget && input.repairBudget.requested >= input.repairBudget.max) {
|
|
275
|
+
input.repairBudget.capped++;
|
|
276
|
+
const reason = `repairMaxPerTick 상한 ${input.repairBudget.max} · 다음 틱에 재판정`;
|
|
277
|
+
try { debug.log('task-agent', 'repair-tick-cap', { card: card.id, pr, head, max: input.repairBudget.max,
|
|
278
|
+
requested: input.repairBudget.requested, capped: input.repairBudget.capped, move: judged.judgement.move }); } catch { /* fail-soft */ }
|
|
279
|
+
return { decision: 'would-repair', reason };
|
|
280
|
+
}
|
|
233
281
|
const next = attempts.length + 1;
|
|
234
282
|
const runId = mintRunId();
|
|
235
|
-
const
|
|
283
|
+
const availability = input.modelAvailability ?? (card.tier === '특' || card.tier === '중' || card.tier === '하'
|
|
284
|
+
? { codexSubscription: false, grokSubscription: false } : await repairModelAvailability(input.readBudgetInputs));
|
|
285
|
+
const { from, to } = alternateRepairModel(card, availability);
|
|
236
286
|
const resultPath = repairResultPath(statePath, card.id, pr, head, next, runId);
|
|
237
287
|
const goalFile = resultPath.replace(/\.json$/, '.goal.txt');
|
|
238
288
|
const goal = `기존 PR #${pr}의 리뷰 때 head ${head}를 같은 가지에서 수리한다. 새 PR을 열지 말고 아래 must-fix 원문만 고쳐 commit-only 결과를 반환한다.\n\n${input.mustFix.map((item, i) => `${i + 1}. ${item}`).join('\n')}`;
|
|
@@ -251,6 +301,7 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
|
|
|
251
301
|
try {
|
|
252
302
|
await (input.request ?? defaultRequestRepair)({ card: card.id, pr, head, repo, resultPath, goalFile,
|
|
253
303
|
runId, model: to, seat: owner.seat });
|
|
304
|
+
if (input.repairBudget) input.repairBudget.requested++;
|
|
254
305
|
} catch (error) {
|
|
255
306
|
const reason = `repair launch failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
256
307
|
updateTaskCard(statePath, card.id, (current) => current?.repairs?.some((entry) => entry.runId === runId && entry.status === 'requested')
|
|
@@ -4,6 +4,7 @@ import { mkdirSync, renameSync, writeFileSync } from 'node:fs';
|
|
|
4
4
|
import { dirname } from 'node:path';
|
|
5
5
|
import type { RepairCommitResult } from './repair-branch-cas.js';
|
|
6
6
|
import type { TaskChildLlm } from './task-hand.js';
|
|
7
|
+
import { publishInsideEvent } from '../nexus/api/inside-events.js';
|
|
7
8
|
|
|
8
9
|
const SHA40 = /^[0-9a-f]{40}$/i;
|
|
9
10
|
const SHA256 = /^[0-9a-f]{64}$/i;
|
|
@@ -70,6 +71,12 @@ export async function runRepairWorker(request: RepairWorkerRequest): Promise<Rep
|
|
|
70
71
|
const tmp = `${request.resultPath}.${process.pid}.tmp`;
|
|
71
72
|
writeFileSync(tmp, JSON.stringify(result));
|
|
72
73
|
renameSync(tmp, request.resultPath);
|
|
74
|
+
// The result file, rather than this best-effort notification, is the durable source.
|
|
75
|
+
try {
|
|
76
|
+
publishInsideEvent({ kind: 'ta.repair.completed', schema: 1, card: request.card,
|
|
77
|
+
pr: request.pr, head: request.head, runId: request.runId,
|
|
78
|
+
resultPath: request.resultPath, completedAt: new Date().toISOString() });
|
|
79
|
+
} catch { /* a missing daemon cannot change the worker result */ }
|
|
73
80
|
return result;
|
|
74
81
|
}
|
|
75
82
|
|