elanous 0.2.29 → 0.2.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → IVKr3AlRUVLKsw2fh7eXF}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{058a98ba.7eb28d5e6dc03565.js → 0bb0ff36.b8d418980951e5ba.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +27 -0
- package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +287 -0
- package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +62 -0
- package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6013-2f769370d8b4c2c6.js → 1335-6731f392c35216eb.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8332.6f0f49df772e163b.js → 1654.32de4b324981a188.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
- package/apps/pwa/out/_next/static/chunks/{8795.32573a185af18c7b.js → 1913.7cc6fb6055b1ed3f.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{419.736c0d6f426249a7.js → 2001.6c7e0fd02190886c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6767.1fcfc9b8be83975f.js → 2213.2ccbada92c33ea0f.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4759.1f76713aefb87db5.js → 2871.0bca6137343b3f76.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6776.06ff1e3b464cc607.js → 2898.fd781bc7cf01a7b7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1782-59db1b5aa06df38a.js → 2940-619bfd8ef337c611.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{8471.8d2a8c74f09c36ff.js → 2985.39ccdecd36848b12.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +115 -0
- package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +64 -0
- package/apps/pwa/out/_next/static/chunks/{bc324b7c.02a09dd93f6a399b.js → 3267c0e6.d34854e7b3984a6e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3278.2e5d15b53a4091c8.js +2 -0
- package/apps/pwa/out/_next/static/chunks/{7725-4f83d5541fbdb81b.js → 3541-ce3a5424ed5ad7f1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +34 -0
- package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{46bd8bea.2f4b4099172fcdb7.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1142.65d002789ab3af7d.js → 4174.92ed04922709ac9e.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +36 -0
- package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +286 -0
- package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +77 -0
- package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +226 -0
- package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +79 -0
- package/apps/pwa/out/_next/static/chunks/5173-233188df2f42c626.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +148 -0
- package/apps/pwa/out/_next/static/chunks/5307.60f2209e809bd627.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3396-97b97928c49190c9.js → 5458-16cd7a2b51b74c8c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3403.7199205e65124486.js → 5525.86debf231e181813.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9143.ff14585db1d275ff.js → 5543.a438b8ab5a13ea47.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +74 -0
- package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +94 -0
- package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8398.73a19b39715eda04.js → 6092.a7f99e68b188ca66.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5591.a35e7a217734a8b9.js → 6157.0c9af021de4fb31b.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7375.050ea0d72968e49f.js → 6433.fc573af22bbc9ab7.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +90 -0
- package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +32 -0
- package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +104 -0
- package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +24 -0
- package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
- package/apps/pwa/out/_next/static/chunks/69-0a2c8209c6d4a158.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1852.7f7b53991fcb99ef.js → 7502.ccd5b8065545edd0.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
- package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6534.1ab00f370db7b105.js → 7862.30a8d6482bb238eb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
- package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
- package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.js → 9221.7d22eaf353a2d4e7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8767-2f6a634f5abeaa01.js → 9279-d28c5b7754d010ae.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.js → 9989.3694300e5f000b14.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-a27b1e5a0d1b308f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-32866485913d6a04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/{page-29900ed0011b2c83.js → page-c219f2ed171131be.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-04d00ae9b0890349.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
- package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
- package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
- package/apps/pwa/out/_next/static/css/b5d88eba78a3d7bf.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +26 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +23 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/bin/elanous.mjs +7 -3
- package/graphs/context/nightly-condense.yaml +1 -0
- package/graphs/implement-loop.yaml +5 -0
- package/graphs/intake/intake-daily.yaml +8 -1
- package/graphs/intake/recipes.yaml +5 -0
- package/graphs/lecture/lecture-note.yaml +2 -2
- package/graphs/ops/harness-gc.yaml +1 -0
- package/graphs/release/recipes.yaml +3 -0
- package/graphs/release/release-loop.yaml +9 -5
- package/graphs/units/recipes.yaml +3 -0
- package/graphs/units/release-gate-recheck.yaml +15 -0
- package/package.json +2 -1
- package/scripts/check-native-tool-wiring.ts +3 -2
- package/scripts/ci-android-unit-tests.ts +16 -0
- package/scripts/ci-typecheck-changed.ts +63 -10
- package/scripts/coord-channel-watch.sh +22 -16
- package/scripts/coord-role-pack.ts +81 -2
- package/scripts/cron-run.ts +96 -3
- package/scripts/detect-test-interference.ts +38 -5
- package/scripts/gate-pr-cache.ts +65 -0
- package/scripts/gh-surface/capture.ts +126 -0
- package/scripts/gh-surface/gh +40 -0
- package/scripts/import-graph-scc.ts +38 -0
- package/scripts/install.ps1 +19 -0
- package/scripts/intake-social.ts +181 -0
- package/scripts/lecture-note/node.ts +71 -4
- package/scripts/lib/android-toolchain.ts +32 -0
- package/scripts/lib/deterministic-env.ts +62 -0
- package/scripts/lib/gate-test-env.ts +19 -0
- package/scripts/measure-goal-grounding-corpus.ts +2 -1
- package/scripts/measure-si-task-cpu.ts +143 -0
- package/scripts/ratchets/test-interference-patterns.allowlist.txt +255 -0
- package/scripts/ratchets/test-interference-patterns.ts +367 -0
- package/scripts/release-loop/cut-branch.ts +4 -3
- package/scripts/release-loop/export-check-node.ts +0 -1
- package/scripts/release-loop/fixtures/warm-failure-assertion/sample.junit.xml +8 -0
- package/scripts/release-loop/fixtures/warm-job-029/sample.json +1 -0
- package/scripts/release-loop/fixtures/warm-job-029/sample.junit.xml +10 -0
- package/scripts/release-loop/gate-closure.ts +12 -8
- package/scripts/release-loop/gate-diff.ts +1 -1
- package/scripts/release-loop/gate-host-mirror.ts +66 -0
- package/scripts/release-loop/gate-node.ts +523 -75
- package/scripts/release-loop/gate-partial.ts +106 -9
- package/scripts/release-loop/gate-pr-cache.ts +66 -0
- package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
- package/scripts/release-loop/gate-r2-verdict.ts +189 -0
- package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
- package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
- package/scripts/release-loop/import-graph-scc-run.ts +54 -0
- package/scripts/release-loop/import-graph-scc.ts +215 -0
- package/scripts/release-loop/node-verdict.ts +2 -0
- package/scripts/release-loop/prepare-node.ts +102 -4
- package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
- package/scripts/release-loop/resume-release.ts +33 -4
- package/scripts/release-loop/resume.ts +13 -5
- package/scripts/release-loop/spawn-lane.ts +2 -19
- package/scripts/release-loop/tui-sim-node.ts +3 -2
- package/scripts/release-loop/unattended-release.ts +16 -0
- package/scripts/test-deterministic.ts +5 -61
- package/scripts/train-reach-grouping.ts +48 -0
- package/scripts/tsc-incremental-cache.ts +86 -0
- package/scripts/tsc-incremental-diagnostics.ts +76 -0
- package/scripts/tsc-main-safety-net.ts +2 -2
- package/src/acp/client.ts +4 -1
- package/src/acp/core-turn-bridge.ts +65 -8
- package/src/acp/elanous-extensions.ts +3 -0
- package/src/acp/server.ts +3 -0
- package/src/acp/tool-trace.ts +186 -11
- package/src/ad-pipeline/run.ts +4 -2
- package/src/agent/runner.ts +169 -3
- package/src/agent/self-ambient-cache.ts +156 -0
- package/src/agent/self-ambient.ts +8 -1
- package/src/agent/subagent-callable.ts +3 -2
- package/src/agent/task-notification.ts +5 -0
- package/src/agent-mission/review-loop.ts +6 -3
- package/src/agent-substrate/acp-implementer.ts +14 -2
- package/src/agent-substrate/pr-reviewer.ts +14 -0
- package/src/agent-substrate/self-review-cli.ts +30 -4
- package/src/ask-user-question/tool.ts +22 -0
- package/src/autopilot/build/llm-conflict-merge.ts +56 -10
- package/src/autopilot/pr-manager.ts +80 -7
- package/src/briefing/brief-items.ts +24 -22
- package/src/capture/frame-state-detect.ts +39 -0
- package/src/capture/tui-self-report.ts +149 -6
- package/src/chat/chat-cli.ts +10 -2
- package/src/chat/index.ts +138 -26
- package/src/chat/input-control-key.ts +5 -3
- package/src/chat/pickers/modal-runtime.ts +6 -0
- package/src/chat/pickers/modals.ts +8 -2
- package/src/chat/tool-interrupt-behavior.ts +38 -0
- package/src/chat/tool-render/dispatch.ts +5 -1
- package/src/chat/turn-typeahead.ts +75 -20
- package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
- package/src/cli/agent-cli.ts +41 -13
- package/src/cli/ask-bare.ts +1 -0
- package/src/cli/config-audit.ts +123 -0
- package/src/cli/decisions-cli.ts +80 -6
- package/src/cli/import-cli.ts +12 -0
- package/src/cli/log-event-names.ts +17 -0
- package/src/cli/mcp-login.ts +21 -5
- package/src/cli/msg-cli.ts +89 -0
- package/src/cli/pod-cli.ts +14 -3
- package/src/cli/pr-cli.ts +273 -81
- package/src/cli/pr-land-base-read.ts +34 -0
- package/src/cli/pr-land-heavy-remote.ts +82 -26
- package/src/cli/pr-land-overlap-evidence.ts +109 -11
- package/src/cli/pr-land-pod-shadow-job.ts +106 -0
- package/src/cli/pr-land-pod-shadow.ts +16 -3
- package/src/cli/pr-land-refusal.ts +20 -5
- package/src/cli/pr-land-virtual-rebase.ts +108 -0
- package/src/cli/pty-takeover-cli.ts +88 -14
- package/src/cli/release-cli.ts +80 -14
- package/src/cli/seat-cli.ts +138 -3
- package/src/cli/self-update.ts +5 -2
- package/src/cli/sim-cli.ts +18 -0
- package/src/cli/tasks-cli.ts +97 -19
- package/src/context-bus/context-first.ts +13 -0
- package/src/context-bus/context-now.ts +13 -2
- package/src/context-bus/ops-events.ts +79 -0
- package/src/control-plane/lease-holder.ts +12 -8
- package/src/control-plane/ledger.ts +163 -4
- package/src/control-plane/server.ts +91 -11
- package/src/core-turn/run-core-turn.ts +2 -0
- package/src/core-turn/run-goal-loop.ts +243 -3
- package/src/core-turn/seat-turn-cap.ts +79 -0
- package/src/core-turn/short-question.ts +38 -6
- package/src/core-turn/types.ts +6 -0
- package/src/dashboard/acp-active-model.ts +42 -1
- package/src/dashboard/acp-boot.ts +3 -0
- package/src/dashboard/background-jobs-status.ts +66 -0
- package/src/dashboard/index.ts +339 -657
- package/src/dashboard/input/agent-wake.ts +242 -0
- package/src/dashboard/input/chat-main-entry-runtime.ts +6 -1
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
- package/src/dashboard/input/chat-main-session.ts +8 -1
- package/src/dashboard/input/chat-main-turn.ts +12 -3
- package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
- package/src/dashboard/input/external-input-host.ts +49 -9
- package/src/dashboard/input/internal-turn.ts +261 -0
- package/src/dashboard/input/mouse-wiring.ts +108 -11
- package/src/dashboard/input/seat-autowake.ts +318 -0
- package/src/dashboard/input/turn-steer-bridge.ts +70 -0
- package/src/dashboard/log-click-runtime.ts +118 -2
- package/src/dashboard/loop-scheduler.ts +72 -0
- package/src/dashboard/seat-boot-preamble.ts +18 -0
- package/src/dashboard/skill-runtime.ts +2 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
- package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
- package/src/dashboard/slash-runtime/index.ts +13 -0
- package/src/dashboard/turn-busy-teardown.ts +50 -0
- package/src/dashboard/turn-preamble.ts +116 -40
- package/src/dashboard/turn-session-layers.ts +4 -2
- package/src/dashboard/turn-start-segments.ts +222 -0
- package/src/decisions/decision-ledger.ts +45 -4
- package/src/discord-self-message.ts +4 -4
- package/src/display/prompt-row-owner.ts +146 -0
- package/src/display/resize-listener.ts +33 -2
- package/src/domains/release-tool.ts +18 -1
- package/src/field-note/transcribe.ts +17 -0
- package/src/fold-stack.ts +4 -2
- package/src/git-fs/index.ts +263 -36
- package/src/github/remote-call.ts +81 -0
- package/src/goals/registry.ts +46 -6
- package/src/goals/types.ts +7 -1
- package/src/graph-runner/runner.ts +1 -0
- package/src/grok/credential.ts +26 -0
- package/src/harness/gate-reserve.ts +87 -0
- package/src/harness/harness-clean.ts +2 -1
- package/src/harness/harness-cli-command.ts +52 -5
- package/src/harness/harness-gc.ts +2 -1
- package/src/harness/harness-incidents.ts +70 -20
- package/src/harness/harness-pod-dispatch.ts +87 -10
- package/src/harness/harness-queue.ts +68 -4
- package/src/harness/harness-stop.ts +4 -3
- package/src/harness/harness-substrate-default.ts +78 -7
- package/src/harness/harness-worktree-auto.ts +2 -1
- package/src/harness/harness-worktrees.ts +3 -2
- package/src/hooks/dispatch.ts +2 -1
- package/src/index.ts +156 -27
- package/src/input/external-input-queue.ts +64 -7
- package/src/intake-plane/slash.ts +14 -3
- package/src/keybindings.ts +4 -1
- package/src/llm/route-decision.ts +36 -0
- package/src/llm/tool-loop-steered-rejection.ts +41 -0
- package/src/llm-request-shape.ts +209 -0
- package/src/llm.ts +301 -283
- package/src/loops/consensus.ts +348 -0
- package/src/loops/msg-wake.ts +206 -4
- package/src/loops/observe.ts +19 -3
- package/src/loops/orchestrator/tick.ts +88 -12
- package/src/loops/orchestrator/traffic.ts +64 -1
- package/src/loops/registry.ts +30 -0
- package/src/market/signed-index.ts +14 -0
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/mcp/mcp-oauth.ts +54 -5
- package/src/models/prompts.ts +28 -0
- package/src/msg/msg-sse-client.ts +223 -0
- package/src/msg/msg-store.ts +86 -2
- package/src/mss/logging/log-store.ts +225 -1
- package/src/mss/logging/render-categories.ts +5 -0
- package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
- package/src/nexus/api/http-server.ts +54 -15
- package/src/nexus/api/loop-resources.ts +19 -3
- package/src/nexus/api/ops-api.ts +11 -0
- package/src/nexus/daemon-thin-inventory.md +37 -0
- package/src/nexus/index.ts +70 -0
- package/src/nexus/state/state.ts +1 -0
- package/src/oauth/store.ts +32 -7
- package/src/onboarding/first-run.ts +28 -3
- package/src/ops/overview-cache.ts +16 -4
- package/src/ops/overview.ts +59 -2
- package/src/ops/resources.ts +82 -0
- package/src/plugins/maker/connector-maker.ts +41 -0
- package/src/plugins/maker/skill-maker.ts +42 -0
- package/src/pr-tool/census.ts +303 -0
- package/src/pr-tool/inflight-registry.ts +143 -0
- package/src/prompt-library/chat-conciseness.ts +13 -0
- package/src/prompt-library/universal-preamble.ts +10 -5
- package/src/pty-shell/pty-manifest.ts +12 -3
- package/src/pty-shell/tui-run-state.ts +34 -3
- package/src/release-loop/gate-host-reservation.ts +97 -0
- package/src/release-loop/landing-freeze.ts +5 -0
- package/src/release-loop/light-rc.ts +5 -2
- package/src/release-loop/placement.ts +92 -1
- package/src/release-loop/rehearsal-shard-plan.ts +149 -0
- package/src/release-loop/rehearsal.ts +73 -17
- package/src/repl/index.ts +20 -2
- package/src/seat-loop/seat-knowhow.ts +282 -0
- package/src/seat-loop/seat-loop.ts +41 -2
- package/src/seat-loop/traffic-signal.ts +5 -1
- package/src/self-dev/ask-launch-flow.ts +37 -3
- package/src/self-dev/decompose-compose-graph.ts +28 -27
- package/src/self-dev/decompose-proposal.ts +53 -38
- package/src/self-dev/decompose.ts +17 -0
- package/src/self-dev/dev-pipeline.ts +31 -2
- package/src/self-dev/draft-residue.ts +267 -33
- package/src/self-dev/draft-sweep.ts +59 -4
- package/src/self-dev/external-call-zero.ts +77 -0
- package/src/self-dev/launch-preflight-text.ts +6 -0
- package/src/self-dev/launch-preflight.ts +25 -3
- package/src/self-dev/local-supervisor-judge.ts +185 -0
- package/src/self-dev/run-supervisor.ts +229 -19
- package/src/self-dev/run-types.ts +20 -0
- package/src/self-dev/shard-aggregate.ts +13 -2
- package/src/self-dev/shard-plan.ts +56 -1
- package/src/self-dev/shard-run.ts +207 -12
- package/src/self-dev/spawn-lane-files.ts +19 -0
- package/src/self-implement/app-api-budget.ts +51 -11
- package/src/self-implement/config-gate.ts +2 -1
- package/src/self-implement/elanous-tui-spawn.ts +14 -0
- package/src/self-implement/expose-gate.ts +2 -1
- package/src/self-implement/follow-up-placement.ts +79 -0
- package/src/self-implement/gate-artifacts.ts +416 -0
- package/src/self-implement/gate-baseline.ts +96 -5
- package/src/self-implement/gate-cli.ts +207 -17
- package/src/self-implement/gate-remote.ts +136 -26
- package/src/self-implement/gate-scenario.ts +85 -0
- package/src/self-implement/goal-author.ts +160 -8
- package/src/self-implement/graph-authority.ts +38 -6
- package/src/self-implement/graph-overlay-condition.ts +92 -1
- package/src/self-implement/heal-triage.ts +79 -0
- package/src/self-implement/host-regate.ts +97 -7
- package/src/self-implement/orchestrator.ts +115 -134
- package/src/self-implement/pr-title.ts +123 -0
- package/src/self-implement/run-checkpoint.ts +235 -0
- package/src/self-implement/run-ledger.ts +162 -15
- package/src/self-implement/run-stop.ts +4 -3
- package/src/self-implement/run-ttl.ts +28 -4
- package/src/self-implement/seams.ts +2 -0
- package/src/self-implement/shadow-stage.ts +7 -6
- package/src/self-implement/stop-autoheal.ts +2 -1
- package/src/self-implement/train-gate-remote.ts +37 -8
- package/src/self-implement/train-reach-grouping.ts +157 -0
- package/src/self-implement/train-scenario-layers.ts +133 -0
- package/src/self-implement/uncommitted-work.ts +2 -0
- package/src/session/pending-input.ts +19 -0
- package/src/session/session-start.ts +224 -0
- package/src/session-runtime/index.ts +22 -267
- package/src/session-runtime/parallel-dispatch.ts +22 -5
- package/src/shell-runner/background-surface.ts +15 -5
- package/src/skills/tools/agent.ts +39 -6
- package/src/skills/tools/dev-harness.ts +6 -4
- package/src/skills/tools/list-dir.ts +11 -0
- package/src/skills/tools/schedule-wakeup.ts +408 -0
- package/src/skills/tools/shell.ts +246 -4
- package/src/status/bar.ts +26 -0
- package/src/steward/digest-delivery.ts +118 -0
- package/src/steward/hold-hygiene.ts +120 -0
- package/src/steward/resync-tick.ts +114 -23
- package/src/steward/ta-repair-event-collect.ts +158 -0
- package/src/steward/triage.ts +10 -0
- package/src/surface/shell-runner-boot.ts +5 -2
- package/src/task-agent/card-evidence.ts +25 -1
- package/src/task-agent/green-sweep.ts +8 -3
- package/src/task-agent/judge.ts +76 -0
- package/src/task-agent/land-queue.ts +79 -0
- package/src/task-agent/live-moves.ts +30 -9
- package/src/task-agent/postland-card.ts +5 -0
- package/src/task-agent/prelaunch-already-done.ts +98 -0
- package/src/task-agent/real-launch-guard.ts +37 -0
- package/src/task-agent/rejudge-on-head.ts +89 -12
- package/src/task-agent/remote-rejudge-bind.ts +28 -8
- package/src/task-agent/repair-cycle.ts +45 -7
- package/src/task-agent/repair-worker.ts +7 -0
- package/src/task-agent/run-identity.ts +200 -0
- package/src/task-agent/shadow.ts +50 -3
- package/src/task-agent/task-hand.ts +182 -5
- package/src/task-agent/train-landing.ts +77 -0
- package/src/task-agent/work-order.ts +104 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +151 -37
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
- package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
- package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
- package/src/task-orchestrator/surfaces/pod-install-slots.ts +121 -9
- package/src/task-orchestrator/surfaces/pod-lease.ts +118 -6
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
- package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +27 -0
- package/src/task-orchestrator/surfaces/pod-pool.ts +3 -1
- package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
- package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +67 -0
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
- package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
- package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +525 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runner.ts +90 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +362 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +138 -19
- package/src/telegram.ts +2 -4
- package/src/tui/chat/execution-badge.ts +5 -1
- package/src/tui/input/pickers.ts +732 -0
- package/src/tui/input-lag-probe.ts +230 -0
- package/src/tui/slash/mission.ts +492 -0
- package/src/tui/slash/term.ts +877 -0
- package/src/tui-client/dashboard-session.ts +9 -0
- package/src/tui.ts +52 -0
- package/src/user-config/gemini-server-tools.ts +9 -0
- package/src/user-config.ts +53 -16
- package/src/util/spawn-sync-output.ts +7 -0
- package/src/ux-sim/fake-bin.ts +154 -0
- package/src/ux-sim/fake-clock.ts +36 -0
- package/src/ux-sim/headless-tui.ts +72 -0
- package/src/ux-sim/in-process-cli.ts +2 -1
- package/src/ux-sim/scenario.ts +255 -0
- package/src/ux-sim/temp-git-remote.ts +82 -0
- package/src/version/packed-revision.json +1 -1
- package/src/video-pipeline/recipes/vlog.ts +25 -7
- package/apps/pwa/out/_next/static/chunks/1015-9cba22a5a4554797.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
- package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
- package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
- package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
- package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
- package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
- package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
- package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
- package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
- package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
- package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
- package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
- package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
- package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
- package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
- package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
- package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
- package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
- package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
- package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
- package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
- package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
- package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
- package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
- package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-a5635eba0d73b84e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9f92737b8766009a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
- package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
- package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
- package/apps/pwa/out/_next/static/css/72becfd42807b50d.css +0 -1
- /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → IVKr3AlRUVLKsw2fh7eXF}/_ssgManifest.js +0 -0
|
@@ -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
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync } from 'node:fs';
|
|
1
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
3
3
|
import { refuseProductionLedgerWriteInTest } from '../harness/ledger-write-guard.js';
|
|
4
4
|
import { tracedPathReferences, verbatimOriginalAsk } from './goal-author.js';
|
|
@@ -20,6 +20,7 @@ export interface RunLedgerEntry {
|
|
|
20
20
|
event: string;
|
|
21
21
|
data: Record<string, unknown>;
|
|
22
22
|
goalId?: string;
|
|
23
|
+
devProject?: string;
|
|
23
24
|
orchestrationId?: string;
|
|
24
25
|
shardId?: string;
|
|
25
26
|
siblingShardIds?: string[];
|
|
@@ -412,8 +413,12 @@ export function appendRunLedgerEntry(entry: RunLedgerEntry, dir = runLedgerDir()
|
|
|
412
413
|
if (refuseProductionLedgerWriteInTest(dir, 'run-ledger')) return;
|
|
413
414
|
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
414
415
|
const live = runLedgerPath(entry.runId, dir);
|
|
416
|
+
const devProject = process.env.ELANOUS_DEV_PROJECT;
|
|
417
|
+
const row = entry.devProject === undefined && typeof devProject === 'string' && devProject.startsWith('prj-')
|
|
418
|
+
? { ...entry, devProject }
|
|
419
|
+
: entry;
|
|
415
420
|
withRunLedgerLock(dir, entry.runId, () => {
|
|
416
|
-
const line = `${JSON.stringify(
|
|
421
|
+
const line = `${JSON.stringify(row)}\n`;
|
|
417
422
|
if (!restoreArchivedRunLedger(dir, entry.runId, line)) appendFileSync(live, line, 'utf8');
|
|
418
423
|
});
|
|
419
424
|
}
|
|
@@ -1315,6 +1320,10 @@ export interface UnfinishedRunLedgerQuery {
|
|
|
1315
1320
|
terminalByTrailingRunStatus?: number;
|
|
1316
1321
|
cacheHits?: number;
|
|
1317
1322
|
cacheMisses?: number;
|
|
1323
|
+
/** Hits served by the persisted cross-process scan index (subset of cacheHits). */
|
|
1324
|
+
indexHits?: number;
|
|
1325
|
+
/** Whether that index was loaded from disk, started fresh, or was bypassed. */
|
|
1326
|
+
indexOrigin?: RunLedgerScanIndexOrigin;
|
|
1318
1327
|
pathFilter?: string;
|
|
1319
1328
|
matchingPathCount?: number;
|
|
1320
1329
|
unknownPathCount?: number;
|
|
@@ -1658,9 +1667,9 @@ interface UnfinishedLedgerFacts {
|
|
|
1658
1667
|
nonBlocking: NonBlockingRunLedgerRecord | null;
|
|
1659
1668
|
}
|
|
1660
1669
|
|
|
1661
|
-
// A full federated scan can exceed 5,000 files; keep the previous scan resident for
|
|
1670
|
+
// A full federated scan can exceed 5,000 files; keep the previous scan resident for stat-checked reuse.
|
|
1662
1671
|
const UNFINISHED_LEDGER_CACHE_LIMIT = 32_768;
|
|
1663
|
-
const unfinishedLedgerCache = new Map<string, { size: number; mtimeMs: number; facts: UnfinishedLedgerFacts }>();
|
|
1672
|
+
const unfinishedLedgerCache = new Map<string, { size: number; mtimeMs: number; ctimeMs: number; facts: UnfinishedLedgerFacts }>();
|
|
1664
1673
|
const unfinishedReaderIds = new WeakMap<RunLedgerReader, number>();
|
|
1665
1674
|
let nextUnfinishedReaderId = 1;
|
|
1666
1675
|
|
|
@@ -1674,6 +1683,97 @@ function unfinishedLedgerCacheKey(path: string, read?: RunLedgerReader): string
|
|
|
1674
1683
|
return `${path}\u0000reader:${id}`;
|
|
1675
1684
|
}
|
|
1676
1685
|
|
|
1686
|
+
// ⭐ 프로세스 간 유효 스캔 색인(칸 CONTEXT-NOW-RUN-SCAN-INDEX).
|
|
1687
|
+
// `/now`(contextNowInWorker)는 요청마다 «새 워커 프로세스»를 띄우므로 위 프로세스 캐시는 매번 빈 채로 시작한다
|
|
1688
|
+
// (실측 2026-10-14: scanned=7893, cacheHits=0, 조회 6.3~8.9초). 색인은 파싱된 파일별 facts 를
|
|
1689
|
+
// 원장 옆에 (size, mtimeMs, ctimeMs) 스탬프로 저장하고, 스탬프가 같으면 재사용한다. 원장에 무엇이 «붙으면»
|
|
1690
|
+
// 스탬프가 바뀌므로 무효화는 자동이다 (같은 크기로 덮고 mtime 을 되돌려도 ctime 이 바뀐다). 읽기 실패는 전부 fail-soft: 색인이 없으면 그냥 새로 읽는다.
|
|
1691
|
+
const RUN_LEDGER_SCAN_INDEX_FILE = '.unfinished-scan-index.json';
|
|
1692
|
+
const RUN_LEDGER_SCAN_INDEX_VERSION = 2;
|
|
1693
|
+
const RUN_LEDGER_SCAN_INDEX_LIMIT = 32_768;
|
|
1694
|
+
|
|
1695
|
+
/** Where the persisted scan index lives: beside its ledgers, never mistaken for one (readdir filters canonical names). */
|
|
1696
|
+
export function runLedgerScanIndexPath(dir: string): string {
|
|
1697
|
+
return join(dir, RUN_LEDGER_SCAN_INDEX_FILE);
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
export interface RunLedgerScanIndexRecord {
|
|
1701
|
+
size: number;
|
|
1702
|
+
mtimeMs: number;
|
|
1703
|
+
ctimeMs: number;
|
|
1704
|
+
facts: UnfinishedLedgerFacts;
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
/** Whether the persisted index was loaded, started fresh, or was bypassed (noCache or an injected reader). */
|
|
1708
|
+
export type RunLedgerScanIndexOrigin = 'loaded' | 'fresh' | 'bypassed';
|
|
1709
|
+
|
|
1710
|
+
const UNFINISHED_LIFECYCLE_WORDS = new Set<string>([
|
|
1711
|
+
'live', 'orphaned', 'human-stopped', 'terminal-other-vocabulary', 'terminal-run-status-superseded', 'unjudgeable',
|
|
1712
|
+
]);
|
|
1713
|
+
|
|
1714
|
+
function isScanIndexFacts(value: unknown): value is UnfinishedLedgerFacts {
|
|
1715
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
|
|
1716
|
+
const facts = value as Record<string, unknown>;
|
|
1717
|
+
return typeof facts.terminal === 'boolean'
|
|
1718
|
+
&& typeof facts.terminalByTrailingRunStatus === 'boolean'
|
|
1719
|
+
&& (facts.branch === null || typeof facts.branch === 'string')
|
|
1720
|
+
&& (facts.lastActivityTimestamp === null || typeof facts.lastActivityTimestamp === 'string')
|
|
1721
|
+
&& typeof facts.lastActivityStatus === 'string'
|
|
1722
|
+
&& (facts.targetRoot === null || typeof facts.targetRoot === 'string')
|
|
1723
|
+
&& (facts.goalFile === null || typeof facts.goalFile === 'string')
|
|
1724
|
+
&& typeof facts.fixedLifecycle === 'string' && UNFINISHED_LIFECYCLE_WORDS.has(facts.fixedLifecycle);
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
function isScanIndexRecord(value: unknown): value is RunLedgerScanIndexRecord {
|
|
1728
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
|
|
1729
|
+
const record = value as Record<string, unknown>;
|
|
1730
|
+
return Number.isFinite(record.size) && Number.isFinite(record.mtimeMs) && Number.isFinite(record.ctimeMs) && isScanIndexFacts(record.facts);
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
const scanIndexCache = new Map<string, { stamp: string; entries: Map<string, RunLedgerScanIndexRecord> }>();
|
|
1734
|
+
|
|
1735
|
+
function scanIndexFileStamp(path: string): string {
|
|
1736
|
+
try { const stat = statSync(path); return `${stat.size}:${stat.mtimeMs}`; } catch { return 'missing'; }
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
/** Load (memoized by index-file stamp) the persisted per-directory scan index; malformed or absent behaves as fresh. */
|
|
1740
|
+
export function loadRunLedgerScanIndex(dir: string): Map<string, RunLedgerScanIndexRecord> {
|
|
1741
|
+
const path = runLedgerScanIndexPath(dir);
|
|
1742
|
+
const stamp = scanIndexFileStamp(path);
|
|
1743
|
+
const cached = scanIndexCache.get(dir);
|
|
1744
|
+
if (cached && cached.stamp === stamp) return cached.entries;
|
|
1745
|
+
const entries = new Map<string, RunLedgerScanIndexRecord>();
|
|
1746
|
+
if (stamp !== 'missing') {
|
|
1747
|
+
try {
|
|
1748
|
+
const parsed: unknown = JSON.parse(readFileSync(path, 'utf8'));
|
|
1749
|
+
const raw = parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
1750
|
+
&& (parsed as Record<string, unknown>).version === RUN_LEDGER_SCAN_INDEX_VERSION
|
|
1751
|
+
&& typeof (parsed as Record<string, unknown>).entries === 'object'
|
|
1752
|
+
&& (parsed as Record<string, unknown>).entries !== null && !Array.isArray((parsed as Record<string, unknown>).entries)
|
|
1753
|
+
? (parsed as { entries: Record<string, unknown> }).entries : null;
|
|
1754
|
+
if (raw) for (const [runId, record] of Object.entries(raw)) {
|
|
1755
|
+
if (isScanIndexRecord(record)) entries.set(runId, record);
|
|
1756
|
+
}
|
|
1757
|
+
} catch { /* a malformed index behaves as absent */ }
|
|
1758
|
+
}
|
|
1759
|
+
scanIndexCache.set(dir, { stamp, entries });
|
|
1760
|
+
return entries;
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
/** Persist the index beside its ledgers, best-effort: any failure just leaves the next scan reading fresh. */
|
|
1764
|
+
function persistRunLedgerScanIndex(dir: string, entries: ReadonlyMap<string, RunLedgerScanIndexRecord>): boolean {
|
|
1765
|
+
if (refuseProductionLedgerWriteInTest(dir, 'run-ledger-scan-index')) return false;
|
|
1766
|
+
const bounded = entries.size > RUN_LEDGER_SCAN_INDEX_LIMIT
|
|
1767
|
+
? new Map([...entries].slice(entries.size - RUN_LEDGER_SCAN_INDEX_LIMIT))
|
|
1768
|
+
: entries;
|
|
1769
|
+
try {
|
|
1770
|
+
writeFileSync(runLedgerScanIndexPath(dir), JSON.stringify({ version: RUN_LEDGER_SCAN_INDEX_VERSION, entries: Object.fromEntries(bounded) }), 'utf8');
|
|
1771
|
+
return true;
|
|
1772
|
+
} catch {
|
|
1773
|
+
return false;
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1677
1777
|
function unfinishedLedgerFacts(ledger: readonly RunLedgerEntry[]): UnfinishedLedgerFacts {
|
|
1678
1778
|
const last = ledger.at(-1)?.timestamp;
|
|
1679
1779
|
const lastActivityTimestamp = last !== undefined && Number.isFinite(Date.parse(last)) ? last : null;
|
|
@@ -1690,31 +1790,52 @@ function unfinishedLedgerFacts(ledger: readonly RunLedgerEntry[]): UnfinishedLed
|
|
|
1690
1790
|
};
|
|
1691
1791
|
}
|
|
1692
1792
|
|
|
1693
|
-
function readUnfinishedLedgerFacts(
|
|
1793
|
+
function readUnfinishedLedgerFacts(
|
|
1794
|
+
runId: string,
|
|
1795
|
+
dir: string,
|
|
1796
|
+
read?: RunLedgerReader,
|
|
1797
|
+
noCache?: boolean,
|
|
1798
|
+
index?: Map<string, RunLedgerScanIndexRecord>,
|
|
1799
|
+
): { facts: UnfinishedLedgerFacts; hit: boolean; source: 'process' | 'index' | 'read' } {
|
|
1694
1800
|
const path = runLedgerPath(runId, dir);
|
|
1695
1801
|
const key = noCache ? null : unfinishedLedgerCacheKey(path, read);
|
|
1696
1802
|
const stamp = noCache ? null : statSync(path);
|
|
1697
1803
|
const cached = key === null ? undefined : unfinishedLedgerCache.get(key);
|
|
1698
|
-
if (cached && stamp && key !== null && cached.size === stamp.size && cached.mtimeMs === stamp.mtimeMs) {
|
|
1804
|
+
if (cached && stamp && key !== null && cached.size === stamp.size && cached.mtimeMs === stamp.mtimeMs && cached.ctimeMs === stamp.ctimeMs) {
|
|
1699
1805
|
unfinishedLedgerCache.delete(key);
|
|
1700
1806
|
unfinishedLedgerCache.set(key, cached);
|
|
1701
|
-
return { facts: cached.facts, hit: true };
|
|
1807
|
+
return { facts: cached.facts, hit: true, source: 'process' };
|
|
1702
1808
|
}
|
|
1703
1809
|
if (key !== null) unfinishedLedgerCache.delete(key);
|
|
1810
|
+
// ⭐ 프로세스 캐시가 비었어도(새 워커) 디스크 색인의 스탬프가 같으면 재사용한다.
|
|
1811
|
+
// 주입된 reader 는 실제 파일 내용과 무관한 대역이라 색인에 넣지 «도», 색인에서 읽지 «도» 않는다.
|
|
1812
|
+
if (index !== undefined && stamp && read === undefined) {
|
|
1813
|
+
const record = index.get(runId);
|
|
1814
|
+
if (record && record.size === stamp.size && record.mtimeMs === stamp.mtimeMs && record.ctimeMs === stamp.ctimeMs) {
|
|
1815
|
+
if (key !== null) unfinishedLedgerCache.set(key, { size: stamp.size, mtimeMs: stamp.mtimeMs, ctimeMs: stamp.ctimeMs, facts: record.facts });
|
|
1816
|
+
return { facts: record.facts, hit: true, source: 'index' };
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1704
1819
|
try {
|
|
1705
1820
|
const ledger = loadRunLedger(runId, dir, read);
|
|
1706
1821
|
if (ledger === null && stamp !== null) throw new Error(`run ledger disappeared after stat: ${path}`);
|
|
1707
1822
|
const facts = unfinishedLedgerFacts(ledger ?? []);
|
|
1708
1823
|
if (stamp !== null && key !== null) {
|
|
1709
1824
|
const after = statSync(path);
|
|
1710
|
-
if (after.size === stamp.size && after.mtimeMs === stamp.mtimeMs) {
|
|
1711
|
-
unfinishedLedgerCache.set(key, { size: stamp.size, mtimeMs: stamp.mtimeMs, facts });
|
|
1825
|
+
if (after.size === stamp.size && after.mtimeMs === stamp.mtimeMs && after.ctimeMs === stamp.ctimeMs) {
|
|
1826
|
+
unfinishedLedgerCache.set(key, { size: stamp.size, mtimeMs: stamp.mtimeMs, ctimeMs: stamp.ctimeMs, facts });
|
|
1712
1827
|
if (unfinishedLedgerCache.size > UNFINISHED_LEDGER_CACHE_LIMIT) unfinishedLedgerCache.delete(unfinishedLedgerCache.keys().next().value!);
|
|
1828
|
+
// Persist only facts read from a stable ledger; an append during the read must be retried next scan.
|
|
1829
|
+
if (index !== undefined && read === undefined) index.set(runId, { size: stamp.size, mtimeMs: stamp.mtimeMs, ctimeMs: stamp.ctimeMs, facts });
|
|
1830
|
+
} else {
|
|
1831
|
+
index?.delete(runId);
|
|
1713
1832
|
}
|
|
1714
1833
|
}
|
|
1715
|
-
return { facts, hit: false };
|
|
1834
|
+
return { facts, hit: false, source: 'read' };
|
|
1716
1835
|
} catch (error) {
|
|
1717
1836
|
if (key !== null) unfinishedLedgerCache.delete(key);
|
|
1837
|
+
// 원장이 사라졌거나 바뀐 사이에 읽었다 — 색인의 스탬프는 이미 무효이므로 치운다(무효화).
|
|
1838
|
+
index?.delete(runId);
|
|
1718
1839
|
throw error;
|
|
1719
1840
|
}
|
|
1720
1841
|
}
|
|
@@ -1734,6 +1855,11 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
1734
1855
|
const goalsDir = resolve(options.goalsDir ?? resolveGoalDocumentsDir(process.cwd()).directory);
|
|
1735
1856
|
const list = options.list ?? readdirSync;
|
|
1736
1857
|
const liveWindowMs = options.liveWindowMs ?? DEFAULT_UNFINISHED_LIVE_WINDOW_MS;
|
|
1858
|
+
// ⭐ 색인은 noCache 나 주입된 reader 가 아니어야만 켠다 — 그 둘은 «정직한 재읽기» 계약을 지켜야 한다.
|
|
1859
|
+
const scanIndex = !options.noCache && options.read === undefined ? loadRunLedgerScanIndex(dir) : undefined;
|
|
1860
|
+
const indexOrigin: RunLedgerScanIndexOrigin = scanIndex === undefined ? 'bypassed' : scanIndex.size > 0 ? 'loaded' : 'fresh';
|
|
1861
|
+
let indexHits = 0;
|
|
1862
|
+
let indexChanged = false;
|
|
1737
1863
|
let fileNames: string[];
|
|
1738
1864
|
try {
|
|
1739
1865
|
fileNames = list(dir);
|
|
@@ -1748,6 +1874,8 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
1748
1874
|
terminalByTrailingRunStatus: 0,
|
|
1749
1875
|
cacheHits: 0,
|
|
1750
1876
|
cacheMisses: 0,
|
|
1877
|
+
indexHits: 0,
|
|
1878
|
+
indexOrigin,
|
|
1751
1879
|
...(options.path === undefined ? {} : { pathFilter: options.path, matchingPathCount: 0, unknownPathCount: 0 }),
|
|
1752
1880
|
scope: 'self-implement-run-ledger',
|
|
1753
1881
|
note: UNFINISHED_RUN_LEDGER_NOTE,
|
|
@@ -1760,6 +1888,8 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
1760
1888
|
terminalByTrailingRunStatus: 0,
|
|
1761
1889
|
cacheHits: 0,
|
|
1762
1890
|
cacheMisses: 0,
|
|
1891
|
+
indexOrigin,
|
|
1892
|
+
indexHits: 0,
|
|
1763
1893
|
ms: Date.now() - startedAt,
|
|
1764
1894
|
});
|
|
1765
1895
|
return missing;
|
|
@@ -1782,12 +1912,18 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
1782
1912
|
scanned += 1;
|
|
1783
1913
|
let facts: UnfinishedLedgerFacts;
|
|
1784
1914
|
try {
|
|
1785
|
-
const observed = readUnfinishedLedgerFacts(runId, dir, options.read, options.noCache);
|
|
1915
|
+
const observed = readUnfinishedLedgerFacts(runId, dir, options.read, options.noCache, scanIndex);
|
|
1786
1916
|
facts = observed.facts;
|
|
1787
|
-
if (observed.hit)
|
|
1788
|
-
|
|
1917
|
+
if (observed.hit) {
|
|
1918
|
+
cacheHits += 1;
|
|
1919
|
+
if (observed.source === 'index') indexHits += 1;
|
|
1920
|
+
} else {
|
|
1921
|
+
cacheMisses += 1;
|
|
1922
|
+
if (scanIndex !== undefined) indexChanged = true;
|
|
1923
|
+
}
|
|
1789
1924
|
} catch {
|
|
1790
1925
|
cacheMisses += 1;
|
|
1926
|
+
if (scanIndex?.delete(runId)) indexChanged = true;
|
|
1791
1927
|
unreadableLedgerCount += 1;
|
|
1792
1928
|
entries.push({ runId, branch: null, status: 'ledger-unreadable', plannedPaths: [], plannedPathStatus: 'unknown', ...unknownDeclaredPaths(), pathMatchReasons: {}, goalDocumentPath: null, goalLookupBasis: 'caller-cwd', goalDocumentSearchDirectory: null, lastActivityTimestamp: null, lastActivityAgeMs: null, lastActivityStatus: 'ledger-unreadable', lifecycle: 'unjudgeable' });
|
|
1793
1929
|
callerCwdCount += 1;
|
|
@@ -1840,6 +1976,7 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
1840
1976
|
}
|
|
1841
1977
|
}
|
|
1842
1978
|
entries.sort((left, right) => left.runId.localeCompare(right.runId));
|
|
1979
|
+
if (scanIndex !== undefined && indexChanged) persistRunLedgerScanIndex(dir, scanIndex);
|
|
1843
1980
|
debug.log('self-implement.run-ledger', 'goal-lookup-basis', { ledgerTarget: ledgerTargetCount, callerCwd: callerCwdCount });
|
|
1844
1981
|
debug.log('self-implement.run-ledger', 'unfinished-query', {
|
|
1845
1982
|
scanned,
|
|
@@ -1848,10 +1985,12 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
1848
1985
|
terminalByTrailingRunStatus,
|
|
1849
1986
|
cacheHits,
|
|
1850
1987
|
cacheMisses,
|
|
1988
|
+
indexOrigin,
|
|
1989
|
+
indexHits,
|
|
1851
1990
|
ms: Date.now() - startedAt,
|
|
1852
1991
|
});
|
|
1853
1992
|
if (options.path === undefined) {
|
|
1854
|
-
return { entries, ledgerDirectory: dir, goalsDirectory: goalsDir, unreadableLedgerCount, ledgerDirectoryMissing: false, terminalByTrailingRunStatus, cacheHits, cacheMisses, scope: 'self-implement-run-ledger', note: UNFINISHED_RUN_LEDGER_NOTE };
|
|
1993
|
+
return { entries, ledgerDirectory: dir, goalsDirectory: goalsDir, unreadableLedgerCount, ledgerDirectoryMissing: false, terminalByTrailingRunStatus, cacheHits, cacheMisses, indexHits, indexOrigin, scope: 'self-implement-run-ledger', note: UNFINISHED_RUN_LEDGER_NOTE };
|
|
1855
1994
|
}
|
|
1856
1995
|
const pathFilter = options.path;
|
|
1857
1996
|
const unknownPathStatus = (entry: UnfinishedRunLedgerEntry): boolean => entry.plannedPathStatus !== 'found-ledger-goal-file'
|
|
@@ -1871,6 +2010,8 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
1871
2010
|
terminalByTrailingRunStatus,
|
|
1872
2011
|
cacheHits,
|
|
1873
2012
|
cacheMisses,
|
|
2013
|
+
indexHits,
|
|
2014
|
+
indexOrigin,
|
|
1874
2015
|
pathFilter,
|
|
1875
2016
|
matchingPathCount: matchingEntries.length,
|
|
1876
2017
|
unknownPathCount: unknownEntries.length,
|
|
@@ -1908,6 +2049,8 @@ export interface FederatedUnfinishedRunLedgerQuery {
|
|
|
1908
2049
|
reconciledTerminatedElsewhereCount: number;
|
|
1909
2050
|
cacheHits?: number;
|
|
1910
2051
|
cacheMisses?: number;
|
|
2052
|
+
/** Hits served by the persisted cross-process scan index (subset of cacheHits). */
|
|
2053
|
+
indexHits?: number;
|
|
1911
2054
|
pathFilter?: string;
|
|
1912
2055
|
matchingPathCount?: number;
|
|
1913
2056
|
unknownPathCount?: number;
|
|
@@ -1947,6 +2090,7 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
|
|
|
1947
2090
|
let unknownPathCount = 0;
|
|
1948
2091
|
let cacheHits = 0;
|
|
1949
2092
|
let cacheMisses = 0;
|
|
2093
|
+
let indexHits = 0;
|
|
1950
2094
|
const recordDirectoryFailure = (kind: FederatedLedgerDirectoryFailureKind): void => {
|
|
1951
2095
|
if (kind === 'missing') missingLedgerDirectoryCount += 1;
|
|
1952
2096
|
else if (kind === 'unreadable') unreadableLedgerDirectoryAccessCount += 1;
|
|
@@ -1972,6 +2116,7 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
|
|
|
1972
2116
|
unknownPathCount += result.unknownPathCount ?? 0;
|
|
1973
2117
|
cacheHits += result.cacheHits ?? 0;
|
|
1974
2118
|
cacheMisses += result.cacheMisses ?? 0;
|
|
2119
|
+
indexHits += result.indexHits ?? 0;
|
|
1975
2120
|
entries.push(...result.entries.map((entry) => ({ ...entry, ledgerDirectory })));
|
|
1976
2121
|
} catch (error) {
|
|
1977
2122
|
recordDirectoryFailure(classifyFederatedLedgerDirectoryReadFailure(error));
|
|
@@ -1993,7 +2138,8 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
|
|
|
1993
2138
|
for (const runId of unfinishedRunIds) {
|
|
1994
2139
|
for (const ledgerDirectory of ledgerDirectories) {
|
|
1995
2140
|
try {
|
|
1996
|
-
|
|
2141
|
+
const reconciliationIndex = options.noCache ? undefined : loadRunLedgerScanIndex(ledgerDirectory);
|
|
2142
|
+
if (readUnfinishedLedgerFacts(runId, ledgerDirectory, undefined, options.noCache, reconciliationIndex).facts.terminal) { terminatedElsewhere.add(runId); break; }
|
|
1997
2143
|
} catch { /* An absent or unreadable sibling cannot establish termination. */ }
|
|
1998
2144
|
}
|
|
1999
2145
|
}
|
|
@@ -2014,6 +2160,7 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
|
|
|
2014
2160
|
reconciledTerminatedElsewhereCount,
|
|
2015
2161
|
cacheHits,
|
|
2016
2162
|
cacheMisses,
|
|
2163
|
+
indexHits,
|
|
2017
2164
|
...(options.path === undefined ? {} : { pathFilter: options.path, matchingPathCount, unknownPathCount }),
|
|
2018
2165
|
scope: 'self-implement-run-ledger-federated',
|
|
2019
2166
|
note: FEDERATED_UNFINISHED_RUN_LEDGER_NOTE,
|
|
@@ -15,7 +15,7 @@ import { appendRunLedgerEntry, type RunLedgerEntry, type RunLedgerWriter, type R
|
|
|
15
15
|
/** 닫힌 목록 — 못 고르면 `unclassified`. */
|
|
16
16
|
export const RUN_STOP_CLASSES = [
|
|
17
17
|
'env-unrelated', 'main-sync', 'pod-died', 'review-repeat',
|
|
18
|
-
'review-out-of-scope', 'evidence-uncovered', 'fabric', 'launch-failed', 'unclassified',
|
|
18
|
+
'review-out-of-scope', 'evidence-uncovered', 'fabric', 'launch-failed', 'gate-failed', 'unclassified',
|
|
19
19
|
] as const;
|
|
20
20
|
export type RunStopClass = typeof RUN_STOP_CLASSES[number];
|
|
21
21
|
|
|
@@ -68,8 +68,9 @@ export function classifyMergeHoldStop(mergeReason: string | undefined): RunStopC
|
|
|
68
68
|
return 'unclassified';
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
/** Pod exit 분류 사유 → 닫힌 목록. */
|
|
72
|
-
export function classifyPodExitStop(reason: string | undefined): RunStopClass {
|
|
71
|
+
/** Pod exit 분류 사유 → 닫힌 목록. `stage` 가 호스트 재게이트 실패(`host-regate-failed`)면 `gate-failed`, 인자가 없으면 지금과 똑같이. */
|
|
72
|
+
export function classifyPodExitStop(reason: string | undefined, stage?: string): RunStopClass {
|
|
73
|
+
if (stage === 'host-regate-failed') return 'gate-failed';
|
|
73
74
|
switch (reason) {
|
|
74
75
|
case 'pod-failure': case 'pod-error': case 'OOMKilled': case 'ENOBUFS': case 'signal': return 'pod-died';
|
|
75
76
|
case 'no-launch': return 'launch-failed';
|