elanous 0.2.36 → 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/{uC-N0emedeNOFuaBQFv-I → 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/{4286.b70c4520306817e8.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/{3410.7f9af5ab77cbe65f.js → 1746.3563617ea64023a3.js} +1 -1
- 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/1ed5e8af.cf424815c7c0efad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9250-072df22eaadaa6b5.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/210.90b2cbd64926cf34.js +32 -0
- package/apps/pwa/out/_next/static/chunks/{3727.7949ccaacaa71242.js → 2283.edd9627b7bdfb546.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/2318-450e75d07605b8fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4615.8525eb0add35eba6.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/{5711.957b095705c12560.js → 3199.6a1a9b0e6cd01dc6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2986.45d7652e4f13557e.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/{7481.39f7a4654907bf6e.js → 4313.76f232c304a15bde.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4324.c99ba3e83eb1b691.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4337e36d.f42c3b391b3d8f20.js +122 -0
- package/apps/pwa/out/_next/static/chunks/{6943.c6b24124853a47b2.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/{3757-180308bc61021b05.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/4833-7934c592c5569f00.js +1 -0
- 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/{771.c3cdb6c1f7f47c02.js → 4931.95cc6dbd230774ca.js} +3 -3
- 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/{552.b7d061ad91eeac51.js → 5046.7fd5cbd859299448.js} +2 -2
- 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/{9f31e478.fefcbcd3c388ebc5.js → 58edce7d.f1b0c72acf13b123.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +93 -0
- package/apps/pwa/out/_next/static/chunks/{3136.30aaaa5fa03662a3.js → 5952.294fc574a8625184.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{da5ecc5c-b005ad8cac737d57.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/{3324.a09703033abcbd2f.js → 6252.240578f10952e091.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8904.7d51af2dc033965c.js → 6680.6a693c28aae4cd19.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{275-02ea4c2a33980422.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/{528.38ce20ef8aa251ff.js → 6819.be5c9c4d67f22922.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6971-fb5f9dc0a2cb5d2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3a3d9966.cc4d4585a2708e7c.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/{4304.e9b2512834a9e23e.js → 7424.c0fe2a595d4232b5.js} +1 -1
- 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/{2683.c9773a0c589b031b.js → 7867.e8725745ddd1d940.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/{6466-92e65a48490b68a9.js → 7893-e444a1b0809cd1e4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{ccae1c4b-0cf414f5eff1b10d.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/{3840-5825d56d46976a92.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/{873d6c12.09bd499f57171543.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/{575.d929793a53f27c4b.js → 9151.a2c51e93f9156dae.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9175-7d383df15a82e2be.js +1 -0
- 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/{190.285c832bd9626f8c.js → 958.53a8dcf4729e6997.js} +1 -1
- 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-e2de2e59111c9aad.js → page-3337c6a1328c2674.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/{page-f2b2e4bf6e981450.js → page-89acd5d68c0bc560.js} +1 -1
- 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-2af16e62c12f22df.js → page-fe986fe79b107546.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-1e5da297557d2354.js +1 -0
- 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-88a1edbff62eaf1d.js +1 -0
- 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-443364c9e4a23b31.js +1 -0
- 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-ac2c1e6169cfce57.js +1 -0
- 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/{053a429e.9a63436527cc751c.js → d9815f84.4918f682a45a8502.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{ceba0382.650712b56b85b582.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/graphs/drafts/recipes.yaml +27 -7
- 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/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/codex-fallback-live-probe.ts +17 -15
- package/scripts/fleet/node-setup.sh +32 -2
- package/scripts/fleet/run-light-worker.sh +9 -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 +140 -0
- package/scripts/release-loop/gate-closure.ts +48 -0
- package/scripts/release-loop/gate-diff.ts +2 -1
- package/scripts/release-loop/known-issues-node.ts +6 -4
- package/scripts/release-loop/notes-repair.ts +216 -0
- package/scripts/release-loop/prepare-node.ts +61 -5
- package/scripts/release-loop/resume-release.ts +114 -4
- package/scripts/release-loop/resume-test-traffic.ts +10 -0
- package/scripts/release-loop/version-node.ts +81 -12
- package/scripts/train/green-leg.ts +176 -0
- package/scripts/tui-continue-real-evidence.ts +47 -0
- package/scripts/ux-sim.ts +1 -1
- package/src/acp/client.ts +31 -5
- package/src/acp/core-turn-bridge.ts +6 -0
- package/src/acp/stderr-summary.ts +49 -0
- package/src/agent/monad-agent-turn.ts +1 -0
- package/src/agent/terminal-surface.ts +217 -0
- package/src/agent-substrate/pr-reviewer.ts +11 -3
- package/src/agent-substrate/self-review-cli.ts +343 -31
- package/src/autopilot/lineage/sources.ts +1 -1
- package/src/autopilot/pr-manager.ts +64 -13
- package/src/boot/daemon-runtime.ts +35 -3
- package/src/boot/daemon-tools/pty-shell.ts +2 -1
- package/src/budget/run-usage-rollup.ts +12 -7
- package/src/budget/unified-usage.ts +20 -0
- package/src/capture/tui-self-report.ts +32 -3
- package/src/cli/autopilot-cli.ts +24 -9
- package/src/cli/decisions-cli.ts +7 -4
- package/src/cli/doctor-cli.ts +116 -7
- package/src/cli/logs-cli.ts +357 -2
- package/src/cli/memory-cli.ts +30 -1
- package/src/cli/msg-cli.ts +15 -11
- package/src/cli/pr-granularity.ts +5 -3
- package/src/cli/release-checklist-read-cli.ts +109 -4
- package/src/cli/release-cli.ts +43 -10
- package/src/cli/self-update.ts +23 -5
- package/src/cli/self-utterances-cli.ts +13 -16
- package/src/cli/tasks-cli.ts +309 -11
- 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-goal-loop.ts +5 -2
- package/src/core-turn/types.ts +2 -0
- package/src/dashboard/chat/acp-chat.ts +9 -0
- package/src/dashboard/index.ts +97 -13
- package/src/dashboard/input/agent-wake.ts +43 -0
- package/src/dashboard/input/chat-main-acp-dispatch.ts +21 -1
- package/src/dashboard/replay-preview.ts +25 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +17 -8
- package/src/dashboard/synchronized-frame-output.ts +74 -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/surface-events.ts +80 -1
- 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/graph-runner/graph-cli.ts +26 -2
- package/src/graph-runner/graph-run-api.ts +3 -2
- package/src/graph-runner/runner.ts +17 -5
- package/src/graph-wizard/generate.ts +29 -6
- package/src/harness/harness-cli-command.ts +179 -33
- package/src/harness/review-adapter.ts +26 -6
- package/src/index.ts +116 -13
- package/src/instance/test-write-guard-real-transport.fixture.ts +52 -0
- 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.ts +123 -11
- 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/orchestrator/anomaly-cluster.ts +243 -0
- package/src/loops/orchestrator/tick.ts +49 -4
- package/src/model-tier/llm-tier-map.ts +12 -17
- package/src/msg/msg-store.ts +17 -0
- package/src/native-tool-catalog.ts +1 -1
- package/src/nexus/api/graph-wizard-api.ts +27 -2
- 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/state/state.ts +7 -1
- package/src/oauth/codex-account-store.ts +34 -1
- package/src/ops/loops-map.ts +46 -0
- package/src/ops/overview-cache.ts +22 -4
- package/src/ops/overview.ts +41 -5
- package/src/policy/llm-policy.ts +3 -1
- package/src/prompt-enhance/enhance.ts +4 -4
- package/src/pty-shell/availability.ts +7 -0
- package/src/pty-shell/herdr-agent-report.ts +40 -31
- 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 +187 -18
- package/src/pty-shell/registry.ts +25 -15
- package/src/pty-shell/tui-run-state.ts +235 -1
- package/src/release-loop/checklist.ts +50 -5
- package/src/release-loop/feature-store.ts +9 -9
- package/src/release-loop/landed-but-yellow.ts +93 -12
- package/src/repl/index.ts +8 -0
- 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 +29 -18
- package/src/self-dev/dev-pipeline.ts +29 -7
- package/src/self-dev/draft-sweep.ts +241 -16
- package/src/self-dev/draft-triage-rules.ts +19 -5
- package/src/self-dev/review-provider-fallback.ts +45 -7
- package/src/self-dev/shard-plan.ts +48 -0
- package/src/self-dev/shard-run.ts +50 -3
- package/src/self-implement/doctor-visit.ts +83 -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.ts +333 -18
- package/src/self-implement/goal-supervisor-fill.ts +75 -26
- package/src/self-implement/importer-test-index.ts +215 -2
- package/src/self-implement/knowhow-pack.ts +5 -5
- package/src/self-implement/orchestrator.ts +318 -25
- package/src/self-implement/review-round-brief.ts +300 -0
- package/src/self-implement/rework-policy.ts +14 -0
- package/src/self-implement/run-ledger.ts +170 -6
- package/src/self-implement/run-stop.ts +1 -1
- package/src/self-implement/running-runs.ts +17 -3
- package/src/self-implement/seams.ts +12 -6
- 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/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/skills/tools/pty.ts +5 -0
- package/src/status/metrics.ts +12 -1
- package/src/steward/rejudge-tick.ts +12 -5
- package/src/steward/resync-tick.ts +31 -4
- package/src/task-agent/actions.ts +199 -4
- 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/live-moves.ts +48 -3
- 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/parent-host.ts +21 -11
- package/src/task-agent/rejudge-on-head.ts +72 -5
- package/src/task-agent/repair-cycle.ts +41 -0
- package/src/task-agent/repair-next-move.ts +12 -2
- package/src/task-agent/review-prior-fix.ts +12 -2
- package/src/task-agent/shadow.ts +188 -5
- package/src/task-agent/task-hand.ts +158 -13
- package/src/task-agent/task-parent-role-llm.ts +9 -0
- package/src/task-agent/tier-split.ts +4 -3
- 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-artifact-return.ts +16 -6
- 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-pool.ts +50 -4
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +15 -9
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +217 -36
- package/src/task-orchestrator/surfaces/self-implement.ts +4 -0
- package/src/testing/linux-env.ts +177 -0
- package/src/tui/chat/goal-interim.ts +5 -1
- package/src/tui/entry.ts +258 -4
- package/src/tui/input/at-picker.ts +55 -0
- package/src/tui/slash/resume.ts +35 -12
- 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 +4 -3
- 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 +158 -4
- package/src/ux-sim/fake-gh.ts +174 -0
- package/src/ux-sim/fake-kubectl.ts +142 -0
- package/src/ux-sim/fake-llm.ts +6 -1
- package/src/ux-sim/next-tui-seat-scenarios.ts +124 -6
- 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/task-agent-parent-host-device.ts +264 -0
- package/src/ux-sim/task-agent-rejudge-on-head-device.ts +114 -0
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +0 -287
- package/apps/pwa/out/_next/static/chunks/1201.afbfc5b1c5e5cbe4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +0 -36
- package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +0 -149
- package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2500.cbc1257b774aae52.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +0 -24
- package/apps/pwa/out/_next/static/chunks/2812ca6a.3b9f4a7a08885744.js +0 -1
- package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2941.3c3546f96bc6efa7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +0 -24
- package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3148-98efd4869d660a87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +0 -226
- package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +0 -8
- package/apps/pwa/out/_next/static/chunks/3538.a445e50bb359d068.js +0 -32
- package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +0 -286
- package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +0 -1
- package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +0 -1
- package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +0 -74
- package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +0 -104
- package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +0 -148
- package/apps/pwa/out/_next/static/chunks/5085-bce4904931767ca6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +0 -93
- package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +0 -122
- package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/599.c39c571b6733f2a2.js +0 -41
- package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +0 -79
- package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +0 -1
- package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +0 -27
- package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6925.562d532110879886.js +0 -1
- package/apps/pwa/out/_next/static/chunks/727.7deb87749b0a343a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7891.03f910124a737985.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +0 -1
- package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +0 -62
- package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +0 -90
- package/apps/pwa/out/_next/static/chunks/914.8abefd48d579547b.js +0 -94
- package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +0 -77
- package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9514.131c52cc75fe6439.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9789.60f723d18097ec30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-083747f1d4518f61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f9a61e4d.1fc2c1dbdd49fe46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +0 -1
- /package/apps/pwa/out/_next/static/{uC-N0emedeNOFuaBQFv-I → 8kITumG9GAZ1LwT9POrAR}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { readFileSync, readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
|
|
5
|
+
export type ReviewFindingKind = 'a' | 'b' | 'c' | 'd' | 'unclassified';
|
|
6
|
+
export type ReviewBriefDirection = 'continue' | 'split' | 'partial-land' | 're-ground' | 'decision-card';
|
|
7
|
+
|
|
8
|
+
export interface ReviewResultFile {
|
|
9
|
+
path: string;
|
|
10
|
+
mtimeMs: number;
|
|
11
|
+
value: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ReviewBriefInput {
|
|
15
|
+
pr: number;
|
|
16
|
+
head: string;
|
|
17
|
+
body: string;
|
|
18
|
+
changedFiles: string[];
|
|
19
|
+
results: ReviewResultFile[];
|
|
20
|
+
/** Explicit, separately attributed PR disposition comments; not saved reviews. */
|
|
21
|
+
comments?: string[];
|
|
22
|
+
/** Files that matched this PR's review-result naming pattern but could not be read. */
|
|
23
|
+
readErrors?: string[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ReviewBriefFinding {
|
|
27
|
+
id: string;
|
|
28
|
+
sourceHead: string;
|
|
29
|
+
text: string;
|
|
30
|
+
kind: ReviewFindingKind;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface ReviewRoundBrief {
|
|
34
|
+
status: 'ready' | 'unmeasured' | 'stale' | 'disposition-only' | 'unavailable';
|
|
35
|
+
/** Saved reviewed-head evidence versus a PR author's explicit split disposition. */
|
|
36
|
+
source: 'saved-review' | 'pr-disposition' | 'none';
|
|
37
|
+
pr: number;
|
|
38
|
+
head: string;
|
|
39
|
+
rounds: number;
|
|
40
|
+
currentHeadMeasured: boolean;
|
|
41
|
+
reviewedHead?: string;
|
|
42
|
+
reviewedVerdict: string;
|
|
43
|
+
reviewedRx: ReviewBriefDirection;
|
|
44
|
+
goalQuestion: string;
|
|
45
|
+
acceptanceSignal: string[];
|
|
46
|
+
declaredScopeBoundary: string[];
|
|
47
|
+
coreItems: ReviewBriefFinding[];
|
|
48
|
+
totalCoreItems: number;
|
|
49
|
+
omittedCoreItems: number;
|
|
50
|
+
resultPaths: string[];
|
|
51
|
+
priorFindings: ReviewBriefFinding[];
|
|
52
|
+
scopeItems: ReviewBriefFinding[];
|
|
53
|
+
totalScopeItems: number;
|
|
54
|
+
omittedScopeItems: number;
|
|
55
|
+
scopeBoundary: string;
|
|
56
|
+
totalPriorFindings: number;
|
|
57
|
+
omittedPriorFindings: number;
|
|
58
|
+
rx: ReviewBriefDirection;
|
|
59
|
+
reason?: string;
|
|
60
|
+
dispositionEvidence?: string;
|
|
61
|
+
readErrors?: string[];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const MAX_CORE_ITEMS = 5;
|
|
65
|
+
const MAX_INTENT_ACCEPTANCE_ITEMS = 5;
|
|
66
|
+
const MAX_INTENT_SOURCE_PATHS = 3;
|
|
67
|
+
const MAX_INTENT_ITEM_CHARS = 400;
|
|
68
|
+
export const REVIEW_BRIEF_INTENT_MAX_CHARS = 12_000;
|
|
69
|
+
|
|
70
|
+
function asString(value: unknown): string | null {
|
|
71
|
+
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function resultPr(value: Record<string, unknown>): number | null {
|
|
75
|
+
const raw = value.pr;
|
|
76
|
+
const parsed = typeof raw === 'number' ? raw : typeof raw === 'string' ? Number(raw) : NaN;
|
|
77
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function resultHead(value: Record<string, unknown>): string | null {
|
|
81
|
+
const head = asString(value.headCommit) ?? asString(value.reviewedHeadCommit);
|
|
82
|
+
return head && /^[a-f0-9]{12,40}$/i.test(head) ? head.toLowerCase() : null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function findings(value: Record<string, unknown>): string[] {
|
|
86
|
+
if (Array.isArray(value.mustFix) && value.mustFix.every((item) => typeof item === 'string')) {
|
|
87
|
+
return value.mustFix.map((item) => item.trim()).filter(Boolean);
|
|
88
|
+
}
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function hasValidFindings(value: Record<string, unknown>): boolean {
|
|
93
|
+
return Array.isArray(value.mustFix) && value.mustFix.every((item) => typeof item === 'string');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function section(body: string, heading: string): string[] {
|
|
97
|
+
const lines = body.split(/\r?\n/);
|
|
98
|
+
const headingPattern = new RegExp(`^(#{1,3})\\s*(?:${heading})(?:\\s*[—–:-].*)?\\s*$`, 'i');
|
|
99
|
+
const start = lines.findIndex((line) => headingPattern.test(line.trim()));
|
|
100
|
+
if (start < 0) return [];
|
|
101
|
+
const level = headingPattern.exec(lines[start]!.trim())?.[1]?.length ?? 2;
|
|
102
|
+
const out: string[] = [];
|
|
103
|
+
for (const line of lines.slice(start + 1)) {
|
|
104
|
+
const nextHeading = /^(#{1,6})\s+/.exec(line.trim());
|
|
105
|
+
if (nextHeading && nextHeading[1]!.length <= level) break;
|
|
106
|
+
const text = line.replace(/^\s*[-*]\s*/, '').trim();
|
|
107
|
+
if (text) out.push(text);
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function hasPathReference(text: string, changedFiles: readonly string[], body: string): boolean {
|
|
113
|
+
const paths = [...new Set([...changedFiles, ...(body.match(/(?:src|scripts|test|docs)\/[A-Za-z0-9_./-]+/g) ?? [])])];
|
|
114
|
+
return paths.some((path) => path.length > 3 && text.includes(path));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function classifyReviewFinding(text: string, input: Pick<ReviewBriefInput, 'changedFiles' | 'body'>): ReviewFindingKind {
|
|
118
|
+
const lower = text.toLowerCase();
|
|
119
|
+
if (/\b(?:junit|telemetry|observability) evidence\b|\bmissing (?:log|artifact|ledger) evidence\b|관측 증거|장부 증거/.test(lower)) return 'b';
|
|
120
|
+
if (/\b(?:late lease|lease timeout|timeout race|concurrent|concurrency race|parallel ordering)\b|늦은 lease|lease 시간 초과|동시성 경합/.test(lower)) return 'c';
|
|
121
|
+
if (/\b(?:new (?:test|fixture|evidence) path|missing fixture|separate evidence file)\b|새 시험 경로|별도 증거 파일/.test(lower)) return 'd';
|
|
122
|
+
if (hasPathReference(text, input.changedFiles, input.body) && /accept|assert|must|should|verify|contract|criteria|pass|통과|수용|기준|검증/.test(lower)) return 'a';
|
|
123
|
+
return 'unclassified';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function parseReviewResultFiles(dir: string, pr: number): { results: ReviewResultFile[]; errors: string[] } {
|
|
127
|
+
let names: string[];
|
|
128
|
+
try { names = readdirSync(dir); } catch (error) {
|
|
129
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return { results: [], errors: [] };
|
|
130
|
+
return { results: [], errors: [`${dir}: ${error instanceof Error ? error.message : String(error)}`] };
|
|
131
|
+
}
|
|
132
|
+
const suffix = new RegExp(`-${pr}-([a-f0-9]{7,40})\\.json$`, 'i');
|
|
133
|
+
const rows: ReviewResultFile[] = [];
|
|
134
|
+
const errors: string[] = [];
|
|
135
|
+
for (const name of names) {
|
|
136
|
+
const filenameHead = suffix.exec(name)?.[1]?.toLowerCase();
|
|
137
|
+
if (!filenameHead) continue;
|
|
138
|
+
const path = join(dir, name);
|
|
139
|
+
try {
|
|
140
|
+
const stat = statSync(path);
|
|
141
|
+
if (!stat.isFile()) continue;
|
|
142
|
+
const raw = readFileSync(path, 'utf8');
|
|
143
|
+
const value = JSON.parse(raw) as Record<string, unknown>;
|
|
144
|
+
const head = resultHead(value);
|
|
145
|
+
if (resultPr(value) !== pr || value.reviewed !== true || !head || !head.startsWith(filenameHead)) continue;
|
|
146
|
+
rows.push({ path, mtimeMs: stat.mtimeMs, value });
|
|
147
|
+
} catch (error) { errors.push(`${path}: ${error instanceof Error ? error.message : String(error)}`); }
|
|
148
|
+
}
|
|
149
|
+
return { results: rows, errors };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function explicitSplitDisposition(comments: readonly string[], input: ReviewBriefInput): Pick<ReviewRoundBrief, 'coreItems' | 'totalCoreItems' | 'omittedCoreItems' | 'dispositionEvidence'> | null {
|
|
153
|
+
for (const body of [...comments].reverse()) {
|
|
154
|
+
const match = /남은 범위\s*=\s*(.+?)\.\s*r(\d+)\s*상한 초과로 분리(?:[.。\s]|$)/i.exec(body);
|
|
155
|
+
if (!match) continue;
|
|
156
|
+
const round = Number(match[2]);
|
|
157
|
+
if (!Number.isSafeInteger(round) || round < 1) continue;
|
|
158
|
+
const items = match[1]!.split(/\s*[·⊕]\s*/).map((text) => text.trim()).filter(Boolean);
|
|
159
|
+
if (!items.length) continue;
|
|
160
|
+
const all = items.map((text, index) => ({ id: `${input.pr}:pr-disposition:${round}:${index + 1}`, sourceHead: input.head, text, kind: classifyReviewFinding(text, input) }));
|
|
161
|
+
return { coreItems: all.slice(0, MAX_CORE_ITEMS), totalCoreItems: all.length,
|
|
162
|
+
omittedCoreItems: Math.max(0, all.length - MAX_CORE_ITEMS), dispositionEvidence: body };
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function buildReviewRoundBrief(input: ReviewBriefInput): ReviewRoundBrief {
|
|
168
|
+
const perHead = new Map<string, ReviewResultFile>();
|
|
169
|
+
for (const result of input.results) {
|
|
170
|
+
const head = resultHead(result.value);
|
|
171
|
+
if (!head || resultPr(result.value) !== input.pr || result.value.reviewed !== true || !hasValidFindings(result.value)) continue;
|
|
172
|
+
const prior = perHead.get(head);
|
|
173
|
+
if (!prior || prior.mtimeMs < result.mtimeMs || (prior.mtimeMs === result.mtimeMs && prior.path.localeCompare(result.path) < 0)) perHead.set(head, result);
|
|
174
|
+
}
|
|
175
|
+
const rounds = perHead.size;
|
|
176
|
+
const currentHeadMeasured = perHead.has(input.head.toLowerCase());
|
|
177
|
+
const latest = [...perHead.values()].sort((left, right) => right.mtimeMs - left.mtimeMs || right.path.localeCompare(left.path))[0] ?? null;
|
|
178
|
+
const current = currentHeadMeasured ? perHead.get(input.head.toLowerCase())! : latest;
|
|
179
|
+
const sourceHead = current ? resultHead(current.value)! : input.head;
|
|
180
|
+
const orderedHeads = [...perHead.entries()].sort((a, b) => a[1].mtimeMs - b[1].mtimeMs || a[1].path.localeCompare(b[1].path));
|
|
181
|
+
const allFindings = orderedHeads.flatMap(([head, result]) => findings(result.value).map((text, index) => ({
|
|
182
|
+
id: `${input.pr}:${head}:mustFix:${index + 1}`, sourceHead: head, text, kind: classifyReviewFinding(text, input),
|
|
183
|
+
})));
|
|
184
|
+
const historicalFindings = allFindings.filter((item) => !currentHeadMeasured || item.sourceHead !== input.head.toLowerCase());
|
|
185
|
+
const prioritizedHistoricalFindings = !currentHeadMeasured && current
|
|
186
|
+
? [...historicalFindings.filter((item) => item.sourceHead === sourceHead), ...historicalFindings.filter((item) => item.sourceHead !== sourceHead)]
|
|
187
|
+
: historicalFindings;
|
|
188
|
+
const rawFindings = currentHeadMeasured && current ? findings(current.value) : [];
|
|
189
|
+
const resultPaths = current
|
|
190
|
+
? [current.path, ...orderedHeads.filter(([head]) => head !== sourceHead).map(([, result]) => result.path)]
|
|
191
|
+
: orderedHeads.map(([, result]) => result.path);
|
|
192
|
+
const classified = rawFindings.map((text, index) => ({ id: `${input.pr}:${sourceHead}:mustFix:${index + 1}`, sourceHead, text, kind: classifyReviewFinding(text, input) }));
|
|
193
|
+
const decisionItems = current ? findings(current.value).map((text, index) => ({ id: `${input.pr}:${sourceHead}:mustFix:${index + 1}`, sourceHead, text, kind: classifyReviewFinding(text, input) })) : [];
|
|
194
|
+
// Saved must-fix entries remain core regardless of their suggested FU kind.
|
|
195
|
+
// b/c/d are routing hints; they never erase a reviewer finding.
|
|
196
|
+
const allCoreItems = classified;
|
|
197
|
+
const coreItems = allCoreItems.slice(0, MAX_CORE_ITEMS);
|
|
198
|
+
const decisionScopeItems = decisionItems.filter((item) => item.kind === 'b' || item.kind === 'c' || item.kind === 'd');
|
|
199
|
+
const allScopeItems = currentHeadMeasured ? decisionScopeItems : [];
|
|
200
|
+
const scopeItems = allScopeItems.slice(0, MAX_CORE_ITEMS);
|
|
201
|
+
const scopeKinds = new Set(allScopeItems.map((item) => item.kind));
|
|
202
|
+
const goalQuestion = section(input.body, 'Q')[0] ?? '';
|
|
203
|
+
const acceptanceSignal = section(input.body, 'A');
|
|
204
|
+
const declaredScopeBoundary = section(input.body, '(?:경계|범위 경계|scope boundary|boundary)');
|
|
205
|
+
const verdict = typeof current?.value.verdict === 'string' ? current.value.verdict.toLowerCase() : '';
|
|
206
|
+
const reviewedRx: ReviewBriefDirection = input.readErrors?.length ? 'decision-card' : decisionItems.length > 0
|
|
207
|
+
? 'continue'
|
|
208
|
+
: ['pass', 'warn'].includes(verdict) && acceptanceSignal.length > 0 ? 'partial-land' : 'decision-card';
|
|
209
|
+
const unresolvedHistoricalCore = !currentHeadMeasured && historicalFindings.length > 0;
|
|
210
|
+
const rx: ReviewBriefDirection = input.readErrors?.length ? 'decision-card' : currentHeadMeasured ? reviewedRx : unresolvedHistoricalCore ? 'continue' : 'decision-card';
|
|
211
|
+
const candidateDisposition = !input.readErrors?.length && !unresolvedHistoricalCore ? explicitSplitDisposition(input.comments ?? [], input) : null;
|
|
212
|
+
const dispositionRound = candidateDisposition ? Number(/r(\d+)\s*상한 초과로 분리/i.exec(candidateDisposition.dispositionEvidence ?? '')?.[1]) : 0;
|
|
213
|
+
const disposition = candidateDisposition && (!currentHeadMeasured || (Number.isSafeInteger(dispositionRound) && rounds >= dispositionRound))
|
|
214
|
+
? candidateDisposition : null;
|
|
215
|
+
const scopeBoundary = disposition
|
|
216
|
+
? currentHeadMeasured
|
|
217
|
+
? 'PR 작성자의 상한 분리 처분 — 저장된 현재 head must-fix는 core에 그대로 남긴다'
|
|
218
|
+
: 'PR 작성자가 분리한 남은 범위 — 저장된 현재 head 리뷰의 판정으로 취급하지 않는다'
|
|
219
|
+
: scopeKinds.size
|
|
220
|
+
? `${[...scopeKinds].sort().join('·')} 항목은 FU 후보로 기록하고 주인·칸을 별도 지정한다 · 이 분류만으로 must-fix 를 제거하지 말 것`
|
|
221
|
+
: '분리할 b·c·d 항목 없음 — 미분류 항목은 핵심 검토에 남긴다';
|
|
222
|
+
const status = input.readErrors?.length ? 'unavailable' : disposition && !currentHeadMeasured ? 'disposition-only' : rounds === 0 ? 'unmeasured' : !currentHeadMeasured ? 'stale' : 'ready';
|
|
223
|
+
return {
|
|
224
|
+
status, source: disposition && !currentHeadMeasured ? 'pr-disposition' : rounds ? 'saved-review' : 'none', pr: input.pr, head: input.head,
|
|
225
|
+
rounds, currentHeadMeasured, ...(current ? { reviewedHead: sourceHead } : {}), reviewedVerdict: currentHeadMeasured && !input.readErrors?.length ? verdict || 'unknown' : 'unknown', reviewedRx, goalQuestion, acceptanceSignal, declaredScopeBoundary,
|
|
226
|
+
coreItems: !currentHeadMeasured && disposition ? disposition.coreItems : coreItems, totalCoreItems: !currentHeadMeasured && disposition ? disposition.totalCoreItems : allCoreItems.length, omittedCoreItems: !currentHeadMeasured && disposition ? disposition.omittedCoreItems : Math.max(0, allCoreItems.length - coreItems.length),
|
|
227
|
+
resultPaths, priorFindings: prioritizedHistoricalFindings.slice(0, MAX_CORE_ITEMS),
|
|
228
|
+
totalPriorFindings: historicalFindings.length, omittedPriorFindings: Math.max(0, historicalFindings.length - MAX_CORE_ITEMS),
|
|
229
|
+
scopeItems, totalScopeItems: allScopeItems.length, omittedScopeItems: Math.max(0, allScopeItems.length - scopeItems.length), scopeBoundary, rx: disposition ? 'split' : rx, ...(disposition ? { dispositionEvidence: disposition.dispositionEvidence } : {}),
|
|
230
|
+
...(status === 'unmeasured' ? { reason: '저장되고 reviewed=true인 리뷰 결과가 없어 라운드를 측정할 수 없습니다' } : {}),
|
|
231
|
+
...(status === 'stale' ? { reason: '저장 리뷰에 현재 PR head가 없어 현재 라운드의 must-fix를 측정할 수 없습니다' } : {}),
|
|
232
|
+
...(status === 'unavailable' ? { reason: '리뷰 결과 파일을 모두 읽지 못해 라운드 판정을 사용할 수 없습니다', readErrors: input.readErrors } : {}),
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export function loadReviewRoundBrief(input: { pr: number; head: string; body: string; changedFiles: string[]; comments?: string[]; reviewResultsDir?: string }): ReviewRoundBrief {
|
|
237
|
+
const dir = input.reviewResultsDir ?? join(effectiveInstanceRoot(), 'review-results');
|
|
238
|
+
const parsed = parseReviewResultFiles(dir, input.pr);
|
|
239
|
+
return buildReviewRoundBrief({ ...input, results: parsed.results, readErrors: parsed.errors });
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function reviewBriefEvidence(brief: ReviewRoundBrief, runId?: string): Record<string, unknown> {
|
|
243
|
+
const intentBlock = renderReviewBriefIntentBlock(brief);
|
|
244
|
+
return {
|
|
245
|
+
pr: brief.pr, head: brief.head, round: brief.rounds, rounds: brief.rounds, source: brief.source,
|
|
246
|
+
verdict: brief.currentHeadMeasured ? brief.reviewedVerdict : 'unknown',
|
|
247
|
+
...(brief.reviewedHead ? { reviewedHead: brief.reviewedHead } : {}),
|
|
248
|
+
key: `${brief.pr}:${brief.head}:${brief.rounds}`, rx: brief.rx,
|
|
249
|
+
coreItems: brief.totalCoreItems, scopeItems: brief.totalScopeItems,
|
|
250
|
+
...(intentBlock ? { intentBlock } : {}),
|
|
251
|
+
status: brief.status, ...(brief.dispositionEvidence ? { dispositionEvidence: brief.dispositionEvidence } : {}),
|
|
252
|
+
...(brief.reason ? { reason: brief.reason } : {}), ...(runId ? { runId } : {}),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** Shadow addendum for a future R3 self-review; this function does not alter the live review path. */
|
|
257
|
+
export function renderReviewBriefIntentBlock(brief: ReviewRoundBrief): string | null {
|
|
258
|
+
if (brief.status === 'unavailable' || brief.source !== 'saved-review' || brief.rounds < 2 || !brief.reviewedHead) return null;
|
|
259
|
+
const shorten = (text: string) => text.length > MAX_INTENT_ITEM_CHARS ? `${text.slice(0, MAX_INTENT_ITEM_CHARS - 1)}…` : text;
|
|
260
|
+
const paths = brief.resultPaths.slice(0, MAX_INTENT_SOURCE_PATHS).map(shorten);
|
|
261
|
+
const essential = [
|
|
262
|
+
`런 닥터 brief · PR #${brief.pr} · ${brief.currentHeadMeasured ? 'current' : 'prior'} head ${brief.reviewedHead.slice(0, 12)} · current PR head ${brief.head.slice(0, 12)} · rounds=${brief.rounds} · verdict=${brief.reviewedVerdict} · rx=${brief.rx}`,
|
|
263
|
+
...(brief.goalQuestion ? [`원래 질문: ${shorten(brief.goalQuestion)}`] : []),
|
|
264
|
+
...(brief.acceptanceSignal.length ? [
|
|
265
|
+
'원래 수용 신호:',
|
|
266
|
+
...brief.acceptanceSignal.slice(0, MAX_INTENT_ACCEPTANCE_ITEMS).map((item) => `- ${shorten(item)}`),
|
|
267
|
+
...(brief.acceptanceSignal.length > MAX_INTENT_ACCEPTANCE_ITEMS ? [`수용 신호 ${brief.acceptanceSignal.length - MAX_INTENT_ACCEPTANCE_ITEMS}개 생략`] : []),
|
|
268
|
+
] : []),
|
|
269
|
+
...(brief.declaredScopeBoundary.length ? [
|
|
270
|
+
'명시적 범위 경계:',
|
|
271
|
+
...brief.declaredScopeBoundary.slice(0, MAX_INTENT_ACCEPTANCE_ITEMS).map((item) => `- ${shorten(item)}`),
|
|
272
|
+
...(brief.declaredScopeBoundary.length > MAX_INTENT_ACCEPTANCE_ITEMS ? [`범위 경계 ${brief.declaredScopeBoundary.length - MAX_INTENT_ACCEPTANCE_ITEMS}개 생략`] : []),
|
|
273
|
+
] : []),
|
|
274
|
+
'저장된 must-fix (FU 분류도 삭제하지 않음):', ...(brief.coreItems.length ? brief.coreItems.map((item) => `- [${item.kind} · ${item.id}] ${shorten(item.text)}`) : [brief.currentHeadMeasured ? '- 현재 head의 must-fix 없음' : `- 현재 PR head 미측정 · 선택한 reviewed head ${brief.reviewedHead?.slice(0, 12) ?? 'unknown'}의 finding은 아래에 표시`]),
|
|
275
|
+
...(brief.omittedCoreItems ? [`${brief.omittedCoreItems}개 생략: 핵심 must-fix`] : []),
|
|
276
|
+
...(!brief.currentHeadMeasured && brief.totalPriorFindings > 0 ? [`실제 처방: 현재 head 리뷰 전까지 과거 미해결 must-fix를 유지하고 계속 진행 (${brief.rx})`] : []),
|
|
277
|
+
`의도적 스코프 경계: ${brief.scopeBoundary}`,
|
|
278
|
+
];
|
|
279
|
+
const optional = [
|
|
280
|
+
`과거 라운드 검토 항목 (${brief.priorFindings.length}/${brief.totalPriorFindings}, head별 저장 결과):`, ...(brief.priorFindings.length ? brief.priorFindings.map((item) => `- [${item.kind} · ${item.id}] ${shorten(item.text)}`) : ['- 저장된 must-fix 없음']),
|
|
281
|
+
...(brief.omittedPriorFindings ? [`과거 finding ${brief.omittedPriorFindings}개 생략`] : []),
|
|
282
|
+
`FU 후보 (${brief.scopeItems.length}/${brief.totalScopeItems}):`, ...(brief.scopeItems.length ? brief.scopeItems.map((item) => `- [${item.kind} · ${item.id}] ${shorten(item.text)}`) : ['- 현재 head에서 분류된 FU 후보 없음']),
|
|
283
|
+
...(brief.omittedCoreItems ? [`핵심 항목 ${brief.omittedCoreItems}개 추가 생략`] : []),
|
|
284
|
+
...(brief.omittedScopeItems ? [`FU 후보 ${brief.omittedScopeItems}개 생략`] : []),
|
|
285
|
+
...(brief.resultPaths.length ? [`리뷰 원문 파일 (${paths.length}/${brief.resultPaths.length}): ${paths.join(', ')}`,
|
|
286
|
+
...(brief.resultPaths.length > MAX_INTENT_SOURCE_PATHS ? [`원문 파일 ${brief.resultPaths.length - MAX_INTENT_SOURCE_PATHS}개 생략`] : [])] : []),
|
|
287
|
+
];
|
|
288
|
+
const lines = [...essential];
|
|
289
|
+
const sourceReference = brief.resultPaths.length
|
|
290
|
+
? `참고 원문 (${paths.length}/${brief.resultPaths.length}): ${paths.join(', ')}${brief.resultPaths.length > MAX_INTENT_SOURCE_PATHS ? ` · ${brief.resultPaths.length - MAX_INTENT_SOURCE_PATHS}개 생략` : ''}`
|
|
291
|
+
: '';
|
|
292
|
+
let omitted = 0;
|
|
293
|
+
for (const line of optional) {
|
|
294
|
+
if (lines.join('\n').length + line.length + 1 + sourceReference.length + 101 <= REVIEW_BRIEF_INTENT_MAX_CHARS) lines.push(line);
|
|
295
|
+
else omitted++;
|
|
296
|
+
}
|
|
297
|
+
if (omitted) lines.push(`보조 내용 ${omitted}줄 생략`);
|
|
298
|
+
if (sourceReference) lines.push(sourceReference);
|
|
299
|
+
return lines.join('\n');
|
|
300
|
+
}
|
|
@@ -11,6 +11,20 @@ import { eligibleRefutationGoalLines, MUST_FIX_REFUTATION_ACKNOWLEDGEMENT, REFUT
|
|
|
11
11
|
import { SUPERVISION_REWORK_SOURCES, type SupervisionReworkSource } from './supervision-vocabulary.js';
|
|
12
12
|
import { lookupLlmTierSpec } from '../model-tier/index.js';
|
|
13
13
|
|
|
14
|
+
export type ReviewRoundDecision = 'pass' | 'rework' | 'follow-up';
|
|
15
|
+
|
|
16
|
+
/** Classifies an actual review result against the current retry budget.
|
|
17
|
+
* A supervisor may extend that budget before the follow-up is finalized. */
|
|
18
|
+
export function decideReviewRound(input: {
|
|
19
|
+
verdict: 'pass' | 'warn' | 'fail';
|
|
20
|
+
mustFix: readonly string[];
|
|
21
|
+
round: number;
|
|
22
|
+
effectiveMax: number;
|
|
23
|
+
}): ReviewRoundDecision {
|
|
24
|
+
if (input.verdict !== 'fail' || input.mustFix.length === 0) return 'pass';
|
|
25
|
+
return input.round < input.effectiveMax ? 'rework' : 'follow-up';
|
|
26
|
+
}
|
|
27
|
+
|
|
14
28
|
export type ReviewFindingRepeatSignal = 'repeat' | 'no-repeat' | 'unmeasurable' | 'insufficient-history';
|
|
15
29
|
export type AdaptiveReworkReason = 'insufficient-fail-history' | 'zero-failures' | 'fail-count-not-decreased' | 'repeat-blocked-extension' | 'extended-by-fail-count' | 'hard-cap';
|
|
16
30
|
|
|
@@ -834,6 +834,8 @@ export interface RunLedgerTimelineEntry {
|
|
|
834
834
|
shardId?: string;
|
|
835
835
|
pieceIndex?: number;
|
|
836
836
|
pieceTotal?: number;
|
|
837
|
+
/** Producer-recorded `graph.unit` visits of this run, with terminal unmatched enters reported as orphans. */
|
|
838
|
+
unitVisits?: GraphUnitVisitClassification;
|
|
837
839
|
}
|
|
838
840
|
|
|
839
841
|
export interface RunLedgerTimelineQueryOptions {
|
|
@@ -875,6 +877,7 @@ export function queryRunLedgerTimeline(missionId: string, options: RunLedgerTime
|
|
|
875
877
|
...(execution.shardId === undefined ? {} : { shardId: execution.shardId }),
|
|
876
878
|
...(execution.pieceIndex === undefined ? {} : { pieceIndex: execution.pieceIndex }),
|
|
877
879
|
...(execution.pieceTotal === undefined ? {} : { pieceTotal: execution.pieceTotal }),
|
|
880
|
+
unitVisits: classifyGraphUnitVisits(ledger),
|
|
878
881
|
});
|
|
879
882
|
} catch {
|
|
880
883
|
// A corrupt or concurrently replaced ledger must not leak a partial run into another mission timeline.
|
|
@@ -883,6 +886,75 @@ export function queryRunLedgerTimeline(missionId: string, options: RunLedgerTime
|
|
|
883
886
|
return entries.sort((left, right) => Date.parse(left.executedAt) - Date.parse(right.executedAt) || left.runId.localeCompare(right.runId));
|
|
884
887
|
}
|
|
885
888
|
|
|
889
|
+
export interface GraphAdaptReport {
|
|
890
|
+
goalId: string;
|
|
891
|
+
runCount: number;
|
|
892
|
+
uniquePathSignatures: number;
|
|
893
|
+
unitCallCount: number;
|
|
894
|
+
adaptationCount: number;
|
|
895
|
+
adapted: { landed: number; denominator: number; rate: number | null };
|
|
896
|
+
nonAdapted: { landed: number; denominator: number; rate: number | null };
|
|
897
|
+
excludedCount: number;
|
|
898
|
+
exclusionReasons: Record<string, number>;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
/** Measure only producer-observed traversals and variant applications; never activate adaptation. */
|
|
902
|
+
export function queryGraphAdaptReport(goalId: string, stateDir = elanousStateRoot()): GraphAdaptReport {
|
|
903
|
+
const dir = runLedgerDir(stateDir);
|
|
904
|
+
const signatures = new Set<string>();
|
|
905
|
+
const counts = { adapted: { landed: 0, denominator: 0 }, nonAdapted: { landed: 0, denominator: 0 } };
|
|
906
|
+
const exclusionReasons: Record<string, number> = {};
|
|
907
|
+
const exclude = (reason: string): void => { exclusionReasons[reason] = (exclusionReasons[reason] ?? 0) + 1; };
|
|
908
|
+
let unitCallCount = 0;
|
|
909
|
+
let adaptationCount = 0;
|
|
910
|
+
let fileNames: string[];
|
|
911
|
+
try { fileNames = readdirSync(dir); }
|
|
912
|
+
catch (error) {
|
|
913
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') fileNames = [];
|
|
914
|
+
else throw error;
|
|
915
|
+
}
|
|
916
|
+
for (const name of fileNames) {
|
|
917
|
+
const runId = runIdFromCanonicalLedgerFile(name);
|
|
918
|
+
if (!runId) continue;
|
|
919
|
+
let ledger: RunLedgerEntry[] | null;
|
|
920
|
+
try { ledger = loadRunLedger(runId, dir); }
|
|
921
|
+
catch { exclude('invalid-ledger'); continue; }
|
|
922
|
+
if (!ledger?.length) { exclude('empty-ledger'); continue; }
|
|
923
|
+
const goalIds = new Set(ledger.map(entry => entry.goalId).filter((id): id is string => typeof id === 'string' && id.length > 0));
|
|
924
|
+
if (goalIds.size === 1 && !goalIds.has(goalId)) continue;
|
|
925
|
+
if (goalIds.size !== 1) { exclude('goal-id-missing-or-conflicting'); continue; }
|
|
926
|
+
const traversals = ledger.filter(entry => entry.event === 'pipeline-traversal-shadow');
|
|
927
|
+
const paths = traversals.map(entry => entry.data.observedNodes);
|
|
928
|
+
if (paths.length === 0 || paths.some(path => !Array.isArray(path) || path.length === 0 || !path.every(node => typeof node === 'string' && node.length > 0))) {
|
|
929
|
+
exclude('path-missing-or-invalid'); continue;
|
|
930
|
+
}
|
|
931
|
+
let graphRun: unknown;
|
|
932
|
+
try { graphRun = JSON.parse(readFileSync(join(stateDir, 'graph-runs', 'self-implement', `${runId}.json`), 'utf8')); }
|
|
933
|
+
catch (error) {
|
|
934
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { exclude('graph-run-unreadable'); continue; }
|
|
935
|
+
}
|
|
936
|
+
const recorded = graphRun && typeof graphRun === 'object' && !Array.isArray(graphRun) ? graphRun as Record<string, unknown> : null;
|
|
937
|
+
if (recorded && (recorded.runId !== runId || recorded.graphId !== 'self-implement' ||
|
|
938
|
+
(recorded.unitCalls !== undefined && !Array.isArray(recorded.unitCalls)))) {
|
|
939
|
+
exclude('unit-calls-invalid'); continue;
|
|
940
|
+
}
|
|
941
|
+
const merge = [...ledger].reverse().find(entry => entry.event === 'merged');
|
|
942
|
+
if (merge && typeof merge.data.merged !== 'boolean') { exclude('landing-invalid'); continue; }
|
|
943
|
+
signatures.add(JSON.stringify(paths.at(-1)));
|
|
944
|
+
unitCallCount += recorded && Array.isArray(recorded.unitCalls) ? recorded.unitCalls.length : 0;
|
|
945
|
+
const adaptations = ledger.filter(entry => entry.event === 'graph-variant-applied');
|
|
946
|
+
adaptationCount += adaptations.length;
|
|
947
|
+
const group = adaptations.length ? counts.adapted : counts.nonAdapted;
|
|
948
|
+
group.denominator += 1;
|
|
949
|
+
if (merge?.data.merged === true) group.landed += 1;
|
|
950
|
+
}
|
|
951
|
+
const rate = (group: { landed: number; denominator: number }) => ({ ...group, rate: group.denominator ? group.landed / group.denominator : null });
|
|
952
|
+
return { goalId, runCount: counts.adapted.denominator + counts.nonAdapted.denominator,
|
|
953
|
+
uniquePathSignatures: signatures.size, unitCallCount, adaptationCount,
|
|
954
|
+
adapted: rate(counts.adapted), nonAdapted: rate(counts.nonAdapted),
|
|
955
|
+
excludedCount: Object.values(exclusionReasons).reduce((total, count) => total + count, 0), exclusionReasons };
|
|
956
|
+
}
|
|
957
|
+
|
|
886
958
|
export interface GoalSourceDistributionQuery {
|
|
887
959
|
ledgerDirectory: string;
|
|
888
960
|
runCount: number;
|
|
@@ -1416,6 +1488,8 @@ export interface UnfinishedRunLedgerEntry {
|
|
|
1416
1488
|
lifecycle: UnfinishedRunLifecycle;
|
|
1417
1489
|
/** Non-blocking request record (kind·reason·next) carried by this runId's ledger; absent for runs without one. */
|
|
1418
1490
|
nonBlocking?: NonBlockingRunLedgerRecord;
|
|
1491
|
+
/** ⭐ graph.unit enter without its exit on a *terminal* ledger — present only when non-empty. */
|
|
1492
|
+
orphanUnitVisits?: readonly GraphUnitOrphanVisit[];
|
|
1419
1493
|
}
|
|
1420
1494
|
|
|
1421
1495
|
export interface UnfinishedRunLedgerQuery {
|
|
@@ -1435,6 +1509,12 @@ export interface UnfinishedRunLedgerQuery {
|
|
|
1435
1509
|
pathFilter?: string;
|
|
1436
1510
|
matchingPathCount?: number;
|
|
1437
1511
|
unknownPathCount?: number;
|
|
1512
|
+
/**
|
|
1513
|
+
* ⭐ Total orphan unit visits across **every scanned ledger** — including terminal runs that are not
|
|
1514
|
+
* returned as entries (they are counted, never revived). 같은 원장을 「미완」으로 되살리지 않고도
|
|
1515
|
+
* 엉킨 visit 을 셀 수 있게 하는 값이다.
|
|
1516
|
+
*/
|
|
1517
|
+
orphanUnitVisitCount?: number;
|
|
1438
1518
|
scope: 'self-implement-run-ledger';
|
|
1439
1519
|
note: string;
|
|
1440
1520
|
}
|
|
@@ -1546,6 +1626,78 @@ function isTerminalOnlyByTrailingRunStatus(ledger: readonly RunLedgerEntry[]): b
|
|
|
1546
1626
|
&& !hasHumanStopEvent(ledger);
|
|
1547
1627
|
}
|
|
1548
1628
|
|
|
1629
|
+
/** One producer-recorded `graph.unit` enter that the run never closed with a matching exit. */
|
|
1630
|
+
export interface GraphUnitOrphanVisit {
|
|
1631
|
+
childRunId: string | null;
|
|
1632
|
+
graphId: string | null;
|
|
1633
|
+
nodeId: string | null;
|
|
1634
|
+
unit: string | null;
|
|
1635
|
+
/** Timestamp of the unmatched enter; null when the producer recorded none. */
|
|
1636
|
+
enteredAt: string | null;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
export interface GraphUnitVisitClassification {
|
|
1640
|
+
/** Whether the ledger itself records the run's end (`run-status`, `terminal`, or `human-stop`). */
|
|
1641
|
+
terminal: boolean;
|
|
1642
|
+
enterCount: number;
|
|
1643
|
+
exitCount: number;
|
|
1644
|
+
/** Unmatched enters in a terminal run. An open enter on a non-terminal ledger is in flight, not an orphan. */
|
|
1645
|
+
orphanCount: number;
|
|
1646
|
+
orphanUnitVisits: readonly GraphUnitOrphanVisit[];
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
function dataString(data: Record<string, unknown>, field: string): string | null {
|
|
1650
|
+
const value = data[field];
|
|
1651
|
+
return typeof value === 'string' && value.length > 0 ? value : null;
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
function graphUnitVisitOf(entry: RunLedgerEntry): GraphUnitOrphanVisit {
|
|
1655
|
+
return {
|
|
1656
|
+
childRunId: dataString(entry.data, 'childRunId'),
|
|
1657
|
+
graphId: dataString(entry.data, 'graphId'),
|
|
1658
|
+
nodeId: dataString(entry.data, 'nodeId'),
|
|
1659
|
+
unit: dataString(entry.data, 'unit'),
|
|
1660
|
+
enteredAt: entry.timestamp ?? null,
|
|
1661
|
+
};
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
/** An exit closes the visit with its own childRunId; without one it closes the latest visit on the same node. */
|
|
1665
|
+
function closesUnitVisit(exitChildRunId: string | null, exitNodeId: string | null, open: GraphUnitOrphanVisit): boolean {
|
|
1666
|
+
if (open.childRunId !== null || exitChildRunId !== null) return open.childRunId === exitChildRunId;
|
|
1667
|
+
return open.nodeId !== null && open.nodeId === exitNodeId;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
/**
|
|
1671
|
+
* Pair each producer-recorded `graph.unit` enter with its exit and report the visits a terminal run left open.
|
|
1672
|
+
* This only reads the already-loaded ledger: it never synthesizes or writes an exit entry.
|
|
1673
|
+
*/
|
|
1674
|
+
export function classifyGraphUnitVisits(ledger: readonly RunLedgerEntry[]): GraphUnitVisitClassification {
|
|
1675
|
+
const open: GraphUnitOrphanVisit[] = [];
|
|
1676
|
+
let enterCount = 0;
|
|
1677
|
+
let exitCount = 0;
|
|
1678
|
+
for (const entry of ledger) {
|
|
1679
|
+
if (entry.event !== 'graph.unit') continue;
|
|
1680
|
+
if (entry.data.phase === 'enter') {
|
|
1681
|
+
enterCount += 1;
|
|
1682
|
+
open.push(graphUnitVisitOf(entry));
|
|
1683
|
+
continue;
|
|
1684
|
+
}
|
|
1685
|
+
// `budget-exhausted` is a recorded failure the runner still follows with an exit, so it closes nothing.
|
|
1686
|
+
if (entry.data.phase !== 'exit') continue;
|
|
1687
|
+
exitCount += 1;
|
|
1688
|
+
const exitChildRunId = dataString(entry.data, 'childRunId');
|
|
1689
|
+
const exitNodeId = dataString(entry.data, 'nodeId');
|
|
1690
|
+
for (let index = open.length - 1; index >= 0; index -= 1) {
|
|
1691
|
+
if (!closesUnitVisit(exitChildRunId, exitNodeId, open[index]!)) continue;
|
|
1692
|
+
open.splice(index, 1);
|
|
1693
|
+
break;
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
const terminal = hasTerminalRunStatus(ledger);
|
|
1697
|
+
const orphanUnitVisits = terminal ? open : [];
|
|
1698
|
+
return { terminal, enterCount, exitCount, orphanCount: orphanUnitVisits.length, orphanUnitVisits };
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1549
1701
|
/** ⛔⭐⭐⭐ 미완 항목의 «상태» — 종전엔 이 조회가 낸 것이 «한 값»(`terminal-status-missing`)뿐이었다.
|
|
1550
1702
|
* 📏 2026-08-11 실측: 그 한 값 안에 서로 «다른 것»이 섞여 있었다 —
|
|
1551
1703
|
* 실제로 도는 것 2 · 오래 전에 죽은 잔해 51(중앙 5.2일) · 종료를 «다른 이름»으로 적은 것 5.
|
|
@@ -1773,6 +1925,8 @@ interface UnfinishedLedgerFacts {
|
|
|
1773
1925
|
goalFile: string | null;
|
|
1774
1926
|
fixedLifecycle: UnfinishedRunLifecycle;
|
|
1775
1927
|
nonBlocking: NonBlockingRunLedgerRecord | null;
|
|
1928
|
+
/** Held here so a terminal ledger's orphan visits are countable before the terminal `continue`. */
|
|
1929
|
+
unitVisits: GraphUnitVisitClassification;
|
|
1776
1930
|
}
|
|
1777
1931
|
|
|
1778
1932
|
// A full federated scan can exceed 5,000 files; keep the previous scan resident for stat-checked reuse.
|
|
@@ -1797,7 +1951,8 @@ function unfinishedLedgerCacheKey(path: string, read?: RunLedgerReader): string
|
|
|
1797
1951
|
// 원장 옆에 (size, mtimeMs, ctimeMs) 스탬프로 저장하고, 스탬프가 같으면 재사용한다. 원장에 무엇이 «붙으면»
|
|
1798
1952
|
// 스탬프가 바뀌므로 무효화는 자동이다 (같은 크기로 덮고 mtime 을 되돌려도 ctime 이 바뀐다). 읽기 실패는 전부 fail-soft: 색인이 없으면 그냥 새로 읽는다.
|
|
1799
1953
|
const RUN_LEDGER_SCAN_INDEX_FILE = '.unfinished-scan-index.json';
|
|
1800
|
-
|
|
1954
|
+
// v3 added facts.unitVisits; a v2 record would hand back a facts object without it.
|
|
1955
|
+
const RUN_LEDGER_SCAN_INDEX_VERSION = 3;
|
|
1801
1956
|
const RUN_LEDGER_SCAN_INDEX_LIMIT = 32_768;
|
|
1802
1957
|
|
|
1803
1958
|
/** Where the persisted scan index lives: beside its ledgers, never mistaken for one (readdir filters canonical names). */
|
|
@@ -1829,7 +1984,9 @@ function isScanIndexFacts(value: unknown): value is UnfinishedLedgerFacts {
|
|
|
1829
1984
|
&& typeof facts.lastActivityStatus === 'string'
|
|
1830
1985
|
&& (facts.targetRoot === null || typeof facts.targetRoot === 'string')
|
|
1831
1986
|
&& (facts.goalFile === null || typeof facts.goalFile === 'string')
|
|
1832
|
-
&& typeof facts.fixedLifecycle === 'string' && UNFINISHED_LIFECYCLE_WORDS.has(facts.fixedLifecycle)
|
|
1987
|
+
&& typeof facts.fixedLifecycle === 'string' && UNFINISHED_LIFECYCLE_WORDS.has(facts.fixedLifecycle)
|
|
1988
|
+
&& typeof (facts.unitVisits as GraphUnitVisitClassification | undefined)?.orphanCount === 'number'
|
|
1989
|
+
&& Array.isArray((facts.unitVisits as GraphUnitVisitClassification | undefined)?.orphanUnitVisits);
|
|
1833
1990
|
}
|
|
1834
1991
|
|
|
1835
1992
|
function isScanIndexRecord(value: unknown): value is RunLedgerScanIndexRecord {
|
|
@@ -1895,6 +2052,7 @@ function unfinishedLedgerFacts(ledger: readonly RunLedgerEntry[]): UnfinishedLed
|
|
|
1895
2052
|
goalFile: ledgerGoalDocument(ledger),
|
|
1896
2053
|
fixedLifecycle: classifyUnfinishedLifecycle(ledger, null, 0),
|
|
1897
2054
|
nonBlocking: readNonBlockingRunRecord(ledger),
|
|
2055
|
+
unitVisits: classifyGraphUnitVisits(ledger),
|
|
1898
2056
|
};
|
|
1899
2057
|
}
|
|
1900
2058
|
|
|
@@ -2014,6 +2172,8 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
2014
2172
|
let cacheMisses = 0;
|
|
2015
2173
|
let ledgerTargetCount = 0;
|
|
2016
2174
|
let callerCwdCount = 0;
|
|
2175
|
+
// ⭐ 터미널 원장도 «세기만» 한다 — entries 로 되살리지 않는다(부활 금지).
|
|
2176
|
+
let orphanUnitVisitCount = 0;
|
|
2017
2177
|
for (const fileName of fileNames) {
|
|
2018
2178
|
const runId = runIdFromCanonicalLedgerFile(fileName);
|
|
2019
2179
|
if (!runId) continue;
|
|
@@ -2037,6 +2197,9 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
2037
2197
|
callerCwdCount += 1;
|
|
2038
2198
|
continue;
|
|
2039
2199
|
}
|
|
2200
|
+
const orphanUnitVisits = facts.unitVisits.orphanUnitVisits;
|
|
2201
|
+
orphanUnitVisitCount += facts.unitVisits.orphanCount;
|
|
2202
|
+
const orphanVisitField = orphanUnitVisits.length > 0 ? { orphanUnitVisits } : {};
|
|
2040
2203
|
if (facts.terminal) {
|
|
2041
2204
|
terminal += 1;
|
|
2042
2205
|
if (facts.terminalByTrailingRunStatus) terminalByTrailingRunStatus += 1;
|
|
@@ -2070,7 +2233,7 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
2070
2233
|
: goalDocument.status === 'directory-unreadable'
|
|
2071
2234
|
? 'goal-directory-unreadable'
|
|
2072
2235
|
: 'goal-document-not-found';
|
|
2073
|
-
entries.push({ runId, branch, status: 'terminal-status-missing', plannedPaths: [], plannedPathStatus, ...unknownDeclaredPaths(), pathMatchReasons: {}, goalDocumentPath: null, goalLookupBasis, goalDocumentSearchDirectory: searchDirectory, ...activity, lifecycle, ...(facts.nonBlocking ? { nonBlocking: facts.nonBlocking } : {}) });
|
|
2236
|
+
entries.push({ runId, branch, status: 'terminal-status-missing', plannedPaths: [], plannedPathStatus, ...unknownDeclaredPaths(), pathMatchReasons: {}, goalDocumentPath: null, goalLookupBasis, goalDocumentSearchDirectory: searchDirectory, ...activity, lifecycle, ...(facts.nonBlocking ? { nonBlocking: facts.nonBlocking } : {}), ...orphanVisitField });
|
|
2074
2237
|
continue;
|
|
2075
2238
|
}
|
|
2076
2239
|
try {
|
|
@@ -2078,9 +2241,9 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
2078
2241
|
const text = typeof document === 'string' ? document : document.toString('utf8');
|
|
2079
2242
|
const paths = [...new Set(tracedPathReferences(text).map((reference) => reference.path))];
|
|
2080
2243
|
const declared = declaredPathsFromGoalDocument(text);
|
|
2081
|
-
entries.push({ runId, branch, status: 'terminal-status-missing', plannedPaths: paths, plannedPathStatus: paths.length > 0 ? goalDocument.source === 'ledger' ? 'found-ledger-goal-file' : 'found-branch-fallback' : 'no-traced-paths', ...declared, pathMatchReasons: pathMatchReasons(declared.declaredPaths, paths), goalDocumentPath: goalDocument.path, goalLookupBasis, goalDocumentSearchDirectory: searchDirectory, ...activity, lifecycle, ...(facts.nonBlocking ? { nonBlocking: facts.nonBlocking } : {}) });
|
|
2244
|
+
entries.push({ runId, branch, status: 'terminal-status-missing', plannedPaths: paths, plannedPathStatus: paths.length > 0 ? goalDocument.source === 'ledger' ? 'found-ledger-goal-file' : 'found-branch-fallback' : 'no-traced-paths', ...declared, pathMatchReasons: pathMatchReasons(declared.declaredPaths, paths), goalDocumentPath: goalDocument.path, goalLookupBasis, goalDocumentSearchDirectory: searchDirectory, ...activity, lifecycle, ...(facts.nonBlocking ? { nonBlocking: facts.nonBlocking } : {}), ...orphanVisitField });
|
|
2082
2245
|
} catch {
|
|
2083
|
-
entries.push({ runId, branch, status: 'terminal-status-missing', plannedPaths: [], plannedPathStatus: 'goal-document-unreadable', declaredPaths: [], declaredPathStatus: 'goal-document-unreadable', pathMatchReasons: {}, goalDocumentPath: goalDocument.path, goalLookupBasis, goalDocumentSearchDirectory: searchDirectory, ...activity, lifecycle, ...(facts.nonBlocking ? { nonBlocking: facts.nonBlocking } : {}) });
|
|
2246
|
+
entries.push({ runId, branch, status: 'terminal-status-missing', plannedPaths: [], plannedPathStatus: 'goal-document-unreadable', declaredPaths: [], declaredPathStatus: 'goal-document-unreadable', pathMatchReasons: {}, goalDocumentPath: goalDocument.path, goalLookupBasis, goalDocumentSearchDirectory: searchDirectory, ...activity, lifecycle, ...(facts.nonBlocking ? { nonBlocking: facts.nonBlocking } : {}), ...orphanVisitField });
|
|
2084
2247
|
}
|
|
2085
2248
|
}
|
|
2086
2249
|
entries.sort((left, right) => left.runId.localeCompare(right.runId));
|
|
@@ -2098,7 +2261,7 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
2098
2261
|
ms: Date.now() - startedAt,
|
|
2099
2262
|
});
|
|
2100
2263
|
if (options.path === undefined) {
|
|
2101
|
-
return { entries, ledgerDirectory: dir, goalsDirectory: goalsDir, unreadableLedgerCount, ledgerDirectoryMissing: false, terminalByTrailingRunStatus, cacheHits, cacheMisses, indexHits, indexOrigin, scope: 'self-implement-run-ledger', note: UNFINISHED_RUN_LEDGER_NOTE };
|
|
2264
|
+
return { entries, ledgerDirectory: dir, goalsDirectory: goalsDir, unreadableLedgerCount, orphanUnitVisitCount, ledgerDirectoryMissing: false, terminalByTrailingRunStatus, cacheHits, cacheMisses, indexHits, indexOrigin, scope: 'self-implement-run-ledger', note: UNFINISHED_RUN_LEDGER_NOTE };
|
|
2102
2265
|
}
|
|
2103
2266
|
const pathFilter = options.path;
|
|
2104
2267
|
const unknownPathStatus = (entry: UnfinishedRunLedgerEntry): boolean => entry.plannedPathStatus !== 'found-ledger-goal-file'
|
|
@@ -2114,6 +2277,7 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
|
|
|
2114
2277
|
ledgerDirectory: dir,
|
|
2115
2278
|
goalsDirectory: goalsDir,
|
|
2116
2279
|
unreadableLedgerCount,
|
|
2280
|
+
orphanUnitVisitCount,
|
|
2117
2281
|
ledgerDirectoryMissing: false,
|
|
2118
2282
|
terminalByTrailingRunStatus,
|
|
2119
2283
|
cacheHits,
|
|
@@ -15,7 +15,7 @@ import type { PodChildEvidence } from '../task-orchestrator/surfaces/self-implem
|
|
|
15
15
|
|
|
16
16
|
/** 닫힌 목록 — 못 고르면 `unclassified`. */
|
|
17
17
|
export const RUN_STOP_CLASSES = [
|
|
18
|
-
'env-unrelated', 'main-sync', 'pod-died', 'review-repeat',
|
|
18
|
+
'env-unrelated', 'main-sync', 'pod-died', 'pod-vanished', 'review-repeat',
|
|
19
19
|
'review-out-of-scope', 'scope-escape', 'evidence-uncovered', 'fabric', 'launch-failed', 'gate-failed', 'unclassified',
|
|
20
20
|
] as const;
|
|
21
21
|
export type RunStopClass = typeof RUN_STOP_CLASSES[number];
|