elanous 0.2.35 → 0.2.36
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/chunks/{d06f9160.a3d9062f95de8ad7.js → 053a429e.9a63436527cc751c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +287 -0
- package/apps/pwa/out/_next/static/chunks/{4346.8601952e73bf5803.js → 1201.afbfc5b1c5e5cbe4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/190.285c832bd9626f8c.js +64 -0
- package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +36 -0
- package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +149 -0
- package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3103.0df8da390948bb84.js → 2500.cbc1257b774aae52.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7644.17e37ba6f1d4226e.js → 2683.c9773a0c589b031b.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{4718-17d2af636796a330.js → 275-02ea4c2a33980422.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/2812ca6a.3b9f4a7a08885744.js +1 -0
- package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8714.ff0b7ce3ec3e3ae2.js → 2941.3c3546f96bc6efa7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{9214.63a510d39178e997.js → 2986.45d7652e4f13557e.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3136.30aaaa5fa03662a3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3677-4215f826f6aa68e5.js → 3148-98efd4869d660a87.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +226 -0
- package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3324.a09703033abcbd2f.js +34 -0
- package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +8 -0
- package/apps/pwa/out/_next/static/chunks/3410.7f9af5ab77cbe65f.js +115 -0
- package/apps/pwa/out/_next/static/chunks/3538.a445e50bb359d068.js +32 -0
- package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +286 -0
- package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9512.5a76207a730e0491.js → 3727.7949ccaacaa71242.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8557-e7898769499cd56f.js → 3757-180308bc61021b05.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +74 -0
- package/apps/pwa/out/_next/static/chunks/{359-2250789a2d3499e7.js → 3840-5825d56d46976a92.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{da5176c6.6773b6c5994e1d99.js → 3a3d9966.cc4d4585a2708e7c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +104 -0
- package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9952.5daf5f94063a2b3e.js → 4286.b70c4520306817e8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4304.e9b2512834a9e23e.js +23 -0
- package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{938.66ad1ef0e5abae1c.js → 4615.8525eb0add35eba6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +148 -0
- package/apps/pwa/out/_next/static/chunks/5085-bce4904931767ca6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +93 -0
- package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6236.e18cced2d5ba6afb.js → 528.38ce20ef8aa251ff.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +122 -0
- package/apps/pwa/out/_next/static/chunks/{3408.21d1570602f4b6c0.js → 552.b7d061ad91eeac51.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5711.957b095705c12560.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1530.0e612369b6fd7ea0.js → 575.d929793a53f27c4b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/599.c39c571b6733f2a2.js +41 -0
- package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +79 -0
- package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6466-92e65a48490b68a9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +1 -0
- package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +27 -0
- package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6925.562d532110879886.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7385.50a308a477bdfc21.js → 6943.c6b24124853a47b2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{630.fe5a46428d63b013.js → 727.7deb87749b0a343a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2018.a741297bce759490.js → 7481.39f7a4654907bf6e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8444.4c26b379ca2b9596.js → 771.c3cdb6c1f7f47c02.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3589.5444a06bcf6e775c.js → 7891.03f910124a737985.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +1 -0
- package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +62 -0
- package/apps/pwa/out/_next/static/chunks/{b2f6ba4d.fb56fdbbf798df33.js → 873d6c12.09bd499f57171543.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5101.e32282718f99ed6f.js → 8904.7d51af2dc033965c.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +90 -0
- package/apps/pwa/out/_next/static/chunks/{5637.281e5dec4ea6ecf1.js → 914.8abefd48d579547b.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4705-194e64e47ca0fbdb.js → 9250-072df22eaadaa6b5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +77 -0
- package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8637.47f5b35afcae5e6b.js → 9514.131c52cc75fe6439.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1674.2a65fd5668e1cc5f.js → 9789.60f723d18097ec30.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9f31e478.fefcbcd3c388ebc5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-083747f1d4518f61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-e2de2e59111c9aad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-f2b2e4bf6e981450.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2af16e62c12f22df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{0368f25d-ad84af92fefee68f.js → ccae1c4b-0cf414f5eff1b10d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{cbe38a15.5a032598e39970c6.js → ceba0382.650712b56b85b582.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{b6705a4f-b9a9047de9eecfd0.js → da5ecc5c-b005ad8cac737d57.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{56d372f2.681ab4ec4c998fae.js → f9a61e4d.1fc2c1dbdd49fe46.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +1 -0
- package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → uC-N0emedeNOFuaBQFv-I}/_buildManifest.js +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +22 -22
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +21 -21
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +22 -22
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +22 -22
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +22 -22
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +21 -21
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +21 -21
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +21 -21
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +21 -21
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +21 -21
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- 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/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/research-report.yaml +2 -0
- package/package.json +1 -1
- package/scripts/ci-typecheck-changed.ts +139 -5
- package/scripts/coord-role-pack.ts +1 -1
- package/scripts/first10-gate.ts +416 -0
- package/scripts/fleet/wsl-node-setup.sh +432 -0
- package/scripts/release-loop/docs-node.ts +204 -8
- package/scripts/release-loop/gate-node.ts +249 -53
- package/scripts/release-loop/node-verdict.ts +2 -0
- package/scripts/release-loop/resume-cap.ts +14 -34
- package/scripts/release-loop/resume-release.ts +37 -11
- package/scripts/release-loop/traffic-node.ts +59 -0
- package/scripts/release-loop/traffic-transition.ts +159 -0
- package/scripts/rhythm/daily.ts +137 -3
- package/scripts/ux-sim.ts +53 -0
- package/skills/README.md +1 -0
- package/src/acp/core-turn-bridge.ts +48 -6
- package/src/agent/delegate-hint.ts +16 -0
- package/src/agent/runner.ts +82 -2
- package/src/agent/task-notification.ts +56 -10
- package/src/agent/types.ts +4 -0
- package/src/agent-substrate/pr-reviewer.ts +55 -3
- 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 +168 -16
- package/src/autopilot/mission-codebase-gate.ts +141 -12
- package/src/autopilot/pr-manager.ts +25 -5
- package/src/boot/daemon-tools/self-implement.ts +1 -0
- package/src/budget/usage-outcomes.ts +8 -4
- package/src/capture/tui-self-report.ts +102 -0
- 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/config-audit.ts +119 -0
- package/src/cli/doctor-cli.ts +22 -0
- 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/make-cli.ts +247 -11
- package/src/cli/msg-cli.ts +117 -3
- package/src/cli/pr-cli.ts +29 -16
- 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-cli.ts +21 -5
- package/src/cli/release-single-flight.ts +1 -1
- package/src/cli/tasks-card-show.ts +162 -0
- package/src/cli/tasks-cli.ts +574 -356
- package/src/cli/tasks-read-cli.ts +197 -0
- package/src/core-turn/run-core-turn.ts +4 -2
- package/src/core-turn/run-goal-loop.ts +73 -16
- package/src/core-turn/types.ts +6 -1
- package/src/dashboard/context/keys.ts +8 -31
- package/src/dashboard/index.ts +202 -49
- package/src/dashboard/input/agent-wake.ts +7 -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/seat-boot-preamble.ts +132 -5
- package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +3 -2
- package/src/dashboard/slash-runtime/model-choices.ts +15 -0
- package/src/dashboard/stale-install-check.ts +3 -99
- 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/domains/standalone-log-sink.ts +15 -2
- package/src/esc-abort-gate.ts +69 -0
- package/src/git-fs/worktree.ts +95 -1
- package/src/graph-runner/graph-cli.ts +18 -0
- package/src/graph-runner/runner.ts +20 -11
- package/src/graph-wizard/generate.ts +108 -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 +51 -7
- package/src/harness/harness-incidents.ts +52 -1
- package/src/harness/pod-control-send.ts +33 -5
- 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 +327 -12
- package/src/input-core/context-key-runtime.ts +21 -0
- package/src/light-cli.ts +6 -1
- package/src/llm-wellformed.ts +70 -0
- package/src/llm.ts +35 -4
- package/src/loops/msg-wake.ts +35 -39
- package/src/loops/orchestrator/inbox.ts +59 -11
- package/src/loops/orchestrator/knowhow-pack.ts +364 -0
- package/src/loops/orchestrator/tick.ts +5 -1
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/models/prompts.ts +17 -2
- package/src/msg/msg-post-office.ts +116 -0
- package/src/mss/logging/log-store.ts +79 -22
- package/src/nexus/api/decisions-route.ts +38 -18
- package/src/nexus/api/graph-wizard-api.ts +20 -2
- package/src/nexus/boot/register-mcp-clients.ts +263 -38
- package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
- package/src/onboarding/first-run.ts +37 -6
- package/src/onboarding/web-first.ts +43 -11
- package/src/ops/overview-collect.ts +12 -6
- package/src/ops/overview.ts +3 -3
- package/src/persona/loader.ts +11 -0
- package/src/persona/types.ts +8 -0
- package/src/prompt-library/session-guidance.ts +14 -0
- package/src/provider-summary.ts +8 -0
- package/src/pty-shell/herdr-agent-report.ts +118 -9
- package/src/pty-shell/herdr-prompt.ts +266 -0
- package/src/pty-shell/pty-control-ipc.ts +151 -8
- package/src/pty-shell/pty-special-keys.ts +42 -2
- package/src/pty-shell/stale-install-check.ts +99 -0
- package/src/pty-shell/tui-run-state.ts +14 -2
- package/src/release-loop/auto-start.ts +20 -2
- package/src/release-loop/checklist.ts +76 -4
- package/src/release-loop/rehearsal.ts +36 -20
- package/src/repl/index.ts +19 -1
- package/src/seat-loop/knowhow-lint.ts +1 -1
- package/src/self-dev/decompose-proposal.ts +172 -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 +8 -2
- package/src/self-dev/draft-triage-rules.ts +31 -0
- 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/run-supervisor.ts +55 -2
- package/src/self-dev/run-types.ts +1 -1
- 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 +239 -1
- package/src/self-implement/evidence-command-budget.ts +80 -0
- 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 +33 -8
- package/src/self-implement/goal-elaborate.ts +176 -22
- package/src/self-implement/goal-refine.ts +3 -0
- package/src/self-implement/graph-variant.ts +40 -6
- package/src/self-implement/headless-elanous-driver.ts +19 -3
- package/src/self-implement/off-diff-evidence.ts +58 -6
- package/src/self-implement/orchestrator.ts +222 -21
- 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/rework-policy.ts +30 -0
- package/src/self-implement/run-ledger.ts +108 -0
- package/src/self-implement/run-ttl.ts +38 -24
- package/src/self-implement/scope-adjacency.ts +3 -1
- package/src/self-implement/seams.ts +60 -4
- package/src/self-implement/wiring-check.ts +358 -0
- 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/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/status-provider-info.ts +37 -6
- package/src/steward/rejudge-tick.ts +10 -2
- package/src/steward/ta-repair-event-collect.ts +17 -6
- package/src/task-agent/actions.ts +3 -1
- package/src/task-agent/land-queue.ts +21 -8
- package/src/task-agent/live-moves.ts +22 -6
- package/src/task-agent/mission.ts +30 -0
- package/src/task-agent/rejudge-on-head.ts +15 -0
- package/src/task-agent/repair-cycle.ts +138 -32
- package/src/task-agent/repair-next-move.ts +31 -3
- package/src/task-agent/repair-outcomes.ts +29 -0
- package/src/task-agent/repair-worker.ts +14 -4
- package/src/task-agent/shadow.ts +41 -3
- package/src/task-agent/task-card-prefix.ts +2 -0
- package/src/task-agent/task-hand.ts +477 -22
- package/src/task-agent/task-parent-role-llm.ts +36 -0
- package/src/task-agent/tier-split.ts +78 -9
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +9 -0
- 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-manifest-test-normalize.ts +11 -0
- package/src/task-orchestrator/surfaces/pod-pool.ts +76 -4
- 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 +485 -36
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +396 -19
- package/src/task-orchestrator/surfaces/self-implement.ts +42 -2
- 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 +173 -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 +370 -81
- 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 +75 -0
- package/src/tui-client/local-chat-turn.ts +45 -2
- 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/ux-sim/classic-tui-seat-scenarios.ts +516 -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-herdr.ts +238 -0
- package/src/ux-sim/fake-llm.ts +111 -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 +631 -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/subagent-tools-device.ts +81 -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/1165.bad13fc9151a7288.js +0 -1
- package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +0 -32
- package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +0 -41
- 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/1dc5a567.9b092bfae3d7099b.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/2833-0fe47af99ed13c29.js +0 -1
- 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/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/3618.f514792d6c59d7fd.js +0 -36
- package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.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/3f7c4ee5.3dde54f01a816613.js +0 -122
- package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.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/5483-dd5d7697f6bdb106.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.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/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/6866-79aa5b4e47cac6aa.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/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/morning/page-47c5d4db587266bd.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/release/page-1f5a60f70cb4dd0c.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/outputs/page-bac7dee94e5eae4a.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/term/page-dc0a532f5b9196ec.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 → uC-N0emedeNOFuaBQFv-I}/_ssgManifest.js +0 -0
|
@@ -13,6 +13,7 @@ import remarkParse from 'remark-parse';
|
|
|
13
13
|
import { unified } from 'unified';
|
|
14
14
|
|
|
15
15
|
import { parseGoalType, type GoalType } from '../self-implement/goal-author.js';
|
|
16
|
+
import { DEVICE_FIRST_STEP } from '../self-implement/device-first.js';
|
|
16
17
|
import type { DesignCheckOutcome } from '../design/design-check.js';
|
|
17
18
|
import type { DesignGateResult } from '../design/design-gate.js';
|
|
18
19
|
import type { PriorDraftFinding } from '../self-implement/prior-draft-findings.js';
|
|
@@ -525,6 +526,30 @@ function goalFileBlock(goalFile: string | undefined): Block | undefined {
|
|
|
525
526
|
: undefined;
|
|
526
527
|
}
|
|
527
528
|
|
|
529
|
+
/** tier-split 이 골 본문에 남긴 조각 표지를 리뷰의 책임 경계로 옮긴다. */
|
|
530
|
+
function sliceReviewScopeBlock(goal: string): Block | undefined {
|
|
531
|
+
const fencedLines = topLevelCodeLines(goal);
|
|
532
|
+
const lines = goal.split('\n').filter((_, index) => !fencedLines.has(index));
|
|
533
|
+
const match = lines.map((line) => /^\s*조각\s+(\d+)\/(\d+)\s*—/.exec(line)).find(Boolean);
|
|
534
|
+
if (!match) return undefined;
|
|
535
|
+
const index = Number(match[1]);
|
|
536
|
+
const total = Number(match[2]);
|
|
537
|
+
if (!Number.isSafeInteger(index) || !Number.isSafeInteger(total) || index < 1 || total < 2 || index > total) return undefined;
|
|
538
|
+
|
|
539
|
+
const deviceStep = `동작: ${DEVICE_FIRST_STEP}`;
|
|
540
|
+
const device = lines.some((line) => line.split('·').some((part) => {
|
|
541
|
+
const stage = part.trimStart();
|
|
542
|
+
return stage === deviceStep || stage.startsWith(`${deviceStep} `);
|
|
543
|
+
}));
|
|
544
|
+
const title = '조각 계약 — 리뷰 범위';
|
|
545
|
+
const scopeLines = [
|
|
546
|
+
`${title}\n조각 ${index}/${total} — 현재 조각의 동작·변경 파일·자기 완료 경계로 이 PR을 판정한다.`,
|
|
547
|
+
...(index < total ? ['다음 조각 몫과 부모 전체 완료 경계의 미완료만으로 이 조각의 must-fix를 만들지 말 것.'] : []),
|
|
548
|
+
...(device ? ['장치 조각: 호출부 없는 export의 소비자는 다음 피처 조각이다. 이 조각에서 호출부 부재만으로 must-fix를 만들지 말고 장치 시험과 사용 가능한 인터페이스를 판정한다.'] : []),
|
|
549
|
+
];
|
|
550
|
+
return { title, text: scopeLines.join('\n') };
|
|
551
|
+
}
|
|
552
|
+
|
|
528
553
|
function isLightweightGoal(goal: string): boolean {
|
|
529
554
|
try {
|
|
530
555
|
const tree = unified().use(remarkParse).use(remarkGfm).parse(goal) as MarkdownNode;
|
|
@@ -599,6 +624,7 @@ export function buildReviewIntent(i: Readonly<ReviewIntentInput>): string {
|
|
|
599
624
|
const boundaries = i.scopeBoundaries ?? mined.scopeBoundaries;
|
|
600
625
|
const unverifiedBoundaryCandidates = mined.unverifiedBoundaryCandidates;
|
|
601
626
|
const goalType = goalTypeBlock(i.goal);
|
|
627
|
+
const sliceScope = sliceReviewScopeBlock(i.goal);
|
|
602
628
|
// ⚠️ 목표 블록에는 **추출된 절을 뺀 나머지**를 넣는다(리뷰 should-fix) — 골 원문을 통째로 넣고
|
|
603
629
|
// 그 안의 수용기준을 다시 목록으로 붙이면 **같은 내용이 두 번** 들어가 4000자 예산을 먹고,
|
|
604
630
|
// 후순위 블록(스코프 경계)이 불필요하게 잘린다.
|
|
@@ -631,7 +657,7 @@ export function buildReviewIntent(i: Readonly<ReviewIntentInput>): string {
|
|
|
631
657
|
const context = lightweightGoalContext(i.goal, i.goalFile!.trim());
|
|
632
658
|
const boundaryBlock = listBlock('의도적 스코프 경계', boundaries);
|
|
633
659
|
const liteBlocks = [
|
|
634
|
-
acceptanceBlock, context, boundaryBlock, shardBoundary, priorFindings, applied,
|
|
660
|
+
acceptanceBlock, context, boundaryBlock, sliceScope, shardBoundary, priorFindings, applied,
|
|
635
661
|
runFacts, goalType, preexisting, importerTestsNotRun,
|
|
636
662
|
gateEvidence, designCheck, designGate, shardSiblings, coverage, claims,
|
|
637
663
|
listBlock('검증 못 한 경계 후보 (결정 아님 — 이것만으로 must-fix 를 면제하지도, 만들지도 말 것)', unverifiedBoundaryCandidates),
|
|
@@ -648,6 +674,7 @@ export function buildReviewIntent(i: Readonly<ReviewIntentInput>): string {
|
|
|
648
674
|
// ⚠️ 이것은 «렌더 순서»만 바꾼다 — 예산 배분 순서(`order`)와 보호 블록은 아래에서 따로 정한다.
|
|
649
675
|
const blocks: Block[] = [
|
|
650
676
|
runFacts,
|
|
677
|
+
sliceScope,
|
|
651
678
|
priorFindings,
|
|
652
679
|
goalFile,
|
|
653
680
|
goalType,
|
|
@@ -667,7 +694,7 @@ export function buildReviewIntent(i: Readonly<ReviewIntentInput>): string {
|
|
|
667
694
|
listBlock('검증 못 한 경계 후보 (결정 아님 — 이것만으로 must-fix 를 면제하지도, 만들지도 말 것)', unverifiedBoundaryCandidates),
|
|
668
695
|
].filter((b): b is Block => Boolean(b));
|
|
669
696
|
|
|
670
|
-
const protectedBlocks = blocks.filter((block) => block.title === '수용기준' || block.title === '의도적 스코프 경계');
|
|
697
|
+
const protectedBlocks = blocks.filter((block) => block.title === '수용기준' || block.title === '의도적 스코프 경계' || block === sliceScope);
|
|
671
698
|
// ⛔⭐ **증거가 목표보다 먼저다**(실측 수리). 종전 순서는 `[보호블록, 목표, 나머지]` 였고, 골이
|
|
672
699
|
// 15,383자면 `목표` 가 남은 예산을 통째로 먹어 자식의 `EVIDENCE/RESULT` 가 **제목만 남고
|
|
673
700
|
// `…[N개 생략됨]`** 이 됐다. 그러면 리뷰는 *"실행하지 않았다 · 증거가 없다"* 를 적고 — 그것이
|
|
@@ -100,6 +100,8 @@ interface ReviewObservation {
|
|
|
100
100
|
readonly mustFix: number;
|
|
101
101
|
/** 목표 범위를 이유로 되돌리거나 분리하라는 MUST-FIX의 관측용 빈도. */
|
|
102
102
|
readonly scopeRevertMustFix: number;
|
|
103
|
+
/** SCOPE-ESCAPE-AS-REFINE — must-fix 에서 shouldFix 로 강등된 범위-되돌림 지적 수. */
|
|
104
|
+
readonly scopeRevertDemoted: number;
|
|
103
105
|
readonly shouldFix: number;
|
|
104
106
|
/** ⭐ 지적 **식별용** 앞부분. 이게 있어야 "같은 지적이 반복되나"를 로그만으로 볼 수 있다. */
|
|
105
107
|
readonly mustFixItems: readonly string[];
|
|
@@ -197,6 +199,7 @@ export function buildReviewObservation(input: ReviewObservationInput): ReviewObs
|
|
|
197
199
|
...(review?.failureReason ? { failureReason: safeLogText(review.failureReason) } : {}),
|
|
198
200
|
mustFix: mustFix.length,
|
|
199
201
|
scopeRevertMustFix: mustFix.filter(isScopeRevertMustFix).length,
|
|
202
|
+
scopeRevertDemoted: review?.scopeRevertDemoted?.length ?? 0,
|
|
200
203
|
shouldFix: shouldFix.length,
|
|
201
204
|
mustFixItems: clip(mustFix),
|
|
202
205
|
shouldFixItems: clip(shouldFix),
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
//
|
|
15
15
|
// index.ts 의 액션은 옵션 파싱과 실제 의존 배선만 남는다(얇은 껍데기).
|
|
16
16
|
|
|
17
|
-
import { mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
17
|
+
import { mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
18
18
|
import { homedir, tmpdir } from 'node:os';
|
|
19
19
|
import { dirname, join } from 'node:path';
|
|
20
20
|
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
@@ -139,27 +139,36 @@ export interface SelfReviewCliOutcome {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
/** Saved results are round evidence only when their PR, exact head and reviewed status agree. */
|
|
142
|
-
|
|
142
|
+
function savedReviewRecords(pr: string, root = effectiveInstanceRoot()): Array<{ head: string; reviewedAt: number }> {
|
|
143
143
|
const dir = join(root, 'review-results');
|
|
144
144
|
let names: string[];
|
|
145
145
|
try { names = readdirSync(dir); } catch { return []; }
|
|
146
146
|
// Manual review saves in the operating house also use head10; the JSON's full head is authoritative.
|
|
147
147
|
const matching = new RegExp(`^.+-${pr}-([a-f0-9]{7,40})\\.json$`, 'i');
|
|
148
|
-
const
|
|
148
|
+
const records = new Map<string, { head: string; reviewedAt: number }>();
|
|
149
149
|
for (const name of names) {
|
|
150
150
|
const match = matching.exec(name);
|
|
151
151
|
if (!match) continue;
|
|
152
152
|
try {
|
|
153
|
-
const
|
|
153
|
+
const recordPath = join(dir, name);
|
|
154
|
+
const raw: unknown = JSON.parse(readFileSync(recordPath, 'utf8'));
|
|
154
155
|
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) continue;
|
|
155
156
|
const result = raw as Record<string, unknown>;
|
|
156
157
|
const head = result.headCommit;
|
|
157
158
|
if (String(result.pr) !== pr || result.reviewed !== true || typeof head !== 'string'
|
|
158
159
|
|| !COMMIT_OID.test(head) || !head.toLowerCase().startsWith(match[1]!.toLowerCase())) continue;
|
|
159
|
-
|
|
160
|
+
const normalized = head.toLowerCase();
|
|
161
|
+
const existing = records.get(normalized);
|
|
162
|
+
const reviewedAt = typeof result.reviewedAt === 'number' && Number.isFinite(result.reviewedAt)
|
|
163
|
+
? result.reviewedAt : statSync(recordPath).mtimeMs;
|
|
164
|
+
if (!existing || reviewedAt > existing.reviewedAt) records.set(normalized, { head: normalized, reviewedAt });
|
|
160
165
|
} catch { /* corrupt or partial result is not a completed round */ }
|
|
161
166
|
}
|
|
162
|
-
return [...
|
|
167
|
+
return [...records.values()];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function savedReviewHeads(pr: string, root = effectiveInstanceRoot()): string[] {
|
|
171
|
+
return savedReviewRecords(pr, root).map(({ head }) => head);
|
|
163
172
|
}
|
|
164
173
|
|
|
165
174
|
function normalizeReviewPrArg(input: string, deps: SelfReviewCliDeps): string | null {
|
|
@@ -178,14 +187,42 @@ function normalizeReviewPrArg(input: string, deps: SelfReviewCliDeps): string |
|
|
|
178
187
|
} catch { return null; }
|
|
179
188
|
}
|
|
180
189
|
|
|
190
|
+
function readCapOverride(pr: string): { head: string; reason: string } | undefined {
|
|
191
|
+
try {
|
|
192
|
+
const value = JSON.parse(readFileSync(join(effectiveInstanceRoot(), 'review-results', `cap-override-${pr}.json`), 'utf8')) as Record<string, unknown>;
|
|
193
|
+
if (String(value.pr) !== pr || typeof value.head !== 'string' || !COMMIT_OID.test(value.head)
|
|
194
|
+
|| typeof value.reason !== 'string' || !value.reason.trim()) return undefined;
|
|
195
|
+
return { head: value.head.toLowerCase(), reason: value.reason };
|
|
196
|
+
} catch { return undefined; }
|
|
197
|
+
}
|
|
198
|
+
|
|
181
199
|
function claimCapOverride(pr: string, head: string, reason: string, now: number): boolean {
|
|
182
200
|
const dir = join(effectiveInstanceRoot(), 'review-results');
|
|
183
201
|
try {
|
|
184
202
|
mkdirSync(dir, { recursive: true });
|
|
185
|
-
|
|
186
|
-
|
|
203
|
+
const normalizedHead = head.toLowerCase();
|
|
204
|
+
const authorizationPath = join(dir, `cap-override-${pr}.json`);
|
|
205
|
+
// The first over-cap review creates the durable, PR-scoped authorization record atomically.
|
|
206
|
+
writeFileSync(authorizationPath, JSON.stringify({ pr, head: normalizedHead, reason, claimedAt: now, use: 'initial-authorization' }) + '\n', { flag: 'wx' });
|
|
187
207
|
return true;
|
|
188
|
-
} catch {
|
|
208
|
+
} catch {
|
|
209
|
+
// An OP authorization applies to later heads of this PR while the allowlist remains active.
|
|
210
|
+
// Keep the initial claim immutable, and atomically record each additional head separately so
|
|
211
|
+
// retries of the same head cannot spend the grant twice.
|
|
212
|
+
try {
|
|
213
|
+
const authorization = JSON.parse(readFileSync(join(dir, `cap-override-${pr}.json`), 'utf8')) as Record<string, unknown>;
|
|
214
|
+
const authorizedHead = authorization.head;
|
|
215
|
+
if (String(authorization.pr) !== pr || typeof authorization.reason !== 'string' || !authorization.reason.trim()
|
|
216
|
+
|| authorization.reason !== reason
|
|
217
|
+
|| typeof authorizedHead !== 'string' || !COMMIT_OID.test(authorizedHead)
|
|
218
|
+
|| authorizedHead.toLowerCase() === head.toLowerCase()) return false;
|
|
219
|
+
const normalizedHead = head.toLowerCase();
|
|
220
|
+
writeFileSync(join(dir, `cap-override-${pr}-head-${normalizedHead}.json`), JSON.stringify({
|
|
221
|
+
pr, head: normalizedHead, reason, claimedAt: now, use: 'subsequent-head', authorizationHead: authorizedHead.toLowerCase(),
|
|
222
|
+
}) + '\n', { flag: 'wx' });
|
|
223
|
+
return true;
|
|
224
|
+
} catch { return false; }
|
|
225
|
+
}
|
|
189
226
|
}
|
|
190
227
|
|
|
191
228
|
/** OP owns this list. Missing, unreadable, or malformed traffic never grants a review exception. */
|
|
@@ -1343,6 +1380,34 @@ export function selfReviewJsonLine(results: readonly unknown[]): string {
|
|
|
1343
1380
|
return JSON.stringify(results.length === 1 ? results[0] : results) + '\n';
|
|
1344
1381
|
}
|
|
1345
1382
|
|
|
1383
|
+
// Normalize only whole-item forms whose complete text is an explicit no-finding
|
|
1384
|
+
// sentinel. Any extra clause stays in mustFix (fail-closed).
|
|
1385
|
+
const NO_FINDING_REVIEW_NOTE_ALLOWLIST: readonly RegExp[] = [
|
|
1386
|
+
/^(?:없음|해당\s*없음|none|nothing|n\/a)[.!。]?$/i,
|
|
1387
|
+
/^\((?:없음|해당\s*없음|none|nothing|n\/a)\)[.!。]?$/i,
|
|
1388
|
+
/^\(이 조각에서 확인된 코어 결함 없음\s*[—–-]\s*명시 intent 기준 mustFix 는 비움\)$/i,
|
|
1389
|
+
/^\(이 조각에서 검증된 (?:차단 )?결함은 발견되지 않음(?:\s*\(mustFix \[\]\))?\)$/i,
|
|
1390
|
+
];
|
|
1391
|
+
|
|
1392
|
+
function isNoFindingReviewNote(finding: string): boolean {
|
|
1393
|
+
const wholeItem = finding.trim();
|
|
1394
|
+
return NO_FINDING_REVIEW_NOTE_ALLOWLIST.some((form) => form.test(wholeItem));
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
function normalizeSavedReviewMustFix(result: Record<string, unknown>): { result: Record<string, unknown>; count: number } {
|
|
1398
|
+
if (!Array.isArray(result.mustFix)) return { result, count: 0 };
|
|
1399
|
+
const noFindingNotes = result.mustFix.filter((finding): finding is string =>
|
|
1400
|
+
typeof finding === 'string' && isNoFindingReviewNote(finding));
|
|
1401
|
+
if (noFindingNotes.length === 0) return { result, count: 0 };
|
|
1402
|
+
const retained = result.mustFix.filter((finding) =>
|
|
1403
|
+
typeof finding !== 'string' || !isNoFindingReviewNote(finding));
|
|
1404
|
+
const existingNotes = Array.isArray(result.noFindingNotes) ? result.noFindingNotes : [];
|
|
1405
|
+
return {
|
|
1406
|
+
result: { ...result, mustFix: retained, noFindingNotes: [...existingNotes, ...noFindingNotes] },
|
|
1407
|
+
count: noFindingNotes.length,
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1346
1411
|
export async function runSelfReviewCliCommand(
|
|
1347
1412
|
prArgs: string[],
|
|
1348
1413
|
opts: SelfReviewCliOpts,
|
|
@@ -1440,7 +1505,9 @@ async function runSelfReviewCliCommandPinned(
|
|
|
1440
1505
|
return { results: opts.json ? [{ error: message, requestedModel }] : [], failed: 1 };
|
|
1441
1506
|
}
|
|
1442
1507
|
const configuredReviewModel = opts.configuredReviewModel?.trim() || undefined;
|
|
1443
|
-
|
|
1508
|
+
// REVIEW-MODEL-ALIAS-PROVIDER: provider pinning needs GLM's OpenRouter model id, not the bare alias.
|
|
1509
|
+
const explicitApiModel = requestedModel?.toLowerCase() === 'glm' ? ROLE_REVIEWER_FALLBACK_MODEL : opts.model;
|
|
1510
|
+
const model = useAcp ? `acp:${acpBackend}${acpModel ? `/${acpModel}` : ''}` : (explicitApiModel || envModel || configuredReviewModel || roleFallbackModel || tierModel('better'));
|
|
1444
1511
|
const configuredReviewSelected = !opts.model?.trim() && !envModel && Boolean(configuredReviewModel);
|
|
1445
1512
|
let roleReviewer: { llm: (prompt: string, images?: readonly ReviewImage[]) => Promise<string>; model: string } | undefined;
|
|
1446
1513
|
let roleReviewerUnavailableReason: string | undefined;
|
|
@@ -1482,16 +1549,17 @@ async function runSelfReviewCliCommandPinned(
|
|
|
1482
1549
|
const previousHeads = savedReviewHeads(pr);
|
|
1483
1550
|
const previousRoundCount = previousHeads.length;
|
|
1484
1551
|
const reason = opts.overCapReason?.trim();
|
|
1552
|
+
const authorization = previousRoundCount >= 5 ? readCapOverride(pr) : undefined;
|
|
1485
1553
|
deps.observeDoctorReview?.('round-counted', { pr, previousRoundCount, round: previousRoundCount + 1 });
|
|
1486
1554
|
const opAllowed = previousRoundCount >= 5 && opAllowsReviewOverCap(pr);
|
|
1487
1555
|
if (previousRoundCount >= 5) {
|
|
1488
1556
|
deps.observeDoctorReview?.('cap-attempt', { pr, previousRoundCount, round: previousRoundCount + 1, reasonProvided: Boolean(reason), opAllowed }, { level: 'warn' });
|
|
1489
1557
|
}
|
|
1490
|
-
if (previousRoundCount >= 5 && (!
|
|
1558
|
+
if (previousRoundCount >= 5 && (!opAllowed || (!authorization && !reason))) {
|
|
1491
1559
|
const refusalHead = prHeadCommit(pr, deps).value;
|
|
1492
1560
|
const message = !opAllowed
|
|
1493
1561
|
? `PR ${pr}: r5 상한 초과 리뷰는 OP traffic.json reviewOverCapAllow 허용 목록에 있어야 합니다.`
|
|
1494
|
-
: `PR ${pr}: 저장된 서로 다른 head 리뷰 ${previousRoundCount}개로 r5 상한에 도달했습니다.
|
|
1562
|
+
: `PR ${pr}: 저장된 서로 다른 head 리뷰 ${previousRoundCount}개로 r5 상한에 도달했습니다. OP 허용 상태와 --over-cap-reason <사유>가 필요합니다.`;
|
|
1495
1563
|
deps.observeDoctorReview?.('cap-refused', { pr, head: refusalHead, previousRoundCount, round: previousRoundCount + 1, reason: opAllowed ? 'missing-reason' : 'not-op-allowlisted' }, { level: 'warn' });
|
|
1496
1564
|
deps.error(message);
|
|
1497
1565
|
if (opts.json || opts.save !== undefined) results.push({ pr, error: message, reviewed: false, refusal: 'cap-refused', previousRoundCount, headCommit: refusalHead });
|
|
@@ -1499,9 +1567,69 @@ async function runSelfReviewCliCommandPinned(
|
|
|
1499
1567
|
continue;
|
|
1500
1568
|
}
|
|
1501
1569
|
const diffRead = readDiffAtHead(pr, deps);
|
|
1502
|
-
if (previousRoundCount >= 5 &&
|
|
1503
|
-
|
|
1504
|
-
|
|
1570
|
+
if (previousRoundCount >= 5 && authorization && diffRead.headCommit.toLowerCase() === authorization.head) {
|
|
1571
|
+
const message = `PR ${pr}: 동일 head는 이미 승인 소모 기록이 있습니다.`;
|
|
1572
|
+
deps.observeDoctorReview?.('cap-refused', { pr, head: diffRead.headCommit, previousRoundCount, round: previousRoundCount + 1, reason: 'same-head-already-used' }, { level: 'warn' });
|
|
1573
|
+
deps.error(message);
|
|
1574
|
+
if (opts.json || opts.save !== undefined) results.push({ pr, error: message, reviewed: false, refusal: 'cap-refused', previousRoundCount, headCommit: diffRead.headCommit });
|
|
1575
|
+
failed += 1;
|
|
1576
|
+
continue;
|
|
1577
|
+
}
|
|
1578
|
+
if (previousRoundCount >= 5 && authorization && reason && reason !== authorization.reason) {
|
|
1579
|
+
const message = `PR ${pr}: 기존 PR 승인의 사유와 일치하지 않습니다.`;
|
|
1580
|
+
deps.observeDoctorReview?.('cap-refused', { pr, head: diffRead.headCommit, previousRoundCount, round: previousRoundCount + 1, reason: 'authorization-reason-mismatch' }, { level: 'warn' });
|
|
1581
|
+
deps.error(message);
|
|
1582
|
+
if (opts.json || opts.save !== undefined) results.push({ pr, error: message, reviewed: false, refusal: 'cap-refused', previousRoundCount, headCommit: diffRead.headCommit });
|
|
1583
|
+
failed += 1;
|
|
1584
|
+
continue;
|
|
1585
|
+
}
|
|
1586
|
+
let mergeOnlyDeltaRange: { base: string; head: string } | undefined;
|
|
1587
|
+
if (previousRoundCount >= 5 && authorization) {
|
|
1588
|
+
const git = deps.git;
|
|
1589
|
+
if (!git || diffRead.source !== 'sha-pinned' || diffRead.headCommitState !== 'known'
|
|
1590
|
+
|| diffRead.currentHeadCommitState !== 'known' || diffRead.stale || diffRead.diff.status !== 0) {
|
|
1591
|
+
const message = `PR ${pr}: 후속 head의 merge-only 여부를 확인할 수 없어 상한 예외 리뷰를 거부합니다.`;
|
|
1592
|
+
deps.error(message);
|
|
1593
|
+
if (opts.json || opts.save !== undefined) results.push({ pr, error: message, reviewed: false, refusal: 'cap-refused', previousRoundCount, headCommit: diffRead.headCommit });
|
|
1594
|
+
failed += 1;
|
|
1595
|
+
continue;
|
|
1596
|
+
}
|
|
1597
|
+
const savedRecords = savedReviewRecords(pr);
|
|
1598
|
+
const latestReviewed = savedRecords.reduce<(typeof savedRecords)[number] | undefined>(
|
|
1599
|
+
(latest, record) => !latest || record.reviewedAt > latest.reviewedAt ? record : latest, undefined,
|
|
1600
|
+
);
|
|
1601
|
+
const classificationBase = latestReviewed?.head ?? authorization.head;
|
|
1602
|
+
const ancestry = git(['merge-base', '--is-ancestor', classificationBase, diffRead.headCommit], 10_000);
|
|
1603
|
+
const parents = git(['rev-list', '--parents', '-n', '1', diffRead.headCommit], 10_000);
|
|
1604
|
+
const parentFields = parents.stdout.trim().split(/\s+/);
|
|
1605
|
+
const headIsMerge = parentFields.length > 2;
|
|
1606
|
+
const deltaHead = headIsMerge ? parentFields[1] : diffRead.headCommit;
|
|
1607
|
+
if ((ancestry.status !== 0 && ancestry.status !== 1) || parents.status !== 0 || parentFields[0]?.toLowerCase() !== diffRead.headCommit.toLowerCase()
|
|
1608
|
+
|| !COMMIT_OID.test(deltaHead) || classificationBase === diffRead.headCommit.toLowerCase()) {
|
|
1609
|
+
const message = `PR ${pr}: 후속 head ancestry 또는 parent 정보를 확인할 수 없어 상한 예외 리뷰를 거부합니다.`;
|
|
1610
|
+
deps.error(message);
|
|
1611
|
+
if (opts.json || opts.save !== undefined) results.push({ pr, error: message, reviewed: false, refusal: 'cap-refused', previousRoundCount, headCommit: diffRead.headCommit });
|
|
1612
|
+
failed += 1;
|
|
1613
|
+
continue;
|
|
1614
|
+
}
|
|
1615
|
+
// A non-ancestor head can be a force-push rewind or rebase. It is still
|
|
1616
|
+
// reviewed from the pinned full PR diff; only a proven descendant can
|
|
1617
|
+
// qualify for the merge-only delta path.
|
|
1618
|
+
if (ancestry.status === 0) {
|
|
1619
|
+
// Non-merge commits brought in from main are reachable but are not on
|
|
1620
|
+
// this first-parent line. A merge-only head ends at its first parent;
|
|
1621
|
+
// a later PR commit remains in the candidate range.
|
|
1622
|
+
const commits = git(['rev-list', '--first-parent', '--no-merges', `${classificationBase}..${deltaHead}`], 10_000);
|
|
1623
|
+
if (commits.status !== 0) {
|
|
1624
|
+
const message = `PR ${pr}: 후속 head의 PR 변경 여부를 확인할 수 없어 상한 예외 리뷰를 거부합니다.`;
|
|
1625
|
+
deps.error(message);
|
|
1626
|
+
if (opts.json || opts.save !== undefined) results.push({ pr, error: message, reviewed: false, refusal: 'cap-refused', previousRoundCount, headCommit: diffRead.headCommit });
|
|
1627
|
+
failed += 1;
|
|
1628
|
+
continue;
|
|
1629
|
+
}
|
|
1630
|
+
if (commits.stdout.trim() === '') mergeOnlyDeltaRange = { base: classificationBase, head: diffRead.headCommit.toLowerCase() };
|
|
1631
|
+
}
|
|
1632
|
+
} else if (previousRoundCount >= 5 && reason) {
|
|
1505
1633
|
const claimable = diffRead.source === 'sha-pinned' && diffRead.headCommitState === 'known'
|
|
1506
1634
|
&& diffRead.currentHeadCommitState === 'known' && !diffRead.stale && diffRead.diff.status === 0;
|
|
1507
1635
|
if (!claimable || !claimCapOverride(pr, diffRead.headCommit, reason, deps.now())) {
|
|
@@ -1514,6 +1642,25 @@ async function runSelfReviewCliCommandPinned(
|
|
|
1514
1642
|
}
|
|
1515
1643
|
deps.observeDoctorReview?.('cap-override', { pr, head: diffRead.headCommit, previousRoundCount, round: previousRoundCount + 1, reason }, { level: 'warn' });
|
|
1516
1644
|
}
|
|
1645
|
+
if (mergeOnlyDeltaRange) {
|
|
1646
|
+
const delta = deps.git?.(['diff', '--no-ext-diff', `${mergeOnlyDeltaRange.base}...${mergeOnlyDeltaRange.head}`], 25_000);
|
|
1647
|
+
if (!delta || delta.status !== 0) {
|
|
1648
|
+
const message = `PR ${pr}: merge-only 후속 head의 delta diff를 고정할 수 없습니다.`;
|
|
1649
|
+
deps.error(message);
|
|
1650
|
+
if (opts.json || opts.save !== undefined) results.push({ pr, error: message, reviewed: false, refusal: 'cap-refused', previousRoundCount, headCommit: diffRead.headCommit });
|
|
1651
|
+
failed += 1;
|
|
1652
|
+
continue;
|
|
1653
|
+
}
|
|
1654
|
+
diffRead.diff = delta;
|
|
1655
|
+
diffRead.baseCommit = mergeOnlyDeltaRange.base;
|
|
1656
|
+
}
|
|
1657
|
+
if (previousRoundCount >= 5 && authorization && !claimCapOverride(pr, diffRead.headCommit, authorization.reason, deps.now())) {
|
|
1658
|
+
const message = `PR ${pr}: 후속 head 승인 사용 기록을 남기지 못했습니다.`;
|
|
1659
|
+
deps.error(message);
|
|
1660
|
+
if (opts.json || opts.save !== undefined) results.push({ pr, error: message, reviewed: false, refusal: 'cap-refused', previousRoundCount, headCommit: diffRead.headCommit });
|
|
1661
|
+
failed += 1;
|
|
1662
|
+
continue;
|
|
1663
|
+
}
|
|
1517
1664
|
const localHeadComparison = compareLocalHead(pr, { value: diffRead.headCommit, state: diffRead.headCommitState }, deps);
|
|
1518
1665
|
const { diff } = diffRead;
|
|
1519
1666
|
const baseReviewerContext = hasProvidedReviewerContext
|
|
@@ -1887,10 +2034,15 @@ async function runSelfReviewCliCommandPinned(
|
|
|
1887
2034
|
if (review.reviewed === true) failed += 1;
|
|
1888
2035
|
} else {
|
|
1889
2036
|
const path = join(effectiveInstanceRoot(), 'review-results', `${opts.save}-${pr}-${diffRead.headCommit.slice(0, 12)}.json`);
|
|
1890
|
-
const
|
|
2037
|
+
const rawResult = results.at(-1);
|
|
2038
|
+
const normalized = rawResult && typeof rawResult === 'object'
|
|
2039
|
+
? normalizeSavedReviewMustFix(rawResult)
|
|
2040
|
+
: { result: rawResult, count: 0 };
|
|
2041
|
+
const result = normalized.result;
|
|
1891
2042
|
try {
|
|
1892
2043
|
mkdirSync(dirname(path), { recursive: true });
|
|
1893
2044
|
writeFileSync(path, selfReviewJsonLine([result]));
|
|
2045
|
+
if (normalized.count > 0) deps.log('mustfix-normalized', { pr, head: diffRead.headCommit, count: normalized.count });
|
|
1894
2046
|
} catch (error) {
|
|
1895
2047
|
failed += 1;
|
|
1896
2048
|
deps.error(`PR ${pr}: --save 실패: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -28,6 +28,116 @@ import { llmUsageCostFields } from '../budget/llm-cost.js';
|
|
|
28
28
|
|
|
29
29
|
const execFileAsync = promisify(execFile);
|
|
30
30
|
|
|
31
|
+
/** git 서브프로세스 대역 — term grep 동시성 계약을 실제 git 없이 재기 위한 교체점. */
|
|
32
|
+
export type ExecFileLike = (
|
|
33
|
+
file: string,
|
|
34
|
+
args: readonly string[],
|
|
35
|
+
options: { cwd?: string; encoding: 'utf-8'; maxBuffer: number },
|
|
36
|
+
) => Promise<{ stdout: string; stderr?: string }>;
|
|
37
|
+
|
|
38
|
+
const defaultExecFile: ExecFileLike = execFileAsync as unknown as ExecFileLike;
|
|
39
|
+
let execFileImpl: ExecFileLike = defaultExecFile;
|
|
40
|
+
|
|
41
|
+
/** 테스트 seam — null/미지정이면 실제 git 서브프로세스로 되돌린다. */
|
|
42
|
+
export function setExecFileForTest(fn?: ExecFileLike | null): void {
|
|
43
|
+
execFileImpl = fn ?? defaultExecFile;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** term 별 git grep 동시 실행 상한(기본 3 · OP 06:3x 실측 13개 동시 부하 101 을 막는다). */
|
|
47
|
+
export const TERM_GREP_CONCURRENCY = 3;
|
|
48
|
+
let termGrepConcurrency: number = TERM_GREP_CONCURRENCY;
|
|
49
|
+
|
|
50
|
+
/** 테스트 seam — 상한 없음(Infinity)과 결과 불변을 비교하기 위해 올린다. */
|
|
51
|
+
export function setTermGrepConcurrencyForTest(value?: number | null): void {
|
|
52
|
+
termGrepConcurrency = value ?? TERM_GREP_CONCURRENCY;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** 상한 클램프 — 풀 크기와 관측값이 같은 규칙을 쓰게 한 곳에 둔다. */
|
|
56
|
+
function effectiveConcurrency(concurrency: number, width: number): number {
|
|
57
|
+
const limit = Number.isFinite(concurrency) ? Math.max(1, Math.floor(concurrency)) : width;
|
|
58
|
+
return Math.max(1, Math.min(limit, width));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** 동시 실행 상한 풀 — 결과 순서는 입력 순서 그대로(순위 계산이 순서에 의존하지 않게). */
|
|
62
|
+
async function mapWithConcurrency<T, R>(
|
|
63
|
+
items: readonly T[],
|
|
64
|
+
concurrency: number,
|
|
65
|
+
worker: (item: T) => Promise<R>,
|
|
66
|
+
): Promise<R[]> {
|
|
67
|
+
const results = new Array<R>(items.length);
|
|
68
|
+
const size = effectiveConcurrency(concurrency, items.length);
|
|
69
|
+
let cursor = 0;
|
|
70
|
+
await Promise.all(
|
|
71
|
+
Array.from({ length: size }, async () => {
|
|
72
|
+
for (let index = cursor++; index < items.length; index = cursor++) {
|
|
73
|
+
results[index] = await worker(items[index]!);
|
|
74
|
+
}
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
return results;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** cwd seam 복원의 **단일 소유** — `process.chdir` 로 되돌리는 곳은 이 묶음(acquire/release) 하나뿐이다.
|
|
81
|
+
*
|
|
82
|
+
* ⛔ 왜 «생산» 이 소유하나: 한 번의 grounding 런은 persistent 코드 채널·skill 도구처럼 **임의 코드**를
|
|
83
|
+
* 지나고(`dispatchTool` → shell·pty), 그 코드가 cwd 를 옮긴 채 끝날 수 있다. 되돌리기를 «각 의존성» 에
|
|
84
|
+
* 맡기면 런이 마감(타임아웃)·예외로 끝나는 순간 그 되돌리기가 통째로 빠지고, 다음 런의 seam
|
|
85
|
+
* (`deps.cwd ?? process.cwd()`)이 **엉뚱한 트리를 저장소 루트로 읽어** 조용히 0건 grounding 을 낸다
|
|
86
|
+
* (#29343 r3 지적: 타임아웃 뒤 cwd seam 오염).
|
|
87
|
+
*
|
|
88
|
+
* ⛔ 소유는 «런마다» 가 아니라 «겹친 런 묶음» 하나다 — cwd 는 프로세스 전역이므로 런별 스냅샷은 겹침에서
|
|
89
|
+
* 깨진다(A 가 임시 트리로 옮긴 사이 B 가 시작하면 B 가 그 임시 트리를 «시작 자리» 로 저장하고, A 가 되돌린
|
|
90
|
+
* 뒤 B 가 다시 임시 트리로 되돌린다). ⇒ 첫 런이 시작 자리를 한 번 스냅샷하고, 겹쳐 들어온 런은 그 값을
|
|
91
|
+
* seam 으로 «물려받으며», 마지막으로 나가는 런만 되돌린다. 마감으로 «버려진» 런도 본문이 끝날 때까지
|
|
92
|
+
* holder 로 남으므로, 마감 뒤에 재개된 본문이 cwd 를 옮겨도 그 뒤의 런은 오염된 자리를 seam 으로 읽지 않고
|
|
93
|
+
* 본문이 끝나는 순간 되돌려진다.
|
|
94
|
+
* ⛔ 복원 보장의 «경계»: 복원은 런의 수명 안에서만 소유한다. 호출자가 마감으로 버렸는데 본문이 «끝나지
|
|
95
|
+
* 않으면» 전역 cwd 는 그 본문이 끝날 때까지 옮겨진 채 남는다 — 이 함수에는 호출자의 마감 신호가 들어오지
|
|
96
|
+
* 않고, 진행 중인 본문 밑의 cwd 를 남이 바꾸면 그 본문을 깨뜨린다. 그 사이 보장되는 것은 «겹쳐 들어온
|
|
97
|
+
* grounding 런의 seam 이 오염된 자리를 읽지 않는다» 이고, 본문이 끝나는 순간 마지막 holder 가 되돌린다
|
|
98
|
+
* (mission-codebase-gate.test.ts «마감 뒤 재개» 시험이 이 경계를 그대로 잰다).
|
|
99
|
+
* ⛔ 되돌리기 실패는 grounding 결과를 바꾸지 않되 «조용히 삼키지» 않는다 — `mission.grounding`
|
|
100
|
+
* `cwd-restore-failed` 로 남긴다(기존 이벤트 형식은 그대로). */
|
|
101
|
+
interface CwdSeamOwner { root: string; holders: number }
|
|
102
|
+
let cwdSeamOwner: CwdSeamOwner | null = null;
|
|
103
|
+
|
|
104
|
+
/** 소유 토큰 — `owned=false` 면 이 런은 묶음에 들지 않았다(시작 자리를 못 읽었다) ⇒ 되돌릴 것도 없다.
|
|
105
|
+
* ⛔ 절대 throw 하지 않는다: 지워진 cwd 에서도 `deps.cwd` 를 받은 호출은 예전처럼 진행해야 한다. */
|
|
106
|
+
interface CwdSeamLease { root: string | null; owned: boolean }
|
|
107
|
+
|
|
108
|
+
function acquireCwdSeam(): CwdSeamLease {
|
|
109
|
+
if (!cwdSeamOwner) {
|
|
110
|
+
let root: string;
|
|
111
|
+
try { root = process.cwd(); } catch { return { root: null, owned: false }; }
|
|
112
|
+
cwdSeamOwner = { root, holders: 0 };
|
|
113
|
+
}
|
|
114
|
+
cwdSeamOwner.holders += 1;
|
|
115
|
+
return { root: cwdSeamOwner.root, owned: true };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function releaseCwdSeam(lease: CwdSeamLease): void {
|
|
119
|
+
if (!lease.owned) return;
|
|
120
|
+
const owner = cwdSeamOwner;
|
|
121
|
+
if (!owner) return;
|
|
122
|
+
owner.holders -= 1;
|
|
123
|
+
if (owner.holders > 0) return;
|
|
124
|
+
cwdSeamOwner = null;
|
|
125
|
+
let current: string | null = null;
|
|
126
|
+
try { current = process.cwd(); } catch { /* 지워진 자리 — 아래에서 되돌린다 */ }
|
|
127
|
+
if (current === owner.root) return;
|
|
128
|
+
try {
|
|
129
|
+
process.chdir(owner.root);
|
|
130
|
+
} catch (e) {
|
|
131
|
+
try {
|
|
132
|
+
debug.log('mission.grounding', 'cwd-restore-failed', {
|
|
133
|
+
root: owner.root,
|
|
134
|
+
current,
|
|
135
|
+
error: e instanceof Error ? e.message.slice(0, 200) : String(e).slice(0, 200),
|
|
136
|
+
}, { level: 'warn' });
|
|
137
|
+
} catch { /* 관측 실패가 grounding 을 바꾸지 않는다 */ }
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
31
141
|
function logLlmUsage(site: 'codebase-gate-injected' | 'codebase-gate-dynamic', model: string, usage: LLMUsage): void {
|
|
32
142
|
try {
|
|
33
143
|
debug.log('llm.usage', 'llm-usage', {
|
|
@@ -215,28 +325,37 @@ export function commonTermCoverageWeight(matchLines: number): number {
|
|
|
215
325
|
}
|
|
216
326
|
|
|
217
327
|
async function searchRepository(terms: string[], limit: number, cwd: string | undefined, paths: string[], commonPaths = paths): Promise<string[]> {
|
|
218
|
-
|
|
328
|
+
// 같은 키워드는 한 번만 실행한다 — 실행·랭킹이 같은 목록을 쓰므로 결과는 결정적이다.
|
|
329
|
+
const uniqueTerms = [...new Set(terms)];
|
|
330
|
+
if (!uniqueTerms.length) return [];
|
|
219
331
|
const fileTerms = new Map<string, Set<string>>(); // file → 매칭된 서로 다른 term
|
|
220
332
|
const fileLines = new Map<string, number>(); // file → 총 매칭 라인 수
|
|
221
333
|
const fileTermLines = new Map<string, Map<string, number>>(); // file → term별 매칭 라인 수
|
|
222
334
|
const tooCommon = new Set<string>(); // 200+ 파일 매칭 = 밀도 감쇠 대상
|
|
223
|
-
const trackedPaths = await
|
|
335
|
+
const trackedPaths = await execFileImpl('git', ['ls-files', '--', ...paths], { ...(cwd ? { cwd } : {}), encoding: 'utf-8', maxBuffer: 8_000_000 })
|
|
224
336
|
.then(({ stdout }) => stdout.split('\n').filter(Boolean))
|
|
225
337
|
.catch(() => [] as string[]);
|
|
226
|
-
const pathMatches = new Map(
|
|
227
|
-
// term별 git grep 을
|
|
228
|
-
//
|
|
229
|
-
|
|
338
|
+
const pathMatches = new Map(uniqueTerms.map((term) => [term, trackedPaths.filter((file) => file.toLowerCase().includes(term)).length]));
|
|
339
|
+
// term별 git grep 을 동시 실행 상한 풀(기본 3)로 돌린다 — 무제한 병렬은 mbp 1분 부하 101·git grep
|
|
340
|
+
// 13개 동시(OP 06:3x 실측)를 만들었다. git grep=현재 워킹트리 파일 검색(history 아님)·
|
|
341
|
+
// gitignore/바이너리 자동 제외. 호출자가 코드와 문서를 분리한다.
|
|
342
|
+
const termGrepStartedAt = Date.now();
|
|
343
|
+
const perTerm = await mapWithConcurrency(uniqueTerms, termGrepConcurrency, async (t) => {
|
|
230
344
|
try {
|
|
231
345
|
// -c: file:count. -i 무시·-I 바이너리제외. term 하나씩(어느 term 이 걸렸는지 추적).
|
|
232
|
-
const { stdout } = await
|
|
346
|
+
const { stdout } = await execFileImpl('git', ['grep', '-c', '-i', '-I', '-e', t, '--', ...paths], { ...(cwd ? { cwd } : {}), encoding: 'utf-8', maxBuffer: 8_000_000 });
|
|
233
347
|
const rows = stdout.split('\n').filter(Boolean);
|
|
234
|
-
const commonRows = commonPaths === paths ? rows : await
|
|
348
|
+
const commonRows = commonPaths === paths ? rows : await execFileImpl('git', ['grep', '-c', '-i', '-I', '-e', t, '--', ...commonPaths], { ...(cwd ? { cwd } : {}), encoding: 'utf-8', maxBuffer: 8_000_000 })
|
|
235
349
|
.then(({ stdout }) => stdout.split('\n').filter(Boolean))
|
|
236
350
|
.catch(() => [] as string[]);
|
|
237
351
|
return { t, rows, commonCount: commonRows.length };
|
|
238
352
|
} catch { return { t, rows: [] as string[], commonCount: 0 }; } // git grep no-match = exit 1(throw) → 빈 결과
|
|
239
|
-
})
|
|
353
|
+
});
|
|
354
|
+
debug.log('grounding.search', 'term-grep-batch', {
|
|
355
|
+
terms: uniqueTerms.length,
|
|
356
|
+
concurrency: effectiveConcurrency(termGrepConcurrency, uniqueTerms.length),
|
|
357
|
+
ms: Date.now() - termGrepStartedAt,
|
|
358
|
+
});
|
|
240
359
|
for (const { t, rows, commonCount } of perTerm) {
|
|
241
360
|
if (commonCount > 200) {
|
|
242
361
|
tooCommon.add(t);
|
|
@@ -260,7 +379,7 @@ async function searchRepository(terms: string[], limit: number, cwd: string | un
|
|
|
260
379
|
const cover = [...ts].reduce((total, term) => total + (tooCommon.has(term)
|
|
261
380
|
? commonTermCoverageWeight(termLines?.get(term) ?? 0)
|
|
262
381
|
: 1), 0);
|
|
263
|
-
const nameTerms =
|
|
382
|
+
const nameTerms = uniqueTerms.filter((t) => f.toLowerCase().includes(t));
|
|
264
383
|
const nameWeight = nameTerms.reduce((total, term) => {
|
|
265
384
|
const matches = pathMatches.get(term) ?? 0;
|
|
266
385
|
// 경로상 유일한 식별자는 강한 +25를 유지하고, 공유 조각은 매칭 경로 수에 반비례해 감쇠한다.
|
|
@@ -531,8 +650,12 @@ export async function groundMissionInCodebase(
|
|
|
531
650
|
goal: string, deps: { cwd?: string; seedPaths?: readonly string[]; searchTerms?: SearchTermFn; skillIndex?: SkillIndexFn; pickSkills?: SkillPickFn; recallMemory?: RecallMemoryFn; recallSelf?: RecallSelfFn; refDigest?: RefDigestFn; persistent?: PersistentGroundingDeps | false } & CapsuleGroundingDeps = {},
|
|
532
651
|
): Promise<CodebaseGrounding> {
|
|
533
652
|
// 호출자가 준 root를 모든 저장소 채널과 corpus 관측에 공유한다. 미지정 호출은 기존처럼 프로세스 cwd를 쓴다.
|
|
653
|
+
// ⛔ seam 은 «읽기» 만 하지 않는다 — 시작 자리를 소유자(acquireCwdSeam)에게서 받고 finally 에서 돌려준다.
|
|
654
|
+
// 겹친 런은 첫 런의 스냅샷을 물려받으므로, 다른 런이 옮겨 놓은 cwd 를 시작 자리로 읽지 않는다.
|
|
655
|
+
const cwdLease = acquireCwdSeam();
|
|
534
656
|
const cwdSource = deps.cwd === undefined ? 'process' : 'caller';
|
|
535
|
-
|
|
657
|
+
// 시작 자리를 못 읽었으면(지워진 cwd) 소유하지 않는다 — caller root 는 그대로 쓰고, 미지정이면 예전처럼 process.cwd() 가 판정한다.
|
|
658
|
+
const searchRoot = deps.cwd ?? cwdLease.root ?? process.cwd();
|
|
536
659
|
const startedAt = performance.now();
|
|
537
660
|
let searchTermsElapsedMs = 0;
|
|
538
661
|
let persistentElapsedMs = 0;
|
|
@@ -695,7 +818,13 @@ export async function groundMissionInCodebase(
|
|
|
695
818
|
debug.log('mission.grounding', 'corpus', { grounded: false, reason: 'error', cwd: searchRoot, cwdSource, error: e instanceof Error ? e.message.slice(0, 200) : String(e).slice(0, 200), persistentEvidence: null, persistentStopReason: null, codeChannel: 'failed' }, { level: 'warn' });
|
|
696
819
|
return { grounded: false, context: '', files: [], persistentEvidence: [], skillFacts: [], codeFacts: [], memoryFacts: [], documentFacts: [], refFacts: [], ptyFacts: [] };
|
|
697
820
|
} finally {
|
|
698
|
-
|
|
821
|
+
// 정상·예외·타임아웃 어느 경로로 끝났든 소유를 돌려준다 — 마지막 holder 가 시작 자리로 되돌린다.
|
|
822
|
+
// 되돌리기를 관측보다 «먼저» 둔다: 관측이 무엇을 하든 복원이 빠지지 않는다.
|
|
823
|
+
try {
|
|
824
|
+
releaseCwdSeam(cwdLease);
|
|
825
|
+
} finally {
|
|
826
|
+
observeTiming();
|
|
827
|
+
}
|
|
699
828
|
}
|
|
700
829
|
}
|
|
701
830
|
|
|
@@ -533,17 +533,37 @@ function reuseSameCellPr(run: CmdRunner, input: UpsertPrInput, target: NonNullab
|
|
|
533
533
|
if (!runKey) return fail(input.runId ? 'new run id invalid for scratch ref' : 'run id required for scratch ref');
|
|
534
534
|
const scratch = `self-impl/pr-create-r${runKey}-${randomUUID()}`;
|
|
535
535
|
const scratchRef = `refs/heads/${scratch}`;
|
|
536
|
+
// ⛔ push 보고는 원격의 진실이 아니다 — ref 를 만든 뒤에도 exit≠0 으로 끝날 수 있고, 삭제가
|
|
537
|
+
// 실패로 보고돼도 이미 지워졌을 수 있다. 그래서 새 draft 결과가 확정되는 즉시 **이 시도가
|
|
538
|
+
// 만든 scratch ref 하나만** 상대로 「남았나 보고 → 지운다」. 지우지 못하면 그 이유를 원장에
|
|
539
|
+
// 남긴다(다른 ref·가지·PR 은 건드리지 않는다).
|
|
540
|
+
const reapScratchRef = (outcome: 'branch-created' | 'create-refused' | 'upload-failed'): void => {
|
|
541
|
+
// 업로드가 실패로 보고돼도 원격에 ref 가 남아 있을 수 있다 — 먼저 읽고 건너뛰면 «읽은 뒤
|
|
542
|
+
// 늦게 착지한» ref 가 남는 창이 생긴다. 그래서 결과와 무관하게 늘 삭제를 시도하고,
|
|
543
|
+
// 원격이 «그런 ref 없음» 이라 답하면 이미 없는 것이므로 정리 실패로 세지 않는다.
|
|
544
|
+
let removed = run('git', ['-C', cwd, 'push', 'origin', `:${scratchRef}`]);
|
|
545
|
+
if (!removed.ok && isTransientPushFailure(removed.err || removed.out))
|
|
546
|
+
removed = run('git', ['-C', cwd, 'push', 'origin', `:${scratchRef}`]);
|
|
547
|
+
if (removed.ok) return;
|
|
548
|
+
if (/remote ref does not exist/i.test(`${removed.err ?? ''}\n${removed.out ?? ''}`)) {
|
|
549
|
+
debug.log('autopilot.pr-manager', 'same-cell-scratch-absent', { scratchRef, outcome });
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
debug.log('autopilot.pr-manager', 'same-cell-scratch-cleanup-failed',
|
|
553
|
+
{ scratchRef, outcome, detail: removed.err || removed.out,
|
|
554
|
+
stderr: removed.err ?? '', stdout: removed.out, truncated: false }, { level: 'warn' });
|
|
555
|
+
};
|
|
536
556
|
const uploaded = run('git', ['-C', cwd, 'push', 'origin', `HEAD:${scratchRef}`]);
|
|
537
|
-
if (!uploaded.ok)
|
|
557
|
+
if (!uploaded.ok) {
|
|
558
|
+
reapScratchRef('upload-failed');
|
|
559
|
+
return fail(`new run object upload failed: ${(uploaded.err || uploaded.out).slice(0, 220)}`);
|
|
560
|
+
}
|
|
538
561
|
const repository = run('gh', ['repo', 'view', '--json', 'nameWithOwner', '-q', '.nameWithOwner'], { cwd });
|
|
539
562
|
const repoName = repository.out.trim();
|
|
540
563
|
const createdRef = repository.ok && /^[^/\s]+\/[^/\s]+$/.test(repoName)
|
|
541
564
|
? run('gh', ['api', '--method', 'POST', `repos/${repoName}/git/refs`, '-f', `ref=${newRef}`, '-f', `sha=${localHead.out.trim()}`], { cwd })
|
|
542
565
|
: { ok: false, out: '', err: 'repository identity unavailable' };
|
|
543
|
-
|
|
544
|
-
if (!removedScratch.ok) debug.log('autopilot.pr-manager', 'same-cell-scratch-cleanup-failed',
|
|
545
|
-
{ scratchRef, detail: removedScratch.err || removedScratch.out,
|
|
546
|
-
stderr: removedScratch.err ?? '', stdout: removedScratch.out, truncated: false }, { level: 'warn' });
|
|
566
|
+
reapScratchRef(createdRef.ok ? 'branch-created' : 'create-refused');
|
|
547
567
|
if (!createdRef.ok) return fail(`new run branch create refused: ${(createdRef.err || createdRef.out).slice(0, 220)}`);
|
|
548
568
|
const stateLabels = new Set(labelsForAxis('state').map(label => label.name));
|
|
549
569
|
const labels = [...new Set([...(input.labels ?? []).filter(label => !stateLabels.has(label as typeof PR_LABEL_NAMES.running)),
|
|
@@ -286,6 +286,7 @@ export async function dispatchSelfImplement(
|
|
|
286
286
|
goalFile = (await authorGoal(goalSourceText, ctx.cwd, {
|
|
287
287
|
goalTitle: feature,
|
|
288
288
|
decomposeSteps: createDecomposeSteps(ctx.signal, {
|
|
289
|
+
repositoryRoot: ctx.cwd,
|
|
289
290
|
...(adversarialReview !== undefined ? { adversarialReview } : {}),
|
|
290
291
|
...(recentStepCounts !== undefined ? { recentStepCounts } : {}),
|
|
291
292
|
}),
|