elanous 0.2.35 → 0.2.37
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/{T1mBQqmkwKDLGtyisDCOd → 8kITumG9GAZ1LwT9POrAR}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1224.2ceca6c180d5130b.js +62 -0
- package/apps/pwa/out/_next/static/chunks/{9952.5daf5f94063a2b3e.js → 1262.a89bb27a5b2f844e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1746.3563617ea64023a3.js +115 -0
- package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1dc5a567.9b092bfae3d7099b.js → 1ed5e8af.cf424815c7c0efad.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4705-194e64e47ca0fbdb.js → 2002-a43a3f380df873ec.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{13.02a07436dec15f89.js → 210.90b2cbd64926cf34.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9512.5a76207a730e0491.js → 2283.edd9627b7bdfb546.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{6866-79aa5b4e47cac6aa.js → 2318-450e75d07605b8fe.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{938.66ad1ef0e5abae1c.js → 2375.bf364c85dbb6f085.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2479-fe7e188bd9402d14.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +148 -0
- package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +27 -0
- package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3199.6a1a9b0e6cd01dc6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9214.63a510d39178e997.js → 3578.4e9f9948a9a6f2f4.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +36 -0
- package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4036.d54e55e1ebf5acdc.js +90 -0
- package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +226 -0
- package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +287 -0
- package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2018.a741297bce759490.js → 4313.76f232c304a15bde.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1165.bad13fc9151a7288.js → 4324.c99ba3e83eb1b691.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3f7c4ee5.3dde54f01a816613.js → 4337e36d.f42c3b391b3d8f20.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7385.50a308a477bdfc21.js → 4383.18e5c54db3a22c88.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8557-e7898769499cd56f.js → 4725-34bed25720cc326b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5483-dd5d7697f6bdb106.js → 4833-7934c592c5569f00.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{8444.4c26b379ca2b9596.js → 4931.95cc6dbd230774ca.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/4937-28d437999b77c9dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3408.21d1570602f4b6c0.js → 5046.7fd5cbd859299448.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +104 -0
- package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +1 -0
- package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/58edce7d.f1b0c72acf13b123.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +93 -0
- package/apps/pwa/out/_next/static/chunks/5952.294fc574a8625184.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b6705a4f-b9a9047de9eecfd0.js → 5f6af561-f90b7a67f4f75d13.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +74 -0
- package/apps/pwa/out/_next/static/chunks/6252.240578f10952e091.js +34 -0
- package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5101.e32282718f99ed6f.js → 6680.6a693c28aae4cd19.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4718-17d2af636796a330.js → 6745-5a63492933959dd9.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +149 -0
- package/apps/pwa/out/_next/static/chunks/{6236.e18cced2d5ba6afb.js → 6819.be5c9c4d67f22922.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2833-0fe47af99ed13c29.js → 6971-fb5f9dc0a2cb5d2d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{da5176c6.6773b6c5994e1d99.js → 709a918c.4fd3b4e2a32cb4e3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +41 -0
- package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7424.c0fe2a595d4232b5.js +23 -0
- package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/757-4fbaf50942b8c424.js +1 -0
- package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7644.17e37ba6f1d4226e.js → 7867.e8725745ddd1d940.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/7893-e444a1b0809cd1e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{0368f25d-ad84af92fefee68f.js → 7c5ed21f-f286708e57cf88f7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{359-2250789a2d3499e7.js → 8080-40d781e7704d3671.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +77 -0
- package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +1 -0
- package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +286 -0
- package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +79 -0
- package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b2f6ba4d.fb56fdbbf798df33.js → 8c58d09b.e8724a299658d86f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1530.0e612369b6fd7ea0.js → 9151.a2c51e93f9156dae.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4441-875b97f5821ed58a.js → 9175-7d383df15a82e2be.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +1 -0
- package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +94 -0
- package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +1 -0
- package/apps/pwa/out/_next/static/chunks/958.53a8dcf4729e6997.js +64 -0
- package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-5c112c6d7c33656e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-3337c6a1328c2674.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-89acd5d68c0bc560.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-fe986fe79b107546.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-47c5d4db587266bd.js → page-1e5da297557d2354.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-1f5a60f70cb4dd0c.js → page-88a1edbff62eaf1d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/{page-bac7dee94e5eae4a.js → page-443364c9e4a23b31.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/page-b9af2ac1c4737ce8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-fb9e639c107f5f72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-dc0a532f5b9196ec.js → page-ac2c1e6169cfce57.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-c1c80e345fa9d6f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{d06f9160.a3d9062f95de8ad7.js → d9815f84.4918f682a45a8502.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{cbe38a15.5a032598e39970c6.js → de8446d3.31b73eb239fecd7b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +1 -0
- package/apps/pwa/out/_next/static/css/{b5d88eba78a3d7bf.css → be9019f696217521.css} +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +23 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
- package/docs/goal-context/README.md +3 -0
- package/graphs/default-loop.yaml +6 -1
- package/graphs/drafts/recipes.yaml +27 -7
- package/graphs/implement-loop.yaml +24 -0
- package/graphs/release/recipes.yaml +6 -0
- package/graphs/release/release-loop.yaml +17 -4
- package/graphs/wizard/recipes.yaml +44 -0
- package/graphs/wizard/wizard-loop.yaml +44 -0
- package/graphs/work/draft-close.yaml +54 -0
- package/graphs/work/green-close.yaml +37 -0
- package/graphs/work/recipes.yaml +46 -1
- package/graphs/work/research-report.yaml +2 -0
- package/graphs/work/run-research.yaml +35 -0
- package/package.json +1 -1
- package/scripts/__fixtures__/authoring-paths-10x3.json +32 -0
- package/scripts/boundary-proof-mapping-audit.ts +88 -0
- package/scripts/ci-typecheck-changed.ts +139 -5
- package/scripts/codex-fallback-live-probe.ts +17 -15
- package/scripts/coord-role-pack.ts +1 -1
- package/scripts/first10-gate.ts +416 -0
- package/scripts/fleet/node-setup.sh +32 -2
- package/scripts/fleet/run-light-worker.sh +9 -0
- package/scripts/fleet/wsl-node-setup.sh +432 -0
- package/scripts/gate-0226-failure-census.ts +507 -0
- package/scripts/goals/authoring-metrics.ts +258 -0
- package/scripts/graph-units/draft-close-node.ts +222 -0
- package/scripts/hook-order-sweep.ts +7 -4
- package/scripts/land-global-checks.ts +69 -1
- package/scripts/measure-nl-routing-corpus.ts +207 -2
- package/scripts/release-loop/docs-node.ts +344 -8
- package/scripts/release-loop/gate-closure.ts +48 -0
- package/scripts/release-loop/gate-diff.ts +2 -1
- package/scripts/release-loop/gate-node.ts +249 -53
- package/scripts/release-loop/known-issues-node.ts +6 -4
- package/scripts/release-loop/node-verdict.ts +2 -0
- package/scripts/release-loop/notes-repair.ts +216 -0
- package/scripts/release-loop/prepare-node.ts +61 -5
- package/scripts/release-loop/resume-cap.ts +14 -34
- package/scripts/release-loop/resume-release.ts +151 -15
- package/scripts/release-loop/resume-test-traffic.ts +10 -0
- package/scripts/release-loop/traffic-node.ts +59 -0
- package/scripts/release-loop/traffic-transition.ts +159 -0
- package/scripts/release-loop/version-node.ts +81 -12
- package/scripts/rhythm/daily.ts +137 -3
- package/scripts/train/green-leg.ts +176 -0
- package/scripts/tui-continue-real-evidence.ts +47 -0
- package/scripts/ux-sim.ts +53 -0
- package/skills/README.md +1 -0
- package/src/acp/client.ts +31 -5
- package/src/acp/core-turn-bridge.ts +54 -6
- package/src/acp/stderr-summary.ts +49 -0
- package/src/agent/delegate-hint.ts +16 -0
- package/src/agent/monad-agent-turn.ts +1 -0
- package/src/agent/runner.ts +82 -2
- package/src/agent/task-notification.ts +56 -10
- package/src/agent/terminal-surface.ts +217 -0
- package/src/agent/types.ts +4 -0
- package/src/agent-substrate/pr-reviewer.ts +64 -4
- package/src/agent-substrate/review-intent.ts +29 -2
- package/src/agent-substrate/review-observation.ts +3 -0
- package/src/agent-substrate/self-review-cli.ts +490 -26
- package/src/autopilot/lineage/sources.ts +1 -1
- package/src/autopilot/mission-codebase-gate.ts +141 -12
- package/src/autopilot/pr-manager.ts +89 -18
- package/src/boot/daemon-runtime.ts +35 -3
- package/src/boot/daemon-tools/pty-shell.ts +2 -1
- package/src/boot/daemon-tools/self-implement.ts +1 -0
- package/src/budget/run-usage-rollup.ts +12 -7
- package/src/budget/unified-usage.ts +20 -0
- package/src/budget/usage-outcomes.ts +8 -4
- package/src/capture/tui-self-report.ts +132 -1
- package/src/chat/goal-continue-verdict.ts +41 -0
- package/src/chat/index.ts +30 -4
- package/src/chat/internal-turn-origin.ts +1 -0
- package/src/chat/paste-fold.ts +86 -0
- package/src/chat/tool-render/block.ts +32 -0
- package/src/chat/tool-render/dispatch.ts +2 -20
- package/src/chat/tool-render/result-text.ts +98 -0
- package/src/chat/turn-typeahead.ts +70 -7
- package/src/cli/autopilot-cli.ts +24 -9
- package/src/cli/config-audit.ts +119 -0
- package/src/cli/decisions-cli.ts +7 -4
- package/src/cli/doctor-cli.ts +137 -6
- package/src/cli/guardian-cli.ts +10 -0
- package/src/cli/herdr-cli.ts +34 -0
- package/src/cli/light-entry-route.ts +6 -3
- package/src/cli/log-event-names.ts +2 -0
- package/src/cli/logs-cli.ts +357 -2
- package/src/cli/make-cli.ts +247 -11
- package/src/cli/memory-cli.ts +30 -1
- package/src/cli/msg-cli.ts +132 -14
- package/src/cli/pr-cli.ts +29 -16
- package/src/cli/pr-granularity.ts +5 -3
- package/src/cli/pr-land-base-read.ts +11 -2
- package/src/cli/pr-land-heavy-remote.ts +6 -3
- package/src/cli/pr-land-overlap-evidence.ts +23 -4
- package/src/cli/pr-land-recovery.ts +117 -1
- package/src/cli/pty-takeover-cli.ts +8 -7
- package/src/cli/release-checklist-read-cli.ts +109 -4
- package/src/cli/release-cli.ts +64 -15
- package/src/cli/release-single-flight.ts +1 -1
- package/src/cli/self-update.ts +23 -5
- package/src/cli/self-utterances-cli.ts +13 -16
- package/src/cli/tasks-card-show.ts +162 -0
- package/src/cli/tasks-cli.ts +868 -352
- package/src/cli/tasks-read-cli.ts +197 -0
- package/src/cli/usage-cli.ts +12 -10
- package/src/context-bus/claude-memory-import.ts +99 -0
- package/src/context-bus/long-term-memory.ts +125 -0
- package/src/core-turn/run-core-turn.ts +4 -2
- package/src/core-turn/run-goal-loop.ts +76 -16
- package/src/core-turn/types.ts +8 -1
- package/src/dashboard/chat/acp-chat.ts +9 -0
- package/src/dashboard/context/keys.ts +8 -31
- package/src/dashboard/index.ts +299 -62
- package/src/dashboard/input/agent-wake.ts +50 -1
- package/src/dashboard/input/chat-main-acp-dispatch.ts +21 -1
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
- package/src/dashboard/input/chat-main-slash-command.ts +4 -2
- package/src/dashboard/input/goal-continue.ts +210 -0
- package/src/dashboard/input/goal-interim.ts +2 -0
- package/src/dashboard/input/internal-turn.ts +2 -8
- package/src/dashboard/input/seat-autowake.ts +9 -7
- package/src/dashboard/input/turn-autoheal.ts +52 -0
- package/src/dashboard/replay-preview.ts +25 -0
- package/src/dashboard/seat-boot-preamble.ts +132 -5
- package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +20 -10
- package/src/dashboard/slash-runtime/model-choices.ts +15 -0
- package/src/dashboard/stale-install-check.ts +3 -99
- package/src/dashboard/synchronized-frame-output.ts +74 -0
- package/src/debug/batch-queue.ts +119 -0
- package/src/debug/tui-log-tag.ts +67 -0
- package/src/display/agent-surface.ts +7 -0
- package/src/display/coordinator.ts +45 -12
- package/src/display/resize-listener.ts +41 -20
- package/src/display/synchronized-output-region.ts +60 -0
- package/src/domains/standalone-log-sink.ts +15 -2
- package/src/domains/surface-events.ts +80 -1
- package/src/esc-abort-gate.ts +69 -0
- package/src/exec-requests/planner.ts +37 -2
- package/src/execution-loop/launch-gate.ts +4 -3
- package/src/git-fs/cli-stderr.ts +45 -0
- package/src/git-fs/gh-cli.ts +6 -3
- package/src/git-fs/git-cli.ts +11 -5
- package/src/git-fs/worktree.ts +95 -1
- package/src/graph-runner/graph-cli.ts +44 -2
- package/src/graph-runner/graph-run-api.ts +3 -2
- package/src/graph-runner/runner.ts +37 -16
- package/src/graph-wizard/generate.ts +131 -4
- package/src/graph-wizard/steps.ts +15 -0
- package/src/grounding/proactive-ground.ts +86 -0
- package/src/harness/control-inbox.ts +49 -1
- package/src/harness/harness-cli-command.ts +230 -40
- package/src/harness/harness-incidents.ts +52 -1
- package/src/harness/pod-control-send.ts +33 -5
- package/src/harness/review-adapter.ts +26 -6
- package/src/harness/self-send-remote.ts +69 -0
- package/src/harness/self-send-routing-guard.ts +6 -0
- package/src/harness/self-send-target.ts +4 -3
- package/src/index.ts +443 -25
- package/src/input-core/context-key-runtime.ts +21 -0
- package/src/instance/test-write-guard-real-transport.fixture.ts +52 -0
- package/src/light-cli.ts +6 -1
- package/src/llm/route-decision.ts +13 -0
- package/src/llm-tool-name.ts +37 -0
- package/src/llm-tool-schema.ts +35 -0
- package/src/llm-wellformed.ts +70 -0
- package/src/llm.ts +158 -15
- package/src/loops/checker.ts +100 -0
- package/src/loops/consensus.ts +26 -2
- package/src/loops/loop-cli.ts +9 -4
- package/src/loops/msg-wake.ts +35 -39
- package/src/loops/orchestrator/anomaly-cluster.ts +243 -0
- package/src/loops/orchestrator/inbox.ts +59 -11
- package/src/loops/orchestrator/knowhow-pack.ts +364 -0
- package/src/loops/orchestrator/tick.ts +54 -5
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/model-tier/llm-tier-map.ts +12 -17
- package/src/models/prompts.ts +17 -2
- package/src/msg/msg-post-office.ts +116 -0
- package/src/msg/msg-store.ts +17 -0
- package/src/mss/logging/log-store.ts +79 -22
- package/src/native-tool-catalog.ts +1 -1
- package/src/nexus/api/decisions-route.ts +38 -18
- package/src/nexus/api/graph-wizard-api.ts +46 -3
- package/src/nexus/api/grid.ts +24 -4
- package/src/nexus/api/http-server.ts +1 -1
- package/src/nexus/api/ops-api.ts +14 -6
- package/src/nexus/boot/register-mcp-clients.ts +263 -38
- package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
- package/src/nexus/state/state.ts +7 -1
- package/src/oauth/codex-account-store.ts +34 -1
- package/src/onboarding/first-run.ts +37 -6
- package/src/onboarding/web-first.ts +43 -11
- package/src/ops/loops-map.ts +46 -0
- package/src/ops/overview-cache.ts +22 -4
- package/src/ops/overview-collect.ts +12 -6
- package/src/ops/overview.ts +44 -8
- package/src/persona/loader.ts +11 -0
- package/src/persona/types.ts +8 -0
- package/src/policy/llm-policy.ts +3 -1
- package/src/prompt-enhance/enhance.ts +4 -4
- package/src/prompt-library/session-guidance.ts +14 -0
- package/src/provider-summary.ts +8 -0
- package/src/pty-shell/availability.ts +7 -0
- package/src/pty-shell/herdr-agent-report.ts +155 -37
- package/src/pty-shell/herdr-prompt.ts +266 -0
- package/src/pty-shell/herdr-prune-stale.ts +17 -0
- package/src/pty-shell/herdr-sequence-lease.ts +60 -0
- package/src/pty-shell/pty-control-ipc.ts +327 -15
- package/src/pty-shell/pty-special-keys.ts +42 -2
- package/src/pty-shell/registry.ts +25 -15
- package/src/pty-shell/stale-install-check.ts +99 -0
- package/src/pty-shell/tui-run-state.ts +249 -3
- package/src/release-loop/auto-start.ts +20 -2
- package/src/release-loop/checklist.ts +126 -9
- package/src/release-loop/feature-store.ts +9 -9
- package/src/release-loop/landed-but-yellow.ts +93 -12
- package/src/release-loop/rehearsal.ts +36 -20
- package/src/repl/index.ts +27 -1
- package/src/seat-loop/knowhow-lint.ts +1 -1
- package/src/seat-loop/seat-report.ts +1 -0
- package/src/self-dev/ask-launch-flow.ts +86 -10
- package/src/self-dev/decompose-proposal.ts +183 -20
- package/src/self-dev/decompose.ts +61 -0
- package/src/self-dev/dev-cli.ts +37 -3
- package/src/self-dev/dev-pipeline.ts +37 -9
- package/src/self-dev/draft-sweep.ts +241 -16
- package/src/self-dev/draft-triage-rules.ts +50 -5
- package/src/self-dev/glm-credential-guard.ts +77 -0
- package/src/self-dev/graph-journey-nodes.ts +1 -0
- package/src/self-dev/graph-journey-route.ts +12 -2
- package/src/self-dev/orchestrate-cli.ts +68 -3
- package/src/self-dev/orchestrate.ts +116 -17
- package/src/self-dev/review-provider-fallback.ts +45 -7
- package/src/self-dev/run-supervisor.ts +55 -2
- package/src/self-dev/run-types.ts +1 -1
- package/src/self-dev/shard-plan.ts +48 -0
- package/src/self-dev/shard-run.ts +50 -3
- package/src/self-health/autoheal.ts +153 -0
- package/src/self-health/signatures.ts +6 -0
- package/src/self-implement/device-first.ts +116 -0
- package/src/self-implement/doctor-visit.ts +322 -1
- package/src/self-implement/evidence-command-budget.ts +80 -0
- package/src/self-implement/gate-artifacts.ts +6 -2
- package/src/self-implement/gate-baseline.ts +64 -1
- package/src/self-implement/gate-cli.ts +93 -9
- package/src/self-implement/gate-remote.ts +28 -4
- package/src/self-implement/gate-scope.ts +13 -1
- package/src/self-implement/goal-author-cli.ts +1 -0
- package/src/self-implement/goal-author-decompose.ts +265 -4
- package/src/self-implement/goal-author.ts +366 -26
- package/src/self-implement/goal-elaborate.ts +176 -22
- package/src/self-implement/goal-refine.ts +3 -0
- package/src/self-implement/goal-supervisor-fill.ts +75 -26
- package/src/self-implement/graph-variant.ts +40 -6
- package/src/self-implement/headless-elanous-driver.ts +19 -3
- package/src/self-implement/importer-test-index.ts +215 -2
- package/src/self-implement/knowhow-pack.ts +5 -5
- package/src/self-implement/off-diff-evidence.ts +58 -6
- package/src/self-implement/orchestrator.ts +536 -42
- package/src/self-implement/pod-warm-pool-profile.ts +1 -0
- package/src/self-implement/pwa-import-graph.ts +1 -1
- package/src/self-implement/review-round-brief.ts +300 -0
- package/src/self-implement/rework-policy.ts +44 -0
- package/src/self-implement/run-ledger.ts +278 -6
- package/src/self-implement/run-stop.ts +1 -1
- package/src/self-implement/run-ttl.ts +38 -24
- package/src/self-implement/running-runs.ts +17 -3
- package/src/self-implement/scope-adjacency.ts +3 -1
- package/src/self-implement/seams.ts +72 -10
- package/src/self-implement/stop-autoheal.ts +1 -0
- package/src/self-implement/test-seams.ts +13 -1
- package/src/self-implement/train-reach-grouping.ts +8 -2
- package/src/self-implement/wiring-check.ts +358 -0
- package/src/session/chat.ts +7 -1
- package/src/session/id-prefix.ts +60 -0
- package/src/session/index.ts +4 -0
- package/src/session-runtime/index.ts +9 -1
- package/src/shell-env-bootstrap.ts +11 -4
- package/src/skills/runner.ts +4 -2
- package/src/skills/tools/agent.ts +290 -48
- package/src/skills/tools/pty.ts +5 -0
- package/src/skills/tools/schedule-wakeup.ts +23 -4
- package/src/skills/tools/shell.ts +61 -6
- package/src/skills/tools/terminal-modal-inject.ts +1 -2
- package/src/skills/tools/terminal-modal.ts +10 -8
- package/src/skills/url-router.ts +41 -1
- package/src/smart-wizard/run.ts +66 -0
- package/src/status/bar.ts +34 -6
- package/src/status/metrics.ts +12 -1
- package/src/status/status-provider-info.ts +37 -6
- package/src/steward/rejudge-tick.ts +22 -7
- package/src/steward/resync-tick.ts +31 -4
- package/src/steward/ta-repair-event-collect.ts +17 -6
- package/src/task-agent/actions.ts +202 -5
- package/src/task-agent/boundary-proof-mapping.ts +12 -0
- package/src/task-agent/boundary-proof-producer.ts +147 -0
- package/src/task-agent/completion-evidence.ts +2 -1
- package/src/task-agent/green-close-recipe.ts +239 -0
- package/src/task-agent/green-sweep.ts +64 -10
- package/src/task-agent/land-queue.ts +21 -8
- package/src/task-agent/live-moves.ts +70 -9
- package/src/task-agent/map-host-adapter.ts +134 -0
- package/src/task-agent/map-reduce.ts +158 -0
- package/src/task-agent/map-run-ledger.ts +226 -0
- package/src/task-agent/mission.ts +30 -0
- package/src/task-agent/parent-host.ts +21 -11
- package/src/task-agent/rejudge-on-head.ts +87 -5
- package/src/task-agent/repair-cycle.ts +179 -32
- package/src/task-agent/repair-next-move.ts +42 -4
- package/src/task-agent/repair-outcomes.ts +29 -0
- package/src/task-agent/repair-worker.ts +14 -4
- package/src/task-agent/review-prior-fix.ts +12 -2
- package/src/task-agent/shadow.ts +229 -8
- package/src/task-agent/task-card-prefix.ts +2 -0
- package/src/task-agent/task-hand.ts +630 -30
- package/src/task-agent/task-parent-role-llm.ts +45 -0
- package/src/task-agent/tier-split.ts +80 -10
- package/src/task-agent/work-order.ts +53 -2
- package/src/task-orchestrator/dispatcher.ts +46 -1
- package/src/task-orchestrator/generator-prompt.ts +6 -0
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +9 -0
- package/src/task-orchestrator/surfaces/pod-artifact-return.ts +16 -6
- package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +86 -5
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
- package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +8 -6
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +97 -0
- package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +11 -0
- package/src/task-orchestrator/surfaces/pod-pool.ts +126 -8
- package/src/task-orchestrator/surfaces/pod-provenance.ts +8 -2
- package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
- package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +4 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +491 -36
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +612 -54
- package/src/task-orchestrator/surfaces/self-implement.ts +46 -2
- package/src/testing/linux-env.ts +177 -0
- package/src/tool-runtime/index.ts +15 -2
- package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
- package/src/tty-foreground.ts +155 -0
- package/src/tui/chat/goal-interim.ts +177 -0
- package/src/tui/chat/log-view.ts +205 -18
- package/src/tui/chat/self-health-status.ts +232 -0
- package/src/tui/entry.ts +623 -80
- package/src/tui/input/at-picker.ts +55 -0
- package/src/tui/input/composer.ts +8 -1
- package/src/tui/slash/compact-command.ts +7 -0
- package/src/tui/slash/compact.ts +1 -7
- package/src/tui/slash/resume.ts +98 -0
- package/src/tui/slash/signals.ts +114 -0
- package/src/tui/slash/term-next.ts +71 -0
- package/src/tui-client/local-chat-turn.ts +49 -5
- package/src/tui-client/next-dashboard-runtime.ts +8 -0
- package/src/tui-client/next-loop-command.ts +70 -0
- package/src/tui-client/next-wakeup.ts +191 -0
- package/src/tui.ts +37 -0
- package/src/ui/modal-adapter.ts +2 -2
- package/src/user-config.ts +19 -1
- package/src/ux-sim/boot-daemon-tools-pty-shell-device.ts +136 -0
- package/src/ux-sim/classic-tui-seat-scenarios.ts +670 -0
- package/src/ux-sim/cli-config-audit-device.ts +121 -0
- package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
- package/src/ux-sim/event-monkey.ts +3 -2
- package/src/ux-sim/fake-bin.ts +45 -0
- package/src/ux-sim/fake-gh.ts +174 -0
- package/src/ux-sim/fake-herdr.ts +238 -0
- package/src/ux-sim/fake-kubectl.ts +142 -0
- package/src/ux-sim/fake-llm.ts +116 -6
- package/src/ux-sim/fault-glm-no-credential.ts +116 -0
- package/src/ux-sim/fault-nextmove-dispatch.ts +102 -1
- package/src/ux-sim/fault-scope-escape-lift.ts +33 -6
- package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
- package/src/ux-sim/goal-device.ts +619 -0
- package/src/ux-sim/in-process-cli.ts +22 -5
- package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
- package/src/ux-sim/mock-authoring-first-run.ts +97 -0
- package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
- package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
- package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
- package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
- package/src/ux-sim/next-tui-seat-scenarios.ts +749 -0
- package/src/ux-sim/onboarding-first-run-device.ts +269 -0
- package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
- package/src/ux-sim/resume-picker-device.ts +173 -0
- package/src/ux-sim/session-id-seed.ts +60 -0
- package/src/ux-sim/skills-tools-shell-device.ts +156 -0
- package/src/ux-sim/subagent-tools-device.ts +81 -0
- package/src/ux-sim/task-agent-parent-host-device.ts +264 -0
- package/src/ux-sim/task-agent-rejudge-on-head-device.ts +114 -0
- package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
- package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +0 -41
- package/apps/pwa/out/_next/static/chunks/1674.2a65fd5668e1cc5f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +0 -24
- package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +0 -74
- package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +0 -148
- package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +0 -34
- package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +0 -77
- package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +0 -62
- package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +0 -90
- package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3589.5444a06bcf6e775c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +0 -36
- package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3677-4215f826f6aa68e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +0 -79
- package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4346.8601952e73bf5803.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +0 -24
- package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +0 -23
- package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +0 -94
- package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/56d372f2.681ab4ec4c998fae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +0 -287
- package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +0 -1
- package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +0 -8
- package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +0 -27
- package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +0 -93
- package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +0 -149
- package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +0 -104
- package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +0 -226
- package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +0 -64
- package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8637.47f5b35afcae5e6b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +0 -115
- package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +0 -1
- /package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → 8kITumG9GAZ1LwT9POrAR}/_ssgManifest.js +0 -0
|
@@ -6,6 +6,7 @@ import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
|
6
6
|
import { constants as osConstants, hostname } from 'node:os';
|
|
7
7
|
import { basename, dirname, join, resolve, sep } from 'node:path';
|
|
8
8
|
import { HarnessCliInputError } from '../cli/cli-user-error.js';
|
|
9
|
+
import { writeStdoutFully } from '../cli/stdout-flush.js';
|
|
9
10
|
import { findGitDir } from '../git-fs/locate.js';
|
|
10
11
|
import { LogStore, logsDbPath } from '../mss/logging/log-store.js';
|
|
11
12
|
import { loadSelfDevRun } from '../self-dev/run-store.js';
|
|
@@ -20,7 +21,7 @@ import { runGitCommand } from '../git-fs/runner.js';
|
|
|
20
21
|
import { GOAL_TYPES, lintGoalFile, parseGoalId, parseGoalType, resolveGoalAuthorGrade, tracedPathReferences, type GoalAuthorGrade, type GoalAuthorGradeSelection, type GoalType } from '../self-implement/goal-author.js';
|
|
21
22
|
import { templateForGoalType } from '../self-implement/graph-templates.js';
|
|
22
23
|
import { appendRunLedgerEntry, listRunLedgers, loadFederatedRunLedger, loadRunLedger, queryRunScreenKey, runLedgerDir, type RunLedgerEntry, type RunLedgerMatch, type RunLedgerWriter } from '../self-implement/run-ledger.js';
|
|
23
|
-
import { classifyPodExit, type PodExitClass } from '../task-orchestrator/surfaces/pod-failure-reason.js';
|
|
24
|
+
import { classifyPodExit, parsePodTermination, type PodExitClass, type PodTermination } from '../task-orchestrator/surfaces/pod-failure-reason.js';
|
|
24
25
|
import type { PodChildEvidence } from '../task-orchestrator/surfaces/self-implement.js';
|
|
25
26
|
import { classifyPodExitStop, readRunStopRecord, recordRunStop, runStopRecorded, RUN_STOP_EVENT } from '../self-implement/run-stop.js';
|
|
26
27
|
import { captureStopKnowhowCandidate } from '../self-implement/stop-autoheal.js';
|
|
@@ -30,7 +31,7 @@ import { buildRunProgressRows, isPartialRunningRuns, queryRunningRuns, renderRun
|
|
|
30
31
|
import { launchBindingRunIds, readLaunchBinding } from './launch-registry.js';
|
|
31
32
|
import { psProcessStartMs } from './harness-stop.js';
|
|
32
33
|
import { DevPipelineError } from '../self-dev/dev-pipeline.js';
|
|
33
|
-
import { collectDraftMetrics, collectOverlapMetrics, DRAFT_SWEEP_CONCURRENCY, mapBounded, resolveDraftSweepCloseCap, runDraftSweep, sweepFailureReason, type DraftSweepAdapters, type DraftSweepResult, type OverlapMetricAdapters, type SweepDraft, type SweepMergedPr, type SweepReviewGate } from '../self-dev/draft-sweep.js';
|
|
34
|
+
import { collectDraftMetrics, collectOverlapMetrics, DRAFT_SWEEP_CONCURRENCY, mapBounded, resolveDraftSweepCloseCap, runDraftSweep, sweepFailureReason, validateDraftSweepApplyPlan, type DraftSweepAdapters, type DraftSweepResult, type OverlapMetricAdapters, type SweepDraft, type SweepMergedPr, type SweepReviewGate } from '../self-dev/draft-sweep.js';
|
|
34
35
|
import { readAskPreflightRowsSince, readSalvagedRowsSince } from '../self-dev/ask-launch-io.js';
|
|
35
36
|
import { replayPodTerminals, type DraftResidueReplayOptions, type PrTerminalRecord } from '../self-dev/draft-residue.js';
|
|
36
37
|
import { draftClaimComment, draftReleaseComment } from '../self-dev/draft-triage-rules.js';
|
|
@@ -419,7 +420,7 @@ function resolveLaunchSubstrate(opts: HarnessSubstrateOpts): ResolvedHarnessSubs
|
|
|
419
420
|
}
|
|
420
421
|
type PodExit = { status: number | null; signal?: string | null };
|
|
421
422
|
type PodExitReason = 'signal' | 'human-stop' | 'supervisor' | 'no-launch' | 'unknown' | 'preflight-refused'
|
|
422
|
-
| 'pod-error' | 'launch-gate-blocked' | 'ENOBUFS' | 'OOMKilled';
|
|
423
|
+
| 'pod-error' | 'launch-gate-blocked' | 'dep-blocked' | 'ENOBUFS' | 'OOMKilled';
|
|
423
424
|
|
|
424
425
|
function unknownPodExitTailReason(output: string): PodExitReason | undefined {
|
|
425
426
|
const tail = output.slice(-16_000);
|
|
@@ -427,6 +428,7 @@ function unknownPodExitTailReason(output: string): PodExitReason | undefined {
|
|
|
427
428
|
if (/\bENOBUFS\b/i.test(tail)) return 'ENOBUFS';
|
|
428
429
|
if (/launch gate[^\r\n]*blocked|blocked[^\r\n]*launch gate/i.test(tail)) return 'launch-gate-blocked';
|
|
429
430
|
if (/\bpod-error\b/i.test(tail)) return 'pod-error';
|
|
431
|
+
if (/\b(?:DEP_FAILED|DEPENDENCY_NEEDS_HUMAN|DEP_BLOCKED_REBASE_READY)\b/.test(tail)) return 'dep-blocked';
|
|
430
432
|
return undefined;
|
|
431
433
|
}
|
|
432
434
|
/** GitHub lists at most this many files for one pull request; a list that reaches it is not provably complete. */
|
|
@@ -575,7 +577,9 @@ export function recordClassifiedHarnessPodExit(runId: string | undefined, reason
|
|
|
575
577
|
context: { entrance?: string; seat?: string; output?: string } = {}): void {
|
|
576
578
|
if (!runId) return;
|
|
577
579
|
try {
|
|
578
|
-
const
|
|
580
|
+
const ledger = reason === 'preflight-refused' ? undefined : loadRunLedger(runId);
|
|
581
|
+
const childEvidence = latestPodChildEvidence(ledger);
|
|
582
|
+
const podTermination = latestPodTermination(ledger);
|
|
579
583
|
const signal = status > 128
|
|
580
584
|
? Object.entries(osConstants.signals).find(([, number]) => number === status - 128)?.[0] ?? null : null;
|
|
581
585
|
const cwd = process.cwd();
|
|
@@ -586,17 +590,42 @@ export function recordClassifiedHarnessPodExit(runId: string | undefined, reason
|
|
|
586
590
|
cwd: `${basename(dirname(cwd))}/${basename(cwd)}`, hostname: hostname().split('.')[0]!, pid: process.pid,
|
|
587
591
|
...(context.output ? { lastLines: incidentLastLines(context.output) } : {}),
|
|
588
592
|
...(childEvidence ? { childEvidence } : {}),
|
|
593
|
+
...(podTermination ? { podTermination } : {}),
|
|
589
594
|
}, effectiveInstanceRoot());
|
|
590
595
|
} catch { /* incident writes cannot change Pod output or exit */ }
|
|
591
596
|
}
|
|
592
597
|
|
|
593
|
-
|
|
598
|
+
/**
|
|
599
|
+
* The current attempt's `pod-child-evidence` rows (same job · childRunId as the last `pod-child-run`), oldest first.
|
|
600
|
+
* Also fenced by position: only rows written after that start count, so a reused job/childRunId pair cannot
|
|
601
|
+
* hand an earlier attempt's row (childEvidence or podTermination) to a later one.
|
|
602
|
+
*/
|
|
603
|
+
function currentPodChildEvidenceRows(entries: readonly RunLedgerEntry[] | null | undefined): { job: string; rows: Record<string, unknown>[] } | undefined {
|
|
594
604
|
// The current attempt's start is the fence. An earlier Pod's terminal facts cannot
|
|
595
605
|
// classify a later attempt when that attempt has no JSON or its ledger write failed.
|
|
596
|
-
|
|
606
|
+
let startIndex = -1;
|
|
607
|
+
entries?.forEach((entry, index) => { if (entry.event === 'pod-child-run') startIndex = index; });
|
|
608
|
+
const current = startIndex >= 0 ? entries![startIndex]!.data : undefined;
|
|
597
609
|
if (typeof current?.job !== 'string' || typeof current.childRunId !== 'string') return undefined;
|
|
598
|
-
const
|
|
599
|
-
&& entry.data?.job === current.job && entry.data?.childRunId === current.childRunId).
|
|
610
|
+
const rows = (entries ?? []).filter((entry, index) => index > startIndex && entry.event === 'pod-child-evidence'
|
|
611
|
+
&& entry.data?.job === current.job && entry.data?.childRunId === current.childRunId).map((entry) => entry.data);
|
|
612
|
+
return { job: current.job, rows };
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/** JOB-FAILURE-TERMINATION-CAPTURE — the current attempt's latest well-formed capture of its own Job (a later
|
|
616
|
+
* evidence row of the same attempt without one does not drop it); another Job's or round's never crosses over. */
|
|
617
|
+
function latestPodTermination(entries: readonly RunLedgerEntry[] | null | undefined): PodTermination | undefined {
|
|
618
|
+
const current = currentPodChildEvidenceRows(entries);
|
|
619
|
+
if (!current) return undefined;
|
|
620
|
+
for (const row of current.rows.slice().reverse()) {
|
|
621
|
+
const parsed = parsePodTermination(row.podTermination, current.job);
|
|
622
|
+
if (parsed) return parsed;
|
|
623
|
+
}
|
|
624
|
+
return undefined;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
function latestPodChildEvidence(entries: readonly RunLedgerEntry[] | null | undefined): PodChildEvidence | undefined {
|
|
628
|
+
const data = currentPodChildEvidenceRows(entries)?.rows.at(-1);
|
|
600
629
|
const evidence = data?.childEvidence;
|
|
601
630
|
if (!evidence || typeof evidence !== 'object' || Array.isArray(evidence)) return undefined;
|
|
602
631
|
const row = evidence as Record<string, unknown>;
|
|
@@ -604,6 +633,8 @@ function latestPodChildEvidence(entries: readonly RunLedgerEntry[] | null | unde
|
|
|
604
633
|
if (('scopeEscape' in row && row.scopeEscape !== true)
|
|
605
634
|
|| ('goalCauseObserved' in row && row.goalCauseObserved !== true)
|
|
606
635
|
|| ('classification' in row && typeof row.classification !== 'string')
|
|
636
|
+
|| ('newScope' in row && !Array.isArray(row.newScope))
|
|
637
|
+
|| ('scopeStopReasons' in row && !Array.isArray(row.scopeStopReasons))
|
|
607
638
|
|| ('abandonedClassification' in row && !object(row.abandonedClassification))
|
|
608
639
|
|| ('accountAvailability' in row && !object(row.accountAvailability))) return undefined;
|
|
609
640
|
return row as PodChildEvidence;
|
|
@@ -783,6 +814,14 @@ export function recordHarnessPodStop(
|
|
|
783
814
|
if (ledger?.some((entry) => entry.event === RUN_STOP_EVENT)) return false;
|
|
784
815
|
const childEvidence = latestPodChildEvidence(ledger);
|
|
785
816
|
const scopeEscape = childEvidence?.scopeEscape === true;
|
|
817
|
+
// SCOPE-ESCAPE-AS-REFINE — out-of-scope edits without a stop reason are «new scope», not a scope-escape stop.
|
|
818
|
+
if (childEvidence?.newScope?.length || childEvidence?.scopeStopReasons?.length) {
|
|
819
|
+
try {
|
|
820
|
+
debug.log('harness.pod', scopeEscape ? 'scope-escape-stop' : 'scope-new-scope', { runId, scopeEscape,
|
|
821
|
+
...(childEvidence.newScope ? { newScope: childEvidence.newScope } : {}),
|
|
822
|
+
...(childEvidence.scopeStopReasons ? { scopeStopReasons: childEvidence.scopeStopReasons } : {}) });
|
|
823
|
+
} catch { /* observation cannot change the stop record */ }
|
|
824
|
+
}
|
|
786
825
|
if (classified.reason === 'preflight-refused') {
|
|
787
826
|
(deps.record ?? recordRunStop)({
|
|
788
827
|
runId, site: 'preflight', class: 'launch-failed',
|
|
@@ -2495,10 +2534,35 @@ const defaultDraftSweepStopRun: DraftSweepStopRun = async (runId) => {
|
|
|
2495
2534
|
return stopHarnessRun(runId, defaultHarnessStopDeps());
|
|
2496
2535
|
};
|
|
2497
2536
|
|
|
2498
|
-
export
|
|
2537
|
+
export interface GithubDraftSweepAdapterOptions {
|
|
2538
|
+
/** Read-only preview bounds. Reaching a bound is reported as an incomplete inventory. */
|
|
2539
|
+
maxInventoryPages?: number;
|
|
2540
|
+
maxDrafts?: number;
|
|
2541
|
+
maxMerged?: number;
|
|
2542
|
+
onInventoryProgress?: (event: { state: 'open' | 'closed'; page: number; rows: number }) => void;
|
|
2543
|
+
/** Test seam: provide an isolated run-ledger inventory instead of enumerating the host's stores. */
|
|
2544
|
+
runLedgerMatches?: () => readonly RunLedgerMatch[];
|
|
2545
|
+
/** Test seam: provide isolated running-run observations instead of inspecting host processes and PTY stores. */
|
|
2546
|
+
runningRunStatuses?: () => ReadonlyMap<string, string>;
|
|
2547
|
+
/** Test seam for bounded GitHub check-run backoff. */
|
|
2548
|
+
checkRunRetryDelaysMs?: readonly number[];
|
|
2549
|
+
checkRunSleep?: (milliseconds: number) => Promise<void>;
|
|
2550
|
+
}
|
|
2551
|
+
|
|
2552
|
+
function createGithubDraftSweepAdapters(execute: GhExecute, git: DraftSweepGitExecute, cwd: string,
|
|
2499
2553
|
executeAsync: (args: string[]) => Promise<string> = execute === executeGh ? executeGhAsync : async (args) => execute(args),
|
|
2500
|
-
stopRun: DraftSweepStopRun = defaultDraftSweepStopRun): GithubDraftSweepAdapters {
|
|
2554
|
+
stopRun: DraftSweepStopRun = defaultDraftSweepStopRun, options: GithubDraftSweepAdapterOptions = {}): GithubDraftSweepAdapters {
|
|
2501
2555
|
const ensuredSweepLabels = new Set<string>();
|
|
2556
|
+
const maxInventoryPages = Number.isSafeInteger(options.maxInventoryPages) && options.maxInventoryPages! > 0
|
|
2557
|
+
? Math.min(options.maxInventoryPages!, 100) : 100;
|
|
2558
|
+
const maxDrafts = Number.isSafeInteger(options.maxDrafts) && options.maxDrafts! > 0 ? options.maxDrafts : undefined;
|
|
2559
|
+
const maxMerged = Number.isSafeInteger(options.maxMerged) && options.maxMerged! > 0 ? options.maxMerged : undefined;
|
|
2560
|
+
let inventoryIncompleteReason: string | undefined;
|
|
2561
|
+
const markInventoryIncomplete = (reason: string) => { inventoryIncompleteReason ??= reason; };
|
|
2562
|
+
const checkRunRetryDelays = options.checkRunRetryDelaysMs ?? [1_000, 2_000, 4_000];
|
|
2563
|
+
const sleepForCheckRunRetry = options.checkRunSleep ?? ((milliseconds: number) => new Promise<void>((resolve) => setTimeout(resolve, milliseconds)));
|
|
2564
|
+
let checkRunsQueue: Promise<void> = Promise.resolve();
|
|
2565
|
+
let checkRunsUnavailableReason: string | undefined;
|
|
2502
2566
|
const inventory = async (repository: string, state: 'open' | 'closed'): Promise<GithubPull[]> => {
|
|
2503
2567
|
// ⛔ A large repository has tens of thousands of closed PRs (2026-09-28: 21k → «exceeded pagination limit», no sweep at all).
|
|
2504
2568
|
// Merged twins only matter after the oldest open draft was opened, so the closed listing stops at that time.
|
|
@@ -2510,15 +2574,28 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2510
2574
|
if (!Number.isFinite(cutoff)) throw new Error('Incomplete GitHub PR inventory');
|
|
2511
2575
|
}
|
|
2512
2576
|
const all: GithubPull[] = [];
|
|
2513
|
-
for (let page = 1; page <=
|
|
2514
|
-
|
|
2577
|
+
for (let page = 1; page <= maxInventoryPages; page++) {
|
|
2578
|
+
let batch: GithubPull[];
|
|
2579
|
+
try { batch = githubPullsPage(repository, state, page, execute); }
|
|
2580
|
+
catch (error) {
|
|
2581
|
+
if (maxInventoryPages < 100) {
|
|
2582
|
+
markInventoryIncomplete(`${state} PR inventory stopped after ${page - 1} pages (${all.length} rows): ${sweepFailureReason(error)}`);
|
|
2583
|
+
return all;
|
|
2584
|
+
}
|
|
2585
|
+
throw error;
|
|
2586
|
+
}
|
|
2515
2587
|
if (!Array.isArray(batch) || batch.length > 100) throw new Error('Incomplete GitHub PR inventory');
|
|
2516
2588
|
all.push(...batch);
|
|
2589
|
+
options.onInventoryProgress?.({ state, page, rows: all.length });
|
|
2517
2590
|
if (batch.length < 100) return all;
|
|
2518
2591
|
// An unknown update time cannot prove the rest is older — keep paging.
|
|
2519
2592
|
const oldest = Date.parse(batch[batch.length - 1]!.updated_at ?? '');
|
|
2520
2593
|
if (cutoff !== undefined && Number.isFinite(oldest) && oldest < cutoff) return all;
|
|
2521
2594
|
}
|
|
2595
|
+
if (maxInventoryPages < 100) {
|
|
2596
|
+
markInventoryIncomplete(`${state} PR inventory capped at ${maxInventoryPages} pages (${all.length} rows observed)`);
|
|
2597
|
+
return all;
|
|
2598
|
+
}
|
|
2522
2599
|
throw new Error('GitHub PR inventory exceeded pagination limit');
|
|
2523
2600
|
};
|
|
2524
2601
|
const open = new Map<string, Promise<GithubPull[]>>();
|
|
@@ -2605,17 +2682,57 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2605
2682
|
}
|
|
2606
2683
|
throw new Error('Review inventory exceeded pagination limit');
|
|
2607
2684
|
};
|
|
2608
|
-
const
|
|
2685
|
+
const readCheckRuns = async (repository: string, sha: string): Promise<Array<{ conclusion?: string | null }>> => {
|
|
2609
2686
|
const runs: Array<{ conclusion?: string | null }> = [];
|
|
2610
2687
|
for (let page = 1; page <= 100; page++) {
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2688
|
+
let result: { total_count?: number; check_runs?: Array<{ conclusion?: string | null }> } | undefined;
|
|
2689
|
+
let attempt = 0;
|
|
2690
|
+
while (true) {
|
|
2691
|
+
try {
|
|
2692
|
+
result = await ghJsonAsync<{ total_count?: number; check_runs?: Array<{ conclusion?: string | null }> }>(
|
|
2693
|
+
['api', `repos/${repository}/commits/${sha}/check-runs?per_page=100&page=${page}`]);
|
|
2694
|
+
break;
|
|
2695
|
+
} catch (error) {
|
|
2696
|
+
const reason = sweepFailureReason(error);
|
|
2697
|
+
const retryable = /(?:\b403\b|\b429\b|rate.?limit|secondary rate)/i.test(reason);
|
|
2698
|
+
if (!retryable || attempt >= checkRunRetryDelays.length) {
|
|
2699
|
+
const incomplete = `check-run inventory incomplete for ${repository}@${sha}: ${reason}`;
|
|
2700
|
+
checkRunsUnavailableReason ??= incomplete;
|
|
2701
|
+
markInventoryIncomplete(incomplete);
|
|
2702
|
+
throw new Error(incomplete);
|
|
2703
|
+
}
|
|
2704
|
+
await sleepForCheckRunRetry(checkRunRetryDelays[attempt++]!);
|
|
2705
|
+
}
|
|
2706
|
+
}
|
|
2707
|
+
if (!Array.isArray(result?.check_runs) || result.check_runs.length > 100 || !Number.isSafeInteger(result.total_count) || result.total_count! < 0) {
|
|
2708
|
+
const incomplete = `check-run inventory incomplete for ${repository}@${sha}: malformed page ${page}`;
|
|
2709
|
+
checkRunsUnavailableReason ??= incomplete;
|
|
2710
|
+
markInventoryIncomplete(incomplete);
|
|
2711
|
+
throw new Error(incomplete);
|
|
2712
|
+
}
|
|
2614
2713
|
runs.push(...result.check_runs);
|
|
2615
|
-
if (
|
|
2616
|
-
if (result.check_runs.length < 100)
|
|
2714
|
+
if (runs.length >= result.total_count!) return runs;
|
|
2715
|
+
if (result.check_runs.length < 100) {
|
|
2716
|
+
const incomplete = `check-run inventory incomplete for ${repository}@${sha}: expected ${result.total_count}, received ${runs.length} (check-runs may have changed during pagination or the response may be incomplete)`;
|
|
2717
|
+
checkRunsUnavailableReason ??= incomplete;
|
|
2718
|
+
markInventoryIncomplete(incomplete);
|
|
2719
|
+
throw new Error(incomplete);
|
|
2720
|
+
}
|
|
2617
2721
|
}
|
|
2618
|
-
|
|
2722
|
+
const incomplete = `check-run inventory incomplete for ${repository}@${sha}: pagination limit reached`;
|
|
2723
|
+
checkRunsUnavailableReason ??= incomplete;
|
|
2724
|
+
markInventoryIncomplete(incomplete);
|
|
2725
|
+
throw new Error(incomplete);
|
|
2726
|
+
};
|
|
2727
|
+
const checkRunsFor = async (repository: string, sha: string): Promise<Array<{ conclusion?: string | null }>> => {
|
|
2728
|
+
let release!: () => void;
|
|
2729
|
+
const previous = checkRunsQueue;
|
|
2730
|
+
checkRunsQueue = new Promise<void>((resolve) => { release = resolve; });
|
|
2731
|
+
await previous;
|
|
2732
|
+
try {
|
|
2733
|
+
if (checkRunsUnavailableReason) throw new Error(checkRunsUnavailableReason);
|
|
2734
|
+
return await readCheckRuns(repository, sha);
|
|
2735
|
+
} finally { release(); }
|
|
2619
2736
|
};
|
|
2620
2737
|
const headCommitTimeFor = async (repository: string, number: number): Promise<string | undefined> => {
|
|
2621
2738
|
let latest: string | undefined;
|
|
@@ -2694,13 +2811,16 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2694
2811
|
const enrichedDrafts = (repository: string): Promise<SweepDraft[]> => {
|
|
2695
2812
|
if (!draftRows.has(repository)) draftRows.set(repository, (async () => {
|
|
2696
2813
|
const prs = (await listed(open, repository, 'open')).filter((pr) => pr.draft);
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2814
|
+
const selected = maxDrafts === undefined ? prs : prs.slice(0, maxDrafts);
|
|
2815
|
+
if (selected.length < prs.length) markInventoryIncomplete(`draft inventory capped at ${maxDrafts} drafts (${prs.length} drafts listed)`);
|
|
2816
|
+
await prefetchDetails(repository, selected.map((pr) => pr.number));
|
|
2817
|
+
const matches = readRunLedgerMatches();
|
|
2818
|
+
return mapBounded(selected, DRAFT_SWEEP_CONCURRENCY, async (pr): Promise<SweepDraft> => {
|
|
2700
2819
|
return {
|
|
2701
2820
|
number: pr.number, title: pr.title, branch: pr.head.ref,
|
|
2702
2821
|
labels: pr.labels.map((item) => item.name), createdAt: pr.created_at, body: pr.body ?? undefined,
|
|
2703
2822
|
changedFiles: await prFiles(repository, pr.number),
|
|
2823
|
+
...(pr.head.sha ? { headSha: pr.head.sha } : {}),
|
|
2704
2824
|
...(pr.updated_at ? { updatedAt: pr.updated_at } : {}),
|
|
2705
2825
|
runId: currentDraftSweepRunId(matches, repository, pr.number),
|
|
2706
2826
|
};
|
|
@@ -2711,8 +2831,10 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2711
2831
|
const enrichedMerged = (repository: string): Promise<SweepMergedPr[]> => {
|
|
2712
2832
|
if (!mergedRows.has(repository)) mergedRows.set(repository, (async () => {
|
|
2713
2833
|
const prs = (await listed(closed, repository, 'closed')).filter((pr) => pr.merged_at !== null && pr.base?.ref === 'main');
|
|
2714
|
-
|
|
2715
|
-
|
|
2834
|
+
const selected = maxMerged === undefined ? prs : prs.slice(0, maxMerged);
|
|
2835
|
+
if (selected.length < prs.length) markInventoryIncomplete(`merged PR inventory capped at ${maxMerged} records (${prs.length} records listed)`);
|
|
2836
|
+
await prefetchDetails(repository, selected.map((pr) => pr.number));
|
|
2837
|
+
return mapBounded(selected, DRAFT_SWEEP_CONCURRENCY, async (pr): Promise<SweepMergedPr> => ({
|
|
2716
2838
|
number: pr.number, title: pr.title, branch: pr.head.ref, body: pr.body ?? undefined,
|
|
2717
2839
|
mergedAt: pr.merged_at ?? undefined, changedFiles: await prFiles(repository, pr.number),
|
|
2718
2840
|
mergeCommitMessage: await mergeCommitMessageFor(repository, pr),
|
|
@@ -2722,19 +2844,35 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2722
2844
|
};
|
|
2723
2845
|
let ledgerMatches: readonly RunLedgerMatch[] | undefined;
|
|
2724
2846
|
let running: ReadonlyMap<string, string> | undefined;
|
|
2725
|
-
const
|
|
2726
|
-
ledgerMatches ??= listRunLedgers().matches;
|
|
2727
|
-
|
|
2847
|
+
const readRunLedgerMatches = (): readonly RunLedgerMatch[] => {
|
|
2848
|
+
ledgerMatches ??= options.runLedgerMatches?.() ?? listRunLedgers().matches;
|
|
2849
|
+
return ledgerMatches;
|
|
2850
|
+
};
|
|
2851
|
+
const readRunningRunStatuses = (): ReadonlyMap<string, string> => {
|
|
2852
|
+
running ??= options.runningRunStatuses?.() ?? new Map(queryRunningRuns().entries.map((entry) => [entry.runId, entry.status]));
|
|
2853
|
+
return running;
|
|
2854
|
+
};
|
|
2855
|
+
const runStatusFor = (draft: Pick<SweepDraft, 'number' | 'branch' | 'runId'>, repository: string): string | undefined => {
|
|
2856
|
+
const matches = readRunLedgerMatches();
|
|
2857
|
+
const statuses = readRunningRunStatuses();
|
|
2728
2858
|
if (draft.runId) {
|
|
2729
|
-
const match =
|
|
2730
|
-
return match ? draftSweepRunStatus([match],
|
|
2859
|
+
const match = matches.find((entry) => entry.runId === draft.runId);
|
|
2860
|
+
return match ? draftSweepRunStatus([match], statuses, repository, draft.number) : undefined;
|
|
2731
2861
|
}
|
|
2732
|
-
return draftSweepRunStatus(
|
|
2862
|
+
return draftSweepRunStatus(matches, statuses, repository, draft.number);
|
|
2733
2863
|
};
|
|
2734
2864
|
return {
|
|
2865
|
+
inventoryStatus: async () => ({ complete: inventoryIncompleteReason === undefined, ...(inventoryIncompleteReason ? { reason: inventoryIncompleteReason } : {}) }),
|
|
2735
2866
|
openPullRequests: (repository) => listed(open, repository, 'open'),
|
|
2736
|
-
runLedgerMatches:
|
|
2867
|
+
runLedgerMatches: readRunLedgerMatches,
|
|
2737
2868
|
getPrFiles: async (repository, number) => prFiles(repository, number),
|
|
2869
|
+
getDraftSnapshot: async (repository, number) => {
|
|
2870
|
+
const pr = await ghJsonAsync<GithubPull>(['api', `repos/${repository}/pulls/${number}`]);
|
|
2871
|
+
if (!pr || pr.number !== number || !Array.isArray(pr.labels) || !pr.head?.sha || !pr.updated_at
|
|
2872
|
+
|| (pr.state !== 'open' && pr.state !== 'closed')) return undefined;
|
|
2873
|
+
return { number: pr.number, state: pr.state, draft: pr.draft, headSha: pr.head.sha,
|
|
2874
|
+
branch: pr.head.ref, updatedAt: pr.updated_at, labels: pr.labels.map((item) => item.name) };
|
|
2875
|
+
},
|
|
2738
2876
|
getPr: async (repository, number) => {
|
|
2739
2877
|
const pr = ghJson<GithubPull>(['api', `repos/${repository}/pulls/${number}`], execute);
|
|
2740
2878
|
if (!pr || pr.number !== number || typeof pr.head?.ref !== 'string' || !Array.isArray(pr.labels)) return undefined;
|
|
@@ -2766,8 +2904,8 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2766
2904
|
getRunStatus: async (draft, repository) => runStatusFor(draft, repository),
|
|
2767
2905
|
getLatestFileChanges: async (draft, repository) => latestFileChangesFor(draft, repository),
|
|
2768
2906
|
hasFinalRunResult: async (draft, repository) => {
|
|
2769
|
-
|
|
2770
|
-
const ownedRuns = new Set(
|
|
2907
|
+
const matches = readRunLedgerMatches();
|
|
2908
|
+
const ownedRuns = new Set(matches.filter((match) => {
|
|
2771
2909
|
const prEvents = match.entries.filter((entry) => entry.event === 'pr-opened' && entry.data.number === draft.number);
|
|
2772
2910
|
return prEvents.length > 0 && prEvents.every((entry) => ledgerPrRepository(entry.data, draft.number) === repository);
|
|
2773
2911
|
}).map((match) => match.runId));
|
|
@@ -2825,7 +2963,7 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2825
2963
|
getActiveClaimRunId: async (repository, number) => activeClaimRunIdFromBodies(await claimCommentsFor(repository, number)),
|
|
2826
2964
|
getLastClaimReleaseAt: async (repository, number) => lastClaimReleaseAtFromBodies(await claimCommentsFor(repository, number)),
|
|
2827
2965
|
listTaskCards: async () => Object.values(readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(taskAgentStatePath()).tasks ?? {}),
|
|
2828
|
-
listPrTerminals: async () =>
|
|
2966
|
+
listPrTerminals: async () => readRunLedgerMatches().flatMap((match) => match.entries.filter((entry) => entry.event === 'pr-terminal')
|
|
2829
2967
|
.map((entry) => entry.data as unknown as PrTerminalRecord)),
|
|
2830
2968
|
commentDraft: async (repository, number, body) => { execute(['pr', 'comment', String(number), '--repo', repository, '--body', body]); },
|
|
2831
2969
|
listIssueComments: async (repository, number) => issueCommentsFor(repository, number, 'same-cell'),
|
|
@@ -2847,6 +2985,18 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2847
2985
|
};
|
|
2848
2986
|
}
|
|
2849
2987
|
|
|
2988
|
+
export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: DraftSweepGitExecute = runGitCommand,
|
|
2989
|
+
cwd = process.cwd(), executeAsync?: (args: string[]) => Promise<string>, stopRun?: DraftSweepStopRun,
|
|
2990
|
+
options: GithubDraftSweepAdapterOptions = {}): GithubDraftSweepAdapters {
|
|
2991
|
+
return createGithubDraftSweepAdapters(execute, git, cwd, executeAsync, stopRun, options);
|
|
2992
|
+
}
|
|
2993
|
+
|
|
2994
|
+
export function githubDraftSweepPreviewAdapters(options: GithubDraftSweepAdapterOptions,
|
|
2995
|
+
execute: GhExecute = executeGh, git: DraftSweepGitExecute = runGitCommand, cwd = process.cwd(),
|
|
2996
|
+
executeAsync?: (args: string[]) => Promise<string>, stopRun?: DraftSweepStopRun): GithubDraftSweepAdapters {
|
|
2997
|
+
return createGithubDraftSweepAdapters(execute, git, cwd, executeAsync, stopRun, options);
|
|
2998
|
+
}
|
|
2999
|
+
|
|
2850
3000
|
export interface HarnessDraftSweepDeps {
|
|
2851
3001
|
/** DRAFT-LINEAGE-ONE-1 test seam for the real adapter's run stop; omitted ⇒ `harness stop`. */
|
|
2852
3002
|
readonly stopRun?: DraftSweepStopRun;
|
|
@@ -2995,7 +3145,12 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
|
|
|
2995
3145
|
.option('--json', '판정 결과를 JSON 으로 출력')
|
|
2996
3146
|
.option('--repo <owner/name>', '조회할 GitHub 저장소')
|
|
2997
3147
|
.option('--close-cap <n>', '이번 틱 최대 종료 수 (1~100 · config tools.selfImplement.draftSweepCloseCap 보다 우선 · 기본 10)')
|
|
2998
|
-
.
|
|
3148
|
+
.option('--max-pages <n>', 'inventory 상한 (페이지, dry-run 기본 1 · apply 기본 100 · 1~100)')
|
|
3149
|
+
.option('--max-drafts <n>', 'draft 상한 (dry-run 기본 10 · apply 기본 무제한)')
|
|
3150
|
+
.option('--max-merged <n>', 'merged PR 상한 (dry-run 기본 50 · apply 기본 무제한)')
|
|
3151
|
+
.option('--emit-apply-plan', '완전한 dry-run 분류에서 고정 적용 계획을 JSON에 포함 (모든 PR에 head SHA와 updatedAt 필요)')
|
|
3152
|
+
.option('--apply-plan-file <path>', '고정 적용 계획 JSON 파일 (apply 전용)')
|
|
3153
|
+
.action(async (opts: { apply?: boolean; json?: boolean; repo?: string; closeCap?: string; maxPages?: string; maxDrafts?: string; maxMerged?: string; emitApplyPlan?: boolean; applyPlanFile?: string }) => {
|
|
2999
3154
|
try {
|
|
3000
3155
|
const write = deps.write ?? console.log;
|
|
3001
3156
|
const execute = deps.execute ?? executeGh;
|
|
@@ -3006,8 +3161,26 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
|
|
|
3006
3161
|
if (!DRAFT_SWEEP_REPOSITORY.test(repository) || repository.includes('..')) {
|
|
3007
3162
|
throw new HarnessCliInputError(`invalid --repo (expected owner/name): ${repository}`);
|
|
3008
3163
|
}
|
|
3164
|
+
const readLimit = (value: string | undefined, fallback: number, name: string, max: number): number => {
|
|
3165
|
+
const limit = value === undefined ? fallback : Number(value);
|
|
3166
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > max) throw new HarnessCliInputError(`invalid ${name} (expected 1~${max})`);
|
|
3167
|
+
return limit;
|
|
3168
|
+
};
|
|
3169
|
+
const applying = opts.apply === true;
|
|
3170
|
+
if (opts.emitApplyPlan && (applying || !opts.json)) throw new HarnessCliInputError('--emit-apply-plan requires dry-run --json');
|
|
3171
|
+
if (opts.applyPlanFile && !applying) throw new HarnessCliInputError('--apply-plan-file requires --apply');
|
|
3172
|
+
const applyPlan = opts.applyPlanFile
|
|
3173
|
+
? validateDraftSweepApplyPlan(JSON.parse(readFileSync(resolve(opts.applyPlanFile), 'utf8')))
|
|
3174
|
+
: undefined;
|
|
3009
3175
|
// One adapter instance per sweep: its open listing and ledger scan are shared with the RUN-TTL step.
|
|
3010
|
-
const
|
|
3176
|
+
const inventoryLimits = {
|
|
3177
|
+
maxInventoryPages: readLimit(opts.maxPages, applying ? 100 : 1, '--max-pages', 100),
|
|
3178
|
+
maxDrafts: opts.maxDrafts === undefined && applying ? undefined : readLimit(opts.maxDrafts, 10, '--max-drafts', 1_000),
|
|
3179
|
+
maxMerged: opts.maxMerged === undefined && applying ? undefined : readLimit(opts.maxMerged, 50, '--max-merged', 1_000),
|
|
3180
|
+
onInventoryProgress: ({ state, page, rows }: { state: 'open' | 'closed'; page: number; rows: number }) =>
|
|
3181
|
+
console.error(`[draft-sweep] inventory state=${state} page=${page} rows=${rows}`),
|
|
3182
|
+
};
|
|
3183
|
+
const github = deps.adapters ? undefined : githubDraftSweepPreviewAdapters(inventoryLimits, deps.execute, undefined, undefined, undefined, deps.stopRun);
|
|
3011
3184
|
const configCap = deps.closeCapConfig
|
|
3012
3185
|
? deps.closeCapConfig()
|
|
3013
3186
|
: (() => { try { return getUserConfig().tools?.selfImplement?.draftSweepCloseCap; } catch { return undefined; } })();
|
|
@@ -3017,7 +3190,7 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
|
|
|
3017
3190
|
try { debug.log('self-dev.draft-sweep', 'close-cap-rejected', { warning, closeCap: cap.closeCap, closeCapSource: cap.closeCapSource }); } catch { /* fail-soft */ }
|
|
3018
3191
|
}
|
|
3019
3192
|
let replayClosed = 0;
|
|
3020
|
-
if (opts.apply && (!deps.adapters || deps.residueReplay)) {
|
|
3193
|
+
if (opts.apply && !applyPlan && (!deps.adapters || deps.residueReplay)) {
|
|
3021
3194
|
try {
|
|
3022
3195
|
replayClosed = (await replayPodTerminals({ ...deps.residueReplay, repository, closeCap: cap.closeCap })).closed;
|
|
3023
3196
|
} catch (error) {
|
|
@@ -3028,12 +3201,23 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
|
|
|
3028
3201
|
}
|
|
3029
3202
|
}
|
|
3030
3203
|
const result: DraftSweepResult = await runDraftSweep({ repository, apply: opts.apply === true, includeTriage: opts.json === true, adapters: deps.adapters ?? github!,
|
|
3031
|
-
closeCap: cap.closeCap, closeCapSource: cap.closeCapSource, alreadyClosed: replayClosed
|
|
3204
|
+
closeCap: cap.closeCap, closeCapSource: cap.closeCapSource, alreadyClosed: replayClosed,
|
|
3205
|
+
includeApplyPlan: opts.emitApplyPlan === true, applyPlan });
|
|
3206
|
+
const frozenPlanMaintenance = applyPlan ? { postSweep: {
|
|
3207
|
+
residueReplay: 'skipped: frozen plan does not include terminal-residue PRs',
|
|
3208
|
+
runTtl: 'skipped: frozen plan does not include RUN-TTL PRs',
|
|
3209
|
+
} } : {};
|
|
3032
3210
|
const reason = result.error ? sweepFailureReason(result.error) : undefined;
|
|
3033
3211
|
const ttlStarted = Date.now();
|
|
3034
|
-
const runTtl = await draftSweepRunTtl(repository, deps, github);
|
|
3212
|
+
const runTtl = result.complete && !applyPlan ? await draftSweepRunTtl(repository, deps, github) : undefined;
|
|
3035
3213
|
try { debug.log('self-dev.draft-sweep', 'timing', { phase: 'run-ttl', ms: Date.now() - ttlStarted, count: runTtl && !('error' in runTtl) ? runTtl.considered : 0 }); } catch { /* fail-soft */ }
|
|
3036
|
-
if (opts.json)
|
|
3214
|
+
if (opts.json) {
|
|
3215
|
+
const output = JSON.stringify({ ...(reason ? { ...result, error: reason } : result), ...frozenPlanMaintenance, ...(runTtl ? { runTtl } : {}) });
|
|
3216
|
+
// `src/index.ts` imports chalk, which makes Bun stdout non-blocking. Await the
|
|
3217
|
+
// write callback so a large JSON result cannot be silently cut at the pipe buffer.
|
|
3218
|
+
if (deps.write) write(output);
|
|
3219
|
+
else await writeStdoutFully(output);
|
|
3220
|
+
}
|
|
3037
3221
|
else {
|
|
3038
3222
|
if (runTtl) {
|
|
3039
3223
|
write('error' in runTtl ? `run-ttl: 실패 (${runTtl.error})`
|
|
@@ -3538,7 +3722,13 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
|
|
|
3538
3722
|
if (say) {
|
|
3539
3723
|
registerHarnessAskSayOptions(harnessCmd.command('say <sentence...>').description('문장을 받아 구동한다'))
|
|
3540
3724
|
.addOption(new Option('--author-grade <grade>', 'say 저작 등급 (full|lite)').choices(['full', 'lite']))
|
|
3725
|
+
.option('--move-id <id>', 'NEXTMOVE-GENERAL-RELAUNCH-MOVEID — 이 발사를 고른 TA next-move 결정의 수 id(관측 조인 칸 · 발사 동작은 바꾸지 않는다)')
|
|
3541
3726
|
.action(async (sentence: string[], opts: HarnessAskSayChildLlmOptions & HarnessDryRunOpts) => {
|
|
3727
|
+
const moveId = (opts as { moveId?: unknown }).moveId;
|
|
3728
|
+
// 발사 쪽 영수증 — TA 일반 재발사가 실은 수 id 를 받았다는 한 줄(관측만 · fail-soft · 옵션은 아래로 내려가지 않는다).
|
|
3729
|
+
if (typeof moveId === 'string' && moveId) {
|
|
3730
|
+
try { debug.log('harness', 'move-id-received', { entrance: 'cli-harness-say', moveId }); } catch { /* fail-soft */ }
|
|
3731
|
+
}
|
|
3542
3732
|
const repair = opts as HarnessSubstrateOpts;
|
|
3543
3733
|
if (repair.repairCommitOnly !== undefined && (repair.substrate !== 'pod' || !/^pr:[1-9]\d*$/.test(repair.source ?? '')
|
|
3544
3734
|
|| !/^[0-9a-f]{40}$/.test(repair.repairCommitOnly) || repair.autoMerge !== false || repair.target !== undefined)) {
|
|
@@ -4,6 +4,7 @@ import { join } from 'node:path';
|
|
|
4
4
|
import { redactSecretText } from '../debug/log.js';
|
|
5
5
|
import { refuseProductionLedgerWriteInTest } from './ledger-write-guard.js';
|
|
6
6
|
import type { PodChildEvidence } from '../task-orchestrator/surfaces/self-implement.js';
|
|
7
|
+
import { parsePodTermination, type PodTermination } from '../task-orchestrator/surfaces/pod-failure-reason.js';
|
|
7
8
|
|
|
8
9
|
export interface RunExit {
|
|
9
10
|
runId: string;
|
|
@@ -18,6 +19,14 @@ export interface RunExit {
|
|
|
18
19
|
pid?: number;
|
|
19
20
|
lastLines?: string[];
|
|
20
21
|
childEvidence?: PodChildEvidence;
|
|
22
|
+
/** JOB-FAILURE-TERMINATION-CAPTURE — the current attempt's Job/Pod termination facts, captured before GC. */
|
|
23
|
+
podTermination?: PodTermination;
|
|
24
|
+
/** INCIDENT-REASON-FROM-LASTLINES — 기록된 reason 이 unknown 이라 lastLines 로 다시 분류했으면 원래 값. */
|
|
25
|
+
recordedReason?: string;
|
|
26
|
+
/** reason 을 어디서 얻었나 — 'lastLines' 면 위 분류 규칙으로 정했다(기록 원문은 recordedReason). */
|
|
27
|
+
reasonSource?: 'lastLines';
|
|
28
|
+
/** lastLines 에 ux-sim 장치 조각 경로가 보였다 — 장치 먼저 조각의 실패를 따로 셀 수 있게. */
|
|
29
|
+
slice?: 'device';
|
|
21
30
|
}
|
|
22
31
|
|
|
23
32
|
export interface IncidentBurst {
|
|
@@ -44,6 +53,40 @@ function kstDate(at: number): string {
|
|
|
44
53
|
return new Date(at + KST_OFFSET_MS).toISOString().slice(0, 10);
|
|
45
54
|
}
|
|
46
55
|
|
|
56
|
+
// ── INCIDENT-REASON-FROM-LASTLINES (0.2.36 · 10-22 · OP 대응 피처) ───────────────────────────────
|
|
57
|
+
// 기록된 reason 이 «unknown» 인데 마지막 출력 줄에 사유가 그대로 있는 사고가 다수(10-22 경보) — 읽는 쪽에서
|
|
58
|
+
// 결정론으로 다시 분류한다. 우선순위 = 더 구체적인 종료 사유 먼저. 아무것도 안 맞으면 unknown 그대로(추측 0).
|
|
59
|
+
const LAST_LINE_REASONS: ReadonlyArray<[RegExp, string]> = [
|
|
60
|
+
// 근본 원인 먼저 — 뒤 조각의 DEPENDENCY_NEEDS_HUMAN 은 앞 조각 실패의 «증상»이라 맨 뒤 쪽.
|
|
61
|
+
[/goal-elaboration needs-human:\s*goal-elaboration-ungrounded-path\b/, 'goal-elaboration-ungrounded-path'],
|
|
62
|
+
[/goal-elaboration needs-human:\s*goal-elaboration-protected-path\b/, 'goal-elaboration-protected-path'],
|
|
63
|
+
[/goal-elaboration needs-human:\s*goal-elaboration-scope-conflict\b/, 'goal-elaboration-scope-conflict'],
|
|
64
|
+
[/goal-elaboration needs-human:\s*goal-elaboration-fixed-layer-conflict\b/, 'goal-elaboration-fixed-layer-conflict'],
|
|
65
|
+
[/pod-deadline-exceeded|DeadlineExceeded/, 'pod-deadline-exceeded'],
|
|
66
|
+
[/GOAL_DONE_BOUNDARY_MISSING/, 'goal-done-boundary-missing'],
|
|
67
|
+
[/BackoffLimitExceeded/, 'pod-backoff-limit'],
|
|
68
|
+
[/childError=no-resul/, 'pod-child-no-result'],
|
|
69
|
+
[/pod-job-failed/, 'pod-job-failed'],
|
|
70
|
+
[/DEPENDENCY_NEEDS_HUMAN/, 'dependency-needs-human'],
|
|
71
|
+
[/\[needs-human\]|needs-human/, 'needs-human'],
|
|
72
|
+
];
|
|
73
|
+
const DEVICE_SLICE_PATH = /src\/ux-sim\/[\w.-]*-device(?:\.test)?\.ts|DEVICE-FIRST/;
|
|
74
|
+
|
|
75
|
+
/** lastLines 에서 종료 사유를 꺼낸다 — 안 맞으면 null(unknown 유지). */
|
|
76
|
+
export function classifyIncidentReasonFromLastLines(lines: readonly string[] | undefined): string | null {
|
|
77
|
+
if (!lines?.length) return null;
|
|
78
|
+
const text = lines.join('\n');
|
|
79
|
+
for (const [pattern, reason] of LAST_LINE_REASONS) if (pattern.test(text)) return reason;
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function refinedReasonFields(reason: string, lines: readonly string[] | undefined): Pick<RunExit, 'reason' | 'recordedReason' | 'reasonSource' | 'slice'> {
|
|
84
|
+
const slice = lines?.some((line) => DEVICE_SLICE_PATH.test(line)) ? { slice: 'device' as const } : {};
|
|
85
|
+
if (reason !== 'unknown') return { reason, ...slice };
|
|
86
|
+
const refined = classifyIncidentReasonFromLastLines(lines);
|
|
87
|
+
return refined ? { reason: refined, recordedReason: reason, reasonSource: 'lastLines', ...slice } : { reason, ...slice };
|
|
88
|
+
}
|
|
89
|
+
|
|
47
90
|
/** Read only recorded exits. Missing ledgers are not evidence that no runs failed. */
|
|
48
91
|
export function readRunExits(root: string): RunExit[] {
|
|
49
92
|
const dir = join(root, 'incidents');
|
|
@@ -71,7 +114,8 @@ export function readRunExits(root: string): RunExit[] {
|
|
|
71
114
|
|| !(row.status === null || typeof row.status === 'number')
|
|
72
115
|
|| !(row.signal === null || typeof row.signal === 'string')) continue;
|
|
73
116
|
seen.add(row.runId);
|
|
74
|
-
|
|
117
|
+
const lines = Array.isArray(row.lastLines) && row.lastLines.every((line) => typeof line === 'string') ? row.lastLines : undefined;
|
|
118
|
+
rows.push({ runId: row.runId, ...refinedReasonFields(row.reason, lines), status: row.status, signal: row.signal, at: row.at,
|
|
75
119
|
...(typeof row.entrance === 'string' ? { entrance: row.entrance } : {}),
|
|
76
120
|
...(typeof row.seat === 'string' ? { seat: row.seat } : {}),
|
|
77
121
|
...(typeof row.cwd === 'string' ? { cwd: row.cwd } : {}),
|
|
@@ -81,12 +125,19 @@ export function readRunExits(root: string): RunExit[] {
|
|
|
81
125
|
? { lastLines: row.lastLines } : {}),
|
|
82
126
|
...(row.childEvidence && typeof row.childEvidence === 'object' && !Array.isArray(row.childEvidence)
|
|
83
127
|
? { childEvidence: row.childEvidence } : {}),
|
|
128
|
+
...podTerminationField(row.podTermination),
|
|
84
129
|
});
|
|
85
130
|
}
|
|
86
131
|
}
|
|
87
132
|
return rows.sort((a, b) => Date.parse(a.at) - Date.parse(b.at) || a.runId.localeCompare(b.runId));
|
|
88
133
|
}
|
|
89
134
|
|
|
135
|
+
function podTerminationField(value: unknown): { podTermination?: PodTermination } {
|
|
136
|
+
const job = value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>).job : undefined;
|
|
137
|
+
const parsed = typeof job === 'string' ? parsePodTermination(value, job) : undefined;
|
|
138
|
+
return parsed ? { podTermination: parsed } : {};
|
|
139
|
+
}
|
|
140
|
+
|
|
90
141
|
/** SQLite's process-owned write lock serializes ledger checks and appends across processes. */
|
|
91
142
|
export function recordRunExit(row: RunExit, root: string): void {
|
|
92
143
|
if (refuseProductionLedgerWriteInTest(root, 'incidents')) return;
|
|
@@ -2,6 +2,14 @@ import { encodeControlMemoFrame, type ControlMemoPayload } from './control-inbox
|
|
|
2
2
|
import type { PodFragmentRecord } from './self-send-target.js';
|
|
3
3
|
import { defaultKubectl, type Kubectl } from '../task-orchestrator/surfaces/self-implement-pod.js';
|
|
4
4
|
|
|
5
|
+
const POD_CONTROL_KUBECTL_TIMEOUT_MS = 120_000;
|
|
6
|
+
|
|
7
|
+
export function parsePodReadWait(value: string | number): number {
|
|
8
|
+
const parsed = typeof value === 'string' && !value.trim() ? Number.NaN : Number(value);
|
|
9
|
+
if (!Number.isFinite(parsed) || parsed < 0 || parsed > 60) throw new Error('self send --read-wait는 0~60초의 유한한 값이어야 합니다');
|
|
10
|
+
return Math.floor(parsed);
|
|
11
|
+
}
|
|
12
|
+
|
|
5
13
|
const PUBLISH = `set -eu
|
|
6
14
|
inbox="$1"
|
|
7
15
|
kind="$2"
|
|
@@ -9,9 +17,24 @@ IFS= read -r line
|
|
|
9
17
|
mkdir -p "\${inbox}.ready"
|
|
10
18
|
if [ "$kind" = memo ]; then
|
|
11
19
|
temp=$(mktemp "\${inbox}.ready/.write-XXXXXXXX")
|
|
12
|
-
|
|
20
|
+
record=''
|
|
21
|
+
cleanup_memo() {
|
|
22
|
+
rm -f "$temp"
|
|
23
|
+
if [ -n "$record" ]; then rm -f "$record.ack-request" "$record.ack"; fi
|
|
24
|
+
}
|
|
25
|
+
trap 'cleanup_memo' EXIT
|
|
26
|
+
trap 'exit 129' HUP
|
|
27
|
+
trap 'exit 130' INT
|
|
28
|
+
trap 'exit 143' TERM
|
|
13
29
|
printf 'memo:%s\\n' "$line" > "$temp"
|
|
14
|
-
|
|
30
|
+
record="\${inbox}.ready/record-$(printf '%016x' "$(date +%s%3N)")-$(cat /proc/sys/kernel/random/uuid)"
|
|
31
|
+
: > "$record.ack-request"
|
|
32
|
+
mv "$temp" "$record"
|
|
33
|
+
printf 'ELANOUS_POD_MEMO_PUBLISHED %s\\n' "\${record##*/}"
|
|
34
|
+
count=0
|
|
35
|
+
while [ ! -e "$record.ack" ] && [ "$count" -lt "$3" ]; do sleep 1; count=$((count + 1)); done
|
|
36
|
+
if [ -e "$record.ack" ]; then printf 'ELANOUS_POD_MEMO_READ %s\\n' "\${record##*/}"
|
|
37
|
+
else printf 'ELANOUS_POD_MEMO_UNVERIFIED %s\\n' "\${record##*/}"; fi
|
|
15
38
|
else
|
|
16
39
|
temp=$(mktemp "\${inbox}.ready/.write-XXXXXXXX")
|
|
17
40
|
trap 'rm -f "$temp"' EXIT
|
|
@@ -25,13 +48,18 @@ else
|
|
|
25
48
|
fi`;
|
|
26
49
|
|
|
27
50
|
/** Publish a control-inbox record inside the child container, not on the host. */
|
|
28
|
-
export function sendPodControl(record: PodFragmentRecord, message: { stop: true } | { memo: ControlMemoPayload }, kubectl: Kubectl = defaultKubectl
|
|
51
|
+
export function sendPodControl(record: PodFragmentRecord, message: { stop: true } | { memo: ControlMemoPayload }, kubectl: Kubectl = defaultKubectl,
|
|
52
|
+
readWaitSeconds = 0): { memoRecord?: string; read?: boolean } {
|
|
29
53
|
const stop = 'stop' in message;
|
|
30
54
|
const input = stop ? 'stop\n' : `${encodeControlMemoFrame(message.memo)}\n`;
|
|
31
55
|
const result = kubectl([
|
|
32
56
|
...(record.context ? ['--context', record.context] : []), '-n', record.namespace,
|
|
33
57
|
'exec', '-i', `job/${record.job}`, '-c', 'child', '--',
|
|
34
|
-
'sh', '-c', PUBLISH, 'pod-control', record.inboxDir, stop ? 'stop' : 'memo',
|
|
35
|
-
], input);
|
|
58
|
+
'sh', '-c', PUBLISH, 'pod-control', record.inboxDir, stop ? 'stop' : 'memo', String(parsePodReadWait(readWaitSeconds)),
|
|
59
|
+
], input, POD_CONTROL_KUBECTL_TIMEOUT_MS);
|
|
36
60
|
if (result.status !== 0) throw new Error(`Pod ${record.job} control send 실패: ${result.stderr.trim() || 'kubectl exec failed'}`);
|
|
61
|
+
if (stop) return {};
|
|
62
|
+
const published = /^ELANOUS_POD_MEMO_PUBLISHED (record-[0-9a-f-]+)$/m.exec(result.stdout)?.[1];
|
|
63
|
+
if (!published) return {};
|
|
64
|
+
return { memoRecord: published, read: result.stdout.includes(`ELANOUS_POD_MEMO_READ ${published}`) };
|
|
37
65
|
}
|