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
|
@@ -40,6 +40,7 @@ import { writeGoalDocumentAtomic } from './goal-document-write.js';
|
|
|
40
40
|
import { hostname, loadavg } from 'node:os';
|
|
41
41
|
import { resolveHostId } from '../platform/host-id.js';
|
|
42
42
|
import { resolveInstanceName } from '../instance-identity.js';
|
|
43
|
+
import { ghAutomationEnv } from '../autopilot/pr-manager.js';
|
|
43
44
|
import { citedReviewSymbols, MAX_CITED_REVIEW_SYMBOL_CHARS, measureReviewFindingKeyOverlap, normalizeReviewFindingKey, REVIEW_FINDING_KEY_VERSION, reviewFindingKey, shortNormalizedReviewFindingHash, type CitedReviewSymbol } from '../agent-substrate/review-finding-key.js';
|
|
44
45
|
export { citedReviewSymbols, MAX_CITED_REVIEW_SYMBOL_CHARS, normalizeReviewFindingKey, REVIEW_FINDING_KEY_VERSION, reviewFindingKey, shortNormalizedReviewFindingHash, type CitedReviewSymbol } from '../agent-substrate/review-finding-key.js';
|
|
45
46
|
|
|
@@ -47,6 +48,46 @@ function displayBranchName(ref: string): string {
|
|
|
47
48
|
return ref.trim().replace(/^refs\/heads\//, '').replace(/^origin\//, '');
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
export const HARVEST_DEFERRED_MARKER = '수확보류: harvest-deferred';
|
|
52
|
+
const execFileAsync = promisify(execFileCallback);
|
|
53
|
+
|
|
54
|
+
export function markHarvestDeferredBody(input: {
|
|
55
|
+
runStatus: string | undefined;
|
|
56
|
+
prNumber: number | undefined;
|
|
57
|
+
body: string | undefined;
|
|
58
|
+
}): string | undefined {
|
|
59
|
+
if (input.runStatus !== 'failed' || input.prNumber === undefined || !Number.isSafeInteger(input.prNumber) || input.prNumber < 1 || input.body === undefined) return undefined;
|
|
60
|
+
if (harvestDeferredMarker(input.body)) return input.body;
|
|
61
|
+
const separator = input.body.endsWith('\n') ? '\n' : '\n\n';
|
|
62
|
+
return `${input.body}${separator}${HARVEST_DEFERRED_MARKER}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function readHarvestPrBody(opts: { number: number; cwd: string }): Promise<{ body: string; state: string; isDraft: boolean } | undefined> {
|
|
66
|
+
const { stdout } = await execFileAsync('gh', ['pr', 'view', String(opts.number), '--json', 'body,state,isDraft'], {
|
|
67
|
+
cwd: opts.cwd,
|
|
68
|
+
env: ghAutomationEnv(process.env),
|
|
69
|
+
encoding: 'utf8',
|
|
70
|
+
timeout: 120_000,
|
|
71
|
+
maxBuffer: 2 * 1024 * 1024,
|
|
72
|
+
});
|
|
73
|
+
const parsed: unknown = JSON.parse(stdout);
|
|
74
|
+
if (!parsed || typeof parsed !== 'object') return undefined;
|
|
75
|
+
const record = parsed as { body?: unknown; state?: unknown; isDraft?: unknown };
|
|
76
|
+
return typeof record.body === 'string' && typeof record.state === 'string' && typeof record.isDraft === 'boolean'
|
|
77
|
+
? { body: record.body, state: record.state, isDraft: record.isDraft }
|
|
78
|
+
: undefined;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export async function updateHarvestPrBody(opts: { number: number; body: string; cwd: string }): Promise<void> {
|
|
82
|
+
await execFileAsync('gh', ['pr', 'edit', String(opts.number), '--body', opts.body], {
|
|
83
|
+
cwd: opts.cwd,
|
|
84
|
+
env: ghAutomationEnv(process.env),
|
|
85
|
+
encoding: 'utf8',
|
|
86
|
+
timeout: 120_000,
|
|
87
|
+
maxBuffer: 2 * 1024 * 1024,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
50
91
|
export function formatAutoMergeSuccessMessage(input: {
|
|
51
92
|
prNumber: number;
|
|
52
93
|
mergedBase?: string | undefined;
|
|
@@ -68,6 +109,7 @@ import { getUserConfig } from '../user-config.js';
|
|
|
68
109
|
import { appendRunLedgerEntry, loadRunLedger, parseRunShardIdentity, queryRunChain, type RunChainShardSibling, type RunLedgerEntry, type RunLedgerWriter, type RunOriginData, type RunShardIdentity } from './run-ledger.js';
|
|
69
110
|
import { classifyMergeHoldStop, forgetRunStop, isRunStopClass, readRunStopRecord, recordRunStop, runStopRecorded } from './run-stop.js';
|
|
70
111
|
import { autohealFromStop, parseAutohealMode, type AutohealActions, type AutohealResult } from './stop-autoheal.js';
|
|
112
|
+
import { recordParentNeedsOwnerVisit } from './doctor-visit.js';
|
|
71
113
|
import { emitSessionEvent, type SessionEventInput } from '../context-bus/session-events.js';
|
|
72
114
|
import { decideLineageSupersede, lineageSupersedeCloseComment, type LineageSupersedeOpenDraft } from './lineage-supersede.js';
|
|
73
115
|
import { basename, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
@@ -79,6 +121,7 @@ import { classifyGateEnvDeficit, DEFAULT_GATE_ENV_RETRY, GATE_ENV_DEFICIT_HARVES
|
|
|
79
121
|
import { recordFailureEvent } from './heal-intake.js';
|
|
80
122
|
import { classifyReworkCapExhaustion, type ReworkCapHealDecision } from './heal-triage.js';
|
|
81
123
|
import { releasePathHold, releasePathHoldComment, RELEASE_PATH_LABEL } from '../self-dev/release-path-guard.js';
|
|
124
|
+
import { harvestDeferredMarker } from '../self-dev/draft-triage-rules.js';
|
|
82
125
|
import { emitDecision } from '../live/detail-switch.js';
|
|
83
126
|
import { reworkDecision } from './decision-events.js';
|
|
84
127
|
import type { LogSink } from '../mss/logging/sink.js';
|
|
@@ -91,7 +134,7 @@ import { classifyError } from '../session-runtime/retry-policy.js';
|
|
|
91
134
|
import { decomposeSelfDevGoal, inferHotPaths, type SelfDevDecomposeOptions } from '../self-dev/decompose.js';
|
|
92
135
|
import { boundaryGlobs, boundaryViolations } from './goal-boundary.js';
|
|
93
136
|
import { askAtExecution, type ExecutionClarificationResult } from './execution-clarification.js';
|
|
94
|
-
import { decideScopeExpansion, renderScopeExpansionSection, SCOPE_EXPANSION_CAP, type ScopeExpansion } from './scope-adjacency.js';
|
|
137
|
+
import { decideScopeExpansion, renderScopeExpansionSection, SCOPE_EXPANSION_CAP, type ScopeExpansion, type ScopeStopReason } from './scope-adjacency.js';
|
|
95
138
|
import { targetScopedGoalText } from './goal-text-path-scope.js';
|
|
96
139
|
import { selectKnowhowPack } from './knowhow-pack.js';
|
|
97
140
|
import { declaredNewFilePaths } from './goal-new-paths.js';
|
|
@@ -175,7 +218,7 @@ function onePrChecklistLine(body: string): string {
|
|
|
175
218
|
}
|
|
176
219
|
import { renderRoundSummaryCard, type RoundSummaryEntry } from './round-summary-card.js';
|
|
177
220
|
import { computeFlexSignals } from './flex-signals.js';
|
|
178
|
-
import { resolveAdaptiveMaxReworkDecision, resolveEscalateTier, resolveEscalateTarget, buildReworkFeature, failIndicator, isRepeatedUnverifiedOnlyGateFailure, unverifiedRepeatKey, appendReworkHistory, truncateReworkHistoryByItem, applyReworkBudgetDecision, parseContractConflictRelaxation, parseReworkBudgetDecision, resolveReworkBudgetCarry, stripReworkBudgetHeaders, countConsecutiveMustFixIds, mergeReworkNotes, resolveReworkKind, type ReworkPlanRevision, type ReworkNotePart } from './rework-policy.js';
|
|
221
|
+
import { resolveAdaptiveMaxReworkDecision, resolveEscalateTier, resolveEscalateTarget, buildReworkFeature, failIndicator, isRepeatedUnverifiedOnlyGateFailure, unverifiedRepeatKey, appendReworkHistory, truncateReworkHistoryByItem, applyReworkBudgetDecision, parseContractConflictRelaxation, parseReworkBudgetDecision, resolveReworkBudgetCarry, stripReworkBudgetHeaders, countConsecutiveMustFixIds, mergeReworkNotes, resolveReworkKind, decideReviewRound, type ReviewRoundDecision, type ReworkPlanRevision, type ReworkNotePart } from './rework-policy.js';
|
|
179
222
|
import type { SupervisionReworkSource } from './supervision-vocabulary.js';
|
|
180
223
|
import { classifyReworkBudgetShadow } from './classify-shadow.js';
|
|
181
224
|
import { createReworkBudgetJudgment, REWORK_BUDGET_JUDGMENT, reworkBudgetEvidenceForObservation, reworkBudgetWorkflow } from './rework-budget-judgment.js';
|
|
@@ -183,7 +226,8 @@ import { formatGateFailedId, type PremiseReviewCard, type PremiseReviewInput } f
|
|
|
183
226
|
import { runWorkflowToCompletion } from '../workflow-runtime/executor.js';
|
|
184
227
|
import { mapReworkVerdict, supervisionObservationFields } from './supervision-vocabulary.js';
|
|
185
228
|
import { resolveRunOutcome } from './run-outcome.js';
|
|
186
|
-
import { authorLimitationCountFromGoal, harvestEvidenceLines, harvestedEvidenceObservation, MAX_HARVESTED_EVIDENCE_CHARS, parseOffDiffEvidence, requiredEvidenceFromGoal,
|
|
229
|
+
import { authorLimitationCountFromGoal, harvestEvidenceLines, harvestedEvidenceObservation, MAX_HARVESTED_EVIDENCE_CHARS, parseOffDiffEvidence, requiredEvidenceFromGoal, createRequiredEvidenceBudget, coverRequiredEvidence, settleUncoveredEvidence, formatUncoveredEvidenceFeedback, type OffDiffEvidenceParse } from './off-diff-evidence.js';
|
|
230
|
+
import { resolveEvidenceHeadCommit } from './evidence-command-budget.js';
|
|
187
231
|
import { pressDecisionSignals, type DecisionSignalPressResult } from './decision-signal-press.js';
|
|
188
232
|
import { inspectDecisionObservations, inspectDecisionSignalKinds, inspectDecisionSignalObservations } from '../../scripts/ask-marker-check.js';
|
|
189
233
|
|
|
@@ -257,7 +301,9 @@ import type { ClassifyShadowCallLLM } from './classify-shadow.js';
|
|
|
257
301
|
import { hasModuleLoadFailure, type GateTestFailure } from './gate-baseline.js';
|
|
258
302
|
import { commitWorktree, defaultBranchRef, preservationHasChanges } from './seams.js';
|
|
259
303
|
import { detectUncommittedWork } from './uncommitted-work.js';
|
|
260
|
-
import { spawnSync } from 'node:child_process';
|
|
304
|
+
import { execFile as execFileCallback, spawnSync } from 'node:child_process';
|
|
305
|
+
import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
|
|
306
|
+
import { promisify } from 'node:util';
|
|
261
307
|
import { blockedDraftDisposition, blockedDraftTargetFor, decideDraftOnStop, nextMoveFor, parseDraftOnStopMode, repairSalvageLinkComment, salvageBranchForRun, syntheticRepairBasePr, type DraftOnStopMode } from './blocked-draft-policy.js';
|
|
262
308
|
import { formatLlmMergeOutcome } from '../autopilot/build/llm-conflict-merge.js';
|
|
263
309
|
import { FOUND_CITED_PATH_REFUTATION_QUOTE, MISSING_CITED_PATH_REFUTATION_QUOTE, MUST_FIX_REFUTATION_ACKNOWLEDGEMENT_WITH_REASON, REFUTATION_QUOTE_GRAMMAR, observeMustFixCitedPaths, parseMustFixRefutationAcknowledgement, parseMustFixRefutations, renderMustFixCitedPathFacts, snapshotMustFixFindings, stableMustFixId, type ReflectEvidenceFacts, type ReflectGateFacts, type MustFixCitedPathFact, type MustFixFinding, type MustFixRecurrenceHistory, type MustFixRefutation, type MustFixRefutationKind } from './reflect-mustfix.js';
|
|
@@ -281,6 +327,7 @@ import { appendGateWorktreeFreshnessEvidence, gateEvidenceNote } from '../harnes
|
|
|
281
327
|
import { diffHeaderPaths } from '../agent-substrate/self-review-cli.js';
|
|
282
328
|
import { format as formatPrComment, type PrCommentRole } from '../agent-substrate/pr-comment-meta.js';
|
|
283
329
|
import { changedFiles, commitTitles, type OpenPrOutcome, type SelfImplementCompletionDisposition } from './seams.js';
|
|
330
|
+
import { findUnwiredExports, gitBaseFileReader } from './wiring-check.js';
|
|
284
331
|
import {
|
|
285
332
|
classifyAbandonedRun,
|
|
286
333
|
isAbandonedClassificationOutcome,
|
|
@@ -291,6 +338,7 @@ import {
|
|
|
291
338
|
export type { QuotaAccountAvailabilityEvidence };
|
|
292
339
|
import { decideReworkSalvage, type ReworkSalvageEvidence } from './rework-salvage.js';
|
|
293
340
|
import { type SupervisorGoalFillEvidence, fillUnverifiableGoalSlots, type SupervisorGoalFillResult } from './goal-supervisor-fill.js';
|
|
341
|
+
import { repairNextMove } from '../task-agent/repair-next-move.js';
|
|
294
342
|
import { escalateGoalDocumentClarifications, recordSupervisorPlanRevision, type GoalClarificationEscalationResult, type SupervisorPlanRevisionRelaxation, type SupervisorPlanRevisionResult } from './goal-clarification-escalation.js';
|
|
295
343
|
import { parseGoalDocumentClarifications, selfAnswerGoalDocumentClarifications, type GoalClarificationSelfResolver } from './goal-author-clarification.js';
|
|
296
344
|
import {
|
|
@@ -1008,6 +1056,7 @@ export type ImplementTerminalStatus = {
|
|
|
1008
1056
|
export interface SelfImplementSeams {
|
|
1009
1057
|
/** Run-observer ledger sink. Tests inject an in-memory sink to avoid touching user state. */
|
|
1010
1058
|
writeRunLedger?: RunLedgerWriter;
|
|
1059
|
+
checkUnwiredExports?: typeof findUnwiredExports;
|
|
1011
1060
|
/** STOP-AUTOHEAL — heal action seams (live mode only runs actions given here; missing = needs-owner). */
|
|
1012
1061
|
stopAutohealActions?: AutohealActions;
|
|
1013
1062
|
/** STOP-AUTOHEAL — one-attempt guard reader. Default: real run ledger, or none when `writeRunLedger` is injected. */
|
|
@@ -1159,6 +1208,8 @@ export interface SelfImplementSeams {
|
|
|
1159
1208
|
/** Test seam for blocked environment branch persistence; return whether the branch was pushed. */
|
|
1160
1209
|
/** Test seam — the worktree commit to pin before main sync (default `git rev-parse HEAD`). */
|
|
1161
1210
|
headCommit?: (cwd: string) => string | undefined;
|
|
1211
|
+
/** Test seam for required evidence command execution; production uses its bounded shell runner. */
|
|
1212
|
+
evidenceCommandRunner?: (command: string, cwd: string) => Pick<ReturnType<typeof spawnSync>, 'status' | 'stdout' | 'stderr' | 'error'>;
|
|
1162
1213
|
/** `commit` pins the pushed state; without it the worktree HEAD is pushed. */
|
|
1163
1214
|
preserveBlockedBranch?: (ctx: { cwd: string; branch: string; title: string; commit?: string }) => boolean | Promise<boolean>;
|
|
1164
1215
|
/** DRAFT-NOT-ARCHIVE — `tools.selfImplement.draftOnStop` 읽기 seam. 생략하면 user-config(실패·부재 = 'always' · 종전). */
|
|
@@ -1173,11 +1224,17 @@ export interface SelfImplementSeams {
|
|
|
1173
1224
|
openPr: (opts: { title: string; body: string; head: string; base?: string; draft?: boolean; labels?: string[]; cwd: string; runId?: string }) => Promise<OpenPrOutcome>;
|
|
1174
1225
|
/** PR 생성 뒤 런의 라운드 대화를 게시한다. 실패는 PR 개설을 되돌리지 않는다. */
|
|
1175
1226
|
postPrComment?: (opts: { number: number; body: string; cwd: string }) => Promise<void>;
|
|
1227
|
+
/** Read-only body/state confirmation for the failed-run draft preservation marker. */
|
|
1228
|
+
readPrBodyForHarvest?: (opts: { number: number; cwd: string }) => Promise<{ body: string; state: string; isDraft: boolean } | undefined>;
|
|
1229
|
+
/** Update only the confirmed existing PR body; never creates a PR. */
|
|
1230
|
+
updatePrBodyForHarvest?: (opts: { number: number; body: string; cwd: string }) => Promise<void>;
|
|
1176
1231
|
/** Read and edit the single marked status comment; missing seams fall back to individual comments. */
|
|
1177
1232
|
findPrComment?: (opts: { number: number; marker: string; cwd: string; comments?: unknown }) => Promise<{ id: number; body: string } | undefined>;
|
|
1178
1233
|
editPrComment?: (opts: { id: number; body: string; cwd: string }) => Promise<void>;
|
|
1179
1234
|
addPrLabel?: (opts: { number: number; label: string; cwd: string }) => Promise<void>;
|
|
1180
1235
|
readPrFiles?: (opts: { number: number; cwd: string; base?: string }) => Promise<string[]>;
|
|
1236
|
+
/** Read the authoritative GitHub head branch and creation timestamp before run attribution. */
|
|
1237
|
+
readPrAttribution?: (opts: { number: number; cwd: string }) => Promise<{ headRefName: string; createdAt: string }>;
|
|
1181
1238
|
/** PR의 base/head SHA와 관측된 PR base를 한 응답에서 고정한다. 미주입·실패·빈 SHA면 검사 대상을 증명할 수 없어 fail-closed로 PR을 열어 둔다. */
|
|
1182
1239
|
readPrCommitShas?: (opts: { number: number; cwd: string }) => Promise<{ baseCommit: string; headCommit: string; baseRefName?: string }>;
|
|
1183
1240
|
/** 고정한 base/head SHA 쌍의 unified diff. 가변 PR 조회를 다시 사용하면 ABA head 변경에 안전하지 않으므로 두 SHA는 필수 입력이다. */
|
|
@@ -2333,6 +2390,8 @@ export interface SelfImplementResult {
|
|
|
2333
2390
|
scopeExpansion?: ScopeExpansion;
|
|
2334
2391
|
/** Bounded names measured by the execution-scope guard on a held edit. */
|
|
2335
2392
|
outOfScopeEdits?: string[];
|
|
2393
|
+
/** SCOPE-ESCAPE-AS-REFINE: why the held edit stops (deletion · protected path · cap) — the parent stops only on these. */
|
|
2394
|
+
scopeStopReasons?: ScopeStopReason[];
|
|
2336
2395
|
nameCapReached?: boolean;
|
|
2337
2396
|
outsideCount?: number;
|
|
2338
2397
|
gate?: SelfImplementGateResult;
|
|
@@ -3507,6 +3566,17 @@ async function autohealRecordedStop(stopEntry: RunLedgerEntry, s: SelfImplementS
|
|
|
3507
3566
|
...(loadLedger ? { loadLedger } : {}),
|
|
3508
3567
|
...(s?.writeRunLedger ? { writeLedger: s.writeRunLedger } : {}),
|
|
3509
3568
|
});
|
|
3569
|
+
if (result.action === 'needs-owner') {
|
|
3570
|
+
try {
|
|
3571
|
+
const stopKey = JSON.stringify([stopEntry.timestamp, record.site ?? '', record.class, record.cause, record.evidenceRef]);
|
|
3572
|
+
const visit = recordParentNeedsOwnerVisit({ runId: stopEntry.runId, stopKey, evidence: result.reason ?? record.cause });
|
|
3573
|
+
if (visit.status === 'missing-ledger') {
|
|
3574
|
+
debug.log('run-doctor', 'visit-failed', { runId: stopEntry.runId, from: 'parent', symptom: 'needs-owner', error: 'run-ledger-missing' });
|
|
3575
|
+
}
|
|
3576
|
+
} catch (error) {
|
|
3577
|
+
try { debug.log('run-doctor', 'visit-failed', { runId: stopEntry.runId, from: 'parent', symptom: 'needs-owner', error: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
|
|
3578
|
+
}
|
|
3579
|
+
}
|
|
3510
3580
|
s?.onStopAutoheal?.(result);
|
|
3511
3581
|
} catch (error) {
|
|
3512
3582
|
try { debug.log('self-implement.autoheal', 'dispatch-failed', { runId: stopEntry.runId, error: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
|
|
@@ -3760,6 +3830,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3760
3830
|
reworkCapProceed = false;
|
|
3761
3831
|
const progressDelivery = { delivered: 0, unwired: 0, callbackFailed: 0 };
|
|
3762
3832
|
let capturedPrNumber: number | undefined;
|
|
3833
|
+
let prAttributionMismatch = false;
|
|
3763
3834
|
let openPrInvoked = false;
|
|
3764
3835
|
const defaultProviderName = opts.seams.currentProviderName?.() ?? currentProviderName();
|
|
3765
3836
|
const runProviderName = opts.childLlm?.provider ?? defaultProviderName;
|
|
@@ -3778,8 +3849,6 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3778
3849
|
openPrInvoked = true;
|
|
3779
3850
|
const pr = await opts.seams.openPr(args);
|
|
3780
3851
|
if (pr.rebind) debug.log('self-implement.same-cell', 'rebind-result', pr.rebind);
|
|
3781
|
-
const number = recordedPrNumber(pr.number);
|
|
3782
|
-
if (number !== undefined) capturedPrNumber = number;
|
|
3783
3852
|
return pr;
|
|
3784
3853
|
},
|
|
3785
3854
|
onProgress: (event) => {
|
|
@@ -4213,6 +4282,9 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
4213
4282
|
hasCurrentCredentialFailure,
|
|
4214
4283
|
(commit: string | undefined) => { finishedImplementationAtMainSync = true; preSyncCommit = commit; },
|
|
4215
4284
|
preserveMergeHarvest,
|
|
4285
|
+
startedAtMs,
|
|
4286
|
+
(number) => { capturedPrNumber = number; },
|
|
4287
|
+
() => { prAttributionMismatch = true; },
|
|
4216
4288
|
);
|
|
4217
4289
|
terminalNode = result.node;
|
|
4218
4290
|
await mergeChildProviderErrors();
|
|
@@ -4257,6 +4329,22 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
4257
4329
|
// ⛔ 이 스코프엔 `progress` 헬퍼가 «없다»(3695행 · 다른 스코프) — seam 을 직접 쓴다.
|
|
4258
4330
|
progress: (stage, message) => { try { opts.seams.onProgress?.({ stage, message }); } catch { /* best-effort */ } },
|
|
4259
4331
|
});
|
|
4332
|
+
if (addressedResult.abandonedClassification?.classification === 'report-deficit') {
|
|
4333
|
+
const classification = addressedResult.abandonedClassification;
|
|
4334
|
+
const basis = classification.classificationBasis;
|
|
4335
|
+
const kind = basis === 'terminal-state-not-reviewed' || basis === 'review-result-observation-unmeasured'
|
|
4336
|
+
? 'unmeasured' as const : 'unverified' as const;
|
|
4337
|
+
const previousEvidence = JSON.stringify({ classification, stage: addressedResult.stage,
|
|
4338
|
+
review: addressedResult.review ?? null, gate: addressedResult.gate ?? null });
|
|
4339
|
+
const deficit = { evidenceId: `report:${runId}:${basis}`, kind, previousEvidence, round: roundCount };
|
|
4340
|
+
observeOuter('supervisor-report-deficit', { ...deficit, supervisorResult: 'unverifiable', classification });
|
|
4341
|
+
if (deficit.kind !== 'unverified') {
|
|
4342
|
+
const move = repairNextMove({ supervisorDeficit: deficit, supervisorResult: 'unverifiable' });
|
|
4343
|
+
if (move.kind === 'grounding') observeOuter('repair-next-move-input', {
|
|
4344
|
+
...move.supervisorDeficit, supervisorResult: 'unverifiable', action: move.action, classification,
|
|
4345
|
+
});
|
|
4346
|
+
}
|
|
4347
|
+
}
|
|
4260
4348
|
observeRunOutcome(observeOuter, {
|
|
4261
4349
|
node: addressedResult.node,
|
|
4262
4350
|
stage: addressedResult.stage,
|
|
@@ -4294,7 +4382,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
4294
4382
|
...terminalDetail(addressedResult.sessionId),
|
|
4295
4383
|
},
|
|
4296
4384
|
});
|
|
4297
|
-
observeRunRollup(observeOuter, addressedResult, roundClassifications, roundCount, capturedPrNumber, openPrInvoked);
|
|
4385
|
+
observeRunRollup(observeOuter, prAttributionMismatch ? { ...addressedResult, prNumber: undefined } : addressedResult, roundClassifications, roundCount, capturedPrNumber, openPrInvoked);
|
|
4298
4386
|
observeProgressDelivery();
|
|
4299
4387
|
return terminalResult;
|
|
4300
4388
|
} catch (e) {
|
|
@@ -4369,7 +4457,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
4369
4457
|
...terminalDetail(addressedResult.sessionId ?? terminalSessionId),
|
|
4370
4458
|
},
|
|
4371
4459
|
});
|
|
4372
|
-
observeRunRollup(observeOuter, addressedResult, roundClassifications, roundCount, capturedPrNumber, openPrInvoked);
|
|
4460
|
+
observeRunRollup(observeOuter, prAttributionMismatch ? { ...addressedResult, prNumber: undefined } : addressedResult, roundClassifications, roundCount, capturedPrNumber, openPrInvoked);
|
|
4373
4461
|
observeProgressDelivery();
|
|
4374
4462
|
return terminalResult;
|
|
4375
4463
|
}
|
|
@@ -4394,6 +4482,50 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
4394
4482
|
} finally {
|
|
4395
4483
|
if (loopRegistered) registerRunLoop('ended');
|
|
4396
4484
|
const terminalStage = terminalResult?.stage ?? 'crashed';
|
|
4485
|
+
// A blocked draft may be opened on the first failed attempt, before the
|
|
4486
|
+
// normal outcome observer has written its terminal status. Persist the
|
|
4487
|
+
// actual terminal result before exposing harvest-deferred on that PR.
|
|
4488
|
+
const terminalOutcome = terminalResult ? mapStageToRunStatus(terminalStage) : undefined;
|
|
4489
|
+
if (terminalOutcome?.runStatus === 'failed'
|
|
4490
|
+
&& loadRunLedger(runId)?.filter((entry) => entry.event === 'run-status').at(-1)?.data.runStatus !== 'failed') {
|
|
4491
|
+
observeOuter('run-status', {
|
|
4492
|
+
stage: terminalStage, node: terminalResult?.node ?? null, ...terminalOutcome,
|
|
4493
|
+
...(terminalResult?.reviewReflectRejectedCount !== undefined
|
|
4494
|
+
? { reviewReflectRejectedCount: terminalResult.reviewReflectRejectedCount }
|
|
4495
|
+
: {}),
|
|
4496
|
+
}, { level: 'warn' });
|
|
4497
|
+
}
|
|
4498
|
+
try {
|
|
4499
|
+
const runStatus = terminalOutcome?.runStatus;
|
|
4500
|
+
const prNumber = recordedPrNumber(terminalResult?.prNumber) ?? capturedPrNumber;
|
|
4501
|
+
// openPr is required on every seam (including production); it cannot
|
|
4502
|
+
// distinguish test PRs from real ones. The production adapter explicitly
|
|
4503
|
+
// supplies both body operations. A test replacing openPr without both
|
|
4504
|
+
// body operations must fail closed instead of touching a real PR.
|
|
4505
|
+
const readPrBody = opts.seams.readPrBodyForHarvest;
|
|
4506
|
+
const updatePrBody = opts.seams.updatePrBodyForHarvest;
|
|
4507
|
+
// The terminal observer must have persisted this run's failure before a
|
|
4508
|
+
// draft can advertise harvest deferral. Even an injected writer must
|
|
4509
|
+
// leave a matching record in the canonical ledger before mutation.
|
|
4510
|
+
const lastPersistedStatus = loadRunLedger(runId)?.filter((entry) => entry.event === 'run-status').at(-1)?.data.runStatus;
|
|
4511
|
+
const persistedFailure = runStatus === 'failed' && lastPersistedStatus === 'failed';
|
|
4512
|
+
if (persistedFailure && prNumber !== undefined && readPrBody && updatePrBody) {
|
|
4513
|
+
const existing = await readPrBody({ number: prNumber, cwd: worktreePath ?? process.cwd() });
|
|
4514
|
+
if (existing?.state === 'OPEN' && existing.isDraft === true) {
|
|
4515
|
+
const markedBody = markHarvestDeferredBody({ runStatus, prNumber, body: existing.body });
|
|
4516
|
+
if (markedBody !== undefined && markedBody !== existing.body) {
|
|
4517
|
+
await updatePrBody({ number: prNumber, body: markedBody, cwd: worktreePath ?? process.cwd() });
|
|
4518
|
+
observeOuter('harvest-deferred', { runStatus, prNumber, marker: HARVEST_DEFERRED_MARKER });
|
|
4519
|
+
}
|
|
4520
|
+
} else {
|
|
4521
|
+
observeOuter('harvest-deferred-skipped', { runStatus, prNumber, reason: 'existing-draft-not-confirmed' }, { level: 'warn' });
|
|
4522
|
+
}
|
|
4523
|
+
} else {
|
|
4524
|
+
observeOuter('harvest-deferred-skipped', { runStatus: runStatus ?? null, prNumber: prNumber ?? null, reason: 'status-pr-body-seam-unavailable' }, { level: 'warn' });
|
|
4525
|
+
}
|
|
4526
|
+
} catch (error) {
|
|
4527
|
+
logRunAwareFailSoft(runId, 'harvest-deferred-failed', { error: safeErrorDescription(error) });
|
|
4528
|
+
}
|
|
4397
4529
|
try {
|
|
4398
4530
|
const mappedStatus = mapStageToRunStatus(terminalStage)?.runStatus;
|
|
4399
4531
|
const reworkCapStop = terminalResult?.stage === 'pr-opened' && (
|
|
@@ -4741,7 +4873,26 @@ export function observeRunOutcome(
|
|
|
4741
4873
|
type RollupPrNumber = number | 'none' | 'unknown';
|
|
4742
4874
|
|
|
4743
4875
|
function recordedPrNumber(value: unknown): number | undefined {
|
|
4744
|
-
return typeof value === 'number' && Number.
|
|
4876
|
+
return typeof value === 'number' && Number.isSafeInteger(value) && value > 0 ? value : undefined;
|
|
4877
|
+
}
|
|
4878
|
+
|
|
4879
|
+
/** GitHub's second-precision createdAt cannot distinguish events within that second. */
|
|
4880
|
+
export function prCreatedInRunWindow(createdAt: string, startedAtMs: number): boolean {
|
|
4881
|
+
const createdAtMs = Date.parse(createdAt);
|
|
4882
|
+
if (!Number.isFinite(createdAtMs) || !Number.isFinite(startedAtMs)) return false;
|
|
4883
|
+
const secondPrecision = !/\.\d+(?:Z|[+-]\d\d:\d\d)$/.test(createdAt);
|
|
4884
|
+
return createdAtMs >= (secondPrecision ? Math.floor(startedAtMs / 1_000) * 1_000 : startedAtMs);
|
|
4885
|
+
}
|
|
4886
|
+
|
|
4887
|
+
function prAttributedToRun(
|
|
4888
|
+
attribution: { headRefName: string; createdAt: string }, branch: string, startedAtMs: number,
|
|
4889
|
+
boundCardReuse: { headRefName: string } | undefined,
|
|
4890
|
+
): boolean {
|
|
4891
|
+
if (attribution.headRefName !== (boundCardReuse?.headRefName ?? branch)) return false;
|
|
4892
|
+
// A verified same-card PR predates this run. The production seam exposes the
|
|
4893
|
+
// exception only after the manager verifies card, PR identity, and leased push.
|
|
4894
|
+
return prCreatedInRunWindow(attribution.createdAt, startedAtMs)
|
|
4895
|
+
|| (!!boundCardReuse && Number.isFinite(Date.parse(attribution.createdAt)));
|
|
4745
4896
|
}
|
|
4746
4897
|
|
|
4747
4898
|
function rollupPrNumber(
|
|
@@ -4839,6 +4990,9 @@ async function runSelfImplementInner(
|
|
|
4839
4990
|
hasCurrentCredentialFailure: () => boolean = hasCredentialFailure,
|
|
4840
4991
|
onMainSyncStarted: (commit: string | undefined) => void = () => {},
|
|
4841
4992
|
preserveMergeHarvest: (reason: string, inputChars?: number) => Promise<boolean> = async () => false,
|
|
4993
|
+
startedAtMs = Date.now(),
|
|
4994
|
+
onPrAttributed: (number: number) => void = () => {},
|
|
4995
|
+
onPrAttributionMismatch: () => void = () => {},
|
|
4842
4996
|
): Promise<Omit<SelfImplementResult, 'runId'>> {
|
|
4843
4997
|
const s = opts.seams;
|
|
4844
4998
|
const pipelineStartedAtMs = Date.now();
|
|
@@ -4869,7 +5023,7 @@ async function runSelfImplementInner(
|
|
|
4869
5023
|
const { graphVersionHash } = await import('./graph-yaml.js');
|
|
4870
5024
|
const { applyGraphOverlays } = await import('./graph-overlay-yaml.js');
|
|
4871
5025
|
const { createGraphVariant } = await import('./graph-variant.js');
|
|
4872
|
-
const {
|
|
5026
|
+
const { saveRunGraphVariant, loadRunGraphVariant } = await import('./run-ledger.js');
|
|
4873
5027
|
const { stringify } = await import('yaml');
|
|
4874
5028
|
const baseSpec = GRAPH_SPECS[graphTemplate.graphId];
|
|
4875
5029
|
const variantRunId = identity?.runId ?? opts.runId;
|
|
@@ -4881,16 +5035,16 @@ async function runSelfImplementInner(
|
|
|
4881
5035
|
: undefined;
|
|
4882
5036
|
if (launch && !launch.ok) throw new Error(`graph variant rejected: ${JSON.stringify(launch.rejections)}`);
|
|
4883
5037
|
const sourceSpec = launch?.ok ? launch.template : baseSpec;
|
|
4884
|
-
|
|
5038
|
+
// ⭐ 최초 변형 선택 — 골 종류(graphGoalType)·대상 경로 수(declaredPremiseScopePaths) 두 입력만으로
|
|
5039
|
+
// 결정론적으로 id·선택 이유를 유도해 검증 결과에 싣는다(종류를 못 읽었으면 지어내지 않는다).
|
|
5040
|
+
const variant = createGraphVariant({ template: sourceSpec, goal: `g_${variantRunId.replace(/[^a-z0-9_-]/gi, '_')}`, plan: opts.graphVariantPlan,
|
|
5041
|
+
...(graphGoalType === undefined ? {} : { goalAnalysis: { goalType: graphGoalType, targetPathCount: declaredPremiseScopePaths(opts.feature).length } }) });
|
|
4885
5042
|
if (!variant.ok) throw new Error(`graph variant rejected: ${JSON.stringify(variant.rejections)}`);
|
|
4886
5043
|
variantSpec = variant.template;
|
|
4887
5044
|
graphTemplate = { ...specToTemplate(variantSpec), version: graphVersionHash(variantSpec) };
|
|
4888
|
-
const
|
|
4889
|
-
const graphFile = `${runLedgerPath(variantRunId)}.graph.yaml`;
|
|
4890
|
-
mkdirSync(runLedgerDir(), { recursive: true });
|
|
4891
|
-
const { writeFileSync } = await import('node:fs');
|
|
4892
|
-
writeFileSync(graphFile, stringify({
|
|
5045
|
+
const graphFile = saveRunGraphVariant(variantRunId, stringify({
|
|
4893
5046
|
graph_id: variantSpec.graphId, version: variantSpec.version,
|
|
5047
|
+
...(variant.selection === undefined ? {} : { variant_id: variant.selection.variantId, reason: variant.selection.reason }),
|
|
4894
5048
|
entry_node: variantSpec.entryNode, terminal_nodes: variantSpec.terminalNodes,
|
|
4895
5049
|
...(variantSpec.journeyStages ? { journey_stages: variantSpec.journeyStages } : {}),
|
|
4896
5050
|
...(variantSpec.runContract ? { run_contract: variantSpec.runContract } : {}),
|
|
@@ -4900,6 +5054,9 @@ async function runSelfImplementInner(
|
|
|
4900
5054
|
...(n.progress ? { progress: n.progress } : {}), ...(n.phases ? { phases: n.phases } : {}),
|
|
4901
5055
|
...(n.terminalStages ? { terminal_stages: n.terminalStages } : {}),
|
|
4902
5056
|
...(n.fanOut ? { fan_out: n.fanOut } : {}), ...(n.contract ? { contract: n.contract } : {}),
|
|
5057
|
+
...(n.call ? { call: n.call } : {}),
|
|
5058
|
+
...(n.callEntry ? { call_entry: n.callEntry } : {}),
|
|
5059
|
+
...(n.budget ? { budget: { inner_steps: n.budget.innerSteps } } : {}),
|
|
4903
5060
|
...(n.skipWhen ? { skip_when: n.skipWhen } : {}),
|
|
4904
5061
|
})),
|
|
4905
5062
|
edges: variantSpec.edges.map(e => ({
|
|
@@ -4908,9 +5065,17 @@ async function runSelfImplementInner(
|
|
|
4908
5065
|
...(e.observed === undefined ? {} : { observed: e.observed }),
|
|
4909
5066
|
...(e.when ? { when: e.when } : {}),
|
|
4910
5067
|
})),
|
|
4911
|
-
})
|
|
5068
|
+
}));
|
|
5069
|
+
// ⭐ 저장·diff — 방금 원장 옆에 쓴 선택(id·이유)을 다시 읽어 «같은지» 확인한다(다르면 이 런의 그래프 신원이 거짓).
|
|
5070
|
+
if (variant.selection !== undefined) {
|
|
5071
|
+
const persisted = loadRunGraphVariant(variantRunId);
|
|
5072
|
+
if (persisted === null || persisted.variantId !== variant.selection.variantId || persisted.reason !== variant.selection.reason) {
|
|
5073
|
+
throw new Error(`graph variant rejected: persisted selection mismatch: ${JSON.stringify(persisted)}`);
|
|
5074
|
+
}
|
|
5075
|
+
}
|
|
4912
5076
|
observe('graph-variant-applied', { graphId: variant.template.graphId, overlayId: variant.overlay.overlayId,
|
|
4913
|
-
graphFile, patches: variant.patches
|
|
5077
|
+
graphFile, patches: variant.patches,
|
|
5078
|
+
...(variant.selection === undefined ? {} : { variantId: variant.selection.variantId, variantReason: variant.selection.reason }) });
|
|
4914
5079
|
}
|
|
4915
5080
|
/** 단계 이름 → 그 템플릿의 노드 이름. */
|
|
4916
5081
|
const node = (stage: PipelineNodeId): PipelineNodeId => nodeNameForStage(stage, graphTemplate) as PipelineNodeId;
|
|
@@ -5017,14 +5182,22 @@ async function runSelfImplementInner(
|
|
|
5017
5182
|
: opts.goalFile
|
|
5018
5183
|
? 'authored-goal-file'
|
|
5019
5184
|
: 'no-goal-file';
|
|
5020
|
-
let activeProvider:
|
|
5021
|
-
provider: 'unknown'; model: 'unknown'; auth: 'unknown';
|
|
5022
|
-
};
|
|
5185
|
+
let activeProvider: { provider: string; model: string; auth: string };
|
|
5023
5186
|
try {
|
|
5024
5187
|
activeProvider = (s.inspectActiveProvider ?? inspectActiveProvider)();
|
|
5025
5188
|
} catch {
|
|
5026
5189
|
activeProvider = { provider: 'unknown', model: 'unknown', auth: 'unknown' };
|
|
5027
5190
|
}
|
|
5191
|
+
const configuredProvider = activeProvider;
|
|
5192
|
+
if (opts.childLlm) {
|
|
5193
|
+
// The configured parent model can be sol while this run's implementation child is
|
|
5194
|
+
// explicitly luna. Attribute the run to the model actually passed to implement.
|
|
5195
|
+
activeProvider = {
|
|
5196
|
+
provider: opts.childLlm.provider,
|
|
5197
|
+
model: opts.childLlm.model,
|
|
5198
|
+
auth: configuredProvider.provider?.replace(/^auto:/, '') === opts.childLlm.provider ? configuredProvider.auth : 'unknown',
|
|
5199
|
+
};
|
|
5200
|
+
}
|
|
5028
5201
|
// ⭐ 관측 이벤트와 «같은 값»을 원장으로도 보낸다 — 로그에만 있으면 원장 질의가 못 센다(`F12`).
|
|
5029
5202
|
try { onActiveProvider(activeProvider); } catch { /* 보조 기록이 런을 죽이지 않는다 */ }
|
|
5030
5203
|
const boundedFeature = boundReadableText(opts.feature, RUN_START_FEATURE_MAX_CHARS);
|
|
@@ -5038,6 +5211,7 @@ async function runSelfImplementInner(
|
|
|
5038
5211
|
nestDepth: nestInfo().depth, goalSource, goalFile: opts.goalFile === undefined ? null : resolve(launchCwd, opts.goalFile),
|
|
5039
5212
|
targetRoot: gitRootOf(launchCwd) ?? launchCwd, ...originObservationFields(),
|
|
5040
5213
|
provider: activeProvider.provider ?? null, model: activeProvider.model ?? null, auth: activeProvider.auth ?? null,
|
|
5214
|
+
...(opts.childLlm ? { configuredProvider: configuredProvider.provider ?? null, configuredModel: configuredProvider.model ?? null, modelSelectionSource: 'child' } : {}),
|
|
5041
5215
|
...(opts.correlationId !== undefined ? { correlationId: opts.correlationId } : {}),
|
|
5042
5216
|
});
|
|
5043
5217
|
try {
|
|
@@ -5091,6 +5265,14 @@ async function runSelfImplementInner(
|
|
|
5091
5265
|
...goalContext,
|
|
5092
5266
|
}), T.worktree, 'worktree');
|
|
5093
5267
|
onWorktreeCreated(wt.path);
|
|
5268
|
+
// Capture the child worktree's HEAD at creation. `wt.invokedHead` names the
|
|
5269
|
+
// caller checkout and may differ after base selection or PR-source checkout.
|
|
5270
|
+
const terminalLaunchHeadRead = runGitCommand(wt.path, ['rev-parse', '--verify', 'HEAD'], { encoding: 'utf8', timeout: 10_000 });
|
|
5271
|
+
const terminalLaunchHeadCandidate = terminalLaunchHeadRead.status === 0 ? terminalLaunchHeadRead.stdout.trim() : '';
|
|
5272
|
+
const terminalLaunchHead = /^[0-9a-f]{40,64}$/i.test(terminalLaunchHeadCandidate) ? terminalLaunchHeadCandidate : undefined;
|
|
5273
|
+
const terminalLaunchWork = detectUncommittedWork(wt.path);
|
|
5274
|
+
const terminalLaunchDirtyPaths = terminalLaunchWork.status === 'unavailable' ? undefined
|
|
5275
|
+
: new Set([...terminalLaunchWork.trackedChanges, ...terminalLaunchWork.untrackedFiles]);
|
|
5094
5276
|
// ⭐ 제1원칙 — **어디서 갈랐나**를 관측에 남긴다. 이것이 없어서 2026-07-29 에 하니스 런 둘이
|
|
5095
5277
|
// `main` 위에서 돌았고(호출자가 브랜치 워크트리에서 발사했는데도) 산출 diff 를 눈으로 봐야 알았다.
|
|
5096
5278
|
// ⚠️ `branch` 는 **새로 만든 브랜치 이름**이라 그 질문에 답하지 않는다.
|
|
@@ -5104,6 +5286,8 @@ async function runSelfImplementInner(
|
|
|
5104
5286
|
observe('worktree', {
|
|
5105
5287
|
path: wt.path,
|
|
5106
5288
|
branch: wt.branch,
|
|
5289
|
+
terminalLaunchHead: terminalLaunchHead ?? null,
|
|
5290
|
+
terminalLaunchDirtyPaths: terminalLaunchDirtyPaths ? [...terminalLaunchDirtyPaths] : null,
|
|
5107
5291
|
// ⭐ 우리가 **무엇을 요청했는지는 이미 안다** — 시임 반환에서 되읽지 않는다.
|
|
5108
5292
|
// 커스텀 시임이 관측 필드를 생략하면 명시/생략이 둘 다 null 이 되어 구분이 사라진다(리뷰 must-fix).
|
|
5109
5293
|
requestedBase,
|
|
@@ -5635,6 +5819,9 @@ async function runSelfImplementInner(
|
|
|
5635
5819
|
};
|
|
5636
5820
|
}
|
|
5637
5821
|
let round = 0;
|
|
5822
|
+
// A timeout is evidence about this command, not an invitation to spend the
|
|
5823
|
+
// next rework round on the identical oversized check.
|
|
5824
|
+
const runBudgetedEvidenceChecks = createRequiredEvidenceBudget({ run: s.evidenceCommandRunner });
|
|
5638
5825
|
// A goal-only retry spends its one allowance for this run even if a later
|
|
5639
5826
|
// gate/review round removes the target diff and reaches the same disposition.
|
|
5640
5827
|
let goalOnlyReworkUsed = false;
|
|
@@ -6121,7 +6308,7 @@ async function runSelfImplementInner(
|
|
|
6121
6308
|
return preserveReviewBlockedBranch(`review-blocked 작업 커밋 실패: ${commitError}`, false, `; 미커밋 작업은 worktree 에 남음: ${wt.path}`);
|
|
6122
6309
|
}
|
|
6123
6310
|
}
|
|
6124
|
-
let pr:
|
|
6311
|
+
let pr: OpenPrOutcome;
|
|
6125
6312
|
try {
|
|
6126
6313
|
pr = await withStepTimeout(s.openPr({
|
|
6127
6314
|
title: prTitle(opts.feature, opts.goalFile),
|
|
@@ -6172,6 +6359,48 @@ async function runSelfImplementInner(
|
|
|
6172
6359
|
: `중단 산출물의 draft PR 생성 실패(worktree·branch 보존 · 판정 본문 보존 실패: ${artifactError ?? 'unknown error'})`);
|
|
6173
6360
|
return undefined;
|
|
6174
6361
|
}
|
|
6362
|
+
let draftAttribution: { headRefName: string; createdAt: string } | undefined;
|
|
6363
|
+
let draftAttributionReadError: string | undefined;
|
|
6364
|
+
try {
|
|
6365
|
+
if (s.readPrAttribution) {
|
|
6366
|
+
draftAttribution = await s.readPrAttribution({ number: pr.number, cwd: wt.path });
|
|
6367
|
+
} else {
|
|
6368
|
+
const viewed = spawnSync('gh', ['pr', 'view', String(pr.number), '--json', 'headRefName,createdAt'], { cwd: wt.path, encoding: 'utf8', timeout: 30_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
|
|
6369
|
+
if (viewed.status !== 0) throw new Error('gh pr view failed');
|
|
6370
|
+
const parsed = JSON.parse(viewed.stdout) as { headRefName?: unknown; createdAt?: unknown };
|
|
6371
|
+
if (typeof parsed.headRefName !== 'string' || typeof parsed.createdAt !== 'string') throw new Error('invalid PR attribution metadata');
|
|
6372
|
+
draftAttribution = { headRefName: parsed.headRefName, createdAt: parsed.createdAt };
|
|
6373
|
+
}
|
|
6374
|
+
} catch (error) { draftAttributionReadError = safeErrorDescription(error); }
|
|
6375
|
+
const expectedPrHead = pr.boundCardReuse?.headRefName ?? wt.branch;
|
|
6376
|
+
const draftAttributed = !draftAttributionReadError && !!draftAttribution
|
|
6377
|
+
&& prAttributedToRun(draftAttribution, wt.branch, startedAtMs, pr.boundCardReuse);
|
|
6378
|
+
if (draftAttributionReadError || !draftAttribution) {
|
|
6379
|
+
onPrAttributionMismatch();
|
|
6380
|
+
observe('pr-attribution-unverified', {
|
|
6381
|
+
expectedBranch: expectedPrHead,
|
|
6382
|
+
number: pr.number,
|
|
6383
|
+
url: pr.url,
|
|
6384
|
+
reason: draftAttributionReadError ?? 'metadata-absent',
|
|
6385
|
+
}, { level: 'warn' });
|
|
6386
|
+
} else if (draftAttributed) {
|
|
6387
|
+
onPrAttributed(pr.number);
|
|
6388
|
+
observe('pr-opened', { url: pr.url, number: pr.number, branch: expectedPrHead, draft: true });
|
|
6389
|
+
} else {
|
|
6390
|
+
onPrAttributionMismatch();
|
|
6391
|
+
observe('pr-attribution-mismatch', {
|
|
6392
|
+
expectedBranch: expectedPrHead,
|
|
6393
|
+
actualBranch: draftAttribution?.headRefName ?? null,
|
|
6394
|
+
createdAt: draftAttribution?.createdAt ?? null,
|
|
6395
|
+
number: pr.number,
|
|
6396
|
+
url: pr.url,
|
|
6397
|
+
}, { level: 'warn' });
|
|
6398
|
+
}
|
|
6399
|
+
if (!draftAttributed) {
|
|
6400
|
+
blockedDraftPrFailure = `draft PR 귀속 확인 실패; worktree·branch 보존: ${wt.branch} (${wt.path})`;
|
|
6401
|
+
progress('aborted', blockedDraftPrFailure);
|
|
6402
|
+
return undefined;
|
|
6403
|
+
}
|
|
6175
6404
|
observe('rework-blocked-draft-pr', {
|
|
6176
6405
|
...observation,
|
|
6177
6406
|
url: pr.url,
|
|
@@ -6389,6 +6618,19 @@ async function runSelfImplementInner(
|
|
|
6389
6618
|
return 'parked';
|
|
6390
6619
|
}
|
|
6391
6620
|
};
|
|
6621
|
+
let pendingReviewTriage: {
|
|
6622
|
+
round: number;
|
|
6623
|
+
verdict: 'fail';
|
|
6624
|
+
rawMustFix: string[];
|
|
6625
|
+
reflectedMustFix: string[];
|
|
6626
|
+
reflectionApplied: boolean;
|
|
6627
|
+
effectiveMax: number;
|
|
6628
|
+
} | undefined;
|
|
6629
|
+
const recordPendingReviewTriage = (decision: ReviewRoundDecision, nextNode: 'open-pr' | 'rework' | 'review-blocked', effectiveMax: number): void => {
|
|
6630
|
+
if (!pendingReviewTriage) return;
|
|
6631
|
+
observe('review-round-triage', { ...pendingReviewTriage, decision, nextNode, effectiveMax });
|
|
6632
|
+
pendingReviewTriage = undefined;
|
|
6633
|
+
};
|
|
6392
6634
|
for (;;) {
|
|
6393
6635
|
if (round > 0) {
|
|
6394
6636
|
const stoppedBeforeRework = honorParentSoftStop('rework');
|
|
@@ -6441,7 +6683,7 @@ async function runSelfImplementInner(
|
|
|
6441
6683
|
const predictionAccuracyBefore = supervisorDecisionHistory.length
|
|
6442
6684
|
? judgePredictionAccuracy(supervisorDecisionHistory)
|
|
6443
6685
|
: undefined;
|
|
6444
|
-
diagnosis = await withStepTimeout(s.diagnose({ runId, note: reworkJudgeNote, kind: reworkKind, round, cwd: wt.path, goal:
|
|
6686
|
+
diagnosis = await withStepTimeout(s.diagnose({ runId, note: reworkJudgeNote, kind: reworkKind, round, cwd: wt.path, goal: roundGoal, history: priorHistory, supervisorDecisionHistory, ...(predictionAccuracyBefore ? { judgePredictionAccuracy: predictionAccuracyBefore } : {}), effectiveMax, priorRuns, reviewFindingTelemetry: reviewFindingTelemetrySnapshot, ...(diagnosisRefutations ? { refutations: diagnosisRefutations.refutations, refutationRound: diagnosisRefutations.round } : {}), purpose: 'budget' }), T.review, 'review');
|
|
6445
6687
|
const diagnosedDecision = parseReworkBudgetDecision(diagnosis);
|
|
6446
6688
|
if (diagnosedDecision?.verdict === 'CONTRACT-CONFLICT') lastSupervisorVerdict = diagnosedDecision.verdict;
|
|
6447
6689
|
let parsedDecision = diagnosedDecision;
|
|
@@ -6546,6 +6788,17 @@ async function runSelfImplementInner(
|
|
|
6546
6788
|
});
|
|
6547
6789
|
}
|
|
6548
6790
|
effectiveMax = budgetDecision.effectiveMax;
|
|
6791
|
+
if (pendingReviewTriage && budgetDecision.stop) {
|
|
6792
|
+
recordPendingReviewTriage('follow-up', budgetDecision.exit === 'proceed' ? 'open-pr' : 'review-blocked', effectiveMax);
|
|
6793
|
+
} else if (pendingReviewTriage && round <= effectiveMax) {
|
|
6794
|
+
const extendedDecision = decideReviewRound({
|
|
6795
|
+
verdict: pendingReviewTriage.verdict,
|
|
6796
|
+
mustFix: pendingReviewTriage.reflectedMustFix,
|
|
6797
|
+
round: pendingReviewTriage.round,
|
|
6798
|
+
effectiveMax,
|
|
6799
|
+
});
|
|
6800
|
+
if (extendedDecision === 'rework') recordPendingReviewTriage('rework', 'rework', effectiveMax);
|
|
6801
|
+
}
|
|
6549
6802
|
if (parsedDecision) {
|
|
6550
6803
|
if (diagnosisRefutations) {
|
|
6551
6804
|
const adjudications = parseSupervisorRefutationAdjudications(diagnosis, diagnosisRefutations.refutations);
|
|
@@ -6754,6 +7007,7 @@ async function runSelfImplementInner(
|
|
|
6754
7007
|
: 'UNCONVERGEABLE' as const;
|
|
6755
7008
|
const supervisorOutcome = { supervisorVerdict, ...(goalCauseObserved ? { goalCauseObserved: true as const } : {}) };
|
|
6756
7009
|
if (isReviewRework(reworkKind)) {
|
|
7010
|
+
recordPendingReviewTriage('follow-up', 'review-blocked', effectiveMax);
|
|
6757
7011
|
if (reflectRejectedAudit.length && review) review.shouldFix = [...review.shouldFix, ...reflectRejectedAudit];
|
|
6758
7012
|
const pr = await preserveBlockedArtifacts({ stage: 'review-blocked', verdict: parsedDecision.verdict, reason: parsedDecision.reason, gate, decomposition: terminalDecomposition, salvageStatusExpected: false });
|
|
6759
7013
|
await draftFollowUpAfterBlocked({ runId, prNumber: pr?.number, stage: 'review-blocked', unresolvedMustFix: review?.mustFix, decompositionPieces: terminalDecomposition?.pieces?.map((p) => p.feature), feature: opts.feature, cellId: opts.goalId, goalFile: opts.goalFile }, s.followUp);
|
|
@@ -6785,6 +7039,7 @@ async function runSelfImplementInner(
|
|
|
6785
7039
|
const terminal = resolveRunOutcome({ termination: 'supervisor-abandoned', verdict: 'UNCONVERGEABLE', applied: true });
|
|
6786
7040
|
const reason = `rework judged unconvergeable after ${round - 1} rework round(s)`;
|
|
6787
7041
|
if (isReviewRework(reworkKind)) {
|
|
7042
|
+
recordPendingReviewTriage('follow-up', 'review-blocked', effectiveMax);
|
|
6788
7043
|
if (reflectRejectedAudit.length && review) review.shouldFix = [...review.shouldFix, ...reflectRejectedAudit];
|
|
6789
7044
|
const pr = await preserveBlockedArtifacts({ stage: 'review-blocked', verdict: lastReworkVerdict, reason, gate, salvageStatusExpected: false });
|
|
6790
7045
|
await draftFollowUpAfterBlocked({ runId, prNumber: pr?.number, stage: 'review-blocked', unresolvedMustFix: review?.mustFix, feature: opts.feature, cellId: opts.goalId, goalFile: opts.goalFile }, s.followUp);
|
|
@@ -6828,6 +7083,7 @@ async function runSelfImplementInner(
|
|
|
6828
7083
|
);
|
|
6829
7084
|
podDecision(acceptance.decision.action === 'accept');
|
|
6830
7085
|
if (acceptance.decision.action === 'accept') {
|
|
7086
|
+
recordPendingReviewTriage('follow-up', 'open-pr', effectiveMax);
|
|
6831
7087
|
if (podReviewBlockedDraft) {
|
|
6832
7088
|
observe('merge-decision', {
|
|
6833
7089
|
autoMerge: autoMergeEnabled(opts), reviewed: review?.reviewed === true, verdict: review?.verdict ?? 'none',
|
|
@@ -6866,6 +7122,7 @@ async function runSelfImplementInner(
|
|
|
6866
7122
|
};
|
|
6867
7123
|
}
|
|
6868
7124
|
} else podDecision(false);
|
|
7125
|
+
recordPendingReviewTriage('follow-up', 'review-blocked', effectiveMax);
|
|
6869
7126
|
const pr = await preserveBlockedArtifacts({ stage: 'review-blocked', reason, gate, salvageStatusExpected: true });
|
|
6870
7127
|
const salvage = blockedDraftNoChanges || blockedDraftPrFailure ? 'parked' : await salvageHardCap(canSalvage, pr);
|
|
6871
7128
|
const disposition = { ...terminal, ...(salvage ? { salvage } : {}) };
|
|
@@ -6885,7 +7142,7 @@ async function runSelfImplementInner(
|
|
|
6885
7142
|
if (escalationEligible && s.diagnose) {
|
|
6886
7143
|
try {
|
|
6887
7144
|
escalationJudgement = await withStepTimeout(s.diagnose({
|
|
6888
|
-
runId, note: reworkNote, kind: reworkKind, round, cwd: wt.path, goal:
|
|
7145
|
+
runId, note: reworkNote, kind: reworkKind, round, cwd: wt.path, goal: roundGoal,
|
|
6889
7146
|
history: reworkHistory.slice(0, -1), supervisorDecisionHistory, effectiveMax,
|
|
6890
7147
|
purpose: 'escalation-triage',
|
|
6891
7148
|
}), T.review, 'review');
|
|
@@ -6906,7 +7163,9 @@ async function runSelfImplementInner(
|
|
|
6906
7163
|
const firstRound = roundSummaryEntries.at(-1);
|
|
6907
7164
|
const refined = await (await import('./goal-refine.js')).runFirstRoundRefine({
|
|
6908
7165
|
goal: opts.feature, round, visit: goalRefineVisits, callLLM: s.elaborateCallLLM, observe,
|
|
6909
|
-
|
|
7166
|
+
// SCOPE-ESCAPE-AS-REFINE — accepted out-of-scope edits are the «new scope» the first implementation found.
|
|
7167
|
+
evidence: { implSummary: firstRound?.tried, findings: reworkNote, changedFiles: firstRound?.filesTouched,
|
|
7168
|
+
...(scopeExpansion?.files.length ? { newScope: scopeExpansion.files.map((file) => file.path) } : {}) },
|
|
6910
7169
|
});
|
|
6911
7170
|
roundGoal = refined.goal;
|
|
6912
7171
|
// PR «골 변경» 절 — 유지(kept · no-provider 포함)여도 «시도 · v1 유지 · 사유» 한 줄을 싣는다(리뷰 r2).
|
|
@@ -7136,6 +7395,45 @@ async function runSelfImplementInner(
|
|
|
7136
7395
|
}
|
|
7137
7396
|
}
|
|
7138
7397
|
}
|
|
7398
|
+
// The child can report changed=false after committing its edits. Compare
|
|
7399
|
+
// against the worktree HEAD captured at creation, not the caller's HEAD or
|
|
7400
|
+
// origin/main: a PR source already had a diff before the child ran.
|
|
7401
|
+
if (!impl.ok && impl.completionDisposition === 'completed-without-changes'
|
|
7402
|
+
&& impl.terminalStatus?.reached === true && impl.terminalStatus.timedOut === false
|
|
7403
|
+
&& !hasCurrentProviderError() && !hasCurrentCredentialFailure()) {
|
|
7404
|
+
const committed = terminalLaunchHead
|
|
7405
|
+
? runGitCommand(wt.path, ['diff', '--name-only', '-z', terminalLaunchHead, 'HEAD'], { encoding: 'utf8', timeout: 10_000 })
|
|
7406
|
+
: undefined;
|
|
7407
|
+
const pending = detectUncommittedWork(wt.path);
|
|
7408
|
+
const observedFiles = committed?.status === 0 && pending.status !== 'unavailable'
|
|
7409
|
+
? [...new Set([
|
|
7410
|
+
...committed.stdout.split('\0').filter(Boolean),
|
|
7411
|
+
...pending.trackedChanges, ...pending.untrackedFiles,
|
|
7412
|
+
])]
|
|
7413
|
+
: [];
|
|
7414
|
+
if (!terminalLaunchHead || terminalLaunchDirtyPaths === undefined || committed?.status !== 0 || pending.status === 'unavailable') {
|
|
7415
|
+
observe('terminal-change-evidence', { round, status: 'unmeasured',
|
|
7416
|
+
reason: !terminalLaunchHead ? 'launch-head-unavailable' : terminalLaunchDirtyPaths === undefined
|
|
7417
|
+
? 'launch-status-unavailable' : committed?.status !== 0 ? 'git-diff-unavailable' : 'git-status-unavailable' }, { level: 'warn' });
|
|
7418
|
+
}
|
|
7419
|
+
// A PR-source worktree may be dirty before this child starts. A path
|
|
7420
|
+
// already dirty at launch cannot prove this child's edits from names
|
|
7421
|
+
// alone, even if the child later commits it. Leave that path unmeasured.
|
|
7422
|
+
const implementationFiles = terminalLaunchDirtyPaths === undefined ? [] : observedFiles.filter(path =>
|
|
7423
|
+
!terminalLaunchDirtyPaths.has(path) && !harnessSeededPaths.includes(path) && !isHarnessTempArtifact(path));
|
|
7424
|
+
const preexistingDirtyPaths = terminalLaunchDirtyPaths === undefined ? [] : observedFiles.filter(path =>
|
|
7425
|
+
terminalLaunchDirtyPaths.has(path) && !harnessSeededPaths.includes(path) && !isHarnessTempArtifact(path));
|
|
7426
|
+
if (preexistingDirtyPaths.length > 0) observe('terminal-change-evidence', {
|
|
7427
|
+
round, status: 'unmeasured', reason: 'preexisting-dirty-path', paths: preexistingDirtyPaths,
|
|
7428
|
+
}, { level: 'warn' });
|
|
7429
|
+
if (implementationFiles.length > 0) {
|
|
7430
|
+
observe('terminal-change-reconciled', {
|
|
7431
|
+
round, source: 'post-launch-git-diff', launchHead: terminalLaunchHead, childDisposition: impl.completionDisposition,
|
|
7432
|
+
paths: implementationFiles, pathCount: implementationFiles.length,
|
|
7433
|
+
});
|
|
7434
|
+
impl = { ...impl, ok: true, completionDisposition: undefined };
|
|
7435
|
+
}
|
|
7436
|
+
}
|
|
7139
7437
|
// A finished child can leave edits without a commit. Measure them before any
|
|
7140
7438
|
// diff/no-changes classification, and commit only paths declared in the goal.
|
|
7141
7439
|
finishedChildCommitMissing = false;
|
|
@@ -7184,7 +7482,7 @@ async function runSelfImplementInner(
|
|
|
7184
7482
|
env.GIT_COMMITTER_NAME = childName;
|
|
7185
7483
|
env.GIT_COMMITTER_EMAIL = childEmail;
|
|
7186
7484
|
const git = (args: string[]) => spawnSync('git', ['--no-optional-locks', ...args], {
|
|
7187
|
-
cwd, env, encoding: 'utf8', timeout: 20_000,
|
|
7485
|
+
cwd, env, encoding: 'utf8', timeout: 20_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER,
|
|
7188
7486
|
});
|
|
7189
7487
|
const staged = git(['add', '-A', '--', ...paths]);
|
|
7190
7488
|
if (staged.status !== 0) return { ok: false, out: staged.stderr || staged.stdout || staged.error?.message || 'git add failed' };
|
|
@@ -7241,7 +7539,13 @@ async function runSelfImplementInner(
|
|
|
7241
7539
|
// E3 — refine 뒤 라운드는 «현재 골»(v2)로 증거를 센다(REQUIRED EVIDENCE 절은 고정 칸이라 v1 과 같다).
|
|
7242
7540
|
const requiredEvidence = requiredEvidenceFromGoal(roundGoal);
|
|
7243
7541
|
const limitationCount = authorLimitationCountFromGoal(roundGoal);
|
|
7244
|
-
const
|
|
7542
|
+
const evidenceHead = resolveEvidenceHeadCommit(s.headCommit?.(wt.path), () =>
|
|
7543
|
+
runGitCommand(wt.path, ['rev-parse', '--verify', 'HEAD'], { encoding: 'utf8', timeout: 10_000 }).stdout.trim());
|
|
7544
|
+
if (!evidenceHead) {
|
|
7545
|
+
try { debug.log('self-implement.evidence', 'command-budget-head-unresolved', { runId, round, cwd: wt.path }); }
|
|
7546
|
+
catch { /* observation is fail-soft */ }
|
|
7547
|
+
}
|
|
7548
|
+
const evidenceChecks = runBudgetedEvidenceChecks(roundGoal, wt.path, runId, evidenceHead);
|
|
7245
7549
|
const tagCoverage = coverRequiredEvidence(requiredEvidence, offDiffEvidence.items);
|
|
7246
7550
|
// EVIDENCE-WIRING-EXEMPT — a requirement whose own `|| bun test …` check passed is covered by what the harness measured.
|
|
7247
7551
|
const settledByCheck = settleUncoveredEvidence(tagCoverage.uncovered, { checks: evidenceChecks, required: requiredEvidence });
|
|
@@ -7387,7 +7691,7 @@ async function runSelfImplementInner(
|
|
|
7387
7691
|
files: decision.expansion.files });
|
|
7388
7692
|
if ('parked' in result) progress('parked', `critical 질문 ${result.questionId} 미응답 — 이 런만 대기`);
|
|
7389
7693
|
return { ok: false, stage: 'parked' in result ? 'parked' : 'soft-stopped', node: 'implement', ...resolveRunOutcome({ termination: 'abandoned' }), sessionId, worktreePath: wt.path, branch: wt.branch,
|
|
7390
|
-
outOfScopeEdits, nameCapReached: scope.nameCapReached, outsideCount: scope.outsideCount,
|
|
7694
|
+
outOfScopeEdits, ...(!decision.accept ? { scopeStopReasons: decision.reasons } : {}), nameCapReached: scope.nameCapReached, outsideCount: scope.outsideCount,
|
|
7391
7695
|
detail: 'parked' in result ? `critical-unanswered: ${result.questionId}` : 'Out-of-scope edits held in the worktree; gate and publication skipped.' };
|
|
7392
7696
|
}
|
|
7393
7697
|
}
|
|
@@ -7684,6 +7988,43 @@ async function runSelfImplementInner(
|
|
|
7684
7988
|
if (untracked.status === 0) untrackedFiles = untracked.stdout.split(/\r?\n/).filter(Boolean);
|
|
7685
7989
|
} catch { /* change discovery must not stop review */ }
|
|
7686
7990
|
}
|
|
7991
|
+
// Gate has passed. Measure newly exported runtime values before review, without
|
|
7992
|
+
// turning a static-analysis guess into a rework verdict during the first rollout.
|
|
7993
|
+
const wiringFiles = [...new Set([...(runFacts.changedFiles ?? []), ...(gateRouteFiles ?? []), ...untrackedFiles])];
|
|
7994
|
+
let goalWiring: 'unwired' | undefined;
|
|
7995
|
+
if (wiringFiles.some((file) => /^(?:src|scripts|apps\/pwa\/src)\/.*\.tsx?$/.test(file))) {
|
|
7996
|
+
const wiringBase = wt.resolvedBase;
|
|
7997
|
+
const wiring = wiringBase && /^[0-9a-f]{40}$/i.test(wiringBase)
|
|
7998
|
+
? (s.checkUnwiredExports ?? findUnwiredExports)({
|
|
7999
|
+
cwd: wt.path,
|
|
8000
|
+
changedFiles: wiringFiles,
|
|
8001
|
+
// Timeouts and git errors throw → recorded as `failure`, never as "absent at base".
|
|
8002
|
+
readBaseFile: gitBaseFileReader(
|
|
8003
|
+
(args) => runGitCommand(wt.path, args, { encoding: 'utf8', timeout: 10_000 }),
|
|
8004
|
+
wiringBase,
|
|
8005
|
+
),
|
|
8006
|
+
})
|
|
8007
|
+
: { checked: 0, unwired: [], failure: 'resolved-base-unavailable' };
|
|
8008
|
+
if (!wiring.failure && opts.goalFile && wiring.unwired.length > 0) {
|
|
8009
|
+
try {
|
|
8010
|
+
const declared = declaredPathsFromGoalDocumentText(readFileSync(opts.goalFile, 'utf8'));
|
|
8011
|
+
if (declared.readable && wiring.unwired.some(({ file }) =>
|
|
8012
|
+
declared.paths.some((target) => normalizeDeclaredScopePath(target) === normalizeDeclaredScopePath(file)))) {
|
|
8013
|
+
goalWiring = 'unwired';
|
|
8014
|
+
}
|
|
8015
|
+
} catch { /* unreadable goal text cannot establish a wiring deficit */ }
|
|
8016
|
+
}
|
|
8017
|
+
const wiringObservation = {
|
|
8018
|
+
round,
|
|
8019
|
+
checked: wiring.checked,
|
|
8020
|
+
unwired: wiring.unwired.length,
|
|
8021
|
+
examples: wiring.unwired.slice(0, 10),
|
|
8022
|
+
...(wiring.failure ? { failure: wiring.failure } : {}),
|
|
8023
|
+
mode: 'warn',
|
|
8024
|
+
};
|
|
8025
|
+
debug.log('self-implement.wiring-check', wiring.failure ? 'unmeasured' : 'measured', wiringObservation);
|
|
8026
|
+
observe('wiring-check', wiringObservation, wiring.failure || wiring.unwired.length ? { level: 'warn' } : {});
|
|
8027
|
+
}
|
|
7687
8028
|
if ([...(runFacts.changedFiles ?? []), ...(gateRouteFiles ?? []), ...untrackedFiles].some((file) => /\.(?:html|css)$/i.test(file))) {
|
|
7688
8029
|
try {
|
|
7689
8030
|
designGate = (s.runDesignGate ?? runDesignGate)({ projectDir: wt.path, base: wt.resolvedBase });
|
|
@@ -7798,15 +8139,74 @@ async function runSelfImplementInner(
|
|
|
7798
8139
|
: `리뷰 미실행${review.failureReason !== undefined ? ` (${review.failureReason})` : ''}`);
|
|
7799
8140
|
if (opts.goalFile) {
|
|
7800
8141
|
let goalSlotFill: SupervisorGoalFillResult = 'unverifiable';
|
|
8142
|
+
let goalSlotDeficit: import('./goal-supervisor-fill.js').SupervisorGoalDeficit | undefined;
|
|
8143
|
+
let goalSlotAction: 'remeasure' | 'connect-goal' | undefined;
|
|
7801
8144
|
try {
|
|
7802
8145
|
goalSlotFill = await fillUnverifiableGoalSlots({
|
|
7803
8146
|
path: opts.goalFile, round, gate, review,
|
|
8147
|
+
...(goalWiring ? { wiring: goalWiring } : {}),
|
|
7804
8148
|
independentlyCheck: s.independentlyCheckGoalSlots ?? (async () => false),
|
|
8149
|
+
observeDeficit: (deficit) => { goalSlotDeficit = deficit; },
|
|
7805
8150
|
});
|
|
7806
8151
|
} catch {
|
|
7807
8152
|
goalSlotFill = 'rejected';
|
|
7808
8153
|
}
|
|
7809
|
-
|
|
8154
|
+
if (goalSlotFill === 'not-applicable') {
|
|
8155
|
+
observe('goal-slot-remeasure-result', { round, result: goalSlotFill, gatePassed: gate.passed,
|
|
8156
|
+
reason: 'test-step-scope-skipped', scopeReason: gate.scopeReason, testStepExecuted: gate.testStepExecuted });
|
|
8157
|
+
}
|
|
8158
|
+
if (goalSlotDeficit) {
|
|
8159
|
+
observe('supervisor-report-deficit', { runId, ...goalSlotDeficit, supervisorResult: goalSlotFill });
|
|
8160
|
+
if (goalSlotDeficit.kind !== 'unverified') {
|
|
8161
|
+
const move = repairNextMove({ supervisorDeficit: goalSlotDeficit,
|
|
8162
|
+
supervisorResult: goalSlotFill === 'rejected' ? 'rejected' : 'unverifiable' });
|
|
8163
|
+
if (move.kind === 'grounding') {
|
|
8164
|
+
goalSlotAction = move.action;
|
|
8165
|
+
observe('repair-next-move-input', { runId, ...move.supervisorDeficit,
|
|
8166
|
+
supervisorResult: goalSlotFill, action: move.action });
|
|
8167
|
+
}
|
|
8168
|
+
}
|
|
8169
|
+
}
|
|
8170
|
+
if (goalSlotFill === 'unverifiable' && gate.passed && goalSlotAction === 'remeasure' && goalSlotDeficit && runsGate) {
|
|
8171
|
+
observe('goal-slot-remeasure', { round, evidenceId: goalSlotDeficit.evidenceId, action: 'remeasure' });
|
|
8172
|
+
const measuredGate = await stepTimeout(s.gate(wt.path, { runId, round }), T.gate, 'gate');
|
|
8173
|
+
gate = measuredGate;
|
|
8174
|
+
let remeasureDeficit: import('./goal-supervisor-fill.js').SupervisorGoalDeficit | undefined;
|
|
8175
|
+
if (gate.passed) {
|
|
8176
|
+
goalSlotFill = await fillUnverifiableGoalSlots({ path: opts.goalFile, round, gate, review,
|
|
8177
|
+
independentlyCheck: s.independentlyCheckGoalSlots ?? (async () => false),
|
|
8178
|
+
observeDeficit: (deficit) => { remeasureDeficit = deficit; } });
|
|
8179
|
+
}
|
|
8180
|
+
observe('goal-slot-remeasure-result', { round, evidenceId: goalSlotDeficit.evidenceId, result: goalSlotFill,
|
|
8181
|
+
gatePassed: measuredGate.passed,
|
|
8182
|
+
...(remeasureDeficit ? { deficitKind: remeasureDeficit.kind,
|
|
8183
|
+
deficitEvidenceId: remeasureDeficit.evidenceId, gateLog: remeasureDeficit.gateLog,
|
|
8184
|
+
reason: remeasureDeficit.reason, inputSummary: remeasureDeficit.inputSummary, gateLogRef: remeasureDeficit.gateLogRef } : {}) });
|
|
8185
|
+
if (!gate.passed || goalSlotFill === 'unverifiable' || goalSlotFill === 'rejected') {
|
|
8186
|
+
finalizeSupervisorDeliveries('goal-slot-remeasure-gate-failed');
|
|
8187
|
+
const reason = `goal-slot remeasurement ${!gate.passed ? 'failed' : goalSlotFill === 'rejected' ? 'rejected' : 'unmeasured'} · evidence ${goalSlotDeficit.evidenceId}`;
|
|
8188
|
+
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', reason, gate, salvageStatusExpected: false });
|
|
8189
|
+
return { ok: false, stage: 'gate-failed', node: 'rework', ...resolveRunOutcome({ termination: 'abandoned' }),
|
|
8190
|
+
sessionId, worktreePath: wt.path, branch: wt.branch, gate,
|
|
8191
|
+
quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(),
|
|
8192
|
+
...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: reason };
|
|
8193
|
+
}
|
|
8194
|
+
}
|
|
8195
|
+
observe('goal-slot-fill', { round, result: goalSlotFill, gatePassed: gate.passed, reviewVerdict: review.verdict,
|
|
8196
|
+
...(goalSlotFill === 'unverifiable' && goalSlotDeficit ? { reason: goalSlotDeficit.reason, inputSummary: goalSlotDeficit.inputSummary, gateLogRef: goalSlotDeficit.gateLogRef } : {}),
|
|
8197
|
+
...(goalSlotFill === 'not-applicable' ? { reason: 'test-step-scope-skipped', scopeReason: gate.scopeReason,
|
|
8198
|
+
testStepExecuted: gate.testStepExecuted } : {}) });
|
|
8199
|
+
if (goalSlotAction === 'connect-goal' && goalSlotDeficit) {
|
|
8200
|
+
finalizeSupervisorDeliveries('goal-slot-connect-goal');
|
|
8201
|
+
const reason = `goal-slot wiring deficit · evidence ${goalSlotDeficit.evidenceId}`;
|
|
8202
|
+
const pr = await preserveBlockedArtifacts({ stage: 'review-blocked', reason, gate, salvageStatusExpected: false });
|
|
8203
|
+
await draftFollowUpAfterBlocked({ runId, prNumber: pr?.number, stage: 'review-blocked',
|
|
8204
|
+
unresolvedMustFix: [reason], feature: opts.feature, cellId: opts.goalId, goalFile: opts.goalFile }, s.followUp);
|
|
8205
|
+
return { ok: false, stage: 'review-blocked', node: 'rework', ...resolveRunOutcome({ termination: 'abandoned' }),
|
|
8206
|
+
sessionId, worktreePath: wt.path, branch: wt.branch, gate, review,
|
|
8207
|
+
quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(),
|
|
8208
|
+
...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: reason };
|
|
8209
|
+
}
|
|
7810
8210
|
}
|
|
7811
8211
|
const evidenceFacts: ReflectEvidenceFacts = evidenceCoverage
|
|
7812
8212
|
? { requiredEvidence: evidenceCoverage.required, coveredEvidence: evidenceCoverage.covered, missingEvidence: evidenceCoverage.uncovered }
|
|
@@ -7868,6 +8268,9 @@ async function runSelfImplementInner(
|
|
|
7868
8268
|
});
|
|
7869
8269
|
} catch { /* fail-safe: REFUTE never changes a finding without supervisor judgment */ }
|
|
7870
8270
|
}
|
|
8271
|
+
const rawReviewMustFix = [...review.mustFix];
|
|
8272
|
+
let reflectionApplied = false;
|
|
8273
|
+
let reviewTriageRecorded = false;
|
|
7871
8274
|
if (review.verdict === 'fail' && review.mustFix.length > 0) {
|
|
7872
8275
|
let effectiveMustFix = review.mustFix;
|
|
7873
8276
|
if (s.reflectMustFix) {
|
|
@@ -7876,6 +8279,7 @@ async function runSelfImplementInner(
|
|
|
7876
8279
|
try {
|
|
7877
8280
|
const recurrenceHistory = recurrenceHistoryFor(review.mustFix);
|
|
7878
8281
|
const reflected = await withStepTimeout(s.reflectMustFix({ mustFix: review.mustFix, goal: roundGoal, cwd: wt.path, evidenceFacts, gateFacts: gate.reflectGateFacts, citedPathFacts, ...(recurrenceHistory.length ? { recurrenceHistory } : {}), runId, round }), T.review, 'review');
|
|
8282
|
+
reflectionApplied = true;
|
|
7879
8283
|
const rejectedItems = new Set(reflected.rejected.filter((r) => r.reason && r.reason.trim().length > 0).map((r) => r.item));
|
|
7880
8284
|
const rejected = reflected.rejected.filter((r) => rejectedItems.has(r.item));
|
|
7881
8285
|
effectiveMustFix = review.mustFix.filter((m) => !rejectedItems.has(m));
|
|
@@ -7912,6 +8316,17 @@ async function runSelfImplementInner(
|
|
|
7912
8316
|
}
|
|
7913
8317
|
}
|
|
7914
8318
|
if (effectiveMustFix.length === 0) {
|
|
8319
|
+
observe('review-round-triage', {
|
|
8320
|
+
round,
|
|
8321
|
+
verdict: 'fail',
|
|
8322
|
+
rawMustFix: rawReviewMustFix,
|
|
8323
|
+
reflectedMustFix: effectiveMustFix,
|
|
8324
|
+
reflectionApplied,
|
|
8325
|
+
decision: 'pass',
|
|
8326
|
+
nextNode: 'open-pr',
|
|
8327
|
+
effectiveMax,
|
|
8328
|
+
});
|
|
8329
|
+
reviewTriageRecorded = true;
|
|
7915
8330
|
finalizeSupervisorDeliveries('review-reflect-converged');
|
|
7916
8331
|
completionStatus = 'review-reflect-converged';
|
|
7917
8332
|
review.mustFix = [];
|
|
@@ -7921,6 +8336,21 @@ async function runSelfImplementInner(
|
|
|
7921
8336
|
progress('reviewed', '리뷰: fail → warn (반사가 must-fix 를 «전부» 기각 — 사유는 위 줄과 PR 코멘트에)');
|
|
7922
8337
|
break;
|
|
7923
8338
|
}
|
|
8339
|
+
const reviewDecision = decideReviewRound({ verdict: review.verdict, mustFix: effectiveMustFix, round, effectiveMax });
|
|
8340
|
+
const reviewTriage = {
|
|
8341
|
+
round,
|
|
8342
|
+
verdict: review.verdict,
|
|
8343
|
+
rawMustFix: rawReviewMustFix,
|
|
8344
|
+
reflectedMustFix: [...effectiveMustFix],
|
|
8345
|
+
reflectionApplied,
|
|
8346
|
+
effectiveMax,
|
|
8347
|
+
};
|
|
8348
|
+
if (reviewDecision === 'follow-up') {
|
|
8349
|
+
pendingReviewTriage = { ...reviewTriage, verdict: 'fail' };
|
|
8350
|
+
} else {
|
|
8351
|
+
observe('review-round-triage', { ...reviewTriage, decision: reviewDecision, nextNode: 'rework' });
|
|
8352
|
+
reviewTriageRecorded = true;
|
|
8353
|
+
}
|
|
7924
8354
|
appliedLastRound = [...effectiveMustFix];
|
|
7925
8355
|
roundSummaryEntries.push({ round, kind: 'review', tried: impl.summary.replace(/\s+/g, ' ').trim().slice(0, 200),
|
|
7926
8356
|
failedIds: effectiveMustFix.map(stableMustFixId), filesTouched: runFacts.changedFiles,
|
|
@@ -7973,6 +8403,18 @@ async function runSelfImplementInner(
|
|
|
7973
8403
|
round++;
|
|
7974
8404
|
continue;
|
|
7975
8405
|
}
|
|
8406
|
+
if (!reviewTriageRecorded && !pendingReviewTriage) {
|
|
8407
|
+
observe('review-round-triage', {
|
|
8408
|
+
round,
|
|
8409
|
+
verdict: review.verdict,
|
|
8410
|
+
rawMustFix: rawReviewMustFix,
|
|
8411
|
+
reflectedMustFix: rawReviewMustFix,
|
|
8412
|
+
reflectionApplied: false,
|
|
8413
|
+
decision: 'pass',
|
|
8414
|
+
nextNode: 'open-pr',
|
|
8415
|
+
effectiveMax,
|
|
8416
|
+
});
|
|
8417
|
+
}
|
|
7976
8418
|
}
|
|
7977
8419
|
// EVIDENCE-WIRING-EXEMPT — a commandless [preservation] is covered once the changed-file gate passed.
|
|
7978
8420
|
if (gate.passed && evidenceCoverage?.uncoveredCount) {
|
|
@@ -8044,10 +8486,13 @@ async function runSelfImplementInner(
|
|
|
8044
8486
|
// (모집단 0인데 distinguishes=1) 틀린 값으로 막으면 새 병목이 된다.
|
|
8045
8487
|
// ⛔ `ran === false`(skipped)는 «다른 것»이다 — 자식이 테스트를 안 건드린 경우이고
|
|
8046
8488
|
// 그건 `skippedReason` 이 이미 가른다. 그래서 여기 조건에 넣지 않는다.
|
|
8047
|
-
|
|
8048
|
-
|
|
8489
|
+
// A new test absent from the fixed base is a structural RED witness when the
|
|
8490
|
+
// head gate passed. Keep that distinct from an executed test that proved nothing.
|
|
8491
|
+
const verifyStructuralRed = gate.verifyByBreaking?.ran === true && (gate.verifyByBreaking.missingAtBase ?? 0) > 0;
|
|
8492
|
+
const verifyInconclusive = gate.verifyByBreaking?.ran === true
|
|
8493
|
+
&& (gate.verifyByBreaking.distinguishes ?? 0) === 0 && !verifyStructuralRed;
|
|
8049
8494
|
let mergeReason = canAuto && reviewDeferredToHost ? REVIEW_DEFERRED_TO_HOST_MERGE_REASON
|
|
8050
|
-
: canAuto ? (
|
|
8495
|
+
: canAuto ? (verifyStructuralRed ? 'review-clean-verify-structural-red' : verifyInconclusive ? 'review-clean-verify-inconclusive' : 'review-clean-armed')
|
|
8051
8496
|
: gateTimeoutUnmeasured ? GATE_TIMEOUT_UNMEASURED_MERGE_REASON
|
|
8052
8497
|
: !autoMerge ? 'no-auto-flag'
|
|
8053
8498
|
: requiredEvidenceMissing ? 'required-evidence-uncovered'
|
|
@@ -8316,7 +8761,7 @@ async function runSelfImplementInner(
|
|
|
8316
8761
|
s.persistPrBodyArtifact,
|
|
8317
8762
|
'self-implement-pr',
|
|
8318
8763
|
);
|
|
8319
|
-
let pr:
|
|
8764
|
+
let pr: OpenPrOutcome;
|
|
8320
8765
|
try {
|
|
8321
8766
|
pr = await withStepTimeout(s.openPr({
|
|
8322
8767
|
title: prTitle(opts.feature, opts.goalFile),
|
|
@@ -8347,15 +8792,64 @@ async function runSelfImplementInner(
|
|
|
8347
8792
|
const current = runGitCommand(wt.path, ['rev-parse', '--verify', 'HEAD'], { encoding: 'utf8', timeout: 10_000 });
|
|
8348
8793
|
if (current.status !== 0 || current.stdout.trim() !== reviewedHeadCommit) delete reviewedHeadResult.reviewedHeadCommit;
|
|
8349
8794
|
}
|
|
8350
|
-
|
|
8351
|
-
|
|
8352
|
-
|
|
8353
|
-
|
|
8354
|
-
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8795
|
+
let prAttribution: { headRefName: string; createdAt: string } | undefined;
|
|
8796
|
+
let prAttributionReadError: string | undefined;
|
|
8797
|
+
try {
|
|
8798
|
+
if (s.readPrAttribution) {
|
|
8799
|
+
prAttribution = await s.readPrAttribution({ number: pr.number, cwd: wt.path });
|
|
8800
|
+
} else {
|
|
8801
|
+
const viewed = spawnSync('gh', ['pr', 'view', String(pr.number), '--json', 'headRefName,createdAt'], {
|
|
8802
|
+
cwd: wt.path, encoding: 'utf8', timeout: 30_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER,
|
|
8803
|
+
});
|
|
8804
|
+
if (viewed.status !== 0) throw new Error(viewed.stderr || viewed.stdout || 'gh pr view failed');
|
|
8805
|
+
const parsed = JSON.parse(viewed.stdout) as { headRefName?: unknown; createdAt?: unknown };
|
|
8806
|
+
if (typeof parsed.headRefName !== 'string' || typeof parsed.createdAt !== 'string') throw new Error('invalid PR attribution metadata');
|
|
8807
|
+
prAttribution = { headRefName: parsed.headRefName, createdAt: parsed.createdAt };
|
|
8808
|
+
}
|
|
8809
|
+
} catch (error) {
|
|
8810
|
+
prAttributionReadError = safeErrorDescription(error);
|
|
8811
|
+
}
|
|
8812
|
+
const expectedPrHead = pr.boundCardReuse?.headRefName ?? wt.branch;
|
|
8813
|
+
const prAttributed = !prAttributionReadError && !!prAttribution
|
|
8814
|
+
&& prAttributedToRun(prAttribution, wt.branch, startedAtMs, pr.boundCardReuse);
|
|
8815
|
+
if (prAttributionReadError || !prAttribution) {
|
|
8816
|
+
onPrAttributionMismatch();
|
|
8817
|
+
observe('pr-attribution-unverified', {
|
|
8818
|
+
expectedBranch: expectedPrHead,
|
|
8819
|
+
number: pr.number,
|
|
8820
|
+
url: pr.url,
|
|
8821
|
+
reason: prAttributionReadError ?? 'metadata-absent',
|
|
8822
|
+
}, { level: 'warn' });
|
|
8823
|
+
} else if (!prAttributed) {
|
|
8824
|
+
onPrAttributionMismatch();
|
|
8825
|
+
observe('pr-attribution-mismatch', {
|
|
8826
|
+
expectedBranch: expectedPrHead,
|
|
8827
|
+
actualBranch: prAttribution.headRefName,
|
|
8828
|
+
createdAt: prAttribution.createdAt,
|
|
8829
|
+
number: pr.number,
|
|
8830
|
+
url: pr.url,
|
|
8831
|
+
}, { level: 'warn' });
|
|
8832
|
+
} else {
|
|
8833
|
+
const attributedNumber = recordedPrNumber(pr.number);
|
|
8834
|
+
if (attributedNumber !== undefined) onPrAttributed(attributedNumber);
|
|
8835
|
+
observe('pr-opened', {
|
|
8836
|
+
url: pr.url,
|
|
8837
|
+
number: pr.number,
|
|
8838
|
+
branch: expectedPrHead,
|
|
8839
|
+
headCommit: runGitCommand(wt.path, ['rev-parse', '--verify', 'HEAD'], { encoding: 'utf8', timeout: 10_000 }).stdout.trim(),
|
|
8840
|
+
autoMerge: canAuto,
|
|
8841
|
+
autoReview: !!labels,
|
|
8842
|
+
...(preparedPrBody.truncated ? { prBodyTruncated: true, prBodyOriginalChars: preparedPrBody.originalChars } : {}),
|
|
8843
|
+
});
|
|
8844
|
+
}
|
|
8845
|
+
if (!prAttributed) {
|
|
8846
|
+
progress('aborted', `PR 귀속 확인 실패 — 외부 PR 후속 처리 중단 (${wt.branch}; worktree: ${wt.path})`);
|
|
8847
|
+
return {
|
|
8848
|
+
ok: false, stage: 'aborted', node: 'open-pr', ...resolveRunOutcome({ termination: 'abandoned' }),
|
|
8849
|
+
...decisionSignalResult, ...scopeExpansionResult, sessionId, worktreePath: wt.path, branch: wt.branch,
|
|
8850
|
+
gate, ...(review ? { review } : {}), detail: 'PR attribution could not be verified; worktree and branch preserved',
|
|
8851
|
+
};
|
|
8852
|
+
}
|
|
8359
8853
|
await flushPrComments(pr);
|
|
8360
8854
|
|
|
8361
8855
|
// Inspect the opened PR itself: the goal text and the pre-sync worktree can differ from its final file list.
|