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
|
@@ -9,7 +9,7 @@ import { appendRunLedgerEntry, listRunLedgers, loadRunLedger, runLedgerDir, type
|
|
|
9
9
|
import { queryRunningRuns } from '../self-implement/running-runs.js';
|
|
10
10
|
import { clipRegateDetail, regateFailureFacts, type HostRegateFailure } from '../self-implement/regate-detail.js';
|
|
11
11
|
import { DRAFT_SWEEP_CLOSE_CAP } from './draft-sweep.js';
|
|
12
|
-
import { PROTECTED_LABELS,
|
|
12
|
+
import { PROTECTED_LABELS, type DraftTriagePr } from './draft-triage-rules.js';
|
|
13
13
|
|
|
14
14
|
export type PodTerminalClass = 'landed' | 'merge-ready-not-merged' | 'failed-with-pr' | 'failed-no-pr' | 'failed-pr-unobserved' | 'timed-out-harvestable';
|
|
15
15
|
export interface PrTerminalRecord {
|
|
@@ -43,7 +43,26 @@ export interface PodTerminalInput {
|
|
|
43
43
|
at?: string;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
function cardOf(text?: string): string | null {
|
|
47
|
+
const lines = (text ?? '').split(/\r?\n/).filter((line) => line.startsWith('칸:'));
|
|
48
|
+
if (lines.length !== 1) return null;
|
|
49
|
+
const slot = lines[0]!.slice('칸:'.length).trim();
|
|
50
|
+
// A blank marker cannot borrow an ID from the following line. Duplicate markers are
|
|
51
|
+
// ambiguous even when they happen to name the same card.
|
|
52
|
+
return slot && !/\s/.test(slot) ? slot : null;
|
|
53
|
+
}
|
|
54
|
+
const validCardSlot = (text: string | null): text is string => !!text && /^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/.test(text);
|
|
55
|
+
const goalLineage = (pr: ResiduePr): string | undefined =>
|
|
56
|
+
/(?:^|[-/])goalid-([a-f0-9]+)(?=-|\/|$)/i.exec(pr.branch)?.[1]?.toLowerCase()
|
|
57
|
+
?? /^골(?: ID)?:\s*(\S.*?)\s*$/m.exec(pr.body ?? '')?.[1];
|
|
58
|
+
const hasCodeDiff = (paths: readonly string[]): boolean => paths.some((path) =>
|
|
59
|
+
!path.startsWith('docs/') && (
|
|
60
|
+
/\.(?:[cm]?[jt]sx?|py|sh|bash|zsh|rs|go|c|cc|cpp|h|hpp|java|kt|swift|rb|php|lua|sql)$/.test(path)
|
|
61
|
+
|| /(?:^|\/)(?:Dockerfile|Containerfile|Makefile)(?:\.[^/]*)?$/.test(path)
|
|
62
|
+
|| (path.startsWith('graphs/') && /\.ya?ml$/.test(path))));
|
|
63
|
+
function sameCardSlot(previous: ResiduePr, current: ResiduePr, slot: string): boolean {
|
|
64
|
+
return cardOf(previous.body) === slot && cardOf(current.body) === slot;
|
|
65
|
+
}
|
|
47
66
|
const harvestable = PR_LABELS.find((label) => label.name === 'elanous:harvestable')!.name;
|
|
48
67
|
const superseded = PR_LABELS.find((label) => label.name === 'elanous:superseded')!.name;
|
|
49
68
|
|
|
@@ -83,6 +102,8 @@ export function classifyPodTerminal(input: PodTerminalInput): PrTerminalRecord {
|
|
|
83
102
|
export interface ResiduePr extends DraftTriagePr {
|
|
84
103
|
createdAt: string;
|
|
85
104
|
labels: readonly string[];
|
|
105
|
+
headSha?: string;
|
|
106
|
+
isDraft?: boolean;
|
|
86
107
|
body?: string;
|
|
87
108
|
comments?: readonly string[];
|
|
88
109
|
/** GitHub PR state at lookup time (review r8) — absent only from injected inventories. */
|
|
@@ -92,7 +113,12 @@ export interface DraftResidueAdapters {
|
|
|
92
113
|
loadLedger(runId: string, ledgerDir: string): readonly RunLedgerEntry[] | null;
|
|
93
114
|
appendLedger(entry: RunLedgerEntry, ledgerDir: string): void;
|
|
94
115
|
getPr(number: number): Promise<ResiduePr | undefined> | ResiduePr | undefined;
|
|
116
|
+
/** Return all issue comments only after pagination completes; undefined means completeness is unknown. */
|
|
117
|
+
getAllComments?(repository: string, number: number): Promise<readonly string[] | undefined> | readonly string[] | undefined;
|
|
118
|
+
/** Undefined means the open-draft inventory could not be observed («못 셌음») — never a disguised zero count. */
|
|
95
119
|
listOpenDrafts(repository: string): Promise<readonly ResiduePr[] | undefined> | readonly ResiduePr[] | undefined;
|
|
120
|
+
/** Complete changed-path inventory for the newly opened PR; undefined is unmeasured. */
|
|
121
|
+
listPrChangedPaths?(repository: string, number: number): Promise<readonly string[] | undefined> | readonly string[] | undefined;
|
|
96
122
|
addLabel(repository: string, number: number, label: string): Promise<void> | void;
|
|
97
123
|
setLabels(repository: string, number: number, change: { add: string; remove: readonly string[] }): Promise<void> | void;
|
|
98
124
|
comment(repository: string, number: number, body: string): Promise<void> | void;
|
|
@@ -112,14 +138,21 @@ export interface DraftResidueContext {
|
|
|
112
138
|
}
|
|
113
139
|
export type DraftResidueResult = { status: 'recorded' | 'skipped' | 'failed'; reason?: string; step?: string };
|
|
114
140
|
|
|
141
|
+
/** A REST pulls page carries up to 100 full PR bodies; the spawn default buffer (1 MiB) overflowed daily as
|
|
142
|
+
* `spawnSync gh ENOBUFS`, so every gh call gets an explicit ceiling that fits a full page of large-bodied drafts. */
|
|
143
|
+
const GH_MAX_BUFFER = 64 * 1024 * 1024;
|
|
144
|
+
/** Only the fields the residue consumes. The raw REST page (base/head repo objects, _links, review metadata, …) is
|
|
145
|
+
* several times larger than this projection, so the listing asks gh to project each page down to these fields. */
|
|
146
|
+
const OPEN_DRAFT_FIELDS = '[.[] | {number, title, headRefName: .head.ref, createdAt: .created_at, body, labels: [.labels[] | {name}], draft}]';
|
|
147
|
+
|
|
115
148
|
function gh(args: string[]): string {
|
|
116
|
-
const result = spawnSync('gh', args, { cwd: findGitDir(process.cwd())?.root ?? process.cwd(), encoding: 'utf8', timeout: 60_000 });
|
|
149
|
+
const result = spawnSync('gh', args, { cwd: findGitDir(process.cwd())?.root ?? process.cwd(), encoding: 'utf8', timeout: 60_000, maxBuffer: GH_MAX_BUFFER });
|
|
117
150
|
if (result.status !== 0) throw new Error((result.stderr || result.error?.message || `gh exited ${result.status}`).trim().slice(0, 200));
|
|
118
151
|
return result.stdout.trim();
|
|
119
152
|
}
|
|
120
|
-
function ghPr(row: { number: number; title: string; headRefName: string; createdAt: string; body: string; labels: Array<{ name: string }>; comments?: Array<{ body: string }>; state?: string }): ResiduePr {
|
|
153
|
+
function ghPr(row: { number: number; title: string; headRefName: string; headRefOid?: string; isDraft?: boolean; createdAt: string; body: string; labels: Array<{ name: string }>; comments?: Array<{ body: string }>; state?: string }): ResiduePr {
|
|
121
154
|
const state = row.state === 'OPEN' || row.state === 'CLOSED' || row.state === 'MERGED' ? row.state : undefined;
|
|
122
|
-
return { number: row.number, title: row.title, branch: row.headRefName, createdAt: row.createdAt, body: row.body,
|
|
155
|
+
return { number: row.number, title: row.title, branch: row.headRefName, headSha: row.headRefOid, isDraft: row.isDraft, createdAt: row.createdAt, body: row.body,
|
|
123
156
|
labels: row.labels.map((label) => label.name), comments: row.comments?.map((comment) => comment.body), ...(state ? { state } : {}) };
|
|
124
157
|
}
|
|
125
158
|
/** Where the default `getRunStatus` reads run facts. Production reads the federated host ledgers and the running-runs
|
|
@@ -166,25 +199,54 @@ export function residueRunStatus(draft: Pick<ResiduePr, 'number'>, repository: s
|
|
|
166
199
|
}
|
|
167
200
|
|
|
168
201
|
export function defaultAdapters(sources: ResidueRunStatusSources = defaultRunStatusSources): DraftResidueAdapters {
|
|
169
|
-
const fields = 'number,title,headRefName,createdAt,body,labels,comments,state';
|
|
202
|
+
const fields = 'number,title,headRefName,headRefOid,isDraft,createdAt,body,labels,comments,state';
|
|
170
203
|
return {
|
|
171
204
|
loadLedger: loadRunLedger,
|
|
172
205
|
appendLedger: appendRunLedgerEntry,
|
|
173
206
|
getPr: (number) => ghPr(JSON.parse(gh(['pr', 'view', String(number), '-R', hostRepository() ?? '', '--json', fields]))),
|
|
207
|
+
getAllComments: (repository, number) => {
|
|
208
|
+
try {
|
|
209
|
+
const pages: unknown = JSON.parse(gh(['api', `repos/${repository}/issues/${number}/comments?per_page=100`, '--paginate', '--slurp']));
|
|
210
|
+
if (!Array.isArray(pages) || !pages.every((page) => Array.isArray(page)
|
|
211
|
+
&& page.every((row: unknown) => !!row && typeof row === 'object' && typeof (row as { body?: unknown }).body === 'string'))) return undefined;
|
|
212
|
+
return (pages as Array<Array<{ body: string }>>).flat().map((row) => row.body);
|
|
213
|
+
} catch (error) {
|
|
214
|
+
debug.log('draft.residue', 'comments-unobserved', { repository, number, reason: error instanceof Error ? error.message : String(error) });
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
217
|
+
},
|
|
174
218
|
listOpenDrafts: (repository) => {
|
|
175
219
|
const rows: ResiduePr[] = [];
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
220
|
+
try {
|
|
221
|
+
for (let page = 1; page <= 100; page++) {
|
|
222
|
+
const result = JSON.parse(gh(['api', `repos/${repository}/pulls?state=open&per_page=100&page=${page}`, '--jq', OPEN_DRAFT_FIELDS])) as Array<{
|
|
223
|
+
number: number; title: string; headRefName: string; createdAt: string; body: string;
|
|
224
|
+
labels: Array<{ name: string }>; draft: boolean;
|
|
225
|
+
}>;
|
|
226
|
+
if (!Array.isArray(result)) throw new Error('Invalid open PR inventory');
|
|
227
|
+
rows.push(...result.filter((pr) => pr.draft).map((pr) => ghPr({ number: pr.number, title: pr.title, headRefName: pr.headRefName, createdAt: pr.createdAt, body: pr.body, labels: pr.labels })));
|
|
228
|
+
if (result.length < 100) return rows;
|
|
229
|
+
}
|
|
230
|
+
throw new Error('Open PR inventory exceeded pagination limit');
|
|
231
|
+
} catch (error) {
|
|
232
|
+
// «못 셌음»: a failed (or truncated) listing is unmeasurable — it must never surface as a counted zero.
|
|
233
|
+
debug.log('draft.residue', 'list-open-drafts-unobserved', { repository, reason: error instanceof Error ? error.message : String(error) });
|
|
234
|
+
return undefined;
|
|
183
235
|
}
|
|
184
|
-
|
|
236
|
+
},
|
|
237
|
+
listPrChangedPaths: (repository, number) => {
|
|
238
|
+
try {
|
|
239
|
+
const pages: unknown = JSON.parse(gh(['api', `repos/${repository}/pulls/${number}/files?per_page=100`, '--paginate', '--slurp']));
|
|
240
|
+
if (!Array.isArray(pages) || !pages.every((page) => Array.isArray(page)
|
|
241
|
+
&& page.every((row: unknown) => !!row && typeof row === 'object' && typeof (row as { filename?: unknown }).filename === 'string'))) return undefined;
|
|
242
|
+
return (pages as Array<Array<{ filename: string }>>).flat().map((row) => row.filename);
|
|
243
|
+
} catch { return undefined; }
|
|
185
244
|
},
|
|
186
245
|
addLabel: (repository, number, label) => { gh(['pr', 'edit', String(number), '-R', repository, '--add-label', label]); },
|
|
187
|
-
setLabels: (repository, number, change) => {
|
|
246
|
+
setLabels: (repository, number, change) => {
|
|
247
|
+
const flags = [...(change.add ? ['--add-label', change.add] : []), ...change.remove.flatMap((label) => ['--remove-label', label])];
|
|
248
|
+
if (flags.length) gh(['pr', 'edit', String(number), '-R', repository, ...flags]);
|
|
249
|
+
},
|
|
188
250
|
comment: (repository, number, body) => { gh(['pr', 'comment', String(number), '-R', repository, '--body', body]); },
|
|
189
251
|
closePr: (repository, number) => { gh(['pr', 'close', String(number), '-R', repository]); },
|
|
190
252
|
listLiveBranches: (repository) => {
|
|
@@ -319,7 +381,7 @@ export async function replayPodTerminals(options: DraftResidueReplayOptions = {}
|
|
|
319
381
|
const outcome = await applyPodTerminal(record, { ledgerDir, ledgerRunId, adapters: replayAdapters, closeBudget });
|
|
320
382
|
if (outcome.status === 'recorded' || outcome.reason === 'already-recorded') recovered++;
|
|
321
383
|
else if (outcome.status === 'skipped' && outcome.reason === 'repository-unobserved') unresolved++;
|
|
322
|
-
else if (outcome.status === 'skipped' && !['previous-run-unverified', 'previous-run-live', 'close-cap', 'host-repository-unobserved'].includes(outcome.reason ?? '')) recovered++;
|
|
384
|
+
else if (outcome.status === 'skipped' && !['previous-run-unverified', 'previous-run-live', 'close-cap', 'host-repository-unobserved', 'restore-unverified'].includes(outcome.reason ?? '')) recovered++;
|
|
323
385
|
else pending++;
|
|
324
386
|
}
|
|
325
387
|
}
|
|
@@ -333,6 +395,7 @@ export async function applyPodTerminal(record: PrTerminalRecord, ctx: DraftResid
|
|
|
333
395
|
const skipped = (reason: string): DraftResidueResult => { log('skipped', { reason }); return { status: 'skipped', reason }; };
|
|
334
396
|
const budget: DraftCloseBudget = ctx.closeBudget ?? { remaining: DRAFT_SWEEP_CLOSE_CAP };
|
|
335
397
|
let step = 'ledger';
|
|
398
|
+
let pendingSupersession: { repository: string; number: number; prNumber: number; commentMayExist: boolean } | null = null;
|
|
336
399
|
try {
|
|
337
400
|
const ledger = adapters.loadLedger(ctx.ledgerRunId, ctx.ledgerDir);
|
|
338
401
|
if (ledger === undefined) throw new Error('Terminal ledger unavailable');
|
|
@@ -407,6 +470,28 @@ export async function applyPodTerminal(record: PrTerminalRecord, ctx: DraftResid
|
|
|
407
470
|
step = 'ledger';
|
|
408
471
|
acknowledge('owner-comment', pr.number);
|
|
409
472
|
}
|
|
473
|
+
// PR1a records a recovery pointer but never closes this failed draft. PR1b owns the close decision.
|
|
474
|
+
if (record.terminalClass === 'failed-with-pr' && !completed('restore-comment', pr.number)) {
|
|
475
|
+
step = 'get-pr';
|
|
476
|
+
let latest: ResiduePr | undefined;
|
|
477
|
+
try { latest = await adapters.getPr(pr.number); }
|
|
478
|
+
catch { return skipped('restore-unverified'); }
|
|
479
|
+
if (!latest || latest.state !== 'OPEN' || latest.isDraft !== true || !record.headSha
|
|
480
|
+
|| latest.headSha?.toLowerCase() !== record.headSha.toLowerCase()
|
|
481
|
+
|| !latest.branch?.trim() || latest.branch !== pr.branch || (record.branch && latest.branch !== record.branch)
|
|
482
|
+
|| !Array.isArray(latest.labels) || latest.labels.some((label) => PROTECTED_LABELS.has(label))) {
|
|
483
|
+
return skipped('restore-unverified');
|
|
484
|
+
}
|
|
485
|
+
step = 'list-comments';
|
|
486
|
+
let comments: readonly string[] | undefined;
|
|
487
|
+
try { comments = await adapters.getAllComments?.(record.repository, pr.number); }
|
|
488
|
+
catch { return skipped('restore-unverified'); }
|
|
489
|
+
if (!Array.isArray(comments) || comments.some((comment) => typeof comment !== 'string'
|
|
490
|
+
|| /landing-verified\s*:|land-enqueue\s*:/i.test(comment))) return skipped('restore-unverified');
|
|
491
|
+
const restore = `Draft residue: failed-run recovery · run=${record.childRunId} · head=${record.headSha} · branch=${latest.branch} preserved. Restore from this branch.`;
|
|
492
|
+
if (!comments.includes(restore)) { step = 'comment'; await adapters.comment(record.repository, pr.number, restore); }
|
|
493
|
+
step = 'ledger'; acknowledge('restore-comment', pr.number);
|
|
494
|
+
}
|
|
410
495
|
} else skipped('landed');
|
|
411
496
|
step = 'list-open-drafts';
|
|
412
497
|
const drafts = await adapters.listOpenDrafts(record.repository);
|
|
@@ -415,12 +500,33 @@ export async function applyPodTerminal(record: PrTerminalRecord, ctx: DraftResid
|
|
|
415
500
|
throw new Error('Open draft lookup unavailable or incomplete');
|
|
416
501
|
}
|
|
417
502
|
const newerAt = Date.parse(pr.createdAt);
|
|
418
|
-
const
|
|
503
|
+
const slot = cardOf(pr.body);
|
|
504
|
+
const taSlot = validCardSlot(slot) ? slot : undefined;
|
|
505
|
+
const earlier: ResiduePr[] = drafts.filter((draft: ResiduePr) => draft.number !== pr.number && draft.branch.startsWith('self-impl/')
|
|
419
506
|
&& Date.parse(draft.createdAt) < newerAt && !draft.labels.some((label: string) => PROTECTED_LABELS.has(label))
|
|
420
|
-
&& !completed('superseded-close', draft.number)
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
507
|
+
&& !completed('superseded-close', draft.number));
|
|
508
|
+
const sameSlot = taSlot ? earlier.filter((draft) => /^[a-f0-9]{40}$/i.test(draft.headSha ?? '') && sameCardSlot(draft, pr, taSlot)
|
|
509
|
+
&& !draft.labels.some((label) => label === 'elanous:running' || label.includes('harvest-claimed'))) : [];
|
|
510
|
+
let codeDiff = false;
|
|
511
|
+
if (taSlot && sameSlot.length) {
|
|
512
|
+
// A changed PR head can turn a measured code PR into a goal-only PR while files are being fetched.
|
|
513
|
+
step = 'get-pr';
|
|
514
|
+
const beforeFiles = await adapters.getPr(pr.number);
|
|
515
|
+
if (!beforeFiles || beforeFiles.number !== pr.number || beforeFiles.state !== pr.state
|
|
516
|
+
|| !pr.headSha || beforeFiles.headSha !== pr.headSha || beforeFiles.branch !== pr.branch
|
|
517
|
+
|| !sameCardSlot(beforeFiles, pr, taSlot)) return skipped('new-pr-changed-before-files');
|
|
518
|
+
step = 'list-pr-changed-paths';
|
|
519
|
+
const paths = await adapters.listPrChangedPaths?.(record.repository, pr.number);
|
|
520
|
+
if (!paths || !Array.isArray(paths) || paths.some((path) => typeof path !== 'string')) return skipped('new-pr-code-diff-unobserved');
|
|
521
|
+
step = 'get-pr';
|
|
522
|
+
const afterFiles = await adapters.getPr(pr.number);
|
|
523
|
+
if (!afterFiles || afterFiles.number !== pr.number || afterFiles.state !== pr.state
|
|
524
|
+
|| afterFiles.headSha !== pr.headSha || afterFiles.branch !== pr.branch
|
|
525
|
+
|| !sameCardSlot(afterFiles, pr, taSlot)) return skipped('new-pr-changed-after-files');
|
|
526
|
+
codeDiff = hasCodeDiff(paths);
|
|
527
|
+
if (!codeDiff) log('skipped', { reason: 'new-pr-goal-only', prNumber: pr.number });
|
|
528
|
+
}
|
|
529
|
+
const candidates = codeDiff ? sameSlot : [];
|
|
424
530
|
let liveBranches: ReadonlySet<string> | undefined;
|
|
425
531
|
if (candidates.length) {
|
|
426
532
|
step = 'list-live-branches';
|
|
@@ -431,6 +537,16 @@ export async function applyPodTerminal(record: PrTerminalRecord, ctx: DraftResid
|
|
|
431
537
|
let capped = false;
|
|
432
538
|
for (const draft of candidates) {
|
|
433
539
|
if (budget.remaining <= 0) { capped = true; break; }
|
|
540
|
+
if (taSlot) {
|
|
541
|
+
step = 'get-pr';
|
|
542
|
+
const latest = await adapters.getPr(draft.number);
|
|
543
|
+
if (!latest || latest.number !== draft.number || latest.state !== 'OPEN' || latest.isDraft !== true
|
|
544
|
+
|| !draft.headSha
|
|
545
|
+
|| latest.branch !== draft.branch || latest.headSha !== draft.headSha
|
|
546
|
+
|| !Array.isArray(latest.labels) || latest.labels.some((label) => PROTECTED_LABELS.has(label)
|
|
547
|
+
|| label === 'elanous:running' || label.includes('harvest-claimed'))
|
|
548
|
+
|| !sameCardSlot(latest, pr, taSlot)) { deferred = true; skipped('previous-pr-changed'); continue; }
|
|
549
|
+
}
|
|
434
550
|
step = 'get-run-status';
|
|
435
551
|
const status = await adapters.getRunStatus(draft, record.repository);
|
|
436
552
|
if (liveBranches!.has(draft.branch) || !['completed', 'failed', 'cancelled', 'abandoned', 'self-implement.result final'].includes(status ?? '')) {
|
|
@@ -438,38 +554,145 @@ export async function applyPodTerminal(record: PrTerminalRecord, ctx: DraftResid
|
|
|
438
554
|
skipped(`previous-run-${status === 'running' || status === 'probable-running' || liveBranches!.has(draft.branch) ? 'live' : 'unobserved'}`);
|
|
439
555
|
continue;
|
|
440
556
|
}
|
|
557
|
+
if (taSlot) {
|
|
558
|
+
step = 'list-live-branches';
|
|
559
|
+
const liveNow = await adapters.listLiveBranches(record.repository);
|
|
560
|
+
step = 'get-run-status';
|
|
561
|
+
const statusNow = await adapters.getRunStatus(draft, record.repository);
|
|
562
|
+
if (!liveNow || liveNow.has(draft.branch)
|
|
563
|
+
|| !['completed', 'failed', 'cancelled', 'abandoned', 'self-implement.result final'].includes(statusNow ?? '')) {
|
|
564
|
+
deferred = true; skipped('previous-run-changed-before-label'); continue;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
// Revalidate the effective diff and both PRs before applying any public supersession marker.
|
|
568
|
+
if (taSlot) {
|
|
569
|
+
const newBeforeClose = await adapters.getPr(pr.number);
|
|
570
|
+
if (!newBeforeClose || newBeforeClose.number !== pr.number || newBeforeClose.state !== pr.state
|
|
571
|
+
|| newBeforeClose.headSha !== pr.headSha || newBeforeClose.branch !== pr.branch
|
|
572
|
+
|| !sameCardSlot(newBeforeClose, pr, taSlot)) { deferred = true; skipped('new-pr-changed-before-close'); continue; }
|
|
573
|
+
// The base can move without changing this PR's head. Re-read the effective diff before closing the old draft.
|
|
574
|
+
step = 'list-pr-changed-paths';
|
|
575
|
+
const currentPaths = await adapters.listPrChangedPaths?.(record.repository, pr.number);
|
|
576
|
+
if (!currentPaths || !Array.isArray(currentPaths) || currentPaths.some((path) => typeof path !== 'string')
|
|
577
|
+
|| !hasCodeDiff(currentPaths)) { deferred = true; skipped('new-pr-code-diff-changed-before-close'); continue; }
|
|
578
|
+
step = 'get-pr';
|
|
579
|
+
const afterCloseDiff = await adapters.getPr(pr.number);
|
|
580
|
+
if (!afterCloseDiff || afterCloseDiff.number !== pr.number || afterCloseDiff.state !== pr.state
|
|
581
|
+
|| afterCloseDiff.headSha !== pr.headSha || afterCloseDiff.branch !== pr.branch
|
|
582
|
+
|| !sameCardSlot(afterCloseDiff, pr, taSlot)) { deferred = true; skipped('new-pr-changed-after-close-diff'); continue; }
|
|
583
|
+
const beforeClose = await adapters.getPr(draft.number);
|
|
584
|
+
if (!beforeClose || beforeClose.number !== draft.number || beforeClose.state !== 'OPEN' || beforeClose.isDraft !== true
|
|
585
|
+
|| !draft.headSha
|
|
586
|
+
|| beforeClose.branch !== draft.branch || beforeClose.headSha !== draft.headSha
|
|
587
|
+
|| !Array.isArray(beforeClose.labels) || beforeClose.labels.some((label) => PROTECTED_LABELS.has(label)
|
|
588
|
+
|| label === 'elanous:running' || label.includes('harvest-claimed'))
|
|
589
|
+
|| !sameCardSlot(beforeClose, pr, taSlot)) { deferred = true; skipped('previous-pr-changed-before-close'); continue; }
|
|
590
|
+
step = 'list-live-branches';
|
|
591
|
+
const liveBeforeClose = await adapters.listLiveBranches(record.repository);
|
|
592
|
+
step = 'get-run-status';
|
|
593
|
+
const statusBeforeClose = await adapters.getRunStatus(draft, record.repository);
|
|
594
|
+
if (!liveBeforeClose || liveBeforeClose.has(draft.branch)
|
|
595
|
+
|| !['completed', 'failed', 'cancelled', 'abandoned', 'self-implement.result final'].includes(statusBeforeClose ?? '')) {
|
|
596
|
+
deferred = true; skipped('previous-run-changed-before-close'); continue;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
441
599
|
if (!completed('supersede-intent', draft.number)) {
|
|
442
600
|
step = 'ledger';
|
|
443
601
|
acknowledge('supersede-intent', draft.number);
|
|
444
602
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
603
|
+
// The inventory was read before the liveness and diff checks. Labels can change while
|
|
604
|
+
// those checks run, so ownership and the state to restore come from a fresh PR read.
|
|
605
|
+
step = 'get-pr';
|
|
606
|
+
const beforeLabel = await adapters.getPr(draft.number);
|
|
607
|
+
if (!beforeLabel || beforeLabel.number !== draft.number || beforeLabel.state !== 'OPEN'
|
|
608
|
+
|| beforeLabel.isDraft !== true || beforeLabel.branch !== draft.branch
|
|
609
|
+
|| beforeLabel.headSha !== draft.headSha || !Array.isArray(beforeLabel.labels)
|
|
610
|
+
|| beforeLabel.labels.some((label) => PROTECTED_LABELS.has(label)
|
|
611
|
+
|| label === 'elanous:running' || label.includes('harvest-claimed'))
|
|
612
|
+
|| (taSlot && !sameCardSlot(beforeLabel, pr, taSlot))) {
|
|
613
|
+
deferred = true; skipped('previous-pr-changed-before-label-write'); continue;
|
|
453
614
|
}
|
|
454
|
-
|
|
615
|
+
// There is no conditional GitHub add-label operation. A label written before close
|
|
616
|
+
// cannot be safely removed on a race: another run may have added that same label
|
|
617
|
+
// between our read and write. Apply the public state marker only after close succeeds.
|
|
618
|
+
pendingSupersession = { repository: record.repository, number: draft.number, prNumber: pr.number,
|
|
619
|
+
commentMayExist: false };
|
|
620
|
+
const body = taSlot
|
|
621
|
+
? `Draft residue: superseded-by #${pr.number} (same card ${taSlot}; old goalid=${goalLineage(draft) ?? 'unobserved'}; new goalid=${goalLineage(pr) ?? 'unobserved'}; newer run ${record.childRunId}). Branch preserved.`
|
|
622
|
+
: `Draft residue: superseded-by #${pr.number} (newer run ${record.childRunId} of the same goal). Branch preserved.`;
|
|
623
|
+
pendingSupersession.commentMayExist = completed('supersede-comment', draft.number);
|
|
455
624
|
if (!completed('supersede-comment', draft.number)) {
|
|
456
|
-
// REST draft listings do not contain comments; fetch them
|
|
625
|
+
// REST draft listings do not contain comments; fetch them before deciding whether to comment.
|
|
457
626
|
let comments = draft.comments;
|
|
458
|
-
if (comments === undefined
|
|
627
|
+
if (comments === undefined) {
|
|
459
628
|
step = 'get-pr';
|
|
460
629
|
const prior = await adapters.getPr(draft.number);
|
|
461
630
|
if (!prior || prior.number !== draft.number) throw new Error('Previous PR lookup unavailable');
|
|
462
631
|
comments = prior.comments;
|
|
463
632
|
}
|
|
464
|
-
if (!comments?.includes(body)) {
|
|
633
|
+
if (!comments?.includes(body)) {
|
|
634
|
+
pendingSupersession.commentMayExist = true;
|
|
635
|
+
step = 'comment'; await adapters.comment(record.repository, draft.number, body);
|
|
636
|
+
}
|
|
465
637
|
step = 'ledger';
|
|
466
638
|
acknowledge('supersede-comment', draft.number);
|
|
467
639
|
}
|
|
640
|
+
if (taSlot) {
|
|
641
|
+
// A claimant or new commit can arrive while GitHub accepts the label/comment writes.
|
|
642
|
+
step = 'list-pr-changed-paths';
|
|
643
|
+
const pathsAfterEffects = await adapters.listPrChangedPaths?.(record.repository, pr.number);
|
|
644
|
+
// The diff lookup can race a new head; bind its result to the head read after it.
|
|
645
|
+
step = 'get-pr';
|
|
646
|
+
const newAfterEffects = await adapters.getPr(pr.number);
|
|
647
|
+
step = 'list-live-branches';
|
|
648
|
+
const liveAfterEffects = await adapters.listLiveBranches(record.repository);
|
|
649
|
+
step = 'get-run-status';
|
|
650
|
+
const statusAfterEffects = await adapters.getRunStatus(draft, record.repository);
|
|
651
|
+
step = 'get-pr';
|
|
652
|
+
const oldAfterEffects = await adapters.getPr(draft.number);
|
|
653
|
+
if (!newAfterEffects || newAfterEffects.number !== pr.number || newAfterEffects.state !== pr.state
|
|
654
|
+
|| newAfterEffects.headSha !== pr.headSha || newAfterEffects.branch !== pr.branch
|
|
655
|
+
|| !sameCardSlot(newAfterEffects, pr, taSlot)
|
|
656
|
+
|| !pathsAfterEffects || !Array.isArray(pathsAfterEffects)
|
|
657
|
+
|| pathsAfterEffects.some((path) => typeof path !== 'string') || !hasCodeDiff(pathsAfterEffects)
|
|
658
|
+
|| !oldAfterEffects || oldAfterEffects.number !== draft.number || oldAfterEffects.state !== 'OPEN'
|
|
659
|
+
|| oldAfterEffects.isDraft !== true || oldAfterEffects.headSha !== draft.headSha
|
|
660
|
+
|| oldAfterEffects.branch !== draft.branch || !Array.isArray(oldAfterEffects.labels)
|
|
661
|
+
|| oldAfterEffects.labels.some((label) => PROTECTED_LABELS.has(label)
|
|
662
|
+
|| label === 'elanous:running' || label.includes('harvest-claimed'))
|
|
663
|
+
|| !sameCardSlot(oldAfterEffects, pr, taSlot)
|
|
664
|
+
|| !liveAfterEffects || liveAfterEffects.has(draft.branch)
|
|
665
|
+
|| !['completed', 'failed', 'cancelled', 'abandoned', 'self-implement.result final'].includes(statusAfterEffects ?? '')) {
|
|
666
|
+
const correction = `Draft residue: supersession by #${pr.number} deferred after PR or run changed; branch preserved. Prior superseded-by comment is no longer a close decision.`;
|
|
667
|
+
if (!oldAfterEffects?.comments?.includes(correction)) {
|
|
668
|
+
step = 'comment';
|
|
669
|
+
await adapters.comment(record.repository, draft.number, correction);
|
|
670
|
+
}
|
|
671
|
+
pendingSupersession = null;
|
|
672
|
+
deferred = true; skipped('supersession-changed-after-effects'); continue;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
468
675
|
step = 'close-pr';
|
|
469
676
|
await adapters.closePr(record.repository, draft.number);
|
|
677
|
+
pendingSupersession = null;
|
|
470
678
|
budget.remaining--;
|
|
471
679
|
step = 'ledger';
|
|
472
680
|
acknowledge('superseded-close', draft.number);
|
|
681
|
+
// The close is irreversible. Label failure is diagnostic, never a reason to retry
|
|
682
|
+
// supersession or to roll back a label whose writer cannot be identified.
|
|
683
|
+
if (!beforeLabel.labels.includes(superseded)) {
|
|
684
|
+
try {
|
|
685
|
+
step = 'set-labels';
|
|
686
|
+
// A state label read before close may have been written by another run
|
|
687
|
+
// before this call. Its writer is unknown, so only add our marker.
|
|
688
|
+
await adapters.setLabels(record.repository, draft.number, { add: superseded, remove: [] });
|
|
689
|
+
step = 'ledger';
|
|
690
|
+
if (!completed('superseded-label', draft.number)) acknowledge('superseded-label', draft.number);
|
|
691
|
+
} catch (labelError) {
|
|
692
|
+
log('superseded-label-unobserved', { previousPrNumber: draft.number,
|
|
693
|
+
reason: labelError instanceof Error ? labelError.message : String(labelError) });
|
|
694
|
+
}
|
|
695
|
+
}
|
|
473
696
|
log('superseded-previous', { previousPrNumber: draft.number });
|
|
474
697
|
}
|
|
475
698
|
if (deferred) return skipped('previous-run-unverified');
|
|
@@ -479,6 +702,17 @@ export async function applyPodTerminal(record: PrTerminalRecord, ctx: DraftResid
|
|
|
479
702
|
return { status: 'recorded' };
|
|
480
703
|
} catch (error) {
|
|
481
704
|
const reason = error instanceof Error ? error.message : String(error);
|
|
705
|
+
if (pendingSupersession) {
|
|
706
|
+
const pending = pendingSupersession;
|
|
707
|
+
try {
|
|
708
|
+
if (pending.commentMayExist) await adapters.comment(pending.repository, pending.number,
|
|
709
|
+
`Draft residue: supersession by #${pending.prNumber} deferred after an interrupted check; branch preserved. Prior superseded-by comment is no longer a close decision.`);
|
|
710
|
+
log('supersession-compensated', { previousPrNumber: pending.number, failedStep: step });
|
|
711
|
+
} catch (compensationError) {
|
|
712
|
+
log('supersession-compensation-failed', { previousPrNumber: pending.number,
|
|
713
|
+
reason: compensationError instanceof Error ? compensationError.message : String(compensationError) });
|
|
714
|
+
}
|
|
715
|
+
}
|
|
482
716
|
log('failed', { step, reason });
|
|
483
717
|
return { status: 'failed', step, reason };
|
|
484
718
|
}
|
|
@@ -154,6 +154,12 @@ export interface DraftMetrics {
|
|
|
154
154
|
readonly inventory: number;
|
|
155
155
|
readonly oldestAgeHours: number | null;
|
|
156
156
|
readonly needsOwner: number;
|
|
157
|
+
/**
|
|
158
|
+
* Per-seat needsOwner counts (own keys, finite numbers only). Unattributed drafts
|
|
159
|
+
* stay in the global `needsOwner` total and are absent here. Optional so existing
|
|
160
|
+
* screen/ledger constructors stay valid; collectDraftMetrics always fills it.
|
|
161
|
+
*/
|
|
162
|
+
readonly needsOwnerBySeat?: Readonly<Record<string, number>>;
|
|
157
163
|
/** Open running claims whose last update cannot be read; neither owned nor needs-owner. */
|
|
158
164
|
readonly claimUnobserved?: number;
|
|
159
165
|
readonly converted48h: number;
|
|
@@ -164,6 +170,8 @@ export interface DraftMetrics {
|
|
|
164
170
|
/** Default maximum unclaimed open harness drafts for one seat. */
|
|
165
171
|
export const DRAFT_NEEDS_OWNER_SEAT_CAP = 15;
|
|
166
172
|
|
|
173
|
+
const NEEDS_OWNER_SEATS = ['OP', 'TC', 'MK', 'UX'] as const;
|
|
174
|
+
|
|
167
175
|
/** Compare one seat's observed needsOwner count; the caller supplies counts of open drafts by seat. */
|
|
168
176
|
export function isSeatDraftNeedsOwnerOverCap(
|
|
169
177
|
seat: string,
|
|
@@ -174,6 +182,50 @@ export function isSeatDraftNeedsOwnerOverCap(
|
|
|
174
182
|
return typeof count === 'number' && Number.isFinite(count) && count > cap;
|
|
175
183
|
}
|
|
176
184
|
|
|
185
|
+
/** Hold that seat's new launches when its needsOwner drafts exceed the default cap of 15. */
|
|
186
|
+
export function shouldHoldSeatNewLaunch(
|
|
187
|
+
seat: string,
|
|
188
|
+
needsOwnerBySeat: Readonly<Record<string, number>>,
|
|
189
|
+
): boolean {
|
|
190
|
+
return isSeatDraftNeedsOwnerOverCap(seat, needsOwnerBySeat, DRAFT_NEEDS_OWNER_SEAT_CAP);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function draftNeedsOwner(draft: SweepDraft, owner: string | undefined, now: Date): boolean {
|
|
194
|
+
const state = draftClaimState(draft, now);
|
|
195
|
+
return state !== 'unobserved' && (state !== 'claimed' || !owner?.trim());
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** Seat for a needsOwner draft: active claim owner, else a unique `elanous:seat-<자리>` label. */
|
|
199
|
+
function needsOwnerSeatOf(draft: SweepDraft, owner: string | undefined): string | undefined {
|
|
200
|
+
const claimed = owner?.trim();
|
|
201
|
+
if (claimed && (NEEDS_OWNER_SEATS as readonly string[]).includes(claimed)) return claimed;
|
|
202
|
+
const found = new Set<string>();
|
|
203
|
+
for (const name of draft.labels) {
|
|
204
|
+
const seat = /^elanous:seat-(OP|TC|MK|UX)$/.exec(name)?.[1];
|
|
205
|
+
if (seat) found.add(seat);
|
|
206
|
+
}
|
|
207
|
+
return found.size === 1 ? [...found][0] : undefined;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** Own-key, finite-number per-seat counts of drafts that still need an owner. */
|
|
211
|
+
export function aggregateNeedsOwnerBySeat(
|
|
212
|
+
drafts: readonly SweepDraft[],
|
|
213
|
+
owners: readonly (string | undefined)[],
|
|
214
|
+
now: Date,
|
|
215
|
+
): Record<string, number> {
|
|
216
|
+
const needsOwnerBySeat: Record<string, number> = {};
|
|
217
|
+
for (let index = 0; index < drafts.length; index++) {
|
|
218
|
+
const draft = drafts[index]!;
|
|
219
|
+
if (!draftNeedsOwner(draft, owners[index], now)) continue;
|
|
220
|
+
const seat = needsOwnerSeatOf(draft, owners[index]);
|
|
221
|
+
if (typeof seat !== 'string' || !seat) continue;
|
|
222
|
+
const current = Object.hasOwn(needsOwnerBySeat, seat) ? needsOwnerBySeat[seat] : 0;
|
|
223
|
+
if (typeof current !== 'number' || !Number.isFinite(current)) continue;
|
|
224
|
+
needsOwnerBySeat[seat] = current + 1;
|
|
225
|
+
}
|
|
226
|
+
return needsOwnerBySeat;
|
|
227
|
+
}
|
|
228
|
+
|
|
177
229
|
export async function collectDraftMetrics(repository: string, adapters: Pick<DraftSweepAdapters, 'listDrafts' | 'listRecentClosed' | 'getActiveClaimOwner'>, now: Date): Promise<DraftMetrics> {
|
|
178
230
|
const clock = now.getTime();
|
|
179
231
|
if (!Number.isFinite(clock)) throw new Error('Invalid draft metric clock');
|
|
@@ -209,13 +261,16 @@ export async function collectDraftMetrics(repository: string, adapters: Pick<Dra
|
|
|
209
261
|
const converted48h = cohort.filter((pr) => 'mergedAt' in pr && typeof pr.mergedAt === 'string'
|
|
210
262
|
&& Date.parse(pr.mergedAt) >= Date.parse(pr.createdAt!) && Date.parse(pr.mergedAt) <= clock
|
|
211
263
|
&& Date.parse(pr.mergedAt) - Date.parse(pr.createdAt!) <= 48 * 3_600_000).length;
|
|
264
|
+
const needsOwnerBySeat = aggregateNeedsOwnerBySeat(open, owners, now);
|
|
265
|
+
// This observation reports over-cap seats; the dispatchers enforce the hold before launch.
|
|
266
|
+
const heldSeats = Object.keys(needsOwnerBySeat).filter((seat) =>
|
|
267
|
+
isSeatDraftNeedsOwnerOverCap(seat, needsOwnerBySeat, DRAFT_NEEDS_OWNER_SEAT_CAP));
|
|
268
|
+
try { debug.log('self-dev.draft-metrics', 'seat-launch-hold', { heldSeats, needsOwnerBySeat }); } catch { /* fail-soft */ }
|
|
212
269
|
return {
|
|
213
270
|
inventory: open.length,
|
|
214
271
|
oldestAgeHours: open.length ? Math.max(...open.map((pr) => Math.max(0, (clock - Date.parse(pr.createdAt)) / 3_600_000))) : null,
|
|
215
|
-
needsOwner: open.filter((draft, index) =>
|
|
216
|
-
|
|
217
|
-
return state !== 'unobserved' && (state !== 'claimed' || !owners[index]?.trim());
|
|
218
|
-
}).length,
|
|
272
|
+
needsOwner: open.filter((draft, index) => draftNeedsOwner(draft, owners[index], now)).length,
|
|
273
|
+
needsOwnerBySeat,
|
|
219
274
|
claimUnobserved: open.filter((draft) => draftClaimState(draft, now) === 'unobserved').length,
|
|
220
275
|
converted48h,
|
|
221
276
|
cohort48h: cohort.length,
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// ── 외부 호출 0 모드 가드 — LLM·검색·크롤 외부 호출을 «거부하고 남긴다» ─────────────
|
|
2
|
+
//
|
|
3
|
+
// «외부 호출 0 모드»(external-call-zero mode)가 켜져 있으면 LLM·검색·크롤 외부 호출
|
|
4
|
+
// 시도는 전부 거부되고, 거부된 시도마다 감사 원장에 한 줄이 덧붙는다(타임스탬프 ·
|
|
5
|
+
// 호출 범주 · 호출자 맥락). 원장은 append-only — 이력은 «덧붙일 수만» 있고,
|
|
6
|
+
// 읽는 쪽이 고치거나 지울 수는 없다.
|
|
7
|
+
//
|
|
8
|
+
// 이 모듈은 순수 가드다. run-supervisor.ts 로의 배선(LLM/검색/크롤 시도를 이 가드로
|
|
9
|
+
// 돌리는 시임)은 이 정의를 소비하는 별도 의존 조각의 몫이다 — 여기서 운영 경로를
|
|
10
|
+
// 건드리지 않는 것은 의도된 경계다.
|
|
11
|
+
|
|
12
|
+
export const EXTERNAL_CALL_CATEGORIES = ['llm', 'search', 'crawl'] as const;
|
|
13
|
+
|
|
14
|
+
export type ExternalCallCategory = (typeof EXTERNAL_CALL_CATEGORIES)[number];
|
|
15
|
+
|
|
16
|
+
/** 거부된 외부 호출 시도 한 건 — 감사 원장의 한 줄. */
|
|
17
|
+
export interface ExternalCallAuditEntry {
|
|
18
|
+
/** 0부터 매 거부 시도마다 하나씩 — 같은 원장에서 재사용되지 않는다. */
|
|
19
|
+
readonly seq: number;
|
|
20
|
+
/** 시각(ISO 8601). */
|
|
21
|
+
readonly at: string;
|
|
22
|
+
/** 시도한 외부 표면(llm | search | crawl). */
|
|
23
|
+
readonly category: ExternalCallCategory;
|
|
24
|
+
/** 호출자 맥락 — 누가(어느 파일·함수·지점) 외부 호출을 청했나. */
|
|
25
|
+
readonly caller: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ExternalCallZeroVerdict {
|
|
29
|
+
readonly denied: boolean;
|
|
30
|
+
/** 거부되어 원장에 덧붙은 줄 — 거부된 시도에만 있다. */
|
|
31
|
+
readonly entry?: ExternalCallAuditEntry;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface ExternalCallZeroOptions {
|
|
35
|
+
/** true = 외부 호출 0 모드. 기본 false — 평소 동작(호출 통과 · 기록 없음). */
|
|
36
|
+
readonly enabled?: boolean;
|
|
37
|
+
/** 시험용 시계 주입 — 운영은 벽시계를 쓴다. */
|
|
38
|
+
readonly now?: () => Date;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class ExternalCallZeroGuard {
|
|
42
|
+
private readonly zeroMode: boolean;
|
|
43
|
+
private readonly clock: () => Date;
|
|
44
|
+
private readonly entries: ExternalCallAuditEntry[] = [];
|
|
45
|
+
|
|
46
|
+
constructor(options: ExternalCallZeroOptions = {}) {
|
|
47
|
+
this.zeroMode = options.enabled ?? false;
|
|
48
|
+
this.clock = options.now ?? (() => new Date());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** 외부 호출 0 모드가 켜져 있는가. */
|
|
52
|
+
get enabled(): boolean {
|
|
53
|
+
return this.zeroMode;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 외부 호출 시도를 가드로 돌린다. 켜진 모드에서는 모든 llm/search/crawl 시도를
|
|
58
|
+
* 거부하고 시도마다 감사 원장에 한 줄을 덧붙인다. 꺼진 모드는 시도를 그대로
|
|
59
|
+
* 통과시키고 아무것도 기록하지 않는다.
|
|
60
|
+
*/
|
|
61
|
+
attempt(category: ExternalCallCategory, caller: string): ExternalCallZeroVerdict {
|
|
62
|
+
if (!this.zeroMode) return { denied: false };
|
|
63
|
+
const entry: ExternalCallAuditEntry = Object.freeze({
|
|
64
|
+
seq: this.entries.length,
|
|
65
|
+
at: this.clock().toISOString(),
|
|
66
|
+
category,
|
|
67
|
+
caller,
|
|
68
|
+
});
|
|
69
|
+
this.entries.push(entry);
|
|
70
|
+
return { denied: true, entry };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Append-only 읽기 뷰 — 얼린 스냅숏. 읽는 쪽은 이력을 못 고친다. */
|
|
74
|
+
ledger(): readonly ExternalCallAuditEntry[] {
|
|
75
|
+
return Object.freeze([...this.entries]);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -22,6 +22,12 @@ export interface LaunchPreflightBlocker {
|
|
|
22
22
|
readonly name: string;
|
|
23
23
|
/** 왜 막혔는지 한 줄 — 경로와 수를 포함한다. */
|
|
24
24
|
readonly detail: string;
|
|
25
|
+
/** 골 판독 실패(`goal-unreadable`)와 traced-path 오류(`missing-traced-path`)를 가르는 사유 코드. */
|
|
26
|
+
readonly reasonCode?: 'goal-unreadable' | 'missing-traced-path';
|
|
27
|
+
/** 어느 검사인지 — 경로를 접지 않은 검사 이름. */
|
|
28
|
+
readonly checkName?: string;
|
|
29
|
+
/** 잘리지 않은 대상 경로. 경로 없는 검사(빈 traced paths)는 생략한다. */
|
|
30
|
+
readonly targetPath?: string;
|
|
25
31
|
/** draft PR 경고가 연 검사 대상 경로. 동일 경로의 경고를 렌더에서 묶는다. */
|
|
26
32
|
readonly draftPaths?: readonly string[];
|
|
27
33
|
/** 라이브 런 충돌의 경로별 역할. ask 대상 표지가 없으면 미상이라 생략한다. */
|