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
|
@@ -24,6 +24,9 @@ export interface GoalFixedLayer {
|
|
|
24
24
|
invariants: string[];
|
|
25
25
|
/** 불변식 문면에서 «바꾸지 않는다/금지» 절에 실린 경로 — 카드가 건드리면 위반이다. */
|
|
26
26
|
protectedPaths: string[];
|
|
27
|
+
/** ELABORATION-PROTECTED-PATH-INVERSION — 골이 «고치라고» 준 경로(대상 경로·신설·증거 명령의 파일).
|
|
28
|
+
* 이 경로는 불변식 문면에 같이 나와도 보호 구역이 되지 않는다(대상을 수정 금지로 뒤집지 않는다). */
|
|
29
|
+
targetPaths: string[];
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
export interface ElaborationCard {
|
|
@@ -37,17 +40,74 @@ export interface ElaborationCard {
|
|
|
37
40
|
|
|
38
41
|
export type ElaborationOutcome =
|
|
39
42
|
| { status: 'elaborated'; card: ElaborationCard; cardSha: string; fileCount: number; level: InjectionLevel; attempts: number; judge: 'llm' | 'deterministic-only'; judgeErrors?: string[]; fixedLayerEmpty?: boolean }
|
|
40
|
-
| { status: 'needs-human'; attempts: number; violations: string[]; cardSha: string }
|
|
43
|
+
| { status: 'needs-human'; reason: ElaborationFailureReason; attempts: number; violations: string[]; cardSha: string }
|
|
41
44
|
| { status: 'skipped'; reason: 'no-provider' | 'provider-failed' | 'card-unparseable'; attempts: number; error?: string };
|
|
42
45
|
|
|
43
46
|
const MAX_LINES = 20;
|
|
44
47
|
const MAX_LINE_CHARS = 300;
|
|
45
48
|
const MAX_CARD_FILES = 30;
|
|
49
|
+
export type ElaborationFailureReason = 'goal-elaboration-ungrounded-path' | 'goal-elaboration-protected-path'
|
|
50
|
+
| 'goal-elaboration-scope-conflict' | 'goal-elaboration-fixed-layer-conflict';
|
|
51
|
+
|
|
52
|
+
function failureReason(violations: readonly string[]): ElaborationFailureReason {
|
|
53
|
+
if (violations.some((violation) => violation.startsWith('ungrounded path:'))) return 'goal-elaboration-ungrounded-path';
|
|
54
|
+
if (violations.some((violation) => violation.startsWith('protected path:'))) return 'goal-elaboration-protected-path';
|
|
55
|
+
// 판정기 자유 문면의 "KPI 범위 약화"는 확장 수복 대상이 아니다. 구조화된 kind=scope만 인정한다.
|
|
56
|
+
if (violations.some((violation) => violation.startsWith('scope expansion:'))) return 'goal-elaboration-scope-conflict';
|
|
57
|
+
return 'goal-elaboration-fixed-layer-conflict';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function repairInstruction(reason: ElaborationFailureReason, fixed: GoalFixedLayer): string {
|
|
61
|
+
switch (reason) {
|
|
62
|
+
case 'goal-elaboration-ungrounded-path':
|
|
63
|
+
return `없는 경로를 다시 접지한다. 저장소에 있는 파일이나 골에 명시된 대상 경로만 고르고, 새 파일은 골이 신설을 요구할 때만 newFiles에 적는다. 대상 경로: ${fixed.targetPaths.join(', ') || '(명시 없음)'}`;
|
|
64
|
+
case 'goal-elaboration-protected-path':
|
|
65
|
+
return `보호 경로를 카드에서 빼고 골의 대상 경로 안에서만 구현한다.${fixed.protectedPaths.length ? ` 보호 경로: ${fixed.protectedPaths.join(', ')}` : ' 위반 목록의 보호 경로 지적을 확인한다.'}`;
|
|
66
|
+
case 'goal-elaboration-scope-conflict':
|
|
67
|
+
return '범위 확장을 좁힌다. 골의 대상과 완료 경계를 유지하고 새 기능이나 새 판정 조건을 더하지 않는다.';
|
|
68
|
+
case 'goal-elaboration-fixed-layer-conflict':
|
|
69
|
+
return '고정 층의 방향·KPI·불변식을 보존한다. 지적된 문장만 고치고 완료 조건을 약화하지 않는다.';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
46
72
|
const KPI_LINE = /판정 신호|수용선|완료 경계|증거 명령|KPI|acceptance|verify:|반증/i;
|
|
47
73
|
const INVARIANT_LINE = /불변|경계:|⛔|바꾸지 않는다|하지 않는다|금지|보호|invariant|must not|do not/i;
|
|
48
74
|
const DIRECTION_LINE = /^(?:[-*]\s*)?(?:바꿀 것|목표|무엇|왜|현재 계약|Goal|Why|What)\s*[::]/i;
|
|
49
75
|
const PROHIBITION = /바꾸지 않는다|건드리지 않는다|하지 않는다|금지|보호|⛔|must not|do not (?:touch|modify|change)/i;
|
|
50
76
|
const PATH_TOKEN = /[\w@.-]+(?:\/[\w@.-]+)*\.(?:ts|tsx|js|mjs|cjs|json|ya?ml|md|sh)\b/g;
|
|
77
|
+
/** 골이 바꾸라고 준 경로가 실리는 줄 — 대상 경로 · 신설 · 증거 명령(bun test <파일>). */
|
|
78
|
+
// ⛔ «줄 처음 ⊕ 콜론» 고정 — 경계 줄 안의 «…판정 신호 불변…» 을 대상 줄로 읽으면 보호 경로가 빠진다.
|
|
79
|
+
// ① 대상·신설 줄 = 그 줄의 모든 경로 ② 증거 명령·판정 신호·현재 계약 줄 = `bun test` 바로 뒤 시험 파일만
|
|
80
|
+
// (그 줄의 «goal-author.ts 는 바꾸지 않는다» 같은 보호 경로를 대상으로 빼지 않게 · r1 must-fix).
|
|
81
|
+
const TARGET_LINE = /^(?:[-*]\s*)?(?:대상 경로|대상|신설|새 파일|target paths?|files?)\s*[::]/i;
|
|
82
|
+
const COMMAND_LINE = /^(?:[-*]\s*)?(?:완료 경계 증거 명령|증거 명령|판정 신호|현재 계약)\s*[::]/i;
|
|
83
|
+
const BUN_TEST_HEAD = /bun test\s+/g;
|
|
84
|
+
/** `bun test` 인자 — 경로 꼴 토큰이 끊기는 곳(`·`·문장·`→`)에서 멈추고 시험 파일만 낸다(r2 must-fix). */
|
|
85
|
+
export function bunTestPathArgs(line: string): string[] {
|
|
86
|
+
const out: string[] = [];
|
|
87
|
+
for (const head of line.matchAll(BUN_TEST_HEAD)) {
|
|
88
|
+
const rest = line.slice(head.index! + head[0].length).split(/\s+/);
|
|
89
|
+
for (const raw of rest) {
|
|
90
|
+
// 따옴표·백틱으로 감싼 인자도 시험 파일이다(r3 must-fix) — 짝이 맞는 감싸기만 벗긴다.
|
|
91
|
+
const tok = /^(["'`])(.*)\1$/.exec(raw)?.[2] ?? raw;
|
|
92
|
+
if (tok.startsWith('-')) continue;
|
|
93
|
+
if (!/^[\w@./-]+$/.test(tok)) break;
|
|
94
|
+
if (/\.(?:test|spec)\.[cm]?[jt]sx?$/.test(tok)) out.push(tok);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
/** 경로 바로 뒤가 «의 …»·«안의 …»·«'s …» 면 그 금지는 파일 «안의 내용»(기존 단언·동작·계약)에 대한 것이다. */
|
|
100
|
+
const CONTENT_SCOPED = /^\s*(?:의|안의|에 있는|속)\s|^'s\s|^\s+(?:existing|assertions?|behaviou?r|contract)\b/i;
|
|
101
|
+
/** 형식이 안 맞아 «검증 불가»로 처리된 경계 줄 — 금지 불변식으로 격상하지 않는다(10-22 실물). */
|
|
102
|
+
const UNVERIFIABLE_LINE = /UNVERIFIABLE|검증 불가|형식 불일치/i;
|
|
103
|
+
/** 사람이 쓴 경계 줄 — 대상 경로를 보호로 이길 수 있는 유일한 자리. */
|
|
104
|
+
const BOUNDARY_LINE = /^(?:[-*]\s*)?경계\s*[::]/;
|
|
105
|
+
/** 경로 «바로 뒤»가 «는/를 바꾸지 않는다» 꼴일 때만 경로 자체 금지다 — «X 를 수정하되 기존 단언은 바꾸지 않는다» 는 아니다(r1 must-fix). */
|
|
106
|
+
const BARE_PATH_PROHIBITION = /^\s*(?:파일)?\s*(?:은|는|을|를|도)?\s*(?:(?:바꾸|건드리|수정하|고치|변경하)지\s*않는다|(?:수정|변경)\s*금지)/;
|
|
107
|
+
|
|
108
|
+
function samePathOrSuffix(a: string, b: string): boolean {
|
|
109
|
+
return a === b || a.endsWith(`/${b}`) || b.endsWith(`/${a}`);
|
|
110
|
+
}
|
|
51
111
|
|
|
52
112
|
function clip(lines: string[]): string[] {
|
|
53
113
|
return lines.slice(0, MAX_LINES).map((line) => (line.length > MAX_LINE_CHARS ? `${line.slice(0, MAX_LINE_CHARS)}…` : line));
|
|
@@ -57,17 +117,46 @@ function clip(lines: string[]): string[] {
|
|
|
57
117
|
export function extractGoalFixedLayer(goal: string): GoalFixedLayer {
|
|
58
118
|
const lines = goal.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
59
119
|
const kpi = lines.filter((line) => KPI_LINE.test(line));
|
|
60
|
-
const invariants = lines.filter((line) => INVARIANT_LINE.test(line));
|
|
120
|
+
const invariants = lines.filter((line) => INVARIANT_LINE.test(line) && !UNVERIFIABLE_LINE.test(line));
|
|
121
|
+
const targetPaths = new Set<string>();
|
|
122
|
+
for (const line of lines.filter((l) => TARGET_LINE.test(l))) {
|
|
123
|
+
// 대상 줄 안의 금지 절(«· X 는 바꾸지 않는다»)은 대상이 아니다 — 보호로 남긴다(r4 must-fix). 쪼개기는 보호 구역과 같은 규칙.
|
|
124
|
+
for (const clause of line.split(/[·;,]|\s-\s/)) {
|
|
125
|
+
if (PROHIBITION.test(clause)) continue;
|
|
126
|
+
for (const match of clause.matchAll(PATH_TOKEN)) targetPaths.add(match[0]);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/** 증거·판정 명령이 «돌리라고» 준 시험 파일 — 어떤 금지 줄로도 보호 구역이 되지 않는다(TA-REMOTE-MIRROR-BIND 10-22). */
|
|
130
|
+
const evidencePaths = new Set<string>();
|
|
131
|
+
for (const line of lines.filter((l) => COMMAND_LINE.test(l))) {
|
|
132
|
+
for (const path of bunTestPathArgs(line)) { targetPaths.add(path); evidencePaths.add(path); }
|
|
133
|
+
}
|
|
61
134
|
let direction = lines.filter((line) => DIRECTION_LINE.test(line));
|
|
62
|
-
|
|
135
|
+
// UNVERIFIABLE 경계 줄은 방향 대체값으로도 고정 층에 들이지 않는다(r6 — 판정기 프롬프트에 «X 수정 금지»가 되살아났다).
|
|
136
|
+
if (!direction.length) direction = lines.filter((line) => !kpi.includes(line) && !invariants.includes(line) && !UNVERIFIABLE_LINE.test(line)).slice(0, 3);
|
|
63
137
|
const protectedPaths = new Set<string>();
|
|
138
|
+
const explicitlyProtected = new Set<string>();
|
|
64
139
|
for (const line of invariants) {
|
|
65
140
|
for (const clause of line.split(/[·;,]|\s-\s/)) {
|
|
66
141
|
if (!PROHIBITION.test(clause)) continue;
|
|
67
|
-
for (const match of clause.matchAll(PATH_TOKEN))
|
|
142
|
+
for (const match of clause.matchAll(PATH_TOKEN)) {
|
|
143
|
+
const isTarget = [...targetPaths].some((target) => samePathOrSuffix(match[0], target));
|
|
144
|
+
if (isTarget) {
|
|
145
|
+
// 골이 고치거나 돌리라고 준 파일(대상·신설·증거 시험)은 «추론»으로 보호되지 않는다 —
|
|
146
|
+
// 저작기가 덧붙인 분해 인용·«단정하지 않는다» 같은 동작 금지 문장이 같은 절의 대상까지 보호로 뒤집었다(TA-REMOTE-MIRROR-BIND 10-22).
|
|
147
|
+
// ⛔ 이기는 것은 사람이 쓴 «경계:» 줄의 맨 «X 는 바꾸지 않는다»(경로 자체 금지)뿐이고, 증거 명령의 시험 파일은 그것으로도 안 막는다(r5 ⊕ 이번 변종).
|
|
148
|
+
// «X 의 기존 단언·동작은 바꾸지 않는다» 는 «내용» 금지다 — 파일은 고친다(10-22 밤샘 parked 다수의 뒤집힘).
|
|
149
|
+
const pathLevel = BOUNDARY_LINE.test(line) && BARE_PATH_PROHIBITION.test(clause.slice(match.index! + match[0].length));
|
|
150
|
+
const isEvidence = [...evidencePaths].some((path) => samePathOrSuffix(match[0], path));
|
|
151
|
+
if (!pathLevel || isEvidence) continue;
|
|
152
|
+
explicitlyProtected.add(match[0]);
|
|
153
|
+
}
|
|
154
|
+
protectedPaths.add(match[0]);
|
|
155
|
+
}
|
|
68
156
|
}
|
|
69
157
|
}
|
|
70
|
-
|
|
158
|
+
const targets = [...targetPaths].filter((target) => ![...explicitlyProtected].some((p) => samePathOrSuffix(p, target)));
|
|
159
|
+
return { direction: clip(direction), kpi: clip(kpi), invariants: clip(invariants), protectedPaths: [...protectedPaths], targetPaths: targets };
|
|
71
160
|
}
|
|
72
161
|
|
|
73
162
|
function stringList(value: unknown): string[] | undefined {
|
|
@@ -132,7 +221,7 @@ export function checkCardAgainstFixedLayer(card: ElaborationCard, fixed: GoalFix
|
|
|
132
221
|
const paths = [...new Set([...card.files, ...card.newFiles, card.firstTest.path])];
|
|
133
222
|
for (const path of paths) {
|
|
134
223
|
const hit = fixed.protectedPaths.find((protectedPath) => touchesProtected(path, protectedPath));
|
|
135
|
-
if (hit) violations.push(
|
|
224
|
+
if (hit) violations.push(protectedPathViolation(path, hit));
|
|
136
225
|
else if (!card.newFiles.includes(path) && !fileExists(path)) violations.push(`ungrounded path: ${path} does not exist and is not listed in newFiles`);
|
|
137
226
|
}
|
|
138
227
|
return violations;
|
|
@@ -145,12 +234,12 @@ function section(title: string, lines: string[]): string {
|
|
|
145
234
|
return [`### ${title}`, ...(lines.length ? lines.map((line) => `- ${line}`) : ['- (없음)'])].join('\n');
|
|
146
235
|
}
|
|
147
236
|
|
|
148
|
-
function buildCardPrompt(goal: string, context: string, fixed: GoalFixedLayer, previousViolations: string[] = []): string {
|
|
237
|
+
function buildCardPrompt(goal: string, context: string, fixed: GoalFixedLayer, previousViolations: string[] = [], repair?: string): string {
|
|
149
238
|
return [
|
|
150
239
|
'## 할 일 — 착수 구체화 카드(E1)',
|
|
151
240
|
'아래 골을 구현하기 전에, 저장소 맥락을 근거로 «구체화 카드»를 쓴다. 고정 층(방향·KPI·불변식·보호 구역)은 바꾸지 않는다 — 카드는 «어디서부터 어떻게» 만 정한다.',
|
|
152
241
|
'JSON 형식: {"files": [실제 건드릴 경로], "newFiles": [그중 새로 만들 경로], "requirements": [세부 요구], "firstTest": {"path": 시험 파일, "name": 시험 이름, "redReason": 지금 왜 실패하는가}, "stage": "unit|integration|live", "level": "L0|L1|L2|L3|L4"(주입 사다리 층)}',
|
|
153
|
-
...(previousViolations.length ? ['', '## 앞 카드가 고정 층과 어긋났다 — 고쳐 다시 쓴다', ...previousViolations.map((v) => `- ${v}`)] : []),
|
|
242
|
+
...(previousViolations.length ? ['', '## 앞 카드가 고정 층과 어긋났다 — 이 사유로 딱 한 번 고쳐 다시 쓴다', ...(repair ? [repair] : []), ...previousViolations.map((v) => `- ${v}`)] : []),
|
|
154
243
|
'',
|
|
155
244
|
'## 고정 층(바꾸지 않는다)',
|
|
156
245
|
section('방향', fixed.direction),
|
|
@@ -166,7 +255,9 @@ function buildCardPrompt(goal: string, context: string, fixed: GoalFixedLayer, p
|
|
|
166
255
|
function buildJudgePrompt(fixed: GoalFixedLayer, card: ElaborationCard): string {
|
|
167
256
|
return [
|
|
168
257
|
'카드가 고정 층과 «맞는지만» 본다. 카드가 KPI·판정 신호를 약화·삭제·대체하거나, 방향을 바꾸거나, 불변식·보호 구역을 어기면 불일치다. 구현 방법의 좋고 나쁨은 판정하지 않는다.',
|
|
169
|
-
'JSON 형식: {"consistent": true|false, "violations": [
|
|
258
|
+
'JSON 형식: {"consistent": true|false, "violations": [{"kind": "path"|"content"|"scope", "path": "<경로 · path 일 때>", "text": "<어긋난 점>"}]}',
|
|
259
|
+
'kind=path = 그 경로를 «건드리는 것 자체»가 금지라는 지적 · kind=content = 기존 단언·동작·계약·KPI 를 바꾸거나 약화했다는 지적 · kind=scope = 골 밖의 새 기능으로 범위를 확장했다는 지적.',
|
|
260
|
+
...(fixed.targetPaths.length ? [`대상 경로(골이 고치라고 준 파일 · 건드리는 것 자체는 위반 아님 · 그 안의 기존 계약을 바꾸면 content 위반): ${fixed.targetPaths.join(', ')}`] : []),
|
|
170
261
|
'',
|
|
171
262
|
section('방향', fixed.direction),
|
|
172
263
|
section('KPI·판정 신호', fixed.kpi),
|
|
@@ -177,11 +268,55 @@ function buildJudgePrompt(fixed: GoalFixedLayer, card: ElaborationCard): string
|
|
|
177
268
|
].join('\n');
|
|
178
269
|
}
|
|
179
270
|
|
|
180
|
-
|
|
271
|
+
type JudgeViolation = { kind: 'path' | 'content' | 'scope' | 'unknown'; path?: string; text: string };
|
|
272
|
+
|
|
273
|
+
const PROTECTED_PATH_PREFIX = 'protected path:';
|
|
274
|
+
function protectedPathViolation(path: string, protectedPath: string): string {
|
|
275
|
+
return `${PROTECTED_PATH_PREFIX} ${path} (goal invariant forbids changing ${protectedPath})`;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function legacyProtectedPath(text: string): string | undefined {
|
|
279
|
+
const trimmed = text.trim();
|
|
280
|
+
if (!trimmed.toLowerCase().startsWith(PROTECTED_PATH_PREFIX)) return undefined;
|
|
281
|
+
const match = /^(\S+?)(?:\s+\(goal invariant forbids changing\s+(\S+)\))?\.?$/i.exec(trimmed.slice(PROTECTED_PATH_PREFIX.length).trim());
|
|
282
|
+
return match && (!match[2] || match[1] === match[2]) ? match[1] : undefined;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/** 판정기 지적이 «대상 경로를 건드리는 것 자체»(kind=path)인가 — 문구가 아니라 판정기가 낸 «종류»로 가른다(r2 must-fix).
|
|
286
|
+
* ⛔ content·종류 없음(옛 문자열 꼴)은 버리지 않는다 — 기존 단언·동작·계약 위반은 문구와 무관하게 남는다. */
|
|
287
|
+
function isTargetInversion(violation: JudgeViolation, targetPaths: readonly string[]): boolean {
|
|
288
|
+
// 이전 판정기는 kind 없이 결정론 검사와 똑같은 보호 경로 문장을 돌려주기도 했다
|
|
289
|
+
// (FIRST10-GATE: 신설 scripts/first10-gate.test.ts). 정확한 경로 수준 문법만 복구한다.
|
|
290
|
+
// 명시적 content 지적은 문구가 비슷해도 기존 계약 위반일 수 있으므로 버리지 않는다.
|
|
291
|
+
const legacy = violation.kind === 'unknown' ? legacyProtectedPath(violation.text) : undefined;
|
|
292
|
+
const path = violation.kind === 'path' ? violation.path
|
|
293
|
+
: legacy;
|
|
294
|
+
if (!path) return false;
|
|
295
|
+
return targetPaths.some((target) => samePathOrSuffix(path, target));
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function judgeViolations(value: unknown): JudgeViolation[] {
|
|
299
|
+
if (!Array.isArray(value)) return [];
|
|
300
|
+
const out: JudgeViolation[] = [];
|
|
301
|
+
for (const item of value) {
|
|
302
|
+
if (typeof item === 'string') { if (item.trim()) out.push({ kind: 'unknown', text: item }); continue; }
|
|
303
|
+
if (!item || typeof item !== 'object') continue;
|
|
304
|
+
const rec = item as Record<string, unknown>;
|
|
305
|
+
const text = typeof rec.text === 'string' && rec.text.trim() ? rec.text : JSON.stringify(rec);
|
|
306
|
+
const kind = rec.kind === 'path' || rec.kind === 'content' || rec.kind === 'scope' ? rec.kind : 'unknown';
|
|
307
|
+
out.push({ kind, text, ...(typeof rec.path === 'string' && rec.path.trim() ? { path: rec.path.trim() } : {}) });
|
|
308
|
+
}
|
|
309
|
+
return out;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function parseJudge(text: string): { consistent: boolean; violations: JudgeViolation[] } | undefined {
|
|
181
313
|
const raw = lastJsonObject(text) as Record<string, unknown> | undefined;
|
|
182
314
|
if (!raw || typeof raw.consistent !== 'boolean') return undefined;
|
|
183
|
-
const violations =
|
|
184
|
-
return {
|
|
315
|
+
const violations = judgeViolations(raw.violations ?? []);
|
|
316
|
+
return {
|
|
317
|
+
consistent: raw.consistent && violations.length === 0,
|
|
318
|
+
violations: raw.consistent ? violations : violations.length ? violations : [{ kind: 'unknown', text: 'judge reported inconsistency' }],
|
|
319
|
+
};
|
|
185
320
|
}
|
|
186
321
|
|
|
187
322
|
function cardSha(card: ElaborationCard): string {
|
|
@@ -198,21 +333,26 @@ function errorText(error: unknown): string {
|
|
|
198
333
|
*/
|
|
199
334
|
export async function elaborateGoalOnArrival(
|
|
200
335
|
input: { goal: string; context?: string; fileExists: (path: string) => boolean },
|
|
201
|
-
deps: { callLLM?: ElaborationCallLLM; maxRewrites?: number },
|
|
336
|
+
deps: { callLLM?: ElaborationCallLLM; maxRewrites?: number; observe?: (event: string, data: Record<string, unknown>) => void },
|
|
202
337
|
): Promise<ElaborationOutcome> {
|
|
203
338
|
if (!deps.callLLM) return { status: 'skipped', reason: 'no-provider', attempts: 0 };
|
|
204
339
|
const fixed = extractGoalFixedLayer(input.goal);
|
|
205
|
-
|
|
340
|
+
// 같은 결함으로 LLM을 계속 부르지 않는다. 과도한 호출자 설정을 조용히 무시하지 않는다.
|
|
341
|
+
if (deps.maxRewrites !== undefined && deps.maxRewrites !== 0 && deps.maxRewrites !== 1) {
|
|
342
|
+
throw new RangeError('goal elaboration maxRewrites must be 0 or 1');
|
|
343
|
+
}
|
|
344
|
+
const maxAttempts = 1 + (deps.maxRewrites ?? 1);
|
|
206
345
|
const fixedLayerEmpty = !fixed.kpi.length && !fixed.invariants.length;
|
|
207
346
|
/** 다시 쓰기 프롬프트에 실을 앞 회차의 문제(판독 실패 포함). */
|
|
208
347
|
let feedback: string[] = [];
|
|
348
|
+
let repair: string | undefined;
|
|
209
349
|
/** 고정 층 위반은 «판독된 카드»에만 귀속한다 — 해시와 위반이 같은 카드를 가리킨다. */
|
|
210
|
-
let lastRejected: { sha: string; violations: string[] } | undefined;
|
|
350
|
+
let lastRejected: { sha: string; violations: string[]; reason: ElaborationFailureReason } | undefined;
|
|
211
351
|
const judgeErrors: string[] = [];
|
|
212
352
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
213
353
|
let text: string;
|
|
214
354
|
try {
|
|
215
|
-
text = await deps.callLLM({ prompt: buildCardPrompt(input.goal, input.context ?? '', fixed, feedback), systemPrompt: CARD_SYSTEM });
|
|
355
|
+
text = await deps.callLLM({ prompt: buildCardPrompt(input.goal, input.context ?? '', fixed, feedback, repair), systemPrompt: CARD_SYSTEM });
|
|
216
356
|
} catch (error) {
|
|
217
357
|
return { status: 'skipped', reason: 'provider-failed', attempts: attempt, error: errorText(error) };
|
|
218
358
|
}
|
|
@@ -230,7 +370,14 @@ export async function elaborateGoalOnArrival(
|
|
|
230
370
|
const verdict = parseJudge(await deps.callLLM({ prompt: buildJudgePrompt(fixed, card), systemPrompt: JUDGE_SYSTEM }));
|
|
231
371
|
if (verdict) {
|
|
232
372
|
judge = 'llm';
|
|
233
|
-
if (!verdict.consistent)
|
|
373
|
+
if (!verdict.consistent) {
|
|
374
|
+
// 판정기가 «대상 경로를 건드렸다 = 보호 구역 위반»이라고 하면 그 지적은 뒤집힘이다 — 버리고 관측에 남긴다.
|
|
375
|
+
const inverted = verdict.violations.filter((v) => isTargetInversion(v, fixed.targetPaths));
|
|
376
|
+
if (inverted.length) judgeErrors.push(`judge-target-inversion-dropped: ${inverted.length}`);
|
|
377
|
+
violations = verdict.violations.filter((v) => !isTargetInversion(v, fixed.targetPaths))
|
|
378
|
+
.map((v) => v.kind === 'scope' ? `scope expansion: ${v.text}`
|
|
379
|
+
: v.kind === 'content' ? `content violation: ${v.text}` : v.text);
|
|
380
|
+
}
|
|
234
381
|
} else judgeErrors.push('judge-unparseable');
|
|
235
382
|
} catch (error) {
|
|
236
383
|
// 판정기 실패는 결정론 대조만으로 — 카드는 고정 층을 다시 쓰지 않는다. 실패 사실은 관측에 남긴다.
|
|
@@ -241,11 +388,16 @@ export async function elaborateGoalOnArrival(
|
|
|
241
388
|
return { status: 'elaborated', card, cardSha: sha, fileCount: card.files.length, level: card.level, attempts: attempt, judge,
|
|
242
389
|
...(judgeErrors.length ? { judgeErrors } : {}), ...(fixedLayerEmpty ? { fixedLayerEmpty } : {}) };
|
|
243
390
|
}
|
|
244
|
-
|
|
391
|
+
const reason = failureReason(violations);
|
|
392
|
+
lastRejected = { sha, violations, reason };
|
|
245
393
|
feedback = violations;
|
|
394
|
+
if (attempt < maxAttempts) {
|
|
395
|
+
repair = [...new Set(violations.map((violation) => failureReason([violation])))].map((kind) => repairInstruction(kind, fixed)).join('\n');
|
|
396
|
+
deps.observe?.('goal-elaboration-self-heal', { reason, attempt, cardSha: sha, violations });
|
|
397
|
+
}
|
|
246
398
|
}
|
|
247
399
|
if (!lastRejected) return { status: 'skipped', reason: 'card-unparseable', attempts: maxAttempts, error: feedback[0] };
|
|
248
|
-
return { status: 'needs-human', attempts: maxAttempts, violations: lastRejected.violations, cardSha: lastRejected.sha };
|
|
400
|
+
return { status: 'needs-human', reason: lastRejected.reason, attempts: maxAttempts, violations: lastRejected.violations, cardSha: lastRejected.sha };
|
|
249
401
|
}
|
|
250
402
|
|
|
251
403
|
export function renderElaborationCard(card: ElaborationCard, sha: string): string {
|
|
@@ -275,8 +427,10 @@ export async function runArrivalElaboration(input: {
|
|
|
275
427
|
const fileExists = input.fileExists ?? ((path: string) => existsSync(join(input.cwd ?? process.cwd(), path)));
|
|
276
428
|
let outcome: ElaborationOutcome;
|
|
277
429
|
try {
|
|
278
|
-
outcome = await elaborateGoalOnArrival({ goal: input.goal, context: input.prompt, fileExists }, { callLLM: input.callLLM
|
|
430
|
+
outcome = await elaborateGoalOnArrival({ goal: input.goal, context: input.prompt, fileExists }, { callLLM: input.callLLM,
|
|
431
|
+
observe: (event, data) => input.observe(event, data, { level: 'warn' }) });
|
|
279
432
|
} catch (error) {
|
|
433
|
+
if (error instanceof RangeError && error.message === 'goal elaboration maxRewrites must be 0 or 1') throw error;
|
|
280
434
|
outcome = { status: 'skipped', reason: 'provider-failed', attempts: 0, error: errorText(error) };
|
|
281
435
|
}
|
|
282
436
|
if (outcome.status === 'elaborated') {
|
|
@@ -287,8 +441,8 @@ export async function runArrivalElaboration(input: {
|
|
|
287
441
|
return { prompt: `${input.prompt}\n\n${renderElaborationCard(outcome.card, outcome.cardSha)}`, parked: false };
|
|
288
442
|
}
|
|
289
443
|
if (outcome.status === 'needs-human') {
|
|
290
|
-
input.observe('goal-elaboration-needs-human', { outcome: 'needs-human', attempts: outcome.attempts, violations: outcome.violations, cardSha: outcome.cardSha }, { level: 'warn' });
|
|
291
|
-
return { prompt: input.prompt, parked: true, detail: `goal-elaboration needs-human: ${outcome.violations.join(' | ').slice(0, 500)}` };
|
|
444
|
+
input.observe('goal-elaboration-needs-human', { outcome: 'needs-human', reason: outcome.reason, attempts: outcome.attempts, violations: outcome.violations, cardSha: outcome.cardSha }, { level: 'warn' });
|
|
445
|
+
return { prompt: input.prompt, parked: true, detail: `goal-elaboration needs-human: ${outcome.reason} (attempts: ${outcome.attempts}) · ${outcome.violations.join(' | ').slice(0, 500)}` };
|
|
292
446
|
}
|
|
293
447
|
input.observe('goal-elaboration-skipped', { outcome: 'skipped', reason: outcome.reason, attempts: outcome.attempts, ...(outcome.error ? { error: outcome.error } : {}) }, outcome.reason === 'no-provider' ? undefined : { level: 'warn' });
|
|
294
448
|
return { prompt: input.prompt, parked: false };
|
|
@@ -177,6 +177,8 @@ export interface FirstRoundEvidence {
|
|
|
177
177
|
findings?: string;
|
|
178
178
|
/** 첫 라운드가 실제로 건드린 파일. */
|
|
179
179
|
changedFiles?: readonly string[];
|
|
180
|
+
/** SCOPE-ESCAPE-AS-REFINE — 대상 경로 밖에서 바뀌었고 수용된 파일(«구현이 알려준 새 범위» · 실패 아님). */
|
|
181
|
+
newScope?: readonly string[];
|
|
180
182
|
}
|
|
181
183
|
|
|
182
184
|
/** 내부 — 시험은 refineGoalFromFirstRound 가 LLM 에 넘긴 프롬프트로 본다. */
|
|
@@ -195,6 +197,7 @@ function buildRegroundingPrompt(v1: string, evidence: FirstRoundEvidence): strin
|
|
|
195
197
|
'## 첫 라운드 실전',
|
|
196
198
|
`- 자식 요약: ${(evidence.implSummary ?? '').replace(/\s+/g, ' ').trim().slice(0, 600) || '(없음)'}`,
|
|
197
199
|
`- 건드린 파일: ${evidence.changedFiles?.length ? evidence.changedFiles.slice(0, 40).join(', ') : '(관측 없음)'}`,
|
|
200
|
+
...(evidence.newScope?.length ? [`- 구현이 알려준 새 범위(대상 경로 밖 편집 · 실패 아님 · 예상 구역에 넣을지 판단): ${evidence.newScope.slice(0, 40).join(', ')}`] : []),
|
|
198
201
|
'### gate·리뷰 지적',
|
|
199
202
|
(evidence.findings ?? '').trim().slice(0, 4000) || '(없음)',
|
|
200
203
|
'',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
import { readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
3
|
import { dirname, join } from 'node:path';
|
|
3
4
|
import { extractGoalDocSections } from './goal-doc/section.js';
|
|
@@ -8,8 +9,8 @@ export interface SupervisorGoalFillEvidence {
|
|
|
8
9
|
reviewVerdict: 'pass' | 'warn' | 'fail';
|
|
9
10
|
/** ⭐ 게이트 로그에서 **실제로 읽은** fail 수. 기대값이 아니다(리뷰 must-fix). */
|
|
10
11
|
observedFail: number;
|
|
11
|
-
/**
|
|
12
|
-
baselineLine
|
|
12
|
+
/** 실패 귀속 baseline이 실제 실행됐을 때만 있는 행. PASS에서는 실행하지 않는다. */
|
|
13
|
+
baselineLine?: string;
|
|
13
14
|
/** ⭐ **원천 그대로** — 독립 검사기가 writer 의 파싱 결과가 아니라 **로그를 직접** 다시 읽는다. */
|
|
14
15
|
gateLog: string;
|
|
15
16
|
}
|
|
@@ -17,28 +18,41 @@ export interface SupervisorGoalFillEvidence {
|
|
|
17
18
|
export interface SupervisorGoalFillInput {
|
|
18
19
|
path: string;
|
|
19
20
|
round: number;
|
|
20
|
-
gate: { passed: boolean; log?: string };
|
|
21
|
+
gate: { passed: boolean; log?: string; testStepExecuted?: boolean; scopeReason?: string };
|
|
21
22
|
review?: { verdict: 'pass' | 'warn' | 'fail' };
|
|
22
23
|
/** An external checker, deliberately separate from this writer/parser. */
|
|
23
24
|
independentlyCheck: (document: string, evidence: SupervisorGoalFillEvidence) => Promise<boolean>;
|
|
25
|
+
wiring?: 'wired' | 'unwired';
|
|
26
|
+
observeDeficit?: (observation: SupervisorGoalDeficit) => void;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
|
-
export
|
|
29
|
+
export interface SupervisorGoalDeficit {
|
|
30
|
+
evidenceId: string;
|
|
31
|
+
kind: 'unmeasured' | 'unwired' | 'unverified';
|
|
32
|
+
previousEvidence: string;
|
|
33
|
+
round: number;
|
|
34
|
+
gateLog?: string;
|
|
35
|
+
/** Decision branch, without gate log or goal text. */
|
|
36
|
+
reason?: 'missing-section' | 'missing-invariant-slot' | 'missing-signal-slot' | 'gate-evidence-unverified' | 'review-unavailable' | 'goal-unwired' | 'slot-format' | 'authored-signal-command-mismatch' | 'independent-check-failed';
|
|
37
|
+
inputSummary?: { gatePassed: boolean; hasGateLog: boolean; hasReview: boolean; invariantSlot: boolean; signalSlot: boolean };
|
|
38
|
+
gateLogRef?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type SupervisorGoalFillResult = 'filled' | 'already-filled' | 'not-applicable' | 'unverifiable' | 'rejected';
|
|
27
42
|
|
|
28
43
|
const UNVERIFIABLE = 'UNVERIFIABLE';
|
|
29
44
|
|
|
30
45
|
interface VerifiedGateEvidence {
|
|
31
46
|
command: string;
|
|
32
47
|
observedFail: number;
|
|
33
|
-
baselineLine
|
|
48
|
+
baselineLine?: string;
|
|
34
49
|
}
|
|
35
50
|
|
|
36
51
|
/**
|
|
37
52
|
* ⛔ **로그가 스스로 모순이면 채우지 않는다.** 종전 판은 ⓐ `[test] PASS` 접두와 명령 모양만 보고
|
|
38
|
-
* ⓑ
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* 같은 로그를 **다시** 판정할 수 있게 한다.
|
|
53
|
+
* ⓑ PASS 로그의 fail 수를 읽지 않아 `[test] PASS ... 5 fail`도 채울 수 있었다.
|
|
54
|
+
* ⇒ PASS의 실제 0 fail 요약을 필수로 읽는다. 실패 귀속용 baseline은 실행된 경우에만
|
|
55
|
+
* 원문을 검증하며, PASS에서 측정하지 않은 baseline 0건을 만들어 적지 않는다.
|
|
42
56
|
*/
|
|
43
57
|
function verifiedGateEvidence(gate: SupervisorGoalFillInput['gate']): VerifiedGateEvidence | undefined {
|
|
44
58
|
if (!gate.passed || !gate.log) return undefined;
|
|
@@ -54,11 +68,13 @@ function verifiedGateEvidence(gate: SupervisorGoalFillInput['gate']): VerifiedGa
|
|
|
54
68
|
const observedFail = Number(failMatch[1]);
|
|
55
69
|
if (observedFail !== 0) return undefined; // PASS 라고 적혀 있어도 fail 이 있으면 모순이다
|
|
56
70
|
|
|
57
|
-
//
|
|
71
|
+
// PASS 자체가 test 0 fail의 측정값이다. 실패 귀속 baseline은 PASS에서 실행되지 않는다.
|
|
72
|
+
// 행이 있다면 실제 값을 검증하고, 잘못된/모순된 행은 조용히 무시하지 않는다.
|
|
73
|
+
const rawBaseline = gate.log.split('\n').find((line) => line.startsWith('[gate-baseline]'));
|
|
58
74
|
const baseline = gate.log.match(/^\[gate-baseline\]\s+introduced=(\d+),\s*preexisting=(\d+),\s*unknown=(\d+),\s*precondition-unmet=(\d+).*$/m);
|
|
59
|
-
if (!baseline) return undefined;
|
|
60
|
-
if (baseline
|
|
61
|
-
return { command, observedFail, baselineLine: baseline[0].trim() };
|
|
75
|
+
if (rawBaseline && !baseline) return undefined;
|
|
76
|
+
if (baseline?.slice(1, 5).some((count) => count !== '0')) return undefined;
|
|
77
|
+
return { command, observedFail, ...(baseline ? { baselineLine: baseline[0].trim() } : {}) };
|
|
62
78
|
}
|
|
63
79
|
|
|
64
80
|
function section(document: string, heading: string): { start: number; end: number; body: string } | undefined {
|
|
@@ -75,11 +91,11 @@ function section(document: string, heading: string): { start: number; end: numbe
|
|
|
75
91
|
* ⛔ 그리고 **기대값이 아니라 관측값**을 적는다 — 종전 판은 로그를 안 읽고 `기대 — fail 0` 을 박았다.
|
|
76
92
|
*/
|
|
77
93
|
function invariantReplacement(evidence: SupervisorGoalFillEvidence): string {
|
|
78
|
-
return `- filled-by: supervisor@round-${evidence.round}\n 조건 — ${evidence.command} 가 실패 없이 끝난다\n 이 라운드에서 관측됨 — fail ${evidence.observedFail}\n 근거 — round-${evidence.round} gate [test] PASS ${evidence.command} · ${evidence.baselineLine}`;
|
|
94
|
+
return `- filled-by: supervisor@round-${evidence.round}\n 조건 — ${evidence.command} 가 실패 없이 끝난다\n 이 라운드에서 관측됨 — fail ${evidence.observedFail}\n 근거 — round-${evidence.round} gate [test] PASS ${evidence.command} · ${evidence.baselineLine ?? 'baseline not run (test PASS)'}`;
|
|
79
95
|
}
|
|
80
96
|
|
|
81
97
|
function signalReplacement(evidence: SupervisorGoalFillEvidence): string {
|
|
82
|
-
return `- filled-by: supervisor@round-${evidence.round}\n 관측 — \`${evidence.command}\` 요약 줄의 fail 수\n 이번 라운드 관측값 — fail ${evidence.observedFail}\n 근거 — round-${evidence.round} review ${evidence.reviewVerdict} · ${evidence.baselineLine}`;
|
|
98
|
+
return `- filled-by: supervisor@round-${evidence.round}\n 관측 — \`${evidence.command}\` 요약 줄의 fail 수\n 이번 라운드 관측값 — fail ${evidence.observedFail}\n 근거 — round-${evidence.round} review ${evidence.reviewVerdict} · ${evidence.baselineLine ?? 'baseline not run (test PASS)'}`;
|
|
83
99
|
}
|
|
84
100
|
|
|
85
101
|
function replaceUnverifiableSlot(body: string, filled: string): string | undefined {
|
|
@@ -88,7 +104,7 @@ function replaceUnverifiableSlot(body: string, filled: string): string | undefin
|
|
|
88
104
|
}
|
|
89
105
|
|
|
90
106
|
/**
|
|
91
|
-
* Fill
|
|
107
|
+
* Fill an empty invariant and either an empty signal or append an observation to an authored signal. Gate evidence is accepted only when
|
|
92
108
|
* its logged test command and PASS status agree; baseline contradictions keep
|
|
93
109
|
* the original document queued and byte-identical.
|
|
94
110
|
*/
|
|
@@ -96,27 +112,60 @@ export async function fillUnverifiableGoalSlots(input: SupervisorGoalFillInput):
|
|
|
96
112
|
const original = readFileSync(input.path, 'utf8');
|
|
97
113
|
const invariant = section(original, '## 불변식');
|
|
98
114
|
const signals = section(original, '## 판정 신호');
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
const signalsNeedFill = signals.body.includes(UNVERIFIABLE);
|
|
102
|
-
if (!invariantNeedsFill && !signalsNeedFill) return 'already-filled';
|
|
103
|
-
|
|
115
|
+
const invariantSlot = Boolean(invariant && /^- UNVERIFIABLE(?:[ \t]*:[^\r\n]*)?[ \t]*$/m.test(invariant.body));
|
|
116
|
+
const signalSlot = Boolean(signals && /^- UNVERIFIABLE(?:[ \t]*:[^\r\n]*)?[ \t]*$/m.test(signals.body));
|
|
104
117
|
const gateEvidence = verifiedGateEvidence(input.gate);
|
|
105
|
-
|
|
118
|
+
const deficit = (reason: NonNullable<SupervisorGoalDeficit['reason']>): void => input.observeDeficit?.({
|
|
119
|
+
evidenceId: createHash('sha256').update(JSON.stringify([input.path, input.round, original])).digest('hex').slice(0, 16),
|
|
120
|
+
kind: !gateEvidence || !input.review ? 'unmeasured' : input.wiring === 'unwired' ? 'unwired' : 'unverified',
|
|
121
|
+
previousEvidence: original,
|
|
122
|
+
round: input.round,
|
|
123
|
+
...(input.gate.log !== undefined ? { gateLog: input.gate.log } : {}),
|
|
124
|
+
reason,
|
|
125
|
+
inputSummary: { gatePassed: input.gate.passed, hasGateLog: Boolean(input.gate.log), hasReview: Boolean(input.review), invariantSlot, signalSlot },
|
|
126
|
+
...(input.gate.log ? { gateLogRef: `sha256:${createHash('sha256').update(input.gate.log).digest('hex').slice(0, 16)}` } : {}),
|
|
127
|
+
});
|
|
128
|
+
if (!invariant || !signals) {
|
|
129
|
+
// A sectionless goal has no slot the supervisor can measure or repair.
|
|
130
|
+
// Report a deficit only when a present section contains an actual slot.
|
|
131
|
+
if (invariantSlot || signalSlot) deficit('missing-section');
|
|
132
|
+
return 'unverifiable';
|
|
133
|
+
}
|
|
134
|
+
if (!invariantSlot && !signalSlot && !invariant.body.includes(UNVERIFIABLE) && !signals.body.includes(UNVERIFIABLE)
|
|
135
|
+
&& input.wiring !== 'unwired') return 'already-filled';
|
|
136
|
+
if (!invariantSlot) { deficit('missing-invariant-slot'); return 'unverifiable'; }
|
|
137
|
+
if (!signalSlot && !signals.body.trim()) { deficit('missing-signal-slot'); return 'unverifiable'; }
|
|
138
|
+
// A docs-only PASS has no test measurement to put into the authored slots.
|
|
139
|
+
// Trust the gate's structured scope, never a free-text log line, and leave the goal unchanged.
|
|
140
|
+
if (input.gate.passed && input.gate.testStepExecuted === false && input.gate.scopeReason === 'docs-only'
|
|
141
|
+
&& input.wiring !== 'unwired') {
|
|
142
|
+
return 'not-applicable';
|
|
143
|
+
}
|
|
144
|
+
if (!gateEvidence) { deficit('gate-evidence-unverified'); return 'unverifiable'; }
|
|
145
|
+
if (!input.review) { deficit('review-unavailable'); return 'unverifiable'; }
|
|
146
|
+
if (input.wiring === 'unwired') { deficit('goal-unwired'); return 'unverifiable'; }
|
|
147
|
+
// The authored completion signal must name the test we actually measured.
|
|
148
|
+
if (!signalSlot) {
|
|
149
|
+
const authoredCommand = signals.body.match(/^\s*- Condition:\s*(bun test\s+[^\r\n]+?)(?:\s+를 실행한다)?\s*$/m)?.[1]?.trim();
|
|
150
|
+
if (!authoredCommand || authoredCommand !== gateEvidence.command) {
|
|
151
|
+
deficit('authored-signal-command-mismatch'); return 'unverifiable';
|
|
152
|
+
}
|
|
153
|
+
}
|
|
106
154
|
|
|
107
155
|
const evidence: SupervisorGoalFillEvidence = {
|
|
108
156
|
round: input.round,
|
|
109
157
|
command: gateEvidence.command,
|
|
110
158
|
reviewVerdict: input.review.verdict,
|
|
111
159
|
observedFail: gateEvidence.observedFail,
|
|
112
|
-
baselineLine: gateEvidence.baselineLine,
|
|
160
|
+
...(gateEvidence.baselineLine ? { baselineLine: gateEvidence.baselineLine } : {}),
|
|
113
161
|
gateLog: input.gate.log ?? '',
|
|
114
162
|
};
|
|
115
163
|
const invariantBody = replaceUnverifiableSlot(invariant.body, invariantReplacement(evidence));
|
|
116
|
-
const signalBody = replaceUnverifiableSlot(signals.body, signalReplacement(evidence))
|
|
117
|
-
|
|
164
|
+
const signalBody = signalSlot ? replaceUnverifiableSlot(signals.body, signalReplacement(evidence))
|
|
165
|
+
: `${signals.body.replace(/\s*$/, '')}\n${signalReplacement(evidence)}\n`;
|
|
166
|
+
if (invariantBody === undefined || signalBody === undefined) { deficit('slot-format'); return 'unverifiable'; }
|
|
118
167
|
const candidate = `${original.slice(0, invariant.start)}## 불변식${invariantBody}${original.slice(invariant.end, signals.start)}## 판정 신호${signalBody}${original.slice(signals.end)}`;
|
|
119
|
-
if (!await input.independentlyCheck(candidate, evidence)) return 'rejected';
|
|
168
|
+
if (!await input.independentlyCheck(candidate, evidence)) { deficit('independent-check-failed'); return 'rejected'; }
|
|
120
169
|
|
|
121
170
|
const temporary = join(dirname(input.path), `.${Math.random().toString(16).slice(2)}.goal-fill.tmp`);
|
|
122
171
|
try {
|
|
@@ -3,6 +3,7 @@ import { applyGraphOverlays, type GraphOverlaySpec, type OverlayPatchOp, type Ov
|
|
|
3
3
|
import { edgeMapOf, graphVersionHash, type GraphEdgeSpec, type GraphNodeSpec, type GraphTemplateSpec } from './graph-yaml.js';
|
|
4
4
|
import { inspectPipelineGraph } from './pipeline-shape.js';
|
|
5
5
|
import { hasNodeKind } from '../graph-kinds/registry.js';
|
|
6
|
+
import { GOAL_TYPES, type GoalType } from './goal-author.js';
|
|
6
7
|
|
|
7
8
|
/** A proposed change to one existing outcome of a conditional route. Unconditional and fallback edges are protected. */
|
|
8
9
|
export interface GraphVariantRoute {
|
|
@@ -24,6 +25,18 @@ export interface GraphVariantPlan {
|
|
|
24
25
|
readonly growth?: GraphVariantGrowth;
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
/** 골 분석 중 최초 변형 선택이 보는 «두» 입력 — 문서 전용·저작 등급 같은 원 칸의 다른 축은 이 조각에 없다. */
|
|
29
|
+
export interface GraphVariantGoalAnalysis {
|
|
30
|
+
readonly goalType: GoalType;
|
|
31
|
+
readonly targetPathCount: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** 최초 graph variant 선택 — id·선택 이유가 런 원장 옆 .graph.yaml 에 함께 저장되고 재조회된다. */
|
|
35
|
+
export interface GraphVariantSelection {
|
|
36
|
+
readonly variantId: string;
|
|
37
|
+
readonly reason: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
27
40
|
export type GraphVariantRejection =
|
|
28
41
|
| { readonly kind: 'invalid-goal' }
|
|
29
42
|
| { readonly kind: 'unknown-node'; readonly node: string }
|
|
@@ -35,25 +48,46 @@ export type GraphVariantRejection =
|
|
|
35
48
|
| { readonly kind: 'unreachable-terminal'; readonly node: string }
|
|
36
49
|
| { readonly kind: 'invalid-graph'; readonly defects: ReturnType<typeof inspectPipelineGraph> }
|
|
37
50
|
| { readonly kind: 'overlay-rejected'; readonly rejections: readonly OverlayRejection[] }
|
|
38
|
-
| { readonly kind: 'invalid-growth'; readonly reason: string }
|
|
51
|
+
| { readonly kind: 'invalid-growth'; readonly reason: string }
|
|
52
|
+
| { readonly kind: 'invalid-goal-analysis' };
|
|
39
53
|
|
|
40
54
|
export type GraphVariantResult =
|
|
41
|
-
| { readonly ok: true; readonly overlay: GraphOverlaySpec; readonly template: GraphTemplateSpec; readonly patches: readonly OverlayPatchOp[] }
|
|
55
|
+
| { readonly ok: true; readonly overlay: GraphOverlaySpec; readonly template: GraphTemplateSpec; readonly patches: readonly OverlayPatchOp[]; readonly selection?: GraphVariantSelection }
|
|
42
56
|
| { readonly ok: false; readonly rejections: readonly GraphVariantRejection[] };
|
|
43
57
|
|
|
58
|
+
/** 최초 변형 선택(id·선택 이유)의 결정론적 유도 — 같은 종류·대상 경로 수면 항상 같은 값을 낸다. */
|
|
59
|
+
export function initialGraphVariantSelection(analysis: GraphVariantGoalAnalysis): GraphVariantSelection {
|
|
60
|
+
const variantId = `variant-${analysis.goalType}-${createHash('sha256')
|
|
61
|
+
.update(JSON.stringify({ goalType: analysis.goalType, targetPathCount: analysis.targetPathCount }))
|
|
62
|
+
.digest('hex').slice(0, 12)}`;
|
|
63
|
+
return {
|
|
64
|
+
variantId,
|
|
65
|
+
reason: `initial graph variant selected from goal type ${analysis.goalType} with ${analysis.targetPathCount} target path${analysis.targetPathCount === 1 ? '' : 's'}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
44
69
|
/** Pure, deterministic variant authoring. Never mutates the supplied template and never writes an overlay. */
|
|
45
70
|
export function createGraphVariant(input: {
|
|
46
71
|
readonly template: GraphTemplateSpec;
|
|
47
72
|
readonly goal: string;
|
|
48
73
|
readonly plan: GraphVariantPlan;
|
|
74
|
+
readonly goalAnalysis?: GraphVariantGoalAnalysis;
|
|
49
75
|
}): GraphVariantResult {
|
|
50
|
-
const { template, goal, plan } = input;
|
|
76
|
+
const { template, goal, plan, goalAnalysis } = input;
|
|
51
77
|
const known = new Set(template.nodes.map((node) => node.nodeId));
|
|
52
78
|
const rejections: GraphVariantRejection[] = [];
|
|
53
79
|
if (!/^g_[a-z0-9_-]+$/i.test(goal)) rejections.push({ kind: 'invalid-goal' });
|
|
80
|
+
let selection: GraphVariantSelection | undefined;
|
|
81
|
+
if (goalAnalysis !== undefined) {
|
|
82
|
+
if (!GOAL_TYPES.includes(goalAnalysis.goalType) || !Number.isSafeInteger(goalAnalysis.targetPathCount) || goalAnalysis.targetPathCount < 0) {
|
|
83
|
+
rejections.push({ kind: 'invalid-goal-analysis' });
|
|
84
|
+
} else {
|
|
85
|
+
selection = initialGraphVariantSelection(goalAnalysis);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
54
88
|
if (plan.growth) {
|
|
55
89
|
const { node, from, outcome, returnTo } = plan.growth;
|
|
56
|
-
if (!node || typeof node !== 'object') return { ok: false, rejections: [{ kind: 'invalid-growth', reason: 'growth requires one new contracted node' }] };
|
|
90
|
+
if (!node || typeof node !== 'object') return { ok: false, rejections: [...rejections, { kind: 'invalid-growth', reason: 'growth requires one new contracted node' }] };
|
|
57
91
|
const edgeIndex = template.edges.findIndex((edge) => edge.from === from);
|
|
58
92
|
const edge = template.edges[edgeIndex];
|
|
59
93
|
if (!known.has(from) || known.has(node.nodeId) || template.terminalNodes.includes(from) ||
|
|
@@ -94,7 +128,7 @@ export function createGraphVariant(input: {
|
|
|
94
128
|
}
|
|
95
129
|
const unreachable = projected.terminalNodes.filter((terminal) => !reached.has(terminal) || (edges[terminal]?.length ?? 0) !== 0);
|
|
96
130
|
if (unreachable.length) return { ok: false, rejections: unreachable.map((terminal) => ({ kind: 'unreachable-terminal', node: terminal })) };
|
|
97
|
-
return { ok: true, overlay, template: projected, patches };
|
|
131
|
+
return { ok: true, overlay, template: projected, patches, ...(selection === undefined ? {} : { selection }) };
|
|
98
132
|
}
|
|
99
133
|
const patches: OverlayPatchOp[] = [];
|
|
100
134
|
|
|
@@ -167,5 +201,5 @@ export function createGraphVariant(input: {
|
|
|
167
201
|
})) };
|
|
168
202
|
const applied = applyGraphOverlays(validationTemplate, [overlay]);
|
|
169
203
|
if (!applied.ok) return { ok: false, rejections: [{ kind: 'overlay-rejected', rejections: applied.rejections }] };
|
|
170
|
-
return { ok: true, overlay, template: projected, patches };
|
|
204
|
+
return { ok: true, overlay, template: projected, patches, ...(selection === undefined ? {} : { selection }) };
|
|
171
205
|
}
|