elanous 0.2.29 → 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/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{058a98ba.7eb28d5e6dc03565.js → 0bb0ff36.b8d418980951e5ba.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +27 -0
- package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +287 -0
- package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +62 -0
- package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6013-2f769370d8b4c2c6.js → 1335-6731f392c35216eb.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8332.6f0f49df772e163b.js → 1654.32de4b324981a188.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1834-50625904996a8fa8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
- package/apps/pwa/out/_next/static/chunks/{8795.32573a185af18c7b.js → 1913.7cc6fb6055b1ed3f.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{419.736c0d6f426249a7.js → 2001.6c7e0fd02190886c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6767.1fcfc9b8be83975f.js → 2213.2ccbada92c33ea0f.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4759.1f76713aefb87db5.js → 2871.0bca6137343b3f76.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6776.06ff1e3b464cc607.js → 2898.fd781bc7cf01a7b7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1782-59db1b5aa06df38a.js → 2940-619bfd8ef337c611.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{8471.8d2a8c74f09c36ff.js → 2985.39ccdecd36848b12.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +115 -0
- package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +64 -0
- package/apps/pwa/out/_next/static/chunks/{bc324b7c.02a09dd93f6a399b.js → 3267c0e6.d34854e7b3984a6e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3278.2e5d15b53a4091c8.js +2 -0
- package/apps/pwa/out/_next/static/chunks/{7725-4f83d5541fbdb81b.js → 3541-ce3a5424ed5ad7f1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +34 -0
- package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{46bd8bea.2f4b4099172fcdb7.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1142.65d002789ab3af7d.js → 4174.92ed04922709ac9e.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +36 -0
- package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +286 -0
- package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +77 -0
- package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +226 -0
- package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +79 -0
- package/apps/pwa/out/_next/static/chunks/5173-233188df2f42c626.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +148 -0
- package/apps/pwa/out/_next/static/chunks/5307.60f2209e809bd627.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3396-97b97928c49190c9.js → 5458-16cd7a2b51b74c8c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3403.7199205e65124486.js → 5525.86debf231e181813.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9143.ff14585db1d275ff.js → 5543.a438b8ab5a13ea47.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +74 -0
- package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +94 -0
- package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8398.73a19b39715eda04.js → 6092.a7f99e68b188ca66.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5591.a35e7a217734a8b9.js → 6157.0c9af021de4fb31b.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7375.050ea0d72968e49f.js → 6433.fc573af22bbc9ab7.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +90 -0
- package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +32 -0
- package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +104 -0
- package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +24 -0
- package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
- package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1852.7f7b53991fcb99ef.js → 7502.ccd5b8065545edd0.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
- package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6534.1ab00f370db7b105.js → 7862.30a8d6482bb238eb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8097-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/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.js → 9221.7d22eaf353a2d4e7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8767-2f6a634f5abeaa01.js → 9279-d28c5b7754d010ae.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.js → 9989.3694300e5f000b14.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-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-a5635eba0d73b84e.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-349f2752d8cd37ad.js +1 -0
- 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-0a07363b130182a1.js +1 -0
- 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-29900ed0011b2c83.js → page-521ee23ac8c0abfa.js} +1 -1
- 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-9f92737b8766009a.js → page-149dc1caba411bb9.js} +1 -1
- 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/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
- package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
- package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
- package/apps/pwa/out/_next/static/css/{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 +9 -5
- package/graphs/units/recipes.yaml +3 -0
- package/graphs/units/release-gate-recheck.yaml +15 -0
- package/package.json +2 -1
- package/scripts/check-native-tool-wiring.ts +3 -2
- package/scripts/ci-android-unit-tests.ts +16 -0
- package/scripts/ci-typecheck-changed.ts +37 -9
- package/scripts/coord-channel-watch.sh +22 -16
- package/scripts/coord-role-pack.ts +81 -2
- package/scripts/cron-run.ts +96 -3
- package/scripts/detect-test-interference.ts +38 -5
- package/scripts/gate-pr-cache.ts +65 -0
- package/scripts/gh-surface/capture.ts +126 -0
- package/scripts/gh-surface/gh +40 -0
- package/scripts/import-graph-scc.ts +38 -0
- package/scripts/install.ps1 +19 -0
- package/scripts/intake-social.ts +181 -0
- package/scripts/lecture-note/node.ts +71 -4
- package/scripts/lib/android-toolchain.ts +32 -0
- package/scripts/lib/deterministic-env.ts +62 -0
- package/scripts/lib/gate-test-env.ts +19 -0
- package/scripts/measure-goal-grounding-corpus.ts +2 -1
- package/scripts/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-closure.ts +12 -8
- package/scripts/release-loop/gate-diff.ts +1 -1
- package/scripts/release-loop/gate-host-mirror.ts +66 -0
- package/scripts/release-loop/gate-node.ts +523 -75
- package/scripts/release-loop/gate-partial.ts +106 -9
- package/scripts/release-loop/gate-pr-cache.ts +66 -0
- package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
- package/scripts/release-loop/gate-r2-verdict.ts +189 -0
- package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
- package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
- package/scripts/release-loop/import-graph-scc-run.ts +54 -0
- package/scripts/release-loop/import-graph-scc.ts +215 -0
- package/scripts/release-loop/node-verdict.ts +2 -0
- package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
- package/scripts/release-loop/resume-release.ts +33 -4
- package/scripts/release-loop/resume.ts +13 -5
- package/scripts/release-loop/spawn-lane.ts +2 -19
- package/scripts/release-loop/tui-sim-node.ts +3 -2
- package/scripts/release-loop/unattended-release.ts +16 -0
- package/scripts/test-deterministic.ts +5 -61
- package/scripts/train-reach-grouping.ts +48 -0
- package/scripts/tsc-incremental-cache.ts +86 -0
- package/scripts/tsc-incremental-diagnostics.ts +76 -0
- package/scripts/tsc-main-safety-net.ts +2 -2
- package/src/acp/client.ts +4 -1
- package/src/acp/core-turn-bridge.ts +50 -5
- package/src/ad-pipeline/run.ts +4 -2
- 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 +12 -0
- 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/capture/tui-self-report.ts +15 -0
- package/src/chat/chat-cli.ts +10 -2
- package/src/chat/index.ts +77 -11
- package/src/chat/input-control-key.ts +5 -3
- package/src/chat/tool-interrupt-behavior.ts +38 -0
- package/src/chat/tool-render/dispatch.ts +5 -1
- package/src/chat/turn-typeahead.ts +75 -20
- package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
- package/src/cli/agent-cli.ts +41 -13
- package/src/cli/config-audit.ts +123 -0
- package/src/cli/decisions-cli.ts +80 -6
- package/src/cli/log-event-names.ts +7 -0
- package/src/cli/mcp-login.ts +21 -5
- package/src/cli/msg-cli.ts +88 -0
- package/src/cli/pr-cli.ts +214 -57
- package/src/cli/pr-land-heavy-remote.ts +2 -2
- package/src/cli/pr-land-overlap-evidence.ts +63 -9
- 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/release-cli.ts +80 -14
- package/src/cli/seat-cli.ts +138 -3
- package/src/cli/self-update.ts +5 -2
- package/src/cli/tasks-cli.ts +97 -19
- package/src/context-bus/context-first.ts +13 -0
- package/src/context-bus/context-now.ts +13 -2
- package/src/context-bus/ops-events.ts +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/run-core-turn.ts +1 -0
- package/src/core-turn/run-goal-loop.ts +222 -3
- package/src/core-turn/seat-turn-cap.ts +79 -0
- package/src/core-turn/short-question.ts +38 -6
- package/src/core-turn/types.ts +3 -0
- package/src/dashboard/acp-boot.ts +3 -0
- package/src/dashboard/index.ts +224 -615
- package/src/dashboard/input/chat-main-entry-runtime.ts +1 -1
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
- package/src/dashboard/input/chat-main-session.ts +8 -1
- package/src/dashboard/input/chat-main-turn.ts +12 -3
- package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
- package/src/dashboard/input/external-input-host.ts +26 -0
- package/src/dashboard/input/internal-turn.ts +261 -0
- package/src/dashboard/input/seat-autowake.ts +318 -0
- package/src/dashboard/input/turn-steer-bridge.ts +70 -0
- package/src/dashboard/loop-scheduler.ts +72 -0
- package/src/dashboard/seat-boot-preamble.ts +18 -0
- package/src/dashboard/skill-runtime.ts +2 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
- package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
- package/src/dashboard/slash-runtime/index.ts +13 -0
- package/src/dashboard/turn-busy-teardown.ts +50 -0
- package/src/decisions/decision-ledger.ts +45 -4
- package/src/discord-self-message.ts +4 -4
- package/src/domains/release-tool.ts +18 -1
- package/src/field-note/transcribe.ts +17 -0
- package/src/github/remote-call.ts +81 -0
- package/src/goals/registry.ts +46 -6
- package/src/goals/types.ts +7 -1
- package/src/graph-runner/runner.ts +1 -0
- package/src/grok/credential.ts +26 -0
- package/src/harness/harness-clean.ts +2 -1
- package/src/harness/harness-cli-command.ts +52 -5
- package/src/harness/harness-gc.ts +2 -1
- package/src/harness/harness-incidents.ts +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 +152 -25
- package/src/input/external-input-queue.ts +33 -1
- package/src/intake-plane/slash.ts +14 -3
- package/src/keybindings.ts +4 -1
- package/src/llm/tool-loop-steered-rejection.ts +33 -0
- package/src/llm.ts +138 -19
- package/src/loops/consensus.ts +348 -0
- package/src/loops/msg-wake.ts +206 -4
- package/src/loops/observe.ts +19 -3
- package/src/loops/orchestrator/tick.ts +64 -10
- package/src/loops/orchestrator/traffic.ts +64 -1
- package/src/loops/registry.ts +30 -0
- package/src/market/signed-index.ts +14 -0
- package/src/mcp/mcp-oauth.ts +54 -5
- package/src/models/prompts.ts +28 -0
- package/src/msg/msg-sse-client.ts +223 -0
- package/src/msg/msg-store.ts +86 -2
- package/src/mss/logging/log-store.ts +225 -1
- package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
- package/src/nexus/api/http-server.ts +54 -15
- package/src/nexus/api/loop-resources.ts +19 -3
- package/src/nexus/api/ops-api.ts +11 -0
- package/src/nexus/daemon-thin-inventory.md +37 -0
- package/src/nexus/index.ts +70 -0
- package/src/nexus/state/state.ts +1 -0
- package/src/oauth/store.ts +32 -7
- package/src/onboarding/first-run.ts +28 -3
- package/src/ops/overview-cache.ts +16 -4
- package/src/ops/resources.ts +82 -0
- package/src/plugins/maker/connector-maker.ts +41 -0
- package/src/plugins/maker/skill-maker.ts +42 -0
- package/src/pr-tool/census.ts +288 -0
- package/src/prompt-library/chat-conciseness.ts +13 -0
- package/src/prompt-library/universal-preamble.ts +10 -5
- package/src/release-loop/gate-host-reservation.ts +97 -0
- package/src/release-loop/landing-freeze.ts +5 -0
- package/src/release-loop/light-rc.ts +5 -2
- package/src/release-loop/placement.ts +92 -1
- package/src/release-loop/rehearsal-shard-plan.ts +149 -0
- package/src/release-loop/rehearsal.ts +73 -17
- package/src/repl/index.ts +20 -2
- package/src/seat-loop/seat-knowhow.ts +282 -0
- package/src/seat-loop/seat-loop.ts +41 -2
- package/src/seat-loop/traffic-signal.ts +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 +229 -19
- package/src/self-dev/run-types.ts +20 -0
- package/src/self-dev/shard-aggregate.ts +13 -2
- package/src/self-dev/shard-plan.ts +47 -0
- package/src/self-dev/shard-run.ts +112 -10
- package/src/self-dev/spawn-lane-files.ts +19 -0
- package/src/self-implement/app-api-budget.ts +51 -11
- package/src/self-implement/config-gate.ts +2 -1
- package/src/self-implement/expose-gate.ts +2 -1
- package/src/self-implement/gate-artifacts.ts +405 -0
- package/src/self-implement/gate-cli.ts +201 -16
- package/src/self-implement/gate-remote.ts +110 -25
- package/src/self-implement/gate-scenario.ts +85 -0
- package/src/self-implement/goal-author.ts +160 -8
- package/src/self-implement/graph-authority.ts +38 -6
- package/src/self-implement/graph-overlay-condition.ts +92 -1
- package/src/self-implement/heal-triage.ts +79 -0
- package/src/self-implement/host-regate.ts +61 -3
- package/src/self-implement/orchestrator.ts +14 -123
- package/src/self-implement/pr-title.ts +123 -0
- package/src/self-implement/run-checkpoint.ts +235 -0
- package/src/self-implement/run-ledger.ts +155 -10
- package/src/self-implement/run-stop.ts +4 -3
- package/src/self-implement/run-ttl.ts +28 -4
- package/src/self-implement/seams.ts +2 -0
- package/src/self-implement/shadow-stage.ts +7 -6
- package/src/self-implement/stop-autoheal.ts +2 -1
- package/src/self-implement/train-gate-remote.ts +37 -8
- package/src/self-implement/train-reach-grouping.ts +157 -0
- package/src/self-implement/train-scenario-layers.ts +133 -0
- package/src/self-implement/uncommitted-work.ts +2 -0
- package/src/session/pending-input.ts +19 -0
- package/src/session/session-start.ts +224 -0
- package/src/session-runtime/parallel-dispatch.ts +22 -5
- package/src/skills/tools/dev-harness.ts +6 -4
- package/src/skills/tools/shell.ts +1 -1
- 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 +89 -12
- package/src/task-agent/remote-rejudge-bind.ts +28 -8
- package/src/task-agent/repair-cycle.ts +45 -7
- package/src/task-agent/repair-worker.ts +7 -0
- package/src/task-agent/run-identity.ts +200 -0
- package/src/task-agent/shadow.ts +50 -3
- package/src/task-agent/task-hand.ts +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/pod-command-job.ts +88 -28
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
- package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
- package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
- package/src/task-orchestrator/surfaces/pod-install-slots.ts +121 -9
- package/src/task-orchestrator/surfaces/pod-lease.ts +20 -6
- package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
- package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +27 -0
- package/src/task-orchestrator/surfaces/pod-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 +132 -15
- package/src/telegram.ts +2 -4
- 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 +48 -0
- package/src/user-config/gemini-server-tools.ts +9 -0
- package/src/user-config.ts +53 -16
- package/src/util/spawn-sync-output.ts +7 -0
- package/src/ux-sim/fake-bin.ts +154 -0
- package/src/ux-sim/fake-clock.ts +36 -0
- package/src/ux-sim/headless-tui.ts +72 -0
- package/src/ux-sim/in-process-cli.ts +2 -1
- package/src/ux-sim/temp-git-remote.ts +82 -0
- package/src/version/packed-revision.json +1 -1
- package/src/video-pipeline/recipes/vlog.ts +25 -7
- package/apps/pwa/out/_next/static/chunks/1015-9cba22a5a4554797.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
- package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
- package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
- package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
- package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
- package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
- package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
- package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
- package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
- package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
- package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
- package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
- package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
- package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
- package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
- package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
- package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
- package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
- package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
- package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
- package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
- package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
- package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
- package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
- package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
- package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
- package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
- /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_ssgManifest.js +0 -0
|
@@ -11,6 +11,7 @@ import { releaseGitDiffPaths, releasePathHold, releasePathHoldShouldPost, releas
|
|
|
11
11
|
import { detectTestInterference, failedNamesFromStreams, parseFailureCount, runBunTest, type MeasuredRun } from '../../scripts/detect-test-interference.js';
|
|
12
12
|
import { MAX_INSPECTED_TEST_FILES, runTestInterferenceGate } from '../../scripts/ci-test-interference-gate.js';
|
|
13
13
|
import { pwaGraph, pwaReach } from '../../scripts/ci-pwa-build-gate.js';
|
|
14
|
+
import { changedPathPairs, changedTsFiles, readGitFile, requiredExportFieldsInChanges } from '../../scripts/ci-typecheck-changed.js';
|
|
14
15
|
import { classifyMergeFailure, clipRegateDetail, parseConflictFiles, type HostRegateFailure } from './regate-detail.js';
|
|
15
16
|
import { buildImporterTestIndex, isTestPath } from './importer-test-index.js';
|
|
16
17
|
|
|
@@ -55,6 +56,48 @@ export type HostRegateDeps = {
|
|
|
55
56
|
syncMergedChecklist?: typeof import('../release-loop/merged-pr-checklist.js').syncMergedPrChecklist;
|
|
56
57
|
};
|
|
57
58
|
|
|
59
|
+
/**
|
|
60
|
+
* REGATE-PWA-DEPS-FOR-TSC (#26698 → #27484 must-fix): the typecheck gate requires apps/pwa dependencies for
|
|
61
|
+
* `runsPwa || wholeRepository` — present .ts/.tsx under apps/pwa/ in its own changed set, or any of its
|
|
62
|
+
* whole-repository promotion triggers (필수 export 필드 추가 · exported 심볼 삭제 · exported 함수 매개변수 증가,
|
|
63
|
+
* in ANY changed file). Decide it with the gate's own collectors — changedTsFiles ⊕ changedPathPairs ⊕
|
|
64
|
+
* requiredExportFieldsInChanges — against the candidate worktree and the same TSC_BASE_REF the gate receives,
|
|
65
|
+
* so dependency provision and restoration can never be narrower than the real typecheck scope. Git observation
|
|
66
|
+
* goes through the regate's injectable `command` seam (hermetic tests); changedTsFiles composes whitespace-token
|
|
67
|
+
* command strings, so its shell runner just splits them into (bin, args).
|
|
68
|
+
*/
|
|
69
|
+
export function typecheckGateTouchesPwa(
|
|
70
|
+
worktree: string,
|
|
71
|
+
typecheckBase: string,
|
|
72
|
+
command: NonNullable<HostRegateDeps['command']>,
|
|
73
|
+
): boolean {
|
|
74
|
+
const git = (bin: string, args: readonly string[]): unknown => {
|
|
75
|
+
const r = command(bin, args, worktree);
|
|
76
|
+
if (r.status !== 0) throw Object.assign(new Error((r.stderr || r.stdout || `${bin} exited ${String(r.status)}`).trim()), { status: r.status });
|
|
77
|
+
return r.stdout;
|
|
78
|
+
};
|
|
79
|
+
const changed = changedTsFiles((cmd) => {
|
|
80
|
+
const [bin, ...args] = cmd.split(' ');
|
|
81
|
+
return git(bin, args) as string;
|
|
82
|
+
}, { ...process.env, TSC_BASE_REF: typecheckBase }, worktree);
|
|
83
|
+
// Collection failures make the gate exit(1) before its dependency requirement; an empty changed set makes it
|
|
84
|
+
// pass without running tsc — neither path can demand apps/pwa dependencies.
|
|
85
|
+
if ((changed.failures?.length ?? 0) > 0 || changed.files.size === 0) return false;
|
|
86
|
+
// runsPwa: a present .ts/.tsx under apps/pwa/ in the gate's own changed set.
|
|
87
|
+
if ([...changed.files].some((file) => file.startsWith('apps/pwa/'))) return true;
|
|
88
|
+
const triggers = requiredExportFieldsInChanges(
|
|
89
|
+
changed.files,
|
|
90
|
+
changed.base,
|
|
91
|
+
changedPathPairs(changed.base, git),
|
|
92
|
+
(ref, path) => readGitFile(ref, path, git),
|
|
93
|
+
(file) => readFileSync(join(worktree, file), 'utf8'),
|
|
94
|
+
);
|
|
95
|
+
// A judgement failure makes the gate exit(1) before its dependency requirement, like the collection failures above.
|
|
96
|
+
if (triggers.failure) return false;
|
|
97
|
+
// wholeRepository: any promotion trigger widens the inspection to the whole repository, apps/pwa included.
|
|
98
|
+
return triggers.fields.length > 0 || triggers.removedSymbols.length > 0 || triggers.parameterIncreases.length > 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
58
101
|
const SPAWN_MAX_BUFFER = 256 * 1024 * 1024;
|
|
59
102
|
|
|
60
103
|
const defaultCommand: NonNullable<HostRegateDeps['command']> = (bin, args, cwd, env) => {
|
|
@@ -271,7 +314,10 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
|
|
|
271
314
|
const result = (event: 'passed' | 'failed' | 'unmeasured', step?: string, detail?: string, facts: Omit<HostRegateFailure, 'step' | 'detail'> = {}): HostRegateResult => {
|
|
272
315
|
if (step) failures.push({ step, detail: clipRegateDetail(detail ?? 'unknown'), ...facts });
|
|
273
316
|
log(event, { pr: input.prNumber, files, os: process.platform, ...interferenceNote, ...(step ? { failedStep: step, detail: clipRegateDetail(detail ?? 'unknown'), ...facts } : {}) });
|
|
274
|
-
|
|
317
|
+
// TA-REGATE-UNMEASURED — noMerge(TA 재게이트) 도 status 를 싣는다: draft `pr-head` 거부 같은 «못 잼»을 «실패»와 가르게.
|
|
318
|
+
return { passed: event === 'passed', failures, os: process.platform,
|
|
319
|
+
...(input.verifyOnly || input.noMerge ? { status: event } : {}),
|
|
320
|
+
...(input.verifyOnly && verifiedBase ? { baseCommit: verifiedBase } : {}) };
|
|
275
321
|
};
|
|
276
322
|
const run = (bin: string, args: readonly string[], cwd: string, env?: NodeJS.ProcessEnv): string => {
|
|
277
323
|
const r = command(bin, args, cwd, env);
|
|
@@ -305,6 +351,11 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
|
|
|
305
351
|
let stalePrBase: string | undefined;
|
|
306
352
|
const initialPrBase = baseCommit;
|
|
307
353
|
let buildPwa = false;
|
|
354
|
+
// REGATE-PWA-DEPS-FOR-TSC (#26698 → #27484 must-fix): the typecheck gate picks its own changed set and its own
|
|
355
|
+
// whole-repository promotion triggers — TSC_BASE_REF..HEAD — which can carry apps/pwa files that landed on
|
|
356
|
+
// main after this PR branched, and root-file export changes that widen the inspection to the whole repository.
|
|
357
|
+
// Set in the worktree phase below.
|
|
358
|
+
let typecheckTouchesPwa = false;
|
|
308
359
|
try {
|
|
309
360
|
let fetchedBase = fetchRef(`refs/heads/${baseRefName}`, 'base');
|
|
310
361
|
if (input.verifyOnly) { baseCommit = fetchedBase; verifiedBase = fetchedBase; }
|
|
@@ -406,7 +457,14 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
|
|
|
406
457
|
const provide = (dir: string, marker: string): void => provideCheckoutDependencies(candidate, input.repoRoot, dir, marker, (cwd) => { run('bun', ['install', '--frozen-lockfile'], cwd); });
|
|
407
458
|
provide('', 'typescript');
|
|
408
459
|
buildPwa = needsPwaBuild(files, worktree);
|
|
409
|
-
|
|
460
|
+
// REGATE-PWA-DEPS-FOR-TSC (#26698 → #27484 must-fix): provide('apps/pwa') must also fire when the typecheck
|
|
461
|
+
// gate's own scope — the same TSC_BASE_REF..HEAD it receives below — holds present .ts/.tsx files under
|
|
462
|
+
// apps/pwa/ OR any of its whole-repository promotion triggers (필수 export 필드 추가 · exported 심볼 삭제 ·
|
|
463
|
+
// exported 함수 매개변수 증가, in ANY changed file), even when buildPwa never turns on: without app deps
|
|
464
|
+
// the gate fails such runs as «의존성 없음» for environment reasons, not code defects.
|
|
465
|
+
const typecheckBase = input.verifyOnly ? baseCommit : base;
|
|
466
|
+
typecheckTouchesPwa = typecheckGateTouchesPwa(worktree, typecheckBase, command);
|
|
467
|
+
if ((buildPwa || typecheckTouchesPwa) && existsSync(join(worktree, 'apps/pwa'))) provide('apps/pwa', 'next');
|
|
410
468
|
} catch (e) { return result('unmeasured', 'worktree', String(e)); }
|
|
411
469
|
try {
|
|
412
470
|
const interferenceOptions = { neighbors: !input.verifyOnly };
|
|
@@ -427,7 +485,7 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
|
|
|
427
485
|
}
|
|
428
486
|
// The checked checkout is shared with interference/exposure gates. Verify dependencies at the
|
|
429
487
|
// typecheck boundary as well: a missing PWA link here made #27414 fail as an unmeasured host regate.
|
|
430
|
-
if (buildPwa && !existsSync(join(worktree, 'apps/pwa/node_modules'))) {
|
|
488
|
+
if ((buildPwa || typecheckTouchesPwa) && !existsSync(join(worktree, 'apps/pwa/node_modules'))) {
|
|
431
489
|
let failure: string | null = null;
|
|
432
490
|
try {
|
|
433
491
|
if (existsSync(join(worktree, 'apps/pwa'))) {
|
|
@@ -86,7 +86,6 @@ import { LogStore, logsDbPath, type LogQuery, type LogStoreRow } from '../mss/lo
|
|
|
86
86
|
import { refreshCodexQuotaSignals } from '../budget/codex-quota-refresh.js';
|
|
87
87
|
import { inspectActiveProvider, type ActiveProviderInfo } from '../provider-summary.js';
|
|
88
88
|
import { recordHitlEvent } from '../self-dev/hitl-log.js';
|
|
89
|
-
import { parseAskProseTitle } from '../self-dev/launch-preflight.js';
|
|
90
89
|
import { classifyReviewProviderFailure } from '../self-dev/review-provider-fallback.js';
|
|
91
90
|
import { classifyError } from '../session-runtime/retry-policy.js';
|
|
92
91
|
import { decomposeSelfDevGoal, inferHotPaths, type SelfDevDecomposeOptions } from '../self-dev/decompose.js';
|
|
@@ -154,6 +153,8 @@ import { plannedSelfImplBranch } from '../harness/worktree-branch-prefix.js';
|
|
|
154
153
|
export { slugifyFeature } from '../harness/worktree-branch-prefix.js';
|
|
155
154
|
import { AUTO_REVIEW_LABEL, resolveAutoReviewLabels } from './context-capsule.js';
|
|
156
155
|
import { GOAL_TYPES, extractVerbatimOriginalAsk, leadingGoalMetadata, parseAskFile, parseGoalType, type GoalType } from './goal-author.js';
|
|
156
|
+
import { goalDocumentForReleaseNote, goalChecklistIds, prTitle } from './pr-title.js';
|
|
157
|
+
export { goalChecklistIds, prTitle } from './pr-title.js';
|
|
157
158
|
import { renderRoundSummaryCard, type RoundSummaryEntry } from './round-summary-card.js';
|
|
158
159
|
import { computeFlexSignals } from './flex-signals.js';
|
|
159
160
|
import { resolveAdaptiveMaxReworkDecision, resolveEscalateTier, resolveEscalateTarget, buildReworkFeature, failIndicator, isRepeatedUnverifiedOnlyGateFailure, unverifiedRepeatKey, appendReworkHistory, truncateReworkHistoryByItem, applyReworkBudgetDecision, parseContractConflictRelaxation, parseReworkBudgetDecision, resolveReworkBudgetCarry, stripReworkBudgetHeaders, countConsecutiveMustFixIds, mergeReworkNotes, resolveReworkKind, type ReworkPlanRevision, type ReworkNotePart } from './rework-policy.js';
|
|
@@ -862,8 +863,15 @@ export function isHarnessTempArtifact(file: string): boolean {
|
|
|
862
863
|
return /(^|\/)\.elanous-typecheck-scope-[^/]+\.json$/.test(file);
|
|
863
864
|
}
|
|
864
865
|
|
|
866
|
+
/** Only this run's GOAL document is a harness artifact; unrelated GOAL edits remain in scope accounting. */
|
|
867
|
+
export function isHarnessGeneratedGoal(file: string, goalDocumentPath?: string): boolean {
|
|
868
|
+
const ownGoal = goalDocumentPath?.replace(/\\/g, '/').match(/(?:^|\/)(docs\/goals\/GOAL-[^/]+\.(?:md|txt))$/)?.[1];
|
|
869
|
+
return !!ownGoal && normalizeDeclaredScopePath(file) === ownGoal;
|
|
870
|
+
}
|
|
871
|
+
|
|
865
872
|
export function detectDeclaredScopeDiff(input: {
|
|
866
873
|
goalDocument?: string | null;
|
|
874
|
+
goalDocumentPath?: string;
|
|
867
875
|
changedFiles?: readonly string[] | null;
|
|
868
876
|
nameCap?: number;
|
|
869
877
|
}): DeclaredScopeDiff {
|
|
@@ -879,7 +887,8 @@ export function detectDeclaredScopeDiff(input: {
|
|
|
879
887
|
return { status: 'unknown-changed-files', outsideCount: null, outsideNames: [], nameCapReached: false, unmadeCount: null, unmadeNames: [], declaredCount: null };
|
|
880
888
|
}
|
|
881
889
|
const outside = [...new Set(input.changedFiles.map(normalizeDeclaredScopePath).filter(Boolean))]
|
|
882
|
-
.filter((file) => !
|
|
890
|
+
.filter((file) => !isHarnessGeneratedGoal(file, input.goalDocumentPath)
|
|
891
|
+
&& !declared.paths.some((target) => changedFileIsInsideDeclaredTarget(file, target)));
|
|
883
892
|
// ⭐ 「선언했는데 «안 채워진»」 것 — `outside` 의 반대 방향이다.
|
|
884
893
|
const changed = [...new Set(input.changedFiles.map(normalizeDeclaredScopePath).filter(Boolean))];
|
|
885
894
|
const unmade = declared.paths.filter((target) => !changed.some((file) => changedFileIsInsideDeclaredTarget(file, target)));
|
|
@@ -914,6 +923,7 @@ function observeDeclaredScopeDiff(
|
|
|
914
923
|
}
|
|
915
924
|
const diff = detectDeclaredScopeDiff({
|
|
916
925
|
goalDocument,
|
|
926
|
+
goalDocumentPath: input.goalFile,
|
|
917
927
|
changedFiles: input.changedFiles,
|
|
918
928
|
nameCap: input.nameCap,
|
|
919
929
|
});
|
|
@@ -2357,120 +2367,6 @@ function addedDiffEvidence(diff: string): { text: string; truncated: boolean } {
|
|
|
2357
2367
|
};
|
|
2358
2368
|
}
|
|
2359
2369
|
|
|
2360
|
-
function isRepositoryRelativePath(candidate: string): boolean {
|
|
2361
|
-
if (/^(?:[A-Za-z][A-Za-z0-9+.-]*:\/\/|[\\/]|[A-Za-z]:[\\/])/.test(candidate)) return false;
|
|
2362
|
-
const parts = candidate.split('/');
|
|
2363
|
-
return parts.length > 1
|
|
2364
|
-
&& parts.every((part) => part !== '.' && part !== '..' && /^[A-Za-z0-9_.-]+$/.test(part))
|
|
2365
|
-
&& /\.[A-Za-z0-9]+$/.test(parts.at(-1)!);
|
|
2366
|
-
}
|
|
2367
|
-
|
|
2368
|
-
function extractRepositoryRelativePaths(first: string): string[] {
|
|
2369
|
-
const candidates = first.split(/[\s,;()[\]{}"'`<>]+/).filter(Boolean);
|
|
2370
|
-
return candidates.filter(isRepositoryRelativePath);
|
|
2371
|
-
}
|
|
2372
|
-
|
|
2373
|
-
function parseAskMarkdownH1(feature: string): string | undefined {
|
|
2374
|
-
// ⛔ 펜스는 «문자»만이 아니라 «길이»로 닫힌다(CommonMark): 닫는 줄은 같은 문자 · 여는 줄 이상의 길이 · 뒤에 정보 문자열 없음.
|
|
2375
|
-
// 🩸 2026-09-23(#20050 착지 직후 실물): GOAL 문서가 원래 ask 를 ```` 네 개 펜스로 싸고, 그 안에 ``` 블록이 있다.
|
|
2376
|
-
// 문자만 보면 안쪽 ``` 이 바깥 ```` 를 «닫아» 안팎이 뒤집히고 ```bash 안의 `# 주석` 이 다시 제목이 됐다.
|
|
2377
|
-
let fence: { marker: '`' | '~'; run: number } | undefined;
|
|
2378
|
-
for (const line of feature.split(/\r?\n/)) {
|
|
2379
|
-
const trimmed = line.trim();
|
|
2380
|
-
const marker = trimmed[0] === '`' || trimmed[0] === '~' ? trimmed[0] : undefined;
|
|
2381
|
-
let run = 0;
|
|
2382
|
-
if (marker) {
|
|
2383
|
-
while (run < trimmed.length && trimmed[run] === marker) run += 1;
|
|
2384
|
-
}
|
|
2385
|
-
if (marker && run >= 3) {
|
|
2386
|
-
if (!fence) {
|
|
2387
|
-
fence = { marker, run };
|
|
2388
|
-
continue;
|
|
2389
|
-
}
|
|
2390
|
-
if (fence.marker === marker && run >= fence.run && trimmed.slice(run).trim() === '') {
|
|
2391
|
-
fence = undefined;
|
|
2392
|
-
continue;
|
|
2393
|
-
}
|
|
2394
|
-
}
|
|
2395
|
-
if (fence) continue;
|
|
2396
|
-
if (line[0] !== '#' || line[1] === '#') continue;
|
|
2397
|
-
if (line.length < 2 || !/\s/.test(line[1]!)) continue;
|
|
2398
|
-
const text = line.slice(1).trim();
|
|
2399
|
-
if (text) return text;
|
|
2400
|
-
}
|
|
2401
|
-
return undefined;
|
|
2402
|
-
}
|
|
2403
|
-
|
|
2404
|
-
function prTitleCodePointCount(text: string): number {
|
|
2405
|
-
return Array.from(text).length;
|
|
2406
|
-
}
|
|
2407
|
-
|
|
2408
|
-
function truncatePrTitle(text: string): string {
|
|
2409
|
-
const points = Array.from(text);
|
|
2410
|
-
return points.length <= 72 ? text : `${points.slice(0, 69).join('')}...`;
|
|
2411
|
-
}
|
|
2412
|
-
|
|
2413
|
-
export function goalChecklistIds(feature: string, goalFile?: string): string[] {
|
|
2414
|
-
const document = goalFile ? goalDocumentForReleaseNote(goalFile) : feature;
|
|
2415
|
-
const declaration = document.split(/\r?\n/).find((line) => line.startsWith('- 칸 id: '));
|
|
2416
|
-
const declared = declaration?.slice('- 칸 id: '.length).trim();
|
|
2417
|
-
if (declared && declared !== 'not declared') {
|
|
2418
|
-
return [...new Set(declared.split(' · ').map((id) => id.trim()).filter(Boolean))];
|
|
2419
|
-
}
|
|
2420
|
-
const firstLine = feature.split(/\r?\n/, 1)[0] ?? '';
|
|
2421
|
-
return [...new Set(Array.from(firstLine.matchAll(/\b[A-Z][A-Z0-9]+-[A-Z0-9]+\b/g), (match) => match[0]))];
|
|
2422
|
-
}
|
|
2423
|
-
|
|
2424
|
-
function prTitleWithoutChecklistId(feature: string): string {
|
|
2425
|
-
const proseTitle = parseAskProseTitle(feature);
|
|
2426
|
-
if (proseTitle) return truncatePrTitle(proseTitle);
|
|
2427
|
-
|
|
2428
|
-
const headingTitle = parseAskMarkdownH1(feature);
|
|
2429
|
-
if (headingTitle) return truncatePrTitle(headingTitle);
|
|
2430
|
-
|
|
2431
|
-
// ⛔ GOAL 문서는 원래 ask 를 `Original ask (verbatim, unmodified):` 아래 ```` 펜스로 싣는다 — 그 안은 «코드»가 아니라 인용된 마크다운이다.
|
|
2432
|
-
// 🩸 2026-09-23: #20051 이 펜스를 길이로 닫게 고치자 그 인용 블록 안의 H1 까지 «건너뛰어»,
|
|
2433
|
-
// 첫 줄이 `대상 경로:` 인 GOAL 문서 대부분이 경로 요약 제목으로 떨어졌다(실물: #20055 `src/self-implement: gate-baseline.ts, …`).
|
|
2434
|
-
// ⇒ 인용된 ask 를 꺼내 그 «안»에서 같은 규칙(제목: 줄 → 펜스 밖 H1)으로 한 번 더 찾는다.
|
|
2435
|
-
// ⚠️ 정보 문자열이 붙은 펜스(```bash 등)로 싸였으면 그 안은 «코드»다 — 인용된 마크다운으로 보지 않는다.
|
|
2436
|
-
const verbatim = extractVerbatimOriginalAsk(feature);
|
|
2437
|
-
const opener = verbatim?.range ? feature.slice(0, verbatim.range.start).split(/\r?\n/).filter((line, i, all) => i === all.length - 2)[0] ?? '' : '';
|
|
2438
|
-
const verbatimAsk = verbatim && /^\s*(`{3,}|~{3,})\s*$/.test(opener) ? verbatim.ask : undefined;
|
|
2439
|
-
if (verbatimAsk) {
|
|
2440
|
-
const askTitle = parseAskProseTitle(verbatimAsk) ?? parseAskMarkdownH1(verbatimAsk);
|
|
2441
|
-
if (askTitle) return truncatePrTitle(askTitle);
|
|
2442
|
-
}
|
|
2443
|
-
|
|
2444
|
-
const first = feature.split('\n')[0]!.trim();
|
|
2445
|
-
const paths = extractRepositoryRelativePaths(first);
|
|
2446
|
-
if (!paths.length) return truncatePrTitle(first);
|
|
2447
|
-
|
|
2448
|
-
const pathParts = paths.map((path) => path.split('/'));
|
|
2449
|
-
const commonParts: string[] = [];
|
|
2450
|
-
for (let index = 0; index < pathParts[0]!.length - 1; index++) {
|
|
2451
|
-
const part = pathParts[0]![index]!;
|
|
2452
|
-
if (!pathParts.every((parts) => parts[index] === part)) break;
|
|
2453
|
-
commonParts.push(part);
|
|
2454
|
-
}
|
|
2455
|
-
const fileNames = pathParts.map((parts) => parts.at(-1)!);
|
|
2456
|
-
const directoryPrefix = commonParts.length ? `${commonParts.join('/')}: ` : '';
|
|
2457
|
-
const titlePrefix = prTitleCodePointCount(directoryPrefix) + prTitleCodePointCount(fileNames[0]!) <= 72 ? directoryPrefix : '';
|
|
2458
|
-
const title = fileNames.reduce((result, fileName) => {
|
|
2459
|
-
const next = result ? `${result}, ${fileName}` : fileName;
|
|
2460
|
-
return prTitleCodePointCount(titlePrefix) + prTitleCodePointCount(next) <= 72 ? next : result;
|
|
2461
|
-
}, '');
|
|
2462
|
-
if (title) return `${titlePrefix}${title}`;
|
|
2463
|
-
const firstFileName = fileNames[0]!;
|
|
2464
|
-
return truncatePrTitle(firstFileName);
|
|
2465
|
-
}
|
|
2466
|
-
|
|
2467
|
-
export function prTitle(feature: string, goalFile?: string): string {
|
|
2468
|
-
const title = prTitleWithoutChecklistId(feature);
|
|
2469
|
-
const id = goalChecklistIds(feature, goalFile)[0];
|
|
2470
|
-
if (!id) return title;
|
|
2471
|
-
return truncatePrTitle(title.startsWith(`${id}: `) ? title : `${id}: ${title}`);
|
|
2472
|
-
}
|
|
2473
|
-
|
|
2474
2370
|
const BLOCKED_DRAFT_PR_HUMAN_JUDGMENT_ANCHOR = '## 사람 판단 필요';
|
|
2475
2371
|
|
|
2476
2372
|
/** 사람이 읽는 중단 사유 상한. 관측 `reason.slice(0, 240)` 과 같은 길이라 표시가 앞부분을 버리지 않는다. */
|
|
@@ -2683,12 +2579,6 @@ export class MergedReleaseNoteWriteError extends Error {
|
|
|
2683
2579
|
}
|
|
2684
2580
|
}
|
|
2685
2581
|
|
|
2686
|
-
function goalDocumentForReleaseNote(goalFile?: string): string {
|
|
2687
|
-
if (!goalFile) return '';
|
|
2688
|
-
try { return readFileSync(goalFile, 'utf8'); }
|
|
2689
|
-
catch { return ''; }
|
|
2690
|
-
}
|
|
2691
|
-
|
|
2692
2582
|
function shardReleaseNote(feature: string): ReleaseNoteSection | undefined {
|
|
2693
2583
|
const matches = [...feature.matchAll(/^## Shard identity\r?\n([^\r\n]+)/gm)];
|
|
2694
2584
|
const identity = matches.at(-1)?.[1];
|
|
@@ -7261,7 +7151,8 @@ async function runSelfImplementInner(
|
|
|
7261
7151
|
try { goalDocument = readFileSync(opts.goalFile, 'utf8'); } catch { /* unknown scope */ }
|
|
7262
7152
|
// 🩸 10-09: 범위 타입검사 임시 tsconfig(.elanous-typecheck-scope-*.json · scoped-typecheck-config.ts)가 옛 가지에 커밋된 뒤 지워지면
|
|
7263
7153
|
// «추적 파일 삭제» 라 impact=critical → 결정 카드가 «irreversible» 로 대표에게 갔다(D-20·35·43·80). 하니스 임시물은 범위 판정 밖이다.
|
|
7264
|
-
const scope = detectDeclaredScopeDiff({ goalDocument,
|
|
7154
|
+
const scope = detectDeclaredScopeDiff({ goalDocument, goalDocumentPath: opts.goalFile,
|
|
7155
|
+
changedFiles: gateRouteFiles?.filter(file => !harnessSeededPaths.includes(file) && !isHarnessTempArtifact(file)), nameCap: gateRouteFiles?.length });
|
|
7265
7156
|
// SCOPE-HELD-DELIVER — no declared target means the declaration was unreadable (e.g. paths listed with spaces), not
|
|
7266
7157
|
// that every edit is outside it: treat it like an unknown declaration and go on to the gate.
|
|
7267
7158
|
if (scope.status === 'known' && scope.declaredCount === 0 && (scope.outsideCount ?? 0) > 0) {
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { parseAskProseTitle } from '../self-dev/launch-preflight.js';
|
|
3
|
+
import { extractVerbatimOriginalAsk } from './goal-author.js';
|
|
4
|
+
|
|
5
|
+
export function goalDocumentForReleaseNote(goalFile?: string): string {
|
|
6
|
+
if (!goalFile) return '';
|
|
7
|
+
try { return readFileSync(goalFile, 'utf8'); }
|
|
8
|
+
catch { return ''; }
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function isRepositoryRelativePath(candidate: string): boolean {
|
|
12
|
+
if (/^(?:[A-Za-z][A-Za-z0-9+.-]*:\/\/|[\\/]|[A-Za-z]:[\\/])/.test(candidate)) return false;
|
|
13
|
+
const parts = candidate.split('/');
|
|
14
|
+
return parts.length > 1
|
|
15
|
+
&& parts.every((part) => part !== '.' && part !== '..' && /^[A-Za-z0-9_.-]+$/.test(part))
|
|
16
|
+
&& /\.[A-Za-z0-9]+$/.test(parts.at(-1)!);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function extractRepositoryRelativePaths(first: string): string[] {
|
|
20
|
+
const candidates = first.split(/[\s,;()[\]{}"'`<>]+/).filter(Boolean);
|
|
21
|
+
return candidates.filter(isRepositoryRelativePath);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function parseAskMarkdownH1(feature: string): string | undefined {
|
|
25
|
+
// ⛔ 펜스는 «문자»만이 아니라 «길이»로 닫힌다(CommonMark): 닫는 줄은 같은 문자 · 여는 줄 이상의 길이 · 뒤에 정보 문자열 없음.
|
|
26
|
+
// 🩸 2026-09-23(#20050 착지 직후 실물): GOAL 문서가 원래 ask 를 ```` 네 개 펜스로 싸고, 그 안에 ``` 블록이 있다.
|
|
27
|
+
// 문자만 보면 안쪽 ``` 이 바깥 ```` 를 «닫아» 안팎이 뒤집히고 ```bash 안의 `# 주석` 이 다시 제목이 됐다.
|
|
28
|
+
let fence: { marker: '`' | '~'; run: number } | undefined;
|
|
29
|
+
for (const line of feature.split(/\r?\n/)) {
|
|
30
|
+
const trimmed = line.trim();
|
|
31
|
+
const marker = trimmed[0] === '`' || trimmed[0] === '~' ? trimmed[0] : undefined;
|
|
32
|
+
let run = 0;
|
|
33
|
+
if (marker) {
|
|
34
|
+
while (run < trimmed.length && trimmed[run] === marker) run += 1;
|
|
35
|
+
}
|
|
36
|
+
if (marker && run >= 3) {
|
|
37
|
+
if (!fence) {
|
|
38
|
+
fence = { marker, run };
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (fence.marker === marker && run >= fence.run && trimmed.slice(run).trim() === '') {
|
|
42
|
+
fence = undefined;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (fence) continue;
|
|
47
|
+
if (line[0] !== '#' || line[1] === '#') continue;
|
|
48
|
+
if (line.length < 2 || !/\s/.test(line[1]!)) continue;
|
|
49
|
+
const text = line.slice(1).trim();
|
|
50
|
+
if (text) return text;
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function prTitleCodePointCount(text: string): number {
|
|
56
|
+
return Array.from(text).length;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function truncatePrTitle(text: string): string {
|
|
60
|
+
const points = Array.from(text);
|
|
61
|
+
return points.length <= 72 ? text : `${points.slice(0, 69).join('')}...`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function goalChecklistIds(feature: string, goalFile?: string): string[] {
|
|
65
|
+
const document = goalFile ? goalDocumentForReleaseNote(goalFile) : feature;
|
|
66
|
+
const declaration = document.split(/\r?\n/).find((line) => line.startsWith('- 칸 id: '));
|
|
67
|
+
const declared = declaration?.slice('- 칸 id: '.length).trim();
|
|
68
|
+
if (declared && declared !== 'not declared') {
|
|
69
|
+
return [...new Set(declared.split(' · ').map((id) => id.trim()).filter(Boolean))];
|
|
70
|
+
}
|
|
71
|
+
const firstLine = feature.split(/\r?\n/, 1)[0] ?? '';
|
|
72
|
+
return [...new Set(Array.from(firstLine.matchAll(/\b[A-Z][A-Z0-9]+-[A-Z0-9]+\b/g), (match) => match[0]))];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function prTitleWithoutChecklistId(feature: string): string {
|
|
76
|
+
const proseTitle = parseAskProseTitle(feature);
|
|
77
|
+
if (proseTitle) return truncatePrTitle(proseTitle);
|
|
78
|
+
|
|
79
|
+
const headingTitle = parseAskMarkdownH1(feature);
|
|
80
|
+
if (headingTitle) return truncatePrTitle(headingTitle);
|
|
81
|
+
|
|
82
|
+
// ⛔ GOAL 문서는 원래 ask 를 `Original ask (verbatim, unmodified):` 아래 ```` 펜스로 싣는다 — 그 안은 «코드»가 아니라 인용된 마크다운이다.
|
|
83
|
+
// 🩸 2026-09-23: #20051 이 펜스를 길이로 닫게 고치자 그 인용 블록 안의 H1 까지 «건너뛰어»,
|
|
84
|
+
// 첫 줄이 `대상 경로:` 인 GOAL 문서 대부분이 경로 요약 제목으로 떨어졌다(실물: #20055 `src/self-implement: gate-baseline.ts, …`).
|
|
85
|
+
// ⇒ 인용된 ask 를 꺼내 그 «안»에서 같은 규칙(제목: 줄 → 펜스 밖 H1)으로 한 번 더 찾는다.
|
|
86
|
+
// ⚠️ 정보 문자열이 붙은 펜스(```bash 등)로 싸였으면 그 안은 «코드»다 — 인용된 마크다운으로 보지 않는다.
|
|
87
|
+
const verbatim = extractVerbatimOriginalAsk(feature);
|
|
88
|
+
const opener = verbatim?.range ? feature.slice(0, verbatim.range.start).split(/\r?\n/).filter((line, i, all) => i === all.length - 2)[0] ?? '' : '';
|
|
89
|
+
const verbatimAsk = verbatim && /^\s*(`{3,}|~{3,})\s*$/.test(opener) ? verbatim.ask : undefined;
|
|
90
|
+
if (verbatimAsk) {
|
|
91
|
+
const askTitle = parseAskProseTitle(verbatimAsk) ?? parseAskMarkdownH1(verbatimAsk);
|
|
92
|
+
if (askTitle) return truncatePrTitle(askTitle);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const first = feature.split('\n')[0]!.trim();
|
|
96
|
+
const paths = extractRepositoryRelativePaths(first);
|
|
97
|
+
if (!paths.length) return truncatePrTitle(first);
|
|
98
|
+
|
|
99
|
+
const pathParts = paths.map((path) => path.split('/'));
|
|
100
|
+
const commonParts: string[] = [];
|
|
101
|
+
for (let index = 0; index < pathParts[0]!.length - 1; index++) {
|
|
102
|
+
const part = pathParts[0]![index]!;
|
|
103
|
+
if (!pathParts.every((parts) => parts[index] === part)) break;
|
|
104
|
+
commonParts.push(part);
|
|
105
|
+
}
|
|
106
|
+
const fileNames = pathParts.map((parts) => parts.at(-1)!);
|
|
107
|
+
const directoryPrefix = commonParts.length ? `${commonParts.join('/')}: ` : '';
|
|
108
|
+
const titlePrefix = prTitleCodePointCount(directoryPrefix) + prTitleCodePointCount(fileNames[0]!) <= 72 ? directoryPrefix : '';
|
|
109
|
+
const title = fileNames.reduce((result, fileName) => {
|
|
110
|
+
const next = result ? `${result}, ${fileName}` : fileName;
|
|
111
|
+
return prTitleCodePointCount(titlePrefix) + prTitleCodePointCount(next) <= 72 ? next : result;
|
|
112
|
+
}, '');
|
|
113
|
+
if (title) return `${titlePrefix}${title}`;
|
|
114
|
+
const firstFileName = fileNames[0]!;
|
|
115
|
+
return truncatePrTitle(firstFileName);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function prTitle(feature: string, goalFile?: string): string {
|
|
119
|
+
const title = prTitleWithoutChecklistId(feature);
|
|
120
|
+
const id = goalChecklistIds(feature, goalFile)[0];
|
|
121
|
+
if (!id) return title;
|
|
122
|
+
return truncatePrTitle(title.startsWith(`${id}: `) ? title : `${id}: ${title}`);
|
|
123
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* run-checkpoint/v1 묶음 스키마 — 런의 «체크포인트» 스냅샷을 판 번호 있는 타입으로 직렬화한다.
|
|
3
|
+
*
|
|
4
|
+
* ⛔ 이 판은 «묶음 정의 ⊕ 조립 ⊕ 디스크 기록»까지만 담는다. orchestrator 배선 · run-ledger
|
|
5
|
+
* additive 이벤트('checkpoint'/'resumed'/'checkpoint-failed') · salvage CLI 명령은
|
|
6
|
+
* 같은 골의 형제 조각이 담당한다(의도적 경계 — 분해 판 4조각의 1번).
|
|
7
|
+
*
|
|
8
|
+
* 📐 run-ledger 패턴을 «어느 것을 왜» 따르나(원문이 'writeCheckpoi'에서 끊겨 임의로 정하지 않는다):
|
|
9
|
+
* ① `runLedgerDir`(run-ledger.ts:205) — 상태 뿌리에서 «자기 저장소 이름»의 디렉터리를 여는 방식.
|
|
10
|
+
* 여기도 `elanousStateRoot()` 아래 `run-checkpoint/` 디렉터리로 열어, 저장 위치가 run-ledger 와
|
|
11
|
+
* 같은 축(state root)에 있게 한다. 원문이 저장 위치의 경로를 정하지 않았으므로 이 패턴을 따른다.
|
|
12
|
+
* ② `runLedgerPath`(run-ledger.ts:209) — runId 를 «normalizeRunId 의 산출 집합»으로 검증하고
|
|
13
|
+
* 거부는 유지하되 정규화는 «하지 않는다»(경로 탈출 방어). 여기도 같은 검사를 쓰되 파일은
|
|
14
|
+
* 스냅샷이므로 JSONL 추가가 아니라 «덮어쓰기» 하나로 `<runId>.checkpoint.json` 을 쓴다.
|
|
15
|
+
* JSONL 이 아닌 이유: 원장은 사건의 «추가», 체크포인트는 마지막 상태의 «스냅샷»이다 —
|
|
16
|
+
* appendRunLedgerEntry 가 줄을 «쌓는» 것과 달리 resume 은 «최신 하나»만 읽으면 된다.
|
|
17
|
+
* ③ `appendRunLedgerEntry`(run-ledger.ts:411) — 쓰기 전 ①`refuseProductionLedgerWriteInTest`
|
|
18
|
+
* 가드(테스트 중 운영 원장 쓰기 차단) ② `mkdirSync(dir, { recursive: true })` 순서를 그대로 따른다.
|
|
19
|
+
* «run-ledger 줄 하나»가 아니라 «JSON 파일 하나»이지만 쓰기 관문·디렉터리 보증은 같아야 한다.
|
|
20
|
+
*/
|
|
21
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
22
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
23
|
+
import { join } from 'node:path';
|
|
24
|
+
import { refuseProductionLedgerWriteInTest } from '../harness/ledger-write-guard.js';
|
|
25
|
+
import { normalizeRunId } from '../harness/harness-space.js';
|
|
26
|
+
import { elanousStateRoot } from '../autopilot/state-paths.js';
|
|
27
|
+
|
|
28
|
+
/** 판 번호 — 묶음 필드 구성이 바뀌면 이 값을 올리고 읽는 쪽은 판을 검사한다. */
|
|
29
|
+
export const CHECKPOINT_SCHEMA_VERSION = 1;
|
|
30
|
+
|
|
31
|
+
/** 판 번호가 문자열 표면(직렬화된 JSON 안)에 남는 형태. */
|
|
32
|
+
export const CHECKPOINT_SCHEMA_ID = 'run-checkpoint/v1';
|
|
33
|
+
|
|
34
|
+
/** 라운드 카드 — 조립 시점에 판을 정하지 않는다(원문이 카드의 필드를 정하지 않았다). */
|
|
35
|
+
export type CheckpointRoundCard = Record<string, unknown>;
|
|
36
|
+
|
|
37
|
+
/** 미배달 감독 지시 한 줄 — 조립자가 주는 문면 그대로. */
|
|
38
|
+
export type UndeliveredSupervisorDirective = string;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* run-checkpoint/v1 묶음 — 전 필드의 원문 명세:
|
|
42
|
+
* runId · 골 문면(goalText) · 판정 상태(verdictStatus) · salvage 가지 sha(salvageBranchSha) ·
|
|
43
|
+
* 세션 대화 기록(sessionTranscript) · 라운드 카드(roundCards) · EVIDENCE/RESULT(evidenceResult) ·
|
|
44
|
+
* 미배달 감독 지시(undeliveredSupervisorDirectives) · 자식 모델(childModel) · 쓴 토큰(tokensUsed) ·
|
|
45
|
+
* sha256(«전 필드 포함» — sha256 자기 자신만 제외한 나머지 전 필드의 정규화 직렬화에 걸친다).
|
|
46
|
+
*/
|
|
47
|
+
export interface RunCheckpointBundle {
|
|
48
|
+
/** 판이자 종류 표지 — 항상 `${CHECKPOINT_SCHEMA_ID}`. */
|
|
49
|
+
schema: typeof CHECKPOINT_SCHEMA_ID;
|
|
50
|
+
/** 판 번호(정수) — CHECKPOINT_SCHEMA_VERSION 과 같다. */
|
|
51
|
+
schemaVersion: typeof CHECKPOINT_SCHEMA_VERSION;
|
|
52
|
+
runId: string;
|
|
53
|
+
goalText: string;
|
|
54
|
+
verdictStatus: string;
|
|
55
|
+
/** 없으면 null — «모름»과 «없음»을 나눈다. */
|
|
56
|
+
salvageBranchSha: string | null;
|
|
57
|
+
/** null = «미확인»(조립자가 주지 않음) — 빈 문자열(«실제로 비어 있음»)과 구별한다. */
|
|
58
|
+
sessionTranscript: string | null;
|
|
59
|
+
/** null = «미확인» — 빈 배열(«카드 0장»)과 구별한다. */
|
|
60
|
+
roundCards: readonly CheckpointRoundCard[] | null;
|
|
61
|
+
/** null = «미확인» — 빈 문자열과 구별한다. */
|
|
62
|
+
evidenceResult: string | null;
|
|
63
|
+
/** null = «미확인» — 빈 배열(«미배달 지시 0건»)과 구별한다. */
|
|
64
|
+
undeliveredSupervisorDirectives: readonly UndeliveredSupervisorDirective[] | null;
|
|
65
|
+
childModel: string | null;
|
|
66
|
+
tokensUsed: number | null;
|
|
67
|
+
/** sha256 — 자기를 제외한 전 필드 정규화 직렬화에 대한 sha256 hex. */
|
|
68
|
+
sha256: string;
|
|
69
|
+
recordedAt: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** 조립 재료 — run 사실 원형. `buildCheckpointBundle` 이 여기서 묶음을 만든다. */
|
|
73
|
+
export interface RunCheckpointFacts {
|
|
74
|
+
runId: string;
|
|
75
|
+
goalText: string;
|
|
76
|
+
verdictStatus: string;
|
|
77
|
+
salvageBranchSha?: string | null;
|
|
78
|
+
sessionTranscript?: string | null;
|
|
79
|
+
roundCards?: readonly CheckpointRoundCard[] | null;
|
|
80
|
+
evidenceResult?: string | null;
|
|
81
|
+
undeliveredSupervisorDirectives?: readonly UndeliveredSupervisorDirective[] | null;
|
|
82
|
+
childModel?: string | null;
|
|
83
|
+
tokensUsed?: number | null;
|
|
84
|
+
recordedAt?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** 정렬된 키 직렬화 — 입력은 이미 «JSON 값»(toJSON·undefined·NaN 이 풀린 뒤)이어야 한다. */
|
|
88
|
+
function sortedJson(value: unknown): string {
|
|
89
|
+
if (value === null || typeof value !== 'object') return JSON.stringify(value);
|
|
90
|
+
if (Array.isArray(value)) return `[${value.map((item) => sortedJson(item)).join(',')}]`;
|
|
91
|
+
const entries = Object.entries(value as Record<string, unknown>)
|
|
92
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
93
|
+
return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${sortedJson(v)}`).join(',')}}`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 객체 키를 «정렬된» 안정 직렬화로 — 같은 값이면 같은 문자열(sha256 재현성).
|
|
98
|
+
* ⭐ 해시와 저장이 «같은 직렬화»를 보도록 먼저 `JSON.stringify` 의미론(toJSON·Date→ISO ·
|
|
99
|
+
* 배열 속 undefined→null · 객체 속 undefined 제거 · NaN→null)으로 한 번 풀고 키만 정렬한다.
|
|
100
|
+
* 그래야 `writeCheckpoint` 가 쓴 파일을 `readCheckpoint` 가 다시 해시해도 같은 값이 나온다.
|
|
101
|
+
*/
|
|
102
|
+
function canonicalJson(value: unknown): string {
|
|
103
|
+
const json = JSON.stringify(value);
|
|
104
|
+
if (json === undefined) return 'null';
|
|
105
|
+
return sortedJson(JSON.parse(json));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** sha256 조수 — hex 문자열. 묶음의 sha256 필드에 넣는 값과 같은 계산이다. */
|
|
109
|
+
export function sha256Hex(value: unknown): string {
|
|
110
|
+
return createHash('sha256').update(canonicalJson(value), 'utf8').digest('hex');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** sha256 자기 자신을 제외한 «전 필드»를 걸치는 다이제스트(원문: 'sha256 전 필드 포함'). */
|
|
114
|
+
export function bundleSha256(bundle: Omit<RunCheckpointBundle, 'sha256'>): string {
|
|
115
|
+
const { sha256: _omit, ...rest } = bundle as RunCheckpointBundle;
|
|
116
|
+
return sha256Hex(rest);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const isStringArray = (v: unknown): boolean => Array.isArray(v) && v.every((x) => typeof x === 'string');
|
|
120
|
+
const isNullableString = (v: unknown): boolean => v === null || typeof v === 'string';
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* 묶음의 판(schema ⊕ schemaVersion)과 필수 필드의 존재·타입을 검증한다 — 쓰기·읽기 공통 관문.
|
|
124
|
+
* 판 번호는 «지원하는 판»과 정확히 같아야 한다(다른 판을 v1 으로 받아들이지 않는다).
|
|
125
|
+
*/
|
|
126
|
+
export function assertCheckpointShape(value: unknown): asserts value is RunCheckpointBundle {
|
|
127
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
128
|
+
throw new Error('invalid checkpoint: not an object');
|
|
129
|
+
}
|
|
130
|
+
const b = value as Record<string, unknown>;
|
|
131
|
+
if (b.schema !== CHECKPOINT_SCHEMA_ID) {
|
|
132
|
+
throw new Error(`unknown checkpoint schema: ${String(b.schema)}`);
|
|
133
|
+
}
|
|
134
|
+
if (b.schemaVersion !== CHECKPOINT_SCHEMA_VERSION) {
|
|
135
|
+
throw new Error(`unsupported checkpoint schemaVersion: ${String(b.schemaVersion)}`);
|
|
136
|
+
}
|
|
137
|
+
const bad: string[] = [];
|
|
138
|
+
for (const key of ['runId', 'goalText', 'verdictStatus', 'sha256', 'recordedAt']) {
|
|
139
|
+
if (typeof b[key] !== 'string') bad.push(key);
|
|
140
|
+
}
|
|
141
|
+
if (!isNullableString(b.salvageBranchSha)) bad.push('salvageBranchSha');
|
|
142
|
+
// null = «미확인» 을 받아들인다(빈 값과 다른 값) — 키 자체가 없으면(undefined) 거부한다.
|
|
143
|
+
if (!isNullableString(b.sessionTranscript)) bad.push('sessionTranscript');
|
|
144
|
+
if (!isNullableString(b.evidenceResult)) bad.push('evidenceResult');
|
|
145
|
+
if (!isNullableString(b.childModel)) bad.push('childModel');
|
|
146
|
+
if (!(b.tokensUsed === null || (typeof b.tokensUsed === 'number' && Number.isFinite(b.tokensUsed)))) {
|
|
147
|
+
bad.push('tokensUsed');
|
|
148
|
+
}
|
|
149
|
+
if (b.roundCards !== null && (!Array.isArray(b.roundCards) || !b.roundCards.every((c) => c !== null && typeof c === 'object' && !Array.isArray(c)))) {
|
|
150
|
+
bad.push('roundCards');
|
|
151
|
+
}
|
|
152
|
+
if (b.undeliveredSupervisorDirectives !== null && !isStringArray(b.undeliveredSupervisorDirectives)) bad.push('undeliveredSupervisorDirectives');
|
|
153
|
+
if (bad.length > 0) throw new Error(`invalid checkpoint fields: ${bad.join(', ')}`);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** run 사실에서 run-checkpoint/v1 묶음을 조립한다 — sha256 도 이 안에서 계산해 넣는다. */
|
|
157
|
+
export function buildCheckpointBundle(facts: RunCheckpointFacts): RunCheckpointBundle {
|
|
158
|
+
const runId = facts.runId;
|
|
159
|
+
// runLedgerPath 패턴: 정규화는 하지 않고, normalizeRunId 의 «산출 집합»만 받아들인다.
|
|
160
|
+
if (!runId || runId !== normalizeRunId(runId)) throw new Error(`invalid runId: ${runId}`);
|
|
161
|
+
const partial: Omit<RunCheckpointBundle, 'sha256'> = {
|
|
162
|
+
schema: CHECKPOINT_SCHEMA_ID,
|
|
163
|
+
schemaVersion: CHECKPOINT_SCHEMA_VERSION,
|
|
164
|
+
runId,
|
|
165
|
+
goalText: facts.goalText,
|
|
166
|
+
verdictStatus: facts.verdictStatus,
|
|
167
|
+
salvageBranchSha: facts.salvageBranchSha ?? null,
|
|
168
|
+
// 생략 = «미확인»(null) — 빈 값으로 채워 «실제로 비어 있음»으로 위장하지 않는다.
|
|
169
|
+
sessionTranscript: facts.sessionTranscript ?? null,
|
|
170
|
+
roundCards: facts.roundCards ?? null,
|
|
171
|
+
evidenceResult: facts.evidenceResult ?? null,
|
|
172
|
+
undeliveredSupervisorDirectives: facts.undeliveredSupervisorDirectives ?? null,
|
|
173
|
+
childModel: facts.childModel ?? null,
|
|
174
|
+
tokensUsed: facts.tokensUsed ?? null,
|
|
175
|
+
recordedAt: facts.recordedAt ?? new Date().toISOString(),
|
|
176
|
+
};
|
|
177
|
+
// 저장될 꼴(JSON 값)로 한 번 풀어, 메모리 묶음 = 파일에서 읽은 묶음이 되게 한다(Date→ISO 등).
|
|
178
|
+
const stored = JSON.parse(JSON.stringify(partial)) as Omit<RunCheckpointBundle, 'sha256'>;
|
|
179
|
+
return { ...stored, sha256: bundleSha256(stored) };
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** runLedgerDir 패턴 — state root 아래 «자기 저장소 이름» 디렉터리. */
|
|
183
|
+
export function checkpointDir(stateDir?: string): string {
|
|
184
|
+
return join(stateDir ?? elanousStateRoot(), 'run-checkpoint');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** runLedgerPath 패턴 — runId 검증(정규화 아님) 후 경로 결정. */
|
|
188
|
+
export function checkpointPath(runId: string, dir = checkpointDir()): string {
|
|
189
|
+
if (runId !== normalizeRunId(runId) || !runId) throw new Error(`invalid runId: ${runId}`);
|
|
190
|
+
return join(dir, `${runId}.checkpoint.json`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* 묶음을 디스크에 기록한다(appendRunLedgerEntry 의 쓰기 관문·디렉터리 보증을 따른다).
|
|
195
|
+
* 반환값은 기록한 파일 경로 — 형제 조각의 원장 이벤트 'checkpoint' {bundleRef} 가 여기 담긴다.
|
|
196
|
+
*
|
|
197
|
+
* ⛔ 스냅샷은 «최신 하나»라 덮어쓰기가 곧 이전 상태의 소실이다. 그래서
|
|
198
|
+
* ① 쓰기 «전»에 판·sha256 을 검증해 무효 묶음이면 던지고 기존 파일을 건드리지 않는다.
|
|
199
|
+
* ② 임시 파일에 쓴 뒤 rename 으로 원자 교체한다(쓰다 죽어도 반쪽 파일이 남지 않는다).
|
|
200
|
+
*/
|
|
201
|
+
export function writeCheckpoint(bundle: RunCheckpointBundle, dir = checkpointDir()): string {
|
|
202
|
+
assertCheckpointShape(bundle);
|
|
203
|
+
const path = checkpointPath(bundle.runId, dir);
|
|
204
|
+
const body = `${JSON.stringify(bundle, null, 2)}\n`;
|
|
205
|
+
// 저장될 꼴 그대로를 다시 해시한다 — 읽기 쪽 검증과 같은 입력이다.
|
|
206
|
+
const expected = bundleSha256(JSON.parse(body) as RunCheckpointBundle);
|
|
207
|
+
if (bundle.sha256 !== expected) {
|
|
208
|
+
throw new Error(`checkpoint sha256 mismatch: ${bundle.sha256} != ${expected}`);
|
|
209
|
+
}
|
|
210
|
+
if (refuseProductionLedgerWriteInTest(dir, 'run-checkpoint')) return '';
|
|
211
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
212
|
+
const tmp = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
213
|
+
try {
|
|
214
|
+
writeFileSync(tmp, body, 'utf8');
|
|
215
|
+
renameSync(tmp, path);
|
|
216
|
+
} catch (error) {
|
|
217
|
+
rmSync(tmp, { force: true });
|
|
218
|
+
throw error;
|
|
219
|
+
}
|
|
220
|
+
return path;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** 기록된 묶음을 읽어 sha256 이 전 필드에 대해 아직 성립하는지 검증과 함께 돌려준다. */
|
|
224
|
+
export function readCheckpoint(runId: string, dir = checkpointDir()): RunCheckpointBundle {
|
|
225
|
+
const raw: unknown = JSON.parse(readFileSync(checkpointPath(runId, dir), 'utf8'));
|
|
226
|
+
assertCheckpointShape(raw);
|
|
227
|
+
if (raw.runId !== runId) {
|
|
228
|
+
throw new Error(`checkpoint runId mismatch: requested ${runId}, file has ${raw.runId}`);
|
|
229
|
+
}
|
|
230
|
+
const expected = bundleSha256(raw);
|
|
231
|
+
if (raw.sha256 !== expected) {
|
|
232
|
+
throw new Error(`checkpoint sha256 mismatch: ${raw.sha256} != ${expected}`);
|
|
233
|
+
}
|
|
234
|
+
return raw;
|
|
235
|
+
}
|