elanous 0.2.34 → 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/{abb4b98b.163e0f56e84ae35d.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/1201.afbfc5b1c5e5cbe4.js +1 -0
- 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/2500.cbc1257b774aae52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6086.913a69e6fa3e4a8b.js → 2683.c9773a0c589b031b.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{5576-82d3703636d5c4b9.js → 275-02ea4c2a33980422.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{ffdc3a04.b9c23c1b28dd4a96.js → 2812ca6a.3b9f4a7a08885744.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2941.3c3546f96bc6efa7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{9550.d5f76828f972058c.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/{8817.61bb7ffbba502ecb.js → 3136.30aaaa5fa03662a3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9131-fce7256c4180c4a5.js → 3148-98efd4869d660a87.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3498.cf2a15a8a9e5b926.js → 3155.2587a55196ecb394.js} +3 -3
- 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/{3103.84470c8445962f04.js → 3324.a09703033abcbd2f.js} +1 -1
- 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/{3819.163d4777f0a597f6.js → 3538.a445e50bb359d068.js} +2 -2
- 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/{3414.172ad4ca2d9b08e8.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/3757-180308bc61021b05.js +1 -0
- package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +74 -0
- package/apps/pwa/out/_next/static/chunks/3840-5825d56d46976a92.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9b48c871.204d5d13e7809bd0.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/{6740.43de73fc427c9fe2.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/{8548.036c344973968847.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/{3411-f87314c6c66ebc73.js → 5085-bce4904931767ca6.js} +1 -1
- 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/{3110.0a7065f25c841818.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/{1644.35dd25240ae24e4b.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/{3837.722e053fb9f321ad.js → 5711.957b095705c12560.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2124.ed5bf480cea7f85b.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/{7562.948255cbc3e79d33.js → 599.c39c571b6733f2a2.js} +2 -2
- 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/{5446.edf141cff9ef647d.js → 6925.562d532110879886.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7005.1623d2aea78eb85f.js → 6943.c6b24124853a47b2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/727.7deb87749b0a343a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8368.014caa8de2f5af34.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/{2554.3b5e200f5f5cfcd6.js → 771.c3cdb6c1f7f47c02.js} +16 -16
- 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/{3121.779fafe3e44612c5.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/{9a8cb466.cc9fc9e6e46038aa.js → 873d6c12.09bd499f57171543.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7431.3051e9b8a4372d2d.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/914.8abefd48d579547b.js +94 -0
- package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1895-60ed0e341c658bd4.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/{2547.dd27303624cb4da8.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/9789.60f723d18097ec30.js +1 -0
- 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-4fb31eb476dcbad3.js → page-083747f1d4518f61.js} +1 -1
- 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/{5014f970-22bef0b5210f7d60.js → ccae1c4b-0cf414f5eff1b10d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4fa33ebd.21c1bd5b294496e6.js → ceba0382.650712b56b85b582.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/da5ecc5c-b005ad8cac737d57.js +1 -0
- package/apps/pwa/out/_next/static/chunks/f9a61e4d.1fc2c1dbdd49fe46.js +1 -0
- 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/{L04y73dlwKeTW-GetaTF3 → 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/bin/elanous.mjs +3 -2
- package/catalog/providers/opengateway.yaml +25 -0
- package/docs/goal-context/01-goal-authoring-checks.md +8 -0
- package/docs/goal-context/03-verification-menu.md +24 -0
- package/docs/goal-context/04-mock-scenarios.md +100 -0
- package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
- package/docs/goal-context/README.md +7 -0
- package/graphs/catalog/catalog.yaml +1 -1
- package/graphs/default-loop.yaml +63 -4
- package/graphs/document-loop.yaml +51 -3
- package/graphs/implement-loop.yaml +77 -4
- package/graphs/journey/ta-journey.yaml +11 -1
- package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
- package/graphs/journey/units/author-dialogue/observe.ts +96 -0
- package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
- package/graphs/operate-loop.yaml +51 -3
- package/graphs/release/recipes.yaml +6 -0
- package/graphs/release/release-loop.yaml +17 -4
- package/graphs/research-loop.yaml +137 -3
- package/graphs/test-diet/test-diet.yaml +3 -0
- 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 +19 -6
- package/scripts/first10-gate.ts +416 -0
- package/scripts/fleet/wsl-node-setup.sh +432 -0
- package/scripts/hq/standby-snapshot.ts +17 -12
- package/scripts/release-loop/docs-land-node.ts +21 -5
- package/scripts/release-loop/docs-node.ts +204 -8
- package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
- package/scripts/release-loop/gate-node.ts +427 -72
- package/scripts/release-loop/gate-partial.ts +65 -11
- package/scripts/release-loop/gate-radius-live.ts +177 -0
- package/scripts/release-loop/gate-radius-shadow.ts +1 -1
- package/scripts/release-loop/node-verdict.ts +14 -1
- package/scripts/release-loop/npm-publish-node.ts +66 -12
- package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
- package/scripts/release-loop/pwa-remote.ts +166 -0
- package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
- package/scripts/release-loop/resume-cap.ts +14 -34
- package/scripts/release-loop/resume-release.ts +78 -15
- package/scripts/release-loop/traffic-node.ts +59 -0
- package/scripts/release-loop/traffic-transition.ts +159 -0
- package/scripts/release-loop/unattended-release.ts +2 -0
- package/scripts/rhythm/daily.ts +137 -3
- package/scripts/test-diet/lib.ts +6 -1
- package/scripts/test-diet/node.ts +194 -13
- package/scripts/ux-sim.ts +92 -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/self-ambient-cache.ts +8 -0
- package/src/agent/task-notification.ts +56 -10
- package/src/agent/types.ts +4 -0
- package/src/agent-substrate/acp-reviewer.ts +39 -4
- package/src/agent-substrate/pr-reviewer.ts +72 -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 +229 -28
- package/src/autopilot/mission-codebase-gate.ts +141 -12
- package/src/autopilot/pr-manager.ts +240 -41
- package/src/boot/daemon-tools/self-implement.ts +1 -0
- package/src/budget/run-usage-rollup.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 -6
- package/src/chat/internal-turn-origin.ts +1 -0
- package/src/chat/paste-fold.ts +86 -0
- package/src/chat/pickers/modal-runtime.ts +10 -27
- 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/agent-cli.ts +13 -2
- package/src/cli/config-audit.ts +119 -0
- package/src/cli/doctor-cli.ts +26 -1
- package/src/cli/guardian-cli.ts +10 -0
- package/src/cli/herdr-cli.ts +34 -0
- package/src/cli/light-entry-route.ts +50 -7
- 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/pod-cli.ts +77 -3
- package/src/cli/pr-cli.ts +34 -18
- 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-pod-shadow-job.ts +3 -0
- package/src/cli/pr-land-recovery.ts +117 -1
- package/src/cli/pty-takeover-cli.ts +8 -7
- package/src/cli/release-checklist-read-cli.ts +79 -0
- package/src/cli/release-cli.ts +92 -106
- package/src/cli/release-single-flight.ts +1 -1
- package/src/cli/remote-resolve.ts +1 -1
- package/src/cli/root-tui-entry.ts +48 -0
- package/src/cli/sim-cli.ts +22 -0
- package/src/cli/tasks-card-show.ts +162 -0
- package/src/cli/tasks-cli.ts +1065 -338
- package/src/cli/tasks-read-cli.ts +197 -0
- package/src/cli/usage-cli.ts +13 -11
- package/src/clipboard/history.ts +179 -13
- package/src/config.ts +8 -1
- 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/chat/acp-chat.ts +8 -0
- package/src/dashboard/context/keys.ts +8 -31
- package/src/dashboard/index.ts +280 -59
- 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/render/theme-resolver.ts +33 -4
- 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/schedule-registry.ts +16 -2
- package/src/domains/standalone-log-sink.ts +15 -2
- package/src/esc-abort-gate.ts +69 -0
- package/src/git-fs/idle-refresh.ts +76 -0
- package/src/git-fs/index.ts +18 -7
- package/src/git-fs/worktree.ts +137 -5
- package/src/graph-kinds/registry.ts +2 -2
- package/src/graph-runner/graph-cli.ts +18 -0
- package/src/graph-runner/runner.ts +173 -21
- package/src/graph-wizard/generate.ts +108 -4
- package/src/graph-wizard/steps.ts +15 -0
- package/src/grok/credential.ts +10 -3
- package/src/grounding/proactive-ground.ts +86 -0
- package/src/harness/control-inbox.ts +49 -1
- package/src/harness/harness-cli-command.ts +163 -35
- package/src/harness/harness-incidents.ts +85 -1
- package/src/harness/launch-utterance-ledger.ts +208 -0
- 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/impl-discipline/detector.ts +16 -4
- package/src/impl-discipline/system-prompt.ts +11 -0
- package/src/impl-discipline/types.ts +2 -2
- package/src/index.ts +822 -154
- package/src/input-core/context-key-runtime.ts +21 -0
- package/src/intake-plane/already-built-hint.ts +4 -2
- package/src/intake-plane/requirement-funnel.ts +29 -1
- package/src/light-cli.ts +32 -11
- package/src/llm/opengateway-models.ts +11 -0
- package/src/llm/provider-credentials.ts +14 -0
- package/src/llm/provider-detect.ts +8 -1
- package/src/llm/runtime-model-family.ts +2 -1
- package/src/llm-wellformed.ts +70 -0
- package/src/llm.ts +247 -59
- 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/model-tier/llm-tier-map.ts +15 -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/native-tool-catalog.ts +15 -1
- package/src/nexus/api/decisions-route.ts +38 -18
- package/src/nexus/api/graph-wizard-api.ts +20 -2
- package/src/nexus/api/loop-resources.ts +13 -1
- package/src/nexus/boot/register-mcp-clients.ts +263 -38
- package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
- package/src/oauth/codex.ts +7 -0
- package/src/onboarding/first-run.ts +37 -6
- package/src/onboarding/web-first.ts +43 -11
- package/src/ops/overview-collect.ts +30 -9
- package/src/ops/overview.ts +22 -9
- package/src/persona/loader.ts +11 -0
- package/src/persona/types.ts +8 -0
- package/src/pr-tool/census.ts +261 -27
- 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-manifest.ts +7 -0
- 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 +100 -4
- package/src/release-loop/landed-but-yellow.ts +129 -5
- package/src/release-loop/light-rc.ts +1 -0
- package/src/release-loop/rehearsal.ts +37 -21
- package/src/repl/index.ts +192 -17
- package/src/repl/ops-msg-bridge.ts +32 -0
- package/src/seat-loop/knowhow-lint.ts +1 -1
- package/src/self-dev/ask-launch-flow.ts +44 -5
- package/src/self-dev/cli-help-text.ts +17 -0
- package/src/self-dev/decompose-proposal.ts +172 -20
- package/src/self-dev/decompose.ts +61 -0
- package/src/self-dev/dev-cli.ts +48 -12
- package/src/self-dev/dev-pipeline.ts +8 -2
- package/src/self-dev/draft-residue.ts +37 -1
- package/src/self-dev/draft-sweep.ts +137 -11
- package/src/self-dev/draft-triage-rules.ts +138 -0
- package/src/self-dev/fleet-reduce.ts +3 -2
- package/src/self-dev/glm-credential-guard.ts +77 -0
- package/src/self-dev/graph-front-nodes.ts +112 -0
- package/src/self-dev/graph-journey-nodes.ts +2 -0
- package/src/self-dev/graph-journey-route.ts +12 -2
- package/src/self-dev/harness-run-cli.ts +3 -15
- package/src/self-dev/orchestrate-cli-text.ts +10 -0
- package/src/self-dev/orchestrate-cli.ts +68 -3
- package/src/self-dev/orchestrate.ts +116 -17
- package/src/self-dev/review-provider-fallback.ts +35 -1
- package/src/self-dev/run-supervisor.ts +55 -2
- package/src/self-dev/run-types.ts +1 -1
- package/src/self-dev/self-orchestrate-runtime.ts +1 -11
- package/src/self-dev/shard-aggregate.ts +42 -5
- package/src/self-dev/shard-run.ts +8 -1
- package/src/self-health/autoheal.ts +153 -0
- package/src/self-health/signatures.ts +6 -0
- package/src/self-implement/blocked-draft-policy.ts +20 -0
- package/src/self-implement/classify-shadow.ts +3 -7
- package/src/self-implement/device-first.ts +116 -0
- package/src/self-implement/doctor-visit.ts +257 -2
- package/src/self-implement/evidence-command-budget.ts +80 -0
- package/src/self-implement/gate-baseline.ts +56 -17
- package/src/self-implement/gate-cli.ts +1 -0
- package/src/self-implement/gate-remote.ts +31 -20
- package/src/self-implement/goal-author-cli.ts +1 -0
- package/src/self-implement/goal-author-decompose.ts +534 -45
- package/src/self-implement/goal-author.ts +282 -7
- package/src/self-implement/goal-elaborate.ts +449 -0
- package/src/self-implement/goal-refine.ts +273 -0
- package/src/self-implement/graph-overlay-yaml.ts +14 -3
- 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 +370 -62
- 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-budget-judgment.ts +5 -8
- package/src/self-implement/rework-policy.ts +30 -0
- package/src/self-implement/run-ledger.ts +108 -0
- package/src/self-implement/run-stop.ts +10 -1
- package/src/self-implement/run-ttl.ts +38 -24
- package/src/self-implement/running-runs.ts +29 -1
- package/src/self-implement/scope-adjacency.ts +115 -0
- package/src/self-implement/seams.ts +187 -28
- package/src/self-implement/stop-autoheal.ts +87 -1
- package/src/self-implement/wiring-check.ts +358 -0
- package/src/session-runtime/index.ts +1 -1
- package/src/setup/llm-env-detect.ts +5 -0
- package/src/shell-env-bootstrap.ts +11 -4
- package/src/skills/runner.ts +4 -2
- package/src/skills/tools/agent.ts +408 -40
- package/src/skills/tools/msg-ask.ts +100 -0
- package/src/skills/tools/ops-ledger.ts +2 -1
- 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/hold-hygiene.ts +24 -6
- package/src/steward/rejudge-tick.ts +10 -2
- package/src/steward/ta-repair-event-collect.ts +17 -6
- package/src/steward/triage-budget.ts +194 -0
- package/src/steward/triage.ts +20 -3
- package/src/task-agent/actions.ts +72 -2
- package/src/task-agent/green-sweep.ts +4 -0
- package/src/task-agent/land-queue.ts +21 -8
- package/src/task-agent/live-moves.ts +182 -10
- package/src/task-agent/mission.ts +30 -0
- package/src/task-agent/parent-host.ts +123 -3
- 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 +48 -4
- package/src/task-agent/task-card-prefix.ts +2 -0
- package/src/task-agent/task-hand.ts +525 -57
- package/src/task-agent/task-parent-role-llm.ts +36 -0
- package/src/task-agent/tier-split.ts +196 -0
- package/src/task-agent/work-order-build.ts +2 -0
- package/src/task-agent/work-order.ts +3 -2
- package/src/task-orchestrator/generator-prompt.ts +60 -11
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +42 -0
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +130 -11
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
- package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
- package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
- package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +19 -2
- package/src/task-orchestrator/surfaces/pod-pool.ts +76 -4
- package/src/task-orchestrator/surfaces/pod-provenance.ts +82 -0
- 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-source-receive.ts +18 -0
- package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +6 -2
- package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +7 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +521 -40
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +759 -50
- package/src/task-orchestrator/surfaces/self-implement.ts +65 -2
- package/src/tool-runtime/index.ts +15 -2
- package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
- package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
- package/src/tty-foreground.ts +155 -0
- package/src/tui/README.md +2 -0
- package/src/tui/chat/background-job-status.ts +54 -0
- package/src/tui/chat/goal-interim.ts +173 -0
- package/src/tui/chat/log-view.ts +267 -0
- package/src/tui/chat/self-health-status.ts +232 -0
- package/src/tui/entry.ts +695 -0
- package/src/tui/input/composer.ts +151 -0
- package/src/tui/seat-mail-boot.ts +59 -0
- package/src/tui/slash/compact-command.ts +7 -0
- package/src/tui/slash/compact.ts +94 -0
- package/src/tui/slash/new-session.ts +35 -0
- package/src/tui/slash/resume.ts +75 -0
- package/src/tui-client/local-chat-turn.ts +282 -0
- package/src/tui-client/local-harness-command.ts +63 -0
- package/src/tui-client/local-provider-command.ts +184 -0
- package/src/tui-client/next-dashboard-runtime.ts +8 -0
- package/src/tui-client/next-loop-command.ts +70 -0
- package/src/tui-client/next-wakeup.ts +191 -0
- package/src/tui.ts +37 -0
- package/src/ui/modal-adapter.ts +2 -2
- package/src/user-config.ts +4 -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 +379 -0
- package/src/ux-sim/fake-bin.ts +87 -7
- 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 +367 -0
- package/src/ux-sim/fault-pod-codex-503.ts +211 -0
- package/src/ux-sim/fault-scope-escape-lift.ts +216 -0
- 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/1162.c69abda138c7ce43.js +0 -79
- package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +0 -94
- package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +0 -23
- package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +0 -115
- package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +0 -8
- package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +0 -1
- package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2987-30cf9c2eb7b8bdd5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3001-5a52788c813b6113.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +0 -104
- package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +0 -149
- package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +0 -148
- package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +0 -64
- package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +0 -74
- package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5028-f0722e6114c313e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5249.96a848656b582a93.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +0 -62
- package/apps/pwa/out/_next/static/chunks/5489.ec2dd1b5272a19dc.js +0 -24
- package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6053-d893974de92e6198.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +0 -1
- package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +0 -77
- package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +0 -90
- package/apps/pwa/out/_next/static/chunks/7193-cf355cca5ba6c5d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7386.5d8e7e42e818dfb6.js +0 -287
- package/apps/pwa/out/_next/static/chunks/7448.478958ffbbba0ac0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +0 -27
- package/apps/pwa/out/_next/static/chunks/7952.b192c31b6a0e00cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +0 -36
- package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +0 -1
- package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +0 -93
- package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +0 -24
- package/apps/pwa/out/_next/static/chunks/9739.8d5f36ac67a3b236.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +0 -1
- package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-d7bff0f0905a662c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-398c0faa173203f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-df3445b207ceceab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +0 -122
- package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +0 -1
- /package/apps/pwa/out/_next/static/{L04y73dlwKeTW-GetaTF3 → uC-N0emedeNOFuaBQFv-I}/_ssgManifest.js +0 -0
|
@@ -40,6 +40,7 @@ import { writeGoalDocumentAtomic } from './goal-document-write.js';
|
|
|
40
40
|
import { hostname, loadavg } from 'node:os';
|
|
41
41
|
import { resolveHostId } from '../platform/host-id.js';
|
|
42
42
|
import { resolveInstanceName } from '../instance-identity.js';
|
|
43
|
+
import { ghAutomationEnv } from '../autopilot/pr-manager.js';
|
|
43
44
|
import { citedReviewSymbols, MAX_CITED_REVIEW_SYMBOL_CHARS, measureReviewFindingKeyOverlap, normalizeReviewFindingKey, REVIEW_FINDING_KEY_VERSION, reviewFindingKey, shortNormalizedReviewFindingHash, type CitedReviewSymbol } from '../agent-substrate/review-finding-key.js';
|
|
44
45
|
export { citedReviewSymbols, MAX_CITED_REVIEW_SYMBOL_CHARS, normalizeReviewFindingKey, REVIEW_FINDING_KEY_VERSION, reviewFindingKey, shortNormalizedReviewFindingHash, type CitedReviewSymbol } from '../agent-substrate/review-finding-key.js';
|
|
45
46
|
|
|
@@ -47,6 +48,46 @@ function displayBranchName(ref: string): string {
|
|
|
47
48
|
return ref.trim().replace(/^refs\/heads\//, '').replace(/^origin\//, '');
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
export const HARVEST_DEFERRED_MARKER = '수확보류: harvest-deferred';
|
|
52
|
+
const execFileAsync = promisify(execFileCallback);
|
|
53
|
+
|
|
54
|
+
export function markHarvestDeferredBody(input: {
|
|
55
|
+
runStatus: string | undefined;
|
|
56
|
+
prNumber: number | undefined;
|
|
57
|
+
body: string | undefined;
|
|
58
|
+
}): string | undefined {
|
|
59
|
+
if (input.runStatus !== 'failed' || input.prNumber === undefined || !Number.isSafeInteger(input.prNumber) || input.prNumber < 1 || input.body === undefined) return undefined;
|
|
60
|
+
if (harvestDeferredMarker(input.body)) return input.body;
|
|
61
|
+
const separator = input.body.endsWith('\n') ? '\n' : '\n\n';
|
|
62
|
+
return `${input.body}${separator}${HARVEST_DEFERRED_MARKER}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function readHarvestPrBody(opts: { number: number; cwd: string }): Promise<{ body: string; state: string; isDraft: boolean } | undefined> {
|
|
66
|
+
const { stdout } = await execFileAsync('gh', ['pr', 'view', String(opts.number), '--json', 'body,state,isDraft'], {
|
|
67
|
+
cwd: opts.cwd,
|
|
68
|
+
env: ghAutomationEnv(process.env),
|
|
69
|
+
encoding: 'utf8',
|
|
70
|
+
timeout: 120_000,
|
|
71
|
+
maxBuffer: 2 * 1024 * 1024,
|
|
72
|
+
});
|
|
73
|
+
const parsed: unknown = JSON.parse(stdout);
|
|
74
|
+
if (!parsed || typeof parsed !== 'object') return undefined;
|
|
75
|
+
const record = parsed as { body?: unknown; state?: unknown; isDraft?: unknown };
|
|
76
|
+
return typeof record.body === 'string' && typeof record.state === 'string' && typeof record.isDraft === 'boolean'
|
|
77
|
+
? { body: record.body, state: record.state, isDraft: record.isDraft }
|
|
78
|
+
: undefined;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export async function updateHarvestPrBody(opts: { number: number; body: string; cwd: string }): Promise<void> {
|
|
82
|
+
await execFileAsync('gh', ['pr', 'edit', String(opts.number), '--body', opts.body], {
|
|
83
|
+
cwd: opts.cwd,
|
|
84
|
+
env: ghAutomationEnv(process.env),
|
|
85
|
+
encoding: 'utf8',
|
|
86
|
+
timeout: 120_000,
|
|
87
|
+
maxBuffer: 2 * 1024 * 1024,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
50
91
|
export function formatAutoMergeSuccessMessage(input: {
|
|
51
92
|
prNumber: number;
|
|
52
93
|
mergedBase?: string | undefined;
|
|
@@ -79,6 +120,7 @@ import { classifyGateEnvDeficit, DEFAULT_GATE_ENV_RETRY, GATE_ENV_DEFICIT_HARVES
|
|
|
79
120
|
import { recordFailureEvent } from './heal-intake.js';
|
|
80
121
|
import { classifyReworkCapExhaustion, type ReworkCapHealDecision } from './heal-triage.js';
|
|
81
122
|
import { releasePathHold, releasePathHoldComment, RELEASE_PATH_LABEL } from '../self-dev/release-path-guard.js';
|
|
123
|
+
import { harvestDeferredMarker } from '../self-dev/draft-triage-rules.js';
|
|
82
124
|
import { emitDecision } from '../live/detail-switch.js';
|
|
83
125
|
import { reworkDecision } from './decision-events.js';
|
|
84
126
|
import type { LogSink } from '../mss/logging/sink.js';
|
|
@@ -91,7 +133,7 @@ import { classifyError } from '../session-runtime/retry-policy.js';
|
|
|
91
133
|
import { decomposeSelfDevGoal, inferHotPaths, type SelfDevDecomposeOptions } from '../self-dev/decompose.js';
|
|
92
134
|
import { boundaryGlobs, boundaryViolations } from './goal-boundary.js';
|
|
93
135
|
import { askAtExecution, type ExecutionClarificationResult } from './execution-clarification.js';
|
|
94
|
-
import {
|
|
136
|
+
import { decideScopeExpansion, renderScopeExpansionSection, SCOPE_EXPANSION_CAP, type ScopeExpansion, type ScopeStopReason } from './scope-adjacency.js';
|
|
95
137
|
import { targetScopedGoalText } from './goal-text-path-scope.js';
|
|
96
138
|
import { selectKnowhowPack } from './knowhow-pack.js';
|
|
97
139
|
import { declaredNewFilePaths } from './goal-new-paths.js';
|
|
@@ -108,6 +150,7 @@ import { originObservationFields } from '../agent/origin-observation.js';
|
|
|
108
150
|
import { resolveLaunchStamp, type LaunchStamp } from '../harness/launch-stamp.js';
|
|
109
151
|
import { getHarnessSpace, normalizeSpaceId, resolveRunIdentity } from '../harness/harness-space.js';
|
|
110
152
|
import { getElanousConfigDir } from '../elanous-config-dir.js';
|
|
153
|
+
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
111
154
|
import { elanousStateRoot } from '../autopilot/state-paths.js';
|
|
112
155
|
import { addNextMdReleaseNote, harnessReleaseNote, parseReleaseNoteSection, releaseNotesDir, renderReleaseNoteSection, writeReleaseNote, type ReleaseNoteFragment, type ReleaseNoteSection } from '../release-loop/release-note.js';
|
|
113
156
|
import { landingFreezeMessage } from '../release-loop/landing-freeze.js';
|
|
@@ -182,7 +225,8 @@ import { formatGateFailedId, type PremiseReviewCard, type PremiseReviewInput } f
|
|
|
182
225
|
import { runWorkflowToCompletion } from '../workflow-runtime/executor.js';
|
|
183
226
|
import { mapReworkVerdict, supervisionObservationFields } from './supervision-vocabulary.js';
|
|
184
227
|
import { resolveRunOutcome } from './run-outcome.js';
|
|
185
|
-
import { authorLimitationCountFromGoal, harvestEvidenceLines, harvestedEvidenceObservation, MAX_HARVESTED_EVIDENCE_CHARS, parseOffDiffEvidence, requiredEvidenceFromGoal,
|
|
228
|
+
import { authorLimitationCountFromGoal, harvestEvidenceLines, harvestedEvidenceObservation, MAX_HARVESTED_EVIDENCE_CHARS, parseOffDiffEvidence, requiredEvidenceFromGoal, createRequiredEvidenceBudget, coverRequiredEvidence, settleUncoveredEvidence, formatUncoveredEvidenceFeedback, type OffDiffEvidenceParse } from './off-diff-evidence.js';
|
|
229
|
+
import { resolveEvidenceHeadCommit } from './evidence-command-budget.js';
|
|
186
230
|
import { pressDecisionSignals, type DecisionSignalPressResult } from './decision-signal-press.js';
|
|
187
231
|
import { inspectDecisionObservations, inspectDecisionSignalKinds, inspectDecisionSignalObservations } from '../../scripts/ask-marker-check.js';
|
|
188
232
|
|
|
@@ -256,8 +300,9 @@ import type { ClassifyShadowCallLLM } from './classify-shadow.js';
|
|
|
256
300
|
import { hasModuleLoadFailure, type GateTestFailure } from './gate-baseline.js';
|
|
257
301
|
import { commitWorktree, defaultBranchRef, preservationHasChanges } from './seams.js';
|
|
258
302
|
import { detectUncommittedWork } from './uncommitted-work.js';
|
|
259
|
-
import { spawnSync } from 'node:child_process';
|
|
260
|
-
import {
|
|
303
|
+
import { execFile as execFileCallback, spawnSync } from 'node:child_process';
|
|
304
|
+
import { promisify } from 'node:util';
|
|
305
|
+
import { blockedDraftDisposition, blockedDraftTargetFor, decideDraftOnStop, nextMoveFor, parseDraftOnStopMode, repairSalvageLinkComment, salvageBranchForRun, syntheticRepairBasePr, type DraftOnStopMode } from './blocked-draft-policy.js';
|
|
261
306
|
import { formatLlmMergeOutcome } from '../autopilot/build/llm-conflict-merge.js';
|
|
262
307
|
import { FOUND_CITED_PATH_REFUTATION_QUOTE, MISSING_CITED_PATH_REFUTATION_QUOTE, MUST_FIX_REFUTATION_ACKNOWLEDGEMENT_WITH_REASON, REFUTATION_QUOTE_GRAMMAR, observeMustFixCitedPaths, parseMustFixRefutationAcknowledgement, parseMustFixRefutations, renderMustFixCitedPathFacts, snapshotMustFixFindings, stableMustFixId, type ReflectEvidenceFacts, type ReflectGateFacts, type MustFixCitedPathFact, type MustFixFinding, type MustFixRecurrenceHistory, type MustFixRefutation, type MustFixRefutationKind } from './reflect-mustfix.js';
|
|
263
308
|
import type { IngestionEntry } from '../agent-substrate/execution/ingestion-policy.js';
|
|
@@ -279,7 +324,8 @@ import { AMBIGUOUS_STAGES, checkPipelineTraversal, nodesForStage, pipelineGraphI
|
|
|
279
324
|
import { appendGateWorktreeFreshnessEvidence, gateEvidenceNote } from '../harness/review-adapter.js';
|
|
280
325
|
import { diffHeaderPaths } from '../agent-substrate/self-review-cli.js';
|
|
281
326
|
import { format as formatPrComment, type PrCommentRole } from '../agent-substrate/pr-comment-meta.js';
|
|
282
|
-
import { changedFiles, commitTitles, type SelfImplementCompletionDisposition } from './seams.js';
|
|
327
|
+
import { changedFiles, commitTitles, type OpenPrOutcome, type SelfImplementCompletionDisposition } from './seams.js';
|
|
328
|
+
import { findUnwiredExports, gitBaseFileReader } from './wiring-check.js';
|
|
283
329
|
import {
|
|
284
330
|
classifyAbandonedRun,
|
|
285
331
|
isAbandonedClassificationOutcome,
|
|
@@ -1087,6 +1133,8 @@ export interface SelfImplementSeams {
|
|
|
1087
1133
|
commitFinishedChildWork?: (cwd: string, paths: readonly string[], message: string) => { ok: boolean; out: string };
|
|
1088
1134
|
/** --ground 코드베이스 prepass seam. cwd는 구현 대상 worktree이며 실패는 goal-loop를 막지 않는다. */
|
|
1089
1135
|
groundGoal?: (goalText: string, deps: { cwd: string }) => Promise<string>;
|
|
1136
|
+
/** E1 GOAL-ELABORATE-ON-ARRIVAL — 착수 구체화 카드 작성·판정 LLM. 미주입이면 카드 없이 진행(`goal-elaboration-skipped`). */
|
|
1137
|
+
elaborateCallLLM?: (args: { prompt: string; systemPrompt?: string }) => Promise<string>;
|
|
1090
1138
|
/** ③ 구현 — cwd(worktree)에서 코딩 에이전트 구동(P1: 헤드리스 elanous spawn·goal-loop 아밍).
|
|
1091
1139
|
* escalateTier(#2) — sol 단일 승급으로 재시도하고 seam 이 그 대상을 honor한다. */
|
|
1092
1140
|
/** ⚠️ `runId` 는 **필수**(리뷰 should-fix) — 오케스트레이터가 항상 보장하므로 옵셔널로 두면 새 seam
|
|
@@ -1156,6 +1204,8 @@ export interface SelfImplementSeams {
|
|
|
1156
1204
|
/** Test seam for blocked environment branch persistence; return whether the branch was pushed. */
|
|
1157
1205
|
/** Test seam — the worktree commit to pin before main sync (default `git rev-parse HEAD`). */
|
|
1158
1206
|
headCommit?: (cwd: string) => string | undefined;
|
|
1207
|
+
/** Test seam for required evidence command execution; production uses its bounded shell runner. */
|
|
1208
|
+
evidenceCommandRunner?: (command: string, cwd: string) => Pick<ReturnType<typeof spawnSync>, 'status' | 'stdout' | 'stderr' | 'error'>;
|
|
1159
1209
|
/** `commit` pins the pushed state; without it the worktree HEAD is pushed. */
|
|
1160
1210
|
preserveBlockedBranch?: (ctx: { cwd: string; branch: string; title: string; commit?: string }) => boolean | Promise<boolean>;
|
|
1161
1211
|
/** DRAFT-NOT-ARCHIVE — `tools.selfImplement.draftOnStop` 읽기 seam. 생략하면 user-config(실패·부재 = 'always' · 종전). */
|
|
@@ -1167,9 +1217,13 @@ export interface SelfImplementSeams {
|
|
|
1167
1217
|
/** Persist a full oversized PR body so its bounded PR counterpart can link to it. */
|
|
1168
1218
|
persistPrBodyArtifact?: (input: { origin: string; body: string; originalChars: number }) => { path: string };
|
|
1169
1219
|
/** ⑥ PR 생성. labels=생성 시 부착할 GitHub 라벨(G8 auto-review 자기판단 통과 시). */
|
|
1170
|
-
openPr: (opts: { title: string; body: string; head: string; base?: string; draft?: boolean; labels?: string[]; cwd: string }) => Promise<
|
|
1220
|
+
openPr: (opts: { title: string; body: string; head: string; base?: string; draft?: boolean; labels?: string[]; cwd: string; runId?: string }) => Promise<OpenPrOutcome>;
|
|
1171
1221
|
/** PR 생성 뒤 런의 라운드 대화를 게시한다. 실패는 PR 개설을 되돌리지 않는다. */
|
|
1172
1222
|
postPrComment?: (opts: { number: number; body: string; cwd: string }) => Promise<void>;
|
|
1223
|
+
/** Read-only body/state confirmation for the failed-run draft preservation marker. */
|
|
1224
|
+
readPrBodyForHarvest?: (opts: { number: number; cwd: string }) => Promise<{ body: string; state: string; isDraft: boolean } | undefined>;
|
|
1225
|
+
/** Update only the confirmed existing PR body; never creates a PR. */
|
|
1226
|
+
updatePrBodyForHarvest?: (opts: { number: number; body: string; cwd: string }) => Promise<void>;
|
|
1173
1227
|
/** Read and edit the single marked status comment; missing seams fall back to individual comments. */
|
|
1174
1228
|
findPrComment?: (opts: { number: number; marker: string; cwd: string; comments?: unknown }) => Promise<{ id: number; body: string } | undefined>;
|
|
1175
1229
|
editPrComment?: (opts: { id: number; body: string; cwd: string }) => Promise<void>;
|
|
@@ -2326,6 +2380,14 @@ export interface SelfImplementResult {
|
|
|
2326
2380
|
sessionId?: string;
|
|
2327
2381
|
worktreePath?: string;
|
|
2328
2382
|
branch?: string;
|
|
2383
|
+
/** SCOPE-AS-DIRECTION: outside-target files the scope guard accepted, each with its kind; rendered as the PR body's «범위 확장». */
|
|
2384
|
+
scopeExpansion?: ScopeExpansion;
|
|
2385
|
+
/** Bounded names measured by the execution-scope guard on a held edit. */
|
|
2386
|
+
outOfScopeEdits?: string[];
|
|
2387
|
+
/** SCOPE-ESCAPE-AS-REFINE: why the held edit stops (deletion · protected path · cap) — the parent stops only on these. */
|
|
2388
|
+
scopeStopReasons?: ScopeStopReason[];
|
|
2389
|
+
nameCapReached?: boolean;
|
|
2390
|
+
outsideCount?: number;
|
|
2329
2391
|
gate?: SelfImplementGateResult;
|
|
2330
2392
|
review?: SelfImplementReview;
|
|
2331
2393
|
rework?: ReviewRework;
|
|
@@ -2366,6 +2428,9 @@ export interface SelfImplementResult {
|
|
|
2366
2428
|
mergeReason?: string;
|
|
2367
2429
|
prUrl?: string;
|
|
2368
2430
|
prNumber?: number;
|
|
2431
|
+
/** REPAIR-BLOCKED-DRAFT-LINK-ORIGINAL: commit-only 수리가 멈춰 새 PR 대신 원 PR 에 이은 수확 가지. */
|
|
2432
|
+
originalPr?: number;
|
|
2433
|
+
salvageRef?: string;
|
|
2369
2434
|
checkedHeadCommit?: string;
|
|
2370
2435
|
detail?: string;
|
|
2371
2436
|
}
|
|
@@ -3490,6 +3555,7 @@ async function autohealRecordedStop(stopEntry: RunLedgerEntry, s: SelfImplementS
|
|
|
3490
3555
|
const loadLedger = s?.stopAutohealLoadLedger ?? (s?.writeRunLedger ? () => null : undefined);
|
|
3491
3556
|
const result = await autohealFromStop({ runId: stopEntry.runId, ...(stopEntry.goalId ? { goalId: stopEntry.goalId } : {}), record }, {
|
|
3492
3557
|
mode,
|
|
3558
|
+
knowhowCandidateDir: join(effectiveInstanceRoot(), 'self-implement', 'knowhow-candidates'),
|
|
3493
3559
|
...(s?.stopAutohealActions ? { actions: s.stopAutohealActions } : {}),
|
|
3494
3560
|
...(loadLedger ? { loadLedger } : {}),
|
|
3495
3561
|
...(s?.writeRunLedger ? { writeLedger: s.writeRunLedger } : {}),
|
|
@@ -3764,6 +3830,7 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3764
3830
|
openPr: async (args) => {
|
|
3765
3831
|
openPrInvoked = true;
|
|
3766
3832
|
const pr = await opts.seams.openPr(args);
|
|
3833
|
+
if (pr.rebind) debug.log('self-implement.same-cell', 'rebind-result', pr.rebind);
|
|
3767
3834
|
const number = recordedPrNumber(pr.number);
|
|
3768
3835
|
if (number !== undefined) capturedPrNumber = number;
|
|
3769
3836
|
return pr;
|
|
@@ -4380,6 +4447,50 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
4380
4447
|
} finally {
|
|
4381
4448
|
if (loopRegistered) registerRunLoop('ended');
|
|
4382
4449
|
const terminalStage = terminalResult?.stage ?? 'crashed';
|
|
4450
|
+
// A blocked draft may be opened on the first failed attempt, before the
|
|
4451
|
+
// normal outcome observer has written its terminal status. Persist the
|
|
4452
|
+
// actual terminal result before exposing harvest-deferred on that PR.
|
|
4453
|
+
const terminalOutcome = terminalResult ? mapStageToRunStatus(terminalStage) : undefined;
|
|
4454
|
+
if (terminalOutcome?.runStatus === 'failed'
|
|
4455
|
+
&& loadRunLedger(runId)?.filter((entry) => entry.event === 'run-status').at(-1)?.data.runStatus !== 'failed') {
|
|
4456
|
+
observeOuter('run-status', {
|
|
4457
|
+
stage: terminalStage, node: terminalResult?.node ?? null, ...terminalOutcome,
|
|
4458
|
+
...(terminalResult?.reviewReflectRejectedCount !== undefined
|
|
4459
|
+
? { reviewReflectRejectedCount: terminalResult.reviewReflectRejectedCount }
|
|
4460
|
+
: {}),
|
|
4461
|
+
}, { level: 'warn' });
|
|
4462
|
+
}
|
|
4463
|
+
try {
|
|
4464
|
+
const runStatus = terminalOutcome?.runStatus;
|
|
4465
|
+
const prNumber = recordedPrNumber(terminalResult?.prNumber) ?? capturedPrNumber;
|
|
4466
|
+
// openPr is required on every seam (including production); it cannot
|
|
4467
|
+
// distinguish test PRs from real ones. The production adapter explicitly
|
|
4468
|
+
// supplies both body operations. A test replacing openPr without both
|
|
4469
|
+
// body operations must fail closed instead of touching a real PR.
|
|
4470
|
+
const readPrBody = opts.seams.readPrBodyForHarvest;
|
|
4471
|
+
const updatePrBody = opts.seams.updatePrBodyForHarvest;
|
|
4472
|
+
// The terminal observer must have persisted this run's failure before a
|
|
4473
|
+
// draft can advertise harvest deferral. Even an injected writer must
|
|
4474
|
+
// leave a matching record in the canonical ledger before mutation.
|
|
4475
|
+
const lastPersistedStatus = loadRunLedger(runId)?.filter((entry) => entry.event === 'run-status').at(-1)?.data.runStatus;
|
|
4476
|
+
const persistedFailure = runStatus === 'failed' && lastPersistedStatus === 'failed';
|
|
4477
|
+
if (persistedFailure && prNumber !== undefined && readPrBody && updatePrBody) {
|
|
4478
|
+
const existing = await readPrBody({ number: prNumber, cwd: worktreePath ?? process.cwd() });
|
|
4479
|
+
if (existing?.state === 'OPEN' && existing.isDraft === true) {
|
|
4480
|
+
const markedBody = markHarvestDeferredBody({ runStatus, prNumber, body: existing.body });
|
|
4481
|
+
if (markedBody !== undefined && markedBody !== existing.body) {
|
|
4482
|
+
await updatePrBody({ number: prNumber, body: markedBody, cwd: worktreePath ?? process.cwd() });
|
|
4483
|
+
observeOuter('harvest-deferred', { runStatus, prNumber, marker: HARVEST_DEFERRED_MARKER });
|
|
4484
|
+
}
|
|
4485
|
+
} else {
|
|
4486
|
+
observeOuter('harvest-deferred-skipped', { runStatus, prNumber, reason: 'existing-draft-not-confirmed' }, { level: 'warn' });
|
|
4487
|
+
}
|
|
4488
|
+
} else {
|
|
4489
|
+
observeOuter('harvest-deferred-skipped', { runStatus: runStatus ?? null, prNumber: prNumber ?? null, reason: 'status-pr-body-seam-unavailable' }, { level: 'warn' });
|
|
4490
|
+
}
|
|
4491
|
+
} catch (error) {
|
|
4492
|
+
logRunAwareFailSoft(runId, 'harvest-deferred-failed', { error: safeErrorDescription(error) });
|
|
4493
|
+
}
|
|
4383
4494
|
try {
|
|
4384
4495
|
const mappedStatus = mapStageToRunStatus(terminalStage)?.runStatus;
|
|
4385
4496
|
const reworkCapStop = terminalResult?.stage === 'pr-opened' && (
|
|
@@ -4727,7 +4838,7 @@ export function observeRunOutcome(
|
|
|
4727
4838
|
type RollupPrNumber = number | 'none' | 'unknown';
|
|
4728
4839
|
|
|
4729
4840
|
function recordedPrNumber(value: unknown): number | undefined {
|
|
4730
|
-
return typeof value === 'number' && Number.
|
|
4841
|
+
return typeof value === 'number' && Number.isSafeInteger(value) && value > 0 ? value : undefined;
|
|
4731
4842
|
}
|
|
4732
4843
|
|
|
4733
4844
|
function rollupPrNumber(
|
|
@@ -4855,7 +4966,7 @@ async function runSelfImplementInner(
|
|
|
4855
4966
|
const { graphVersionHash } = await import('./graph-yaml.js');
|
|
4856
4967
|
const { applyGraphOverlays } = await import('./graph-overlay-yaml.js');
|
|
4857
4968
|
const { createGraphVariant } = await import('./graph-variant.js');
|
|
4858
|
-
const {
|
|
4969
|
+
const { saveRunGraphVariant, loadRunGraphVariant } = await import('./run-ledger.js');
|
|
4859
4970
|
const { stringify } = await import('yaml');
|
|
4860
4971
|
const baseSpec = GRAPH_SPECS[graphTemplate.graphId];
|
|
4861
4972
|
const variantRunId = identity?.runId ?? opts.runId;
|
|
@@ -4867,16 +4978,16 @@ async function runSelfImplementInner(
|
|
|
4867
4978
|
: undefined;
|
|
4868
4979
|
if (launch && !launch.ok) throw new Error(`graph variant rejected: ${JSON.stringify(launch.rejections)}`);
|
|
4869
4980
|
const sourceSpec = launch?.ok ? launch.template : baseSpec;
|
|
4870
|
-
|
|
4981
|
+
// ⭐ 최초 변형 선택 — 골 종류(graphGoalType)·대상 경로 수(declaredPremiseScopePaths) 두 입력만으로
|
|
4982
|
+
// 결정론적으로 id·선택 이유를 유도해 검증 결과에 싣는다(종류를 못 읽었으면 지어내지 않는다).
|
|
4983
|
+
const variant = createGraphVariant({ template: sourceSpec, goal: `g_${variantRunId.replace(/[^a-z0-9_-]/gi, '_')}`, plan: opts.graphVariantPlan,
|
|
4984
|
+
...(graphGoalType === undefined ? {} : { goalAnalysis: { goalType: graphGoalType, targetPathCount: declaredPremiseScopePaths(opts.feature).length } }) });
|
|
4871
4985
|
if (!variant.ok) throw new Error(`graph variant rejected: ${JSON.stringify(variant.rejections)}`);
|
|
4872
4986
|
variantSpec = variant.template;
|
|
4873
4987
|
graphTemplate = { ...specToTemplate(variantSpec), version: graphVersionHash(variantSpec) };
|
|
4874
|
-
const
|
|
4875
|
-
const graphFile = `${runLedgerPath(variantRunId)}.graph.yaml`;
|
|
4876
|
-
mkdirSync(runLedgerDir(), { recursive: true });
|
|
4877
|
-
const { writeFileSync } = await import('node:fs');
|
|
4878
|
-
writeFileSync(graphFile, stringify({
|
|
4988
|
+
const graphFile = saveRunGraphVariant(variantRunId, stringify({
|
|
4879
4989
|
graph_id: variantSpec.graphId, version: variantSpec.version,
|
|
4990
|
+
...(variant.selection === undefined ? {} : { variant_id: variant.selection.variantId, reason: variant.selection.reason }),
|
|
4880
4991
|
entry_node: variantSpec.entryNode, terminal_nodes: variantSpec.terminalNodes,
|
|
4881
4992
|
...(variantSpec.journeyStages ? { journey_stages: variantSpec.journeyStages } : {}),
|
|
4882
4993
|
...(variantSpec.runContract ? { run_contract: variantSpec.runContract } : {}),
|
|
@@ -4886,6 +4997,9 @@ async function runSelfImplementInner(
|
|
|
4886
4997
|
...(n.progress ? { progress: n.progress } : {}), ...(n.phases ? { phases: n.phases } : {}),
|
|
4887
4998
|
...(n.terminalStages ? { terminal_stages: n.terminalStages } : {}),
|
|
4888
4999
|
...(n.fanOut ? { fan_out: n.fanOut } : {}), ...(n.contract ? { contract: n.contract } : {}),
|
|
5000
|
+
...(n.call ? { call: n.call } : {}),
|
|
5001
|
+
...(n.callEntry ? { call_entry: n.callEntry } : {}),
|
|
5002
|
+
...(n.budget ? { budget: { inner_steps: n.budget.innerSteps } } : {}),
|
|
4889
5003
|
...(n.skipWhen ? { skip_when: n.skipWhen } : {}),
|
|
4890
5004
|
})),
|
|
4891
5005
|
edges: variantSpec.edges.map(e => ({
|
|
@@ -4894,9 +5008,17 @@ async function runSelfImplementInner(
|
|
|
4894
5008
|
...(e.observed === undefined ? {} : { observed: e.observed }),
|
|
4895
5009
|
...(e.when ? { when: e.when } : {}),
|
|
4896
5010
|
})),
|
|
4897
|
-
})
|
|
5011
|
+
}));
|
|
5012
|
+
// ⭐ 저장·diff — 방금 원장 옆에 쓴 선택(id·이유)을 다시 읽어 «같은지» 확인한다(다르면 이 런의 그래프 신원이 거짓).
|
|
5013
|
+
if (variant.selection !== undefined) {
|
|
5014
|
+
const persisted = loadRunGraphVariant(variantRunId);
|
|
5015
|
+
if (persisted === null || persisted.variantId !== variant.selection.variantId || persisted.reason !== variant.selection.reason) {
|
|
5016
|
+
throw new Error(`graph variant rejected: persisted selection mismatch: ${JSON.stringify(persisted)}`);
|
|
5017
|
+
}
|
|
5018
|
+
}
|
|
4898
5019
|
observe('graph-variant-applied', { graphId: variant.template.graphId, overlayId: variant.overlay.overlayId,
|
|
4899
|
-
graphFile, patches: variant.patches
|
|
5020
|
+
graphFile, patches: variant.patches,
|
|
5021
|
+
...(variant.selection === undefined ? {} : { variantId: variant.selection.variantId, variantReason: variant.selection.reason }) });
|
|
4900
5022
|
}
|
|
4901
5023
|
/** 단계 이름 → 그 템플릿의 노드 이름. */
|
|
4902
5024
|
const node = (stage: PipelineNodeId): PipelineNodeId => nodeNameForStage(stage, graphTemplate) as PipelineNodeId;
|
|
@@ -5018,6 +5140,8 @@ async function runSelfImplementInner(
|
|
|
5018
5140
|
observe('start', {
|
|
5019
5141
|
feature: boundedFeature.text, featureTruncated: boundedFeature.truncated, featureOriginalChars: boundedFeature.originalChars,
|
|
5020
5142
|
branch, base: opts.base ?? null, draft: opts.draft ?? true,
|
|
5143
|
+
// OPT #25551: 런 모드가 원장에 없었다 — PR 개설 의도 ⊕ commit-only 수리의 원 PR 번호(합성 base pr-<N>).
|
|
5144
|
+
openPr: opts.completion === undefined ? null : opts.completion !== 'worktree-only', repairCommitOnly: syntheticRepairBasePr(opts.base) ?? null,
|
|
5021
5145
|
willFork: !!(opts.parentSessionId && s.forkSession), parentSessionId: opts.parentSessionId ?? null,
|
|
5022
5146
|
nestDepth: nestInfo().depth, goalSource, goalFile: opts.goalFile === undefined ? null : resolve(launchCwd, opts.goalFile),
|
|
5023
5147
|
targetRoot: gitRootOf(launchCwd) ?? launchCwd, ...originObservationFields(),
|
|
@@ -5075,6 +5199,14 @@ async function runSelfImplementInner(
|
|
|
5075
5199
|
...goalContext,
|
|
5076
5200
|
}), T.worktree, 'worktree');
|
|
5077
5201
|
onWorktreeCreated(wt.path);
|
|
5202
|
+
// Capture the child worktree's HEAD at creation. `wt.invokedHead` names the
|
|
5203
|
+
// caller checkout and may differ after base selection or PR-source checkout.
|
|
5204
|
+
const terminalLaunchHeadRead = runGitCommand(wt.path, ['rev-parse', '--verify', 'HEAD'], { encoding: 'utf8', timeout: 10_000 });
|
|
5205
|
+
const terminalLaunchHeadCandidate = terminalLaunchHeadRead.status === 0 ? terminalLaunchHeadRead.stdout.trim() : '';
|
|
5206
|
+
const terminalLaunchHead = /^[0-9a-f]{40,64}$/i.test(terminalLaunchHeadCandidate) ? terminalLaunchHeadCandidate : undefined;
|
|
5207
|
+
const terminalLaunchWork = detectUncommittedWork(wt.path);
|
|
5208
|
+
const terminalLaunchDirtyPaths = terminalLaunchWork.status === 'unavailable' ? undefined
|
|
5209
|
+
: new Set([...terminalLaunchWork.trackedChanges, ...terminalLaunchWork.untrackedFiles]);
|
|
5078
5210
|
// ⭐ 제1원칙 — **어디서 갈랐나**를 관측에 남긴다. 이것이 없어서 2026-07-29 에 하니스 런 둘이
|
|
5079
5211
|
// `main` 위에서 돌았고(호출자가 브랜치 워크트리에서 발사했는데도) 산출 diff 를 눈으로 봐야 알았다.
|
|
5080
5212
|
// ⚠️ `branch` 는 **새로 만든 브랜치 이름**이라 그 질문에 답하지 않는다.
|
|
@@ -5088,6 +5220,8 @@ async function runSelfImplementInner(
|
|
|
5088
5220
|
observe('worktree', {
|
|
5089
5221
|
path: wt.path,
|
|
5090
5222
|
branch: wt.branch,
|
|
5223
|
+
terminalLaunchHead: terminalLaunchHead ?? null,
|
|
5224
|
+
terminalLaunchDirtyPaths: terminalLaunchDirtyPaths ? [...terminalLaunchDirtyPaths] : null,
|
|
5091
5225
|
// ⭐ 우리가 **무엇을 요청했는지는 이미 안다** — 시임 반환에서 되읽지 않는다.
|
|
5092
5226
|
// 커스텀 시임이 관측 필드를 생략하면 명시/생략이 둘 다 null 이 되어 구분이 사라진다(리뷰 must-fix).
|
|
5093
5227
|
requestedBase,
|
|
@@ -5259,6 +5393,14 @@ async function runSelfImplementInner(
|
|
|
5259
5393
|
if (knowhow.text) round0Feature = `${knowhow.text}\n\n${round0Feature}`;
|
|
5260
5394
|
observe('knowhow-pack', { ids: knowhow.ids, bytes: knowhow.bytes, injected: knowhow.bytes > 0 });
|
|
5261
5395
|
|
|
5396
|
+
// E1 착수 구체화(RFC-progressive-goal-elaboration §2 E1 · §7 간선 ①) — 고정 층(KPI·판정 신호)은 그대로, 카드만 덧붙인다.
|
|
5397
|
+
const elaboration = await (await import('./goal-elaborate.js')).runArrivalElaboration({ goal: opts.feature, prompt: round0Feature, cwd: wt.path, callLLM: s.elaborateCallLLM, observe });
|
|
5398
|
+
round0Feature = elaboration.prompt;
|
|
5399
|
+
if (elaboration.parked) {
|
|
5400
|
+
progress('parked', '착수 구체화 카드가 골 고정 층과 어긋남(다시 쓰기 뒤에도) — 사람 판단 대기');
|
|
5401
|
+
return { ok: false, stage: 'parked', node: 'implement', ...resolveRunOutcome({ termination: 'abandoned' }), sessionId, worktreePath: wt.path, branch: wt.branch, detail: elaboration.detail };
|
|
5402
|
+
}
|
|
5403
|
+
|
|
5262
5404
|
const maxRework = Math.max(0, opts.maxReworkRounds ?? 2);
|
|
5263
5405
|
const selfImplementConfig = (await import('../user-config.js')).getUserConfig().tools.selfImplement;
|
|
5264
5406
|
const shadowStop = opts.reworkBudgetShadowStop ?? selfImplementConfig.reworkBudget.shadowStop;
|
|
@@ -5290,6 +5432,8 @@ async function runSelfImplementInner(
|
|
|
5290
5432
|
let gate!: SelfImplementGateResult;
|
|
5291
5433
|
/** GATE-ENV-RETRY: 재시도 뒤에도 남은 환경 결손의 종류. 정의되면 이 라운드의 gate 실패는 «수확 대기»로 끝난다. */
|
|
5292
5434
|
let gateEnvDeficitKind: GateEnvDeficitKind | undefined;
|
|
5435
|
+
/** SCOPE-AS-DIRECTION: outside-target files accepted by the scope guard (latest round); rendered in the PR body. */
|
|
5436
|
+
let scopeExpansion: ScopeExpansion | undefined;
|
|
5293
5437
|
let review: SelfImplementReview | undefined;
|
|
5294
5438
|
let reviewedHeadCommit: string | undefined;
|
|
5295
5439
|
/** Review-budget leftovers and the body that carried them, so a later merge drafts from the same text. */
|
|
@@ -5609,9 +5753,17 @@ async function runSelfImplementInner(
|
|
|
5609
5753
|
};
|
|
5610
5754
|
}
|
|
5611
5755
|
let round = 0;
|
|
5756
|
+
// A timeout is evidence about this command, not an invitation to spend the
|
|
5757
|
+
// next rework round on the identical oversized check.
|
|
5758
|
+
const runBudgetedEvidenceChecks = createRequiredEvidenceBudget({ run: s.evidenceCommandRunner });
|
|
5612
5759
|
// A goal-only retry spends its one allowance for this run even if a later
|
|
5613
5760
|
// gate/review round removes the target diff and reaches the same disposition.
|
|
5614
5761
|
let goalOnlyReworkUsed = false;
|
|
5762
|
+
// E3 GOAL-REFINE-FROM-FIRST-IMPL — 첫 라운드 뒤 골 v2(재그라운딩). 둘째 라운드부터 프롬프트의 골은 roundGoal 이다.
|
|
5763
|
+
// 방향·KPI 줄은 불변(goal-refine.ts 가 강제) · 되돌이는 런당 GOAL_REFINE_MAX_VISITS 번.
|
|
5764
|
+
let roundGoal = opts.feature;
|
|
5765
|
+
let goalRefineVisits = 0;
|
|
5766
|
+
let goalRefinement: import('./goal-refine.js').GoalRefinement | undefined;
|
|
5615
5767
|
// PR이 열리기 전에 프로세스가 죽으면 PR 자체가 없으므로 잃을 대화도 없다. 따라서 파일로 영속화하지 않는다.
|
|
5616
5768
|
const prCommentBuffer: string[] = [];
|
|
5617
5769
|
// GitHub PR comment bodies are bounded; retain the RFC header and disclose omitted source rather than losing the whole record.
|
|
@@ -5730,10 +5882,12 @@ async function runSelfImplementInner(
|
|
|
5730
5882
|
};
|
|
5731
5883
|
let blockedDraftNoChanges = false;
|
|
5732
5884
|
let blockedDraftPrFailure: string | undefined;
|
|
5885
|
+
let repairLink: { originalPr: number; salvageRef: string } | undefined;
|
|
5733
5886
|
const reviewBlockedResult = (pr: { url: string; number: number } | undefined) => ({
|
|
5734
5887
|
stage: blockedDraftNoChanges && podReviewBlockedDraft ? 'no-changes' as const : podReviewBlockedDraft && !pr ? 'aborted' as const : 'review-blocked' as const,
|
|
5735
5888
|
mustFix: [...(review?.mustFix ?? [])],
|
|
5736
5889
|
...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}),
|
|
5890
|
+
...(repairLink ?? {}),
|
|
5737
5891
|
});
|
|
5738
5892
|
const preserveBlockedArtifacts = async ({ stage, reason, verdict, gate: preservedGate, typecheck, decomposition, childSummary, reasonTruncated, failureKind, terminalStatus, salvageStatusExpected }: { stage: 'review-blocked' | 'gate-failed' | 'aborted'; reason: string; verdict?: ReworkBudgetVerdict; gate?: SelfImplementGateResult; typecheck?: { passed: boolean; log?: string }; decomposition?: TerminalDecomposition; childSummary?: string; reasonTruncated?: boolean; failureKind?: ReturnType<typeof classifyReviewProviderFailure> | null; terminalStatus?: ImplementTerminalStatus; salvageStatusExpected: boolean }): Promise<{ url: string; number: number } | undefined> => {
|
|
5739
5893
|
let childSummaryArtifact: ChildSummaryArtifactRef | undefined;
|
|
@@ -5940,6 +6094,47 @@ async function runSelfImplementInner(
|
|
|
5940
6094
|
progress(stage, '보존할 변경이 없어 draft PR을 열지 않음');
|
|
5941
6095
|
return undefined;
|
|
5942
6096
|
}
|
|
6097
|
+
// REPAIR-BLOCKED-DRAFT-LINK-ORIGINAL: 합성 base pr-<N>(commit-only 수리)은 origin 에 없다 — 새 draft 대신 수확 가지를 원 PR #N 에 잇는다.
|
|
6098
|
+
const blockedTarget = blockedDraftTargetFor(opts.base);
|
|
6099
|
+
if (blockedTarget.action === 'link-original') {
|
|
6100
|
+
const salvageRef = salvageBranchForRun(runId, wt.branch);
|
|
6101
|
+
let salvageSha: string | undefined;
|
|
6102
|
+
let pushError: string | undefined;
|
|
6103
|
+
try {
|
|
6104
|
+
if (s.preserveBlockedBranch) {
|
|
6105
|
+
if (!await s.preserveBlockedBranch({ cwd: wt.path, branch: salvageRef, title: prTitle(opts.feature, opts.goalFile) })) throw new Error('수확 가지 push가 성공하지 않았음');
|
|
6106
|
+
} else {
|
|
6107
|
+
const commit = commitWorktree(wt.path, prTitle(opts.feature, opts.goalFile));
|
|
6108
|
+
if (!commit.ok && !/nothing to commit/.test(commit.out)) throw new Error(`로컬 커밋 실패: ${commit.out}`);
|
|
6109
|
+
const push = runGitCommand(wt.path, ['push', 'origin', `HEAD:refs/heads/${salvageRef}`]);
|
|
6110
|
+
if (push.status !== 0) throw new Error(push.stderr || push.stdout || 'git push failed');
|
|
6111
|
+
}
|
|
6112
|
+
const head = existsSync(wt.path) ? runGitCommand(wt.path, ['rev-parse', 'HEAD']) : undefined;
|
|
6113
|
+
if (head?.status === 0) salvageSha = head.stdout.trim();
|
|
6114
|
+
} catch (error) {
|
|
6115
|
+
pushError = safeErrorDescription(error);
|
|
6116
|
+
}
|
|
6117
|
+
let commentError: string | undefined;
|
|
6118
|
+
if (pushError === undefined) {
|
|
6119
|
+
try {
|
|
6120
|
+
if (!s.postPrComment) throw new Error('postPrComment seam unavailable');
|
|
6121
|
+
await s.postPrComment({ number: blockedTarget.originalPr, body: repairSalvageLinkComment({ salvageRef, ...(salvageSha ? { sha: salvageSha } : {}), runId, stage }), cwd: wt.path });
|
|
6122
|
+
} catch (error) {
|
|
6123
|
+
commentError = safeErrorDescription(error);
|
|
6124
|
+
}
|
|
6125
|
+
}
|
|
6126
|
+
if (pushError === undefined) repairLink = { originalPr: blockedTarget.originalPr, salvageRef };
|
|
6127
|
+
observe('rework-blocked-draft-pr', {
|
|
6128
|
+
...observation, skipped: 'repair-link-original', originalPr: blockedTarget.originalPr, salvageRef,
|
|
6129
|
+
...(salvageSha ? { salvageSha } : {}), pushed: pushError === undefined, ...(pushError ? { pushError } : {}),
|
|
6130
|
+
commentPosted: pushError === undefined && commentError === undefined, ...(commentError ? { commentError } : {}),
|
|
6131
|
+
}, pushError || commentError ? { level: 'warn' } : undefined);
|
|
6132
|
+
blockedDraftPrFailure = pushError
|
|
6133
|
+
? `수리 산출물 수확 가지 push 실패(원 PR #${blockedTarget.originalPr} · 새 PR 안 엶): ${pushError}; worktree: ${wt.path}`
|
|
6134
|
+
: `수리 산출물을 기존 PR #${blockedTarget.originalPr} 에 연결: salvage ${salvageRef}${commentError ? ` (코멘트 실패: ${commentError})` : ''}`;
|
|
6135
|
+
progress('aborted', blockedDraftPrFailure);
|
|
6136
|
+
return undefined;
|
|
6137
|
+
}
|
|
5943
6138
|
// DRAFT-NOT-ARCHIVE (RFC R1): harvestable 멈춤은 draft PR 대신 수확 가지 ⊕ 런 원장(사유·다음 수).
|
|
5944
6139
|
// ⛔ Pod review-blocked 는 결과 stage 가 PR 유무로 갈리므로 이 조각에서는 건드리지 않는다.
|
|
5945
6140
|
const draftOnStopMode = readDraftOnStopMode();
|
|
@@ -6051,6 +6246,7 @@ async function runSelfImplementInner(
|
|
|
6051
6246
|
try {
|
|
6052
6247
|
pr = await withStepTimeout(s.openPr({
|
|
6053
6248
|
title: prTitle(opts.feature, opts.goalFile),
|
|
6249
|
+
runId,
|
|
6054
6250
|
body: assembled.body,
|
|
6055
6251
|
head: wt.branch,
|
|
6056
6252
|
...(opts.base ? { base: opts.base } : {}),
|
|
@@ -6097,6 +6293,9 @@ async function runSelfImplementInner(
|
|
|
6097
6293
|
: `중단 산출물의 draft PR 생성 실패(worktree·branch 보존 · 판정 본문 보존 실패: ${artifactError ?? 'unknown error'})`);
|
|
6098
6294
|
return undefined;
|
|
6099
6295
|
}
|
|
6296
|
+
// The production draft sweep resolves run ownership from pr-opened, not
|
|
6297
|
+
// from the blocked-draft diagnostic event. Bind this PR to the same run.
|
|
6298
|
+
observe('pr-opened', { url: pr.url, number: pr.number, branch: wt.branch, draft: true });
|
|
6100
6299
|
observe('rework-blocked-draft-pr', {
|
|
6101
6300
|
...observation,
|
|
6102
6301
|
url: pr.url,
|
|
@@ -6199,7 +6398,7 @@ async function runSelfImplementInner(
|
|
|
6199
6398
|
// and pushes this worktree after the note is written and before creating the PR.
|
|
6200
6399
|
addNextMdReleaseNote(wt.path, releaseNote);
|
|
6201
6400
|
const preparedPrBody = preparePrBody(
|
|
6202
|
-
`${prBody(
|
|
6401
|
+
`${prBody(roundGoal, impl.summary, gate.log, review, reviewIntent, undefined, harvestedForPr(), opts.goalFile, lastPlanRevision, releaseNote)}${renderScopeExpansionSection(scopeExpansion)}${goalRefinement ? `\n\n${(await import('./goal-refine.js')).renderGoalChangeSection(goalRefinement)}` : ''}${followUpMustFix}`,
|
|
6203
6402
|
s.persistPrBodyArtifact,
|
|
6204
6403
|
'self-implement-review-budget-pr',
|
|
6205
6404
|
followUpMustFix,
|
|
@@ -6207,6 +6406,7 @@ async function runSelfImplementInner(
|
|
|
6207
6406
|
preparedReviewBudgetPrBody = preparedPrBody.body;
|
|
6208
6407
|
const pr = await withStepTimeout(s.openPr({
|
|
6209
6408
|
title: prTitle(opts.feature, opts.goalFile),
|
|
6409
|
+
runId,
|
|
6210
6410
|
body: preparedPrBody.body,
|
|
6211
6411
|
head: wt.branch,
|
|
6212
6412
|
...(opts.base ? { base: opts.base } : {}),
|
|
@@ -6365,7 +6565,7 @@ async function runSelfImplementInner(
|
|
|
6365
6565
|
const predictionAccuracyBefore = supervisorDecisionHistory.length
|
|
6366
6566
|
? judgePredictionAccuracy(supervisorDecisionHistory)
|
|
6367
6567
|
: undefined;
|
|
6368
|
-
diagnosis = await withStepTimeout(s.diagnose({ runId, note: reworkJudgeNote, kind: reworkKind, round, cwd: wt.path, goal:
|
|
6568
|
+
diagnosis = await withStepTimeout(s.diagnose({ runId, note: reworkJudgeNote, kind: reworkKind, round, cwd: wt.path, goal: roundGoal, history: priorHistory, supervisorDecisionHistory, ...(predictionAccuracyBefore ? { judgePredictionAccuracy: predictionAccuracyBefore } : {}), effectiveMax, priorRuns, reviewFindingTelemetry: reviewFindingTelemetrySnapshot, ...(diagnosisRefutations ? { refutations: diagnosisRefutations.refutations, refutationRound: diagnosisRefutations.round } : {}), purpose: 'budget' }), T.review, 'review');
|
|
6369
6569
|
const diagnosedDecision = parseReworkBudgetDecision(diagnosis);
|
|
6370
6570
|
if (diagnosedDecision?.verdict === 'CONTRACT-CONFLICT') lastSupervisorVerdict = diagnosedDecision.verdict;
|
|
6371
6571
|
let parsedDecision = diagnosedDecision;
|
|
@@ -6809,7 +7009,7 @@ async function runSelfImplementInner(
|
|
|
6809
7009
|
if (escalationEligible && s.diagnose) {
|
|
6810
7010
|
try {
|
|
6811
7011
|
escalationJudgement = await withStepTimeout(s.diagnose({
|
|
6812
|
-
runId, note: reworkNote, kind: reworkKind, round, cwd: wt.path, goal:
|
|
7012
|
+
runId, note: reworkNote, kind: reworkKind, round, cwd: wt.path, goal: roundGoal,
|
|
6813
7013
|
history: reworkHistory.slice(0, -1), supervisorDecisionHistory, effectiveMax,
|
|
6814
7014
|
purpose: 'escalation-triage',
|
|
6815
7015
|
}), T.review, 'review');
|
|
@@ -6822,8 +7022,24 @@ async function runSelfImplementInner(
|
|
|
6822
7022
|
}, { level: 'warn' });
|
|
6823
7023
|
}
|
|
6824
7024
|
}
|
|
7025
|
+
// 라운드 «번호»가 아니라 «첫 gate·리뷰 지적을 받은 뒤 첫 rework 진입»에서 한 번 — goal-only-rework·증거 되먹임이
|
|
7026
|
+
// 번호를 당겨도(round = retryRound/nextRound) 한 번 돈다(리뷰 r1 should-fix 6).
|
|
7027
|
+
if (round > 0 && goalRefineVisits === 0 && reworkNote.trim().length > 0) {
|
|
7028
|
+
goalRefineVisits++;
|
|
7029
|
+
// ta-journey author-dialogue 되돌이(judge findings → author → deliver v2) — 노트 LLM 은 E1 과 같은 저작 래퍼를 쓴다.
|
|
7030
|
+
const firstRound = roundSummaryEntries.at(-1);
|
|
7031
|
+
const refined = await (await import('./goal-refine.js')).runFirstRoundRefine({
|
|
7032
|
+
goal: opts.feature, round, visit: goalRefineVisits, callLLM: s.elaborateCallLLM, observe,
|
|
7033
|
+
// SCOPE-ESCAPE-AS-REFINE — accepted out-of-scope edits are the «new scope» the first implementation found.
|
|
7034
|
+
evidence: { implSummary: firstRound?.tried, findings: reworkNote, changedFiles: firstRound?.filesTouched,
|
|
7035
|
+
...(scopeExpansion?.files.length ? { newScope: scopeExpansion.files.map((file) => file.path) } : {}) },
|
|
7036
|
+
});
|
|
7037
|
+
roundGoal = refined.goal;
|
|
7038
|
+
// PR «골 변경» 절 — 유지(kept · no-provider 포함)여도 «시도 · v1 유지 · 사유» 한 줄을 싣는다(리뷰 r2).
|
|
7039
|
+
goalRefinement = refined.refinement;
|
|
7040
|
+
}
|
|
6825
7041
|
const reworkFeature = round === 0 ? ''
|
|
6826
|
-
: buildReworkFeature(
|
|
7042
|
+
: buildReworkFeature(roundGoal, round, effectiveMax, reworkPromptNote, stripReworkBudgetHeaders(diagnosis), appliedLastRound, refutableFindings, pendingPlanRevision, reworkKind, buildRefutationGuidance(), escalationJudgement);
|
|
6827
7043
|
const card = round === 0 ? '' : renderRoundSummaryCard(roundSummaryEntries);
|
|
6828
7044
|
const feature = round === 0 ? round0Feature : reworkFeature + (card ? `\n\n${card}` : '');
|
|
6829
7045
|
if (card) {
|
|
@@ -7046,6 +7262,45 @@ async function runSelfImplementInner(
|
|
|
7046
7262
|
}
|
|
7047
7263
|
}
|
|
7048
7264
|
}
|
|
7265
|
+
// The child can report changed=false after committing its edits. Compare
|
|
7266
|
+
// against the worktree HEAD captured at creation, not the caller's HEAD or
|
|
7267
|
+
// origin/main: a PR source already had a diff before the child ran.
|
|
7268
|
+
if (!impl.ok && impl.completionDisposition === 'completed-without-changes'
|
|
7269
|
+
&& impl.terminalStatus?.reached === true && impl.terminalStatus.timedOut === false
|
|
7270
|
+
&& !hasCurrentProviderError() && !hasCurrentCredentialFailure()) {
|
|
7271
|
+
const committed = terminalLaunchHead
|
|
7272
|
+
? runGitCommand(wt.path, ['diff', '--name-only', '-z', terminalLaunchHead, 'HEAD'], { encoding: 'utf8', timeout: 10_000 })
|
|
7273
|
+
: undefined;
|
|
7274
|
+
const pending = detectUncommittedWork(wt.path);
|
|
7275
|
+
const observedFiles = committed?.status === 0 && pending.status !== 'unavailable'
|
|
7276
|
+
? [...new Set([
|
|
7277
|
+
...committed.stdout.split('\0').filter(Boolean),
|
|
7278
|
+
...pending.trackedChanges, ...pending.untrackedFiles,
|
|
7279
|
+
])]
|
|
7280
|
+
: [];
|
|
7281
|
+
if (!terminalLaunchHead || terminalLaunchDirtyPaths === undefined || committed?.status !== 0 || pending.status === 'unavailable') {
|
|
7282
|
+
observe('terminal-change-evidence', { round, status: 'unmeasured',
|
|
7283
|
+
reason: !terminalLaunchHead ? 'launch-head-unavailable' : terminalLaunchDirtyPaths === undefined
|
|
7284
|
+
? 'launch-status-unavailable' : committed?.status !== 0 ? 'git-diff-unavailable' : 'git-status-unavailable' }, { level: 'warn' });
|
|
7285
|
+
}
|
|
7286
|
+
// A PR-source worktree may be dirty before this child starts. A path
|
|
7287
|
+
// already dirty at launch cannot prove this child's edits from names
|
|
7288
|
+
// alone, even if the child later commits it. Leave that path unmeasured.
|
|
7289
|
+
const implementationFiles = terminalLaunchDirtyPaths === undefined ? [] : observedFiles.filter(path =>
|
|
7290
|
+
!terminalLaunchDirtyPaths.has(path) && !harnessSeededPaths.includes(path) && !isHarnessTempArtifact(path));
|
|
7291
|
+
const preexistingDirtyPaths = terminalLaunchDirtyPaths === undefined ? [] : observedFiles.filter(path =>
|
|
7292
|
+
terminalLaunchDirtyPaths.has(path) && !harnessSeededPaths.includes(path) && !isHarnessTempArtifact(path));
|
|
7293
|
+
if (preexistingDirtyPaths.length > 0) observe('terminal-change-evidence', {
|
|
7294
|
+
round, status: 'unmeasured', reason: 'preexisting-dirty-path', paths: preexistingDirtyPaths,
|
|
7295
|
+
}, { level: 'warn' });
|
|
7296
|
+
if (implementationFiles.length > 0) {
|
|
7297
|
+
observe('terminal-change-reconciled', {
|
|
7298
|
+
round, source: 'post-launch-git-diff', launchHead: terminalLaunchHead, childDisposition: impl.completionDisposition,
|
|
7299
|
+
paths: implementationFiles, pathCount: implementationFiles.length,
|
|
7300
|
+
});
|
|
7301
|
+
impl = { ...impl, ok: true, completionDisposition: undefined };
|
|
7302
|
+
}
|
|
7303
|
+
}
|
|
7049
7304
|
// A finished child can leave edits without a commit. Measure them before any
|
|
7050
7305
|
// diff/no-changes classification, and commit only paths declared in the goal.
|
|
7051
7306
|
finishedChildCommitMissing = false;
|
|
@@ -7075,12 +7330,12 @@ async function runSelfImplementInner(
|
|
|
7075
7330
|
const declared = goalDocument === undefined ? undefined : declaredPathsFromGoalDocumentText(goalDocument);
|
|
7076
7331
|
const targets = declared?.readable
|
|
7077
7332
|
? declared.paths
|
|
7078
|
-
: inferHotPaths(targetScopedGoalText(
|
|
7333
|
+
: inferHotPaths(targetScopedGoalText(roundGoal));
|
|
7079
7334
|
const eligible = [...new Set([...work.trackedChanges, ...work.untrackedFiles])]
|
|
7080
7335
|
.filter((path) => !harnessSeededPaths.includes(path)
|
|
7081
7336
|
&& targets.some((target) => changedFileIsInsideDeclaredTarget(path, target)));
|
|
7082
7337
|
if (eligible.length) {
|
|
7083
|
-
inspectStaleReverts(revertGuardTargetPaths(
|
|
7338
|
+
inspectStaleReverts(revertGuardTargetPaths(roundGoal, goalDocument)); // E3 — refine 뒤 v2 «대상 경로»
|
|
7084
7339
|
const message = `self-implement: ${prTitle(opts.feature, opts.goalFile)}`;
|
|
7085
7340
|
let outcome: { ok: boolean; out: string };
|
|
7086
7341
|
try {
|
|
@@ -7148,9 +7403,16 @@ async function runSelfImplementInner(
|
|
|
7148
7403
|
const evidenceText = diffEvidence ? `${childEvidenceSource}\n${diffEvidence}` : childEvidenceSource;
|
|
7149
7404
|
evidenceSource = diffEvidence ? 'diff-added-lines' : harvested ? 'harvested' : 'summary-tail';
|
|
7150
7405
|
offDiffEvidence = parseOffDiffEvidence(evidenceText);
|
|
7151
|
-
|
|
7152
|
-
const
|
|
7153
|
-
const
|
|
7406
|
+
// E3 — refine 뒤 라운드는 «현재 골»(v2)로 증거를 센다(REQUIRED EVIDENCE 절은 고정 칸이라 v1 과 같다).
|
|
7407
|
+
const requiredEvidence = requiredEvidenceFromGoal(roundGoal);
|
|
7408
|
+
const limitationCount = authorLimitationCountFromGoal(roundGoal);
|
|
7409
|
+
const evidenceHead = resolveEvidenceHeadCommit(s.headCommit?.(wt.path), () =>
|
|
7410
|
+
runGitCommand(wt.path, ['rev-parse', '--verify', 'HEAD'], { encoding: 'utf8', timeout: 10_000 }).stdout.trim());
|
|
7411
|
+
if (!evidenceHead) {
|
|
7412
|
+
try { debug.log('self-implement.evidence', 'command-budget-head-unresolved', { runId, round, cwd: wt.path }); }
|
|
7413
|
+
catch { /* observation is fail-soft */ }
|
|
7414
|
+
}
|
|
7415
|
+
const evidenceChecks = runBudgetedEvidenceChecks(roundGoal, wt.path, runId, evidenceHead);
|
|
7154
7416
|
const tagCoverage = coverRequiredEvidence(requiredEvidence, offDiffEvidence.items);
|
|
7155
7417
|
// EVIDENCE-WIRING-EXEMPT — a requirement whose own `|| bun test …` check passed is covered by what the harness measured.
|
|
7156
7418
|
const settledByCheck = settleUncoveredEvidence(tagCoverage.uncovered, { checks: evidenceChecks, required: requiredEvidence });
|
|
@@ -7244,6 +7506,7 @@ async function runSelfImplementInner(
|
|
|
7244
7506
|
// Unknown declaration or changed files cannot justify an invented choice.
|
|
7245
7507
|
let gateRouteFiles: readonly string[] | undefined;
|
|
7246
7508
|
try { gateRouteFiles = (s.changedFilesForGateRoute ?? changedFiles)(wt.path); } catch { gateRouteFiles = undefined; }
|
|
7509
|
+
scopeExpansion = undefined;
|
|
7247
7510
|
if (opts.goalFile) {
|
|
7248
7511
|
let goalDocument: string | undefined;
|
|
7249
7512
|
try { goalDocument = readFileSync(opts.goalFile, 'utf8'); } catch { /* unknown scope */ }
|
|
@@ -7257,20 +7520,24 @@ async function runSelfImplementInner(
|
|
|
7257
7520
|
observe('execution-scope-undeclared', { outsideCount: scope.outsideCount });
|
|
7258
7521
|
progress('implementing', `⚠️ 대상 경로를 하나도 못 읽었다 — 범위 밖 ${scope.outsideCount}개를 묻지 않고 게이트로 간다`);
|
|
7259
7522
|
} else if (scope.status === 'known' && scope.outsideCount !== null && scope.outsideCount > 0) {
|
|
7260
|
-
|
|
7523
|
+
// SCOPE-AS-DIRECTION — target paths are the starting point: outside edits are accepted by default and named for the
|
|
7524
|
+
// reviewer. Only a deletion, a protected path, or more than SCOPE_EXPANSION_CAP outside files stops for the owner.
|
|
7525
|
+
const deleted = scope.outsideNames.filter(file => {
|
|
7261
7526
|
if (existsSync(join(wt.path, file))) return false;
|
|
7262
7527
|
const tracked = runGitCommand(wt.path, ['ls-files', '--error-unmatch', '--', file], { encoding: 'utf8', timeout: 20_000 });
|
|
7263
7528
|
return tracked.status === 0;
|
|
7264
|
-
})
|
|
7529
|
+
});
|
|
7530
|
+
const impact = deleted.length > 0 ? 'critical' : 'high';
|
|
7265
7531
|
const declaredPaths = declaredPathsFromGoalDocumentText(goalDocument!).paths;
|
|
7266
|
-
const {
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
observe('execution-scope-
|
|
7271
|
-
|
|
7532
|
+
const decision = decideScopeExpansion({ outsideFiles: scope.outsideNames, declaredPaths, deleted, nameCapReached: scope.nameCapReached,
|
|
7533
|
+
readFile: file => { try { return readFileSync(join(wt.path, file), 'utf8'); } catch { return undefined; } } });
|
|
7534
|
+
if (decision.accept) {
|
|
7535
|
+
scopeExpansion = decision.expansion;
|
|
7536
|
+
observe('execution-scope-accepted', { outsideCount: scope.outsideCount, count: decision.expansion.count, cap: SCOPE_EXPANSION_CAP,
|
|
7537
|
+
files: decision.expansion.files, round });
|
|
7538
|
+
progress('implementing', `범위 확장 ${decision.expansion.count}개 수용 — 대상 경로는 출발점, PR 본문 «범위 확장»에서 리뷰가 판단한다: ${decision.expansion.files.map(file => `${file.path}(${file.kind})`).join(' · ')}`);
|
|
7272
7539
|
}
|
|
7273
|
-
const result: ExecutionClarificationResult =
|
|
7540
|
+
const result: ExecutionClarificationResult = decision.accept ? { choice: 'Expand scope', by: 'assumed' } : await (s.askExecutionClarification ?? askAtExecution)({
|
|
7274
7541
|
id: 'execution_scope', decision: 'Changing files outside the authored target paths',
|
|
7275
7542
|
prompt: 'Implementation changed files outside the authored target paths. Keep the original scope or expand it?',
|
|
7276
7543
|
whyNow: 'Continuing to gate or publish these edits would expand the requested scope.',
|
|
@@ -7280,11 +7547,18 @@ async function runSelfImplementInner(
|
|
|
7280
7547
|
{ label: 'Expand scope', description: 'Accept the changed files outside the target paths.' },
|
|
7281
7548
|
],
|
|
7282
7549
|
}, { runId, outsideFiles: scope.outsideNames, outsideCount: scope.outsideCount, declaredPaths }, { writeRunLedger: s.writeRunLedger });
|
|
7550
|
+
if (!decision.accept && !('parked' in result) && !('deferred' in result) && result.choice === 'Expand scope') scopeExpansion = decision.expansion;
|
|
7283
7551
|
if ('parked' in result || 'deferred' in result || result.choice !== 'Expand scope') {
|
|
7284
7552
|
finalizeSupervisorDeliveries('execution-scope-not-approved');
|
|
7285
|
-
|
|
7553
|
+
const outOfScopeEdits = [...scope.outsideNames];
|
|
7554
|
+
observe('execution-scope-held', { outOfScopeEdits, nameCapReached: scope.nameCapReached,
|
|
7555
|
+
outsideCount: scope.outsideCount, worktreePath: wt.path, branch: wt.branch,
|
|
7556
|
+
disposition: 'parked' in result ? 'parked' : 'in-scope-only',
|
|
7557
|
+
...(!decision.accept ? { stopReasons: decision.reasons, deleted: decision.deleted, protectedPaths: decision.protectedPaths, cap: SCOPE_EXPANSION_CAP } : {}),
|
|
7558
|
+
files: decision.expansion.files });
|
|
7286
7559
|
if ('parked' in result) progress('parked', `critical 질문 ${result.questionId} 미응답 — 이 런만 대기`);
|
|
7287
7560
|
return { ok: false, stage: 'parked' in result ? 'parked' : 'soft-stopped', node: 'implement', ...resolveRunOutcome({ termination: 'abandoned' }), sessionId, worktreePath: wt.path, branch: wt.branch,
|
|
7561
|
+
outOfScopeEdits, ...(!decision.accept ? { scopeStopReasons: decision.reasons } : {}), nameCapReached: scope.nameCapReached, outsideCount: scope.outsideCount,
|
|
7288
7562
|
detail: 'parked' in result ? `critical-unanswered: ${result.questionId}` : 'Out-of-scope edits held in the worktree; gate and publication skipped.' };
|
|
7289
7563
|
}
|
|
7290
7564
|
}
|
|
@@ -7581,6 +7855,33 @@ async function runSelfImplementInner(
|
|
|
7581
7855
|
if (untracked.status === 0) untrackedFiles = untracked.stdout.split(/\r?\n/).filter(Boolean);
|
|
7582
7856
|
} catch { /* change discovery must not stop review */ }
|
|
7583
7857
|
}
|
|
7858
|
+
// Gate has passed. Measure newly exported runtime values before review, without
|
|
7859
|
+
// turning a static-analysis guess into a rework verdict during the first rollout.
|
|
7860
|
+
const wiringFiles = [...new Set([...(runFacts.changedFiles ?? []), ...(gateRouteFiles ?? []), ...untrackedFiles])];
|
|
7861
|
+
if (wiringFiles.some((file) => /^(?:src|scripts|apps\/pwa\/src)\/.*\.tsx?$/.test(file))) {
|
|
7862
|
+
const wiringBase = wt.resolvedBase;
|
|
7863
|
+
const wiring = wiringBase && /^[0-9a-f]{40}$/i.test(wiringBase)
|
|
7864
|
+
? findUnwiredExports({
|
|
7865
|
+
cwd: wt.path,
|
|
7866
|
+
changedFiles: wiringFiles,
|
|
7867
|
+
// Timeouts and git errors throw → recorded as `failure`, never as "absent at base".
|
|
7868
|
+
readBaseFile: gitBaseFileReader(
|
|
7869
|
+
(args) => runGitCommand(wt.path, args, { encoding: 'utf8', timeout: 10_000 }),
|
|
7870
|
+
wiringBase,
|
|
7871
|
+
),
|
|
7872
|
+
})
|
|
7873
|
+
: { checked: 0, unwired: [], failure: 'resolved-base-unavailable' };
|
|
7874
|
+
const wiringObservation = {
|
|
7875
|
+
round,
|
|
7876
|
+
checked: wiring.checked,
|
|
7877
|
+
unwired: wiring.unwired.length,
|
|
7878
|
+
examples: wiring.unwired.slice(0, 10),
|
|
7879
|
+
...(wiring.failure ? { failure: wiring.failure } : {}),
|
|
7880
|
+
mode: 'warn',
|
|
7881
|
+
};
|
|
7882
|
+
debug.log('self-implement.wiring-check', wiring.failure ? 'unmeasured' : 'measured', wiringObservation);
|
|
7883
|
+
observe('wiring-check', wiringObservation, wiring.failure || wiring.unwired.length ? { level: 'warn' } : {});
|
|
7884
|
+
}
|
|
7584
7885
|
if ([...(runFacts.changedFiles ?? []), ...(gateRouteFiles ?? []), ...untrackedFiles].some((file) => /\.(?:html|css)$/i.test(file))) {
|
|
7585
7886
|
try {
|
|
7586
7887
|
designGate = (s.runDesignGate ?? runDesignGate)({ projectDir: wt.path, base: wt.resolvedBase });
|
|
@@ -7600,7 +7901,8 @@ async function runSelfImplementInner(
|
|
|
7600
7901
|
const reviewContext = {
|
|
7601
7902
|
runId,
|
|
7602
7903
|
...runFacts,
|
|
7603
|
-
|
|
7904
|
+
// E3 — refine 뒤 라운드의 리뷰는 «현재 골»(v2)로 판정한다. v1 은 PR «골 변경» 절에만 남는다(리뷰 r1 must-fix).
|
|
7905
|
+
goal: roundGoal,
|
|
7604
7906
|
goalFile: opts.goalFile,
|
|
7605
7907
|
...(priorRunFindings.length ? { priorRunFindings } : {}),
|
|
7606
7908
|
...(goalDocumentPath ? { goalDocumentPath } : {}),
|
|
@@ -7721,7 +8023,7 @@ async function runSelfImplementInner(
|
|
|
7721
8023
|
}, { category: 'self-dev.rework' });
|
|
7722
8024
|
}
|
|
7723
8025
|
const refutations = refutableFindings.length
|
|
7724
|
-
? parseMustFixRefutations(impl.summary,
|
|
8026
|
+
? parseMustFixRefutations(impl.summary, roundGoal, refutableFindings, ({ stage, findingId }) => {
|
|
7725
8027
|
observe('refute-rejected', { round, stage, ...(findingId ? { findingId } : {}) });
|
|
7726
8028
|
}, { citedPathFacts, round })
|
|
7727
8029
|
: [];
|
|
@@ -7753,7 +8055,7 @@ async function runSelfImplementInner(
|
|
|
7753
8055
|
try {
|
|
7754
8056
|
const originalMustFix = refutableFindings.map((finding) => finding.item);
|
|
7755
8057
|
const recurrenceHistory = recurrenceHistoryFor(originalMustFix);
|
|
7756
|
-
const adjudicated = await withStepTimeout(s.reflectMustFix({ mustFix: originalMustFix, goal:
|
|
8058
|
+
const adjudicated = await withStepTimeout(s.reflectMustFix({ mustFix: originalMustFix, goal: roundGoal, cwd: wt.path, evidenceFacts, gateFacts: gate.reflectGateFacts, refutations, citedPathFacts, ...(recurrenceHistory.length ? { recurrenceHistory } : {}), runId, round }), T.review, 'review');
|
|
7757
8059
|
observe('review-refute-adjudicated', {
|
|
7758
8060
|
round,
|
|
7759
8061
|
submittedCount: refutations.length,
|
|
@@ -7771,7 +8073,7 @@ async function runSelfImplementInner(
|
|
|
7771
8073
|
const oneLine = (text: string): string => text.replace(/\s+/g, ' ').trim().slice(0, 60);
|
|
7772
8074
|
try {
|
|
7773
8075
|
const recurrenceHistory = recurrenceHistoryFor(review.mustFix);
|
|
7774
|
-
const reflected = await withStepTimeout(s.reflectMustFix({ mustFix: review.mustFix, goal:
|
|
8076
|
+
const reflected = await withStepTimeout(s.reflectMustFix({ mustFix: review.mustFix, goal: roundGoal, cwd: wt.path, evidenceFacts, gateFacts: gate.reflectGateFacts, citedPathFacts, ...(recurrenceHistory.length ? { recurrenceHistory } : {}), runId, round }), T.review, 'review');
|
|
7775
8077
|
const rejectedItems = new Set(reflected.rejected.filter((r) => r.reason && r.reason.trim().length > 0).map((r) => r.item));
|
|
7776
8078
|
const rejected = reflected.rejected.filter((r) => rejectedItems.has(r.item));
|
|
7777
8079
|
effectiveMustFix = review.mustFix.filter((m) => !rejectedItems.has(m));
|
|
@@ -7872,7 +8174,7 @@ async function runSelfImplementInner(
|
|
|
7872
8174
|
}
|
|
7873
8175
|
// EVIDENCE-WIRING-EXEMPT — a commandless [preservation] is covered once the changed-file gate passed.
|
|
7874
8176
|
if (gate.passed && evidenceCoverage?.uncoveredCount) {
|
|
7875
|
-
const settledByGate = settleUncoveredEvidence(evidenceCoverage.uncovered, { gatePassed: true, required: requiredEvidenceFromGoal(
|
|
8177
|
+
const settledByGate = settleUncoveredEvidence(evidenceCoverage.uncovered, { gatePassed: true, required: requiredEvidenceFromGoal(roundGoal) });
|
|
7876
8178
|
if (settledByGate.coveredByGate.length) {
|
|
7877
8179
|
debug.log('self-implement.evidence', 'covered-by-gate', { round, tags: settledByGate.coveredByGate });
|
|
7878
8180
|
evidenceCoverage = { ...evidenceCoverage, uncovered: settledByGate.uncovered, uncoveredCount: settledByGate.uncovered.length };
|
|
@@ -7910,6 +8212,7 @@ async function runSelfImplementInner(
|
|
|
7910
8212
|
|
|
7911
8213
|
const { decisionSignalPress, decisionSignalPressReason } = resolveDecisionSignalPress(opts.goalFile, wt.path, opts.decisionSignalPressSources);
|
|
7912
8214
|
const decisionSignalResult = decisionSignalPress ? { decisionSignalPress } : {};
|
|
8215
|
+
const scopeExpansionResult = scopeExpansion ? { scopeExpansion } : {};
|
|
7913
8216
|
const decisionSignalRed = (decisionSignalPress?.pressedRed.length ?? 0) > 0;
|
|
7914
8217
|
const decisionSignalBaselineOnly = decisionSignalPress?.pressedBaselineOnly.length ?? 0;
|
|
7915
8218
|
const preservedCompletionResult = !decisionSignalRed && completionDisposition
|
|
@@ -7939,10 +8242,13 @@ async function runSelfImplementInner(
|
|
|
7939
8242
|
// (모집단 0인데 distinguishes=1) 틀린 값으로 막으면 새 병목이 된다.
|
|
7940
8243
|
// ⛔ `ran === false`(skipped)는 «다른 것»이다 — 자식이 테스트를 안 건드린 경우이고
|
|
7941
8244
|
// 그건 `skippedReason` 이 이미 가른다. 그래서 여기 조건에 넣지 않는다.
|
|
7942
|
-
|
|
7943
|
-
|
|
8245
|
+
// A new test absent from the fixed base is a structural RED witness when the
|
|
8246
|
+
// head gate passed. Keep that distinct from an executed test that proved nothing.
|
|
8247
|
+
const verifyStructuralRed = gate.verifyByBreaking?.ran === true && (gate.verifyByBreaking.missingAtBase ?? 0) > 0;
|
|
8248
|
+
const verifyInconclusive = gate.verifyByBreaking?.ran === true
|
|
8249
|
+
&& (gate.verifyByBreaking.distinguishes ?? 0) === 0 && !verifyStructuralRed;
|
|
7944
8250
|
let mergeReason = canAuto && reviewDeferredToHost ? REVIEW_DEFERRED_TO_HOST_MERGE_REASON
|
|
7945
|
-
: canAuto ? (
|
|
8251
|
+
: canAuto ? (verifyStructuralRed ? 'review-clean-verify-structural-red' : verifyInconclusive ? 'review-clean-verify-inconclusive' : 'review-clean-armed')
|
|
7946
8252
|
: gateTimeoutUnmeasured ? GATE_TIMEOUT_UNMEASURED_MERGE_REASON
|
|
7947
8253
|
: !autoMerge ? 'no-auto-flag'
|
|
7948
8254
|
: requiredEvidenceMissing ? 'required-evidence-uncovered'
|
|
@@ -7990,7 +8296,7 @@ async function runSelfImplementInner(
|
|
|
7990
8296
|
progress('worktree-completed', '✅ 작업 트리 완료 — PR 생성 없이 worktree 보존');
|
|
7991
8297
|
observe('worktree-completed', { branch: wt.branch, hadApprover: !!s.approvePr });
|
|
7992
8298
|
return {
|
|
7993
|
-
ok: true, stage: 'worktree-completed', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...(mergeSkipReason ? { mergeReason: mergeSkipReason } : {}),
|
|
8299
|
+
ok: true, stage: 'worktree-completed', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...scopeExpansionResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...(mergeSkipReason ? { mergeReason: mergeSkipReason } : {}),
|
|
7994
8300
|
detail: 'worktree-only completion: PR creation skipped',
|
|
7995
8301
|
};
|
|
7996
8302
|
}
|
|
@@ -8001,7 +8307,7 @@ async function runSelfImplementInner(
|
|
|
8001
8307
|
recordMergeDecision();
|
|
8002
8308
|
observe('pr-declined', { branch: wt.branch, hadApprover: !!s.approvePr });
|
|
8003
8309
|
return {
|
|
8004
|
-
ok: false, stage: 'pr-declined', node: 'open-pr', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...(mergeSkipReason ? { mergeReason: mergeSkipReason } : {}),
|
|
8310
|
+
ok: false, stage: 'pr-declined', node: 'open-pr', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, ...scopeExpansionResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...(mergeSkipReason ? { mergeReason: mergeSkipReason } : {}),
|
|
8005
8311
|
detail: s.approvePr ? 'PR not approved' : 'no approvePr seam — fail-closed(자동승인 금지)',
|
|
8006
8312
|
};
|
|
8007
8313
|
}
|
|
@@ -8012,7 +8318,7 @@ async function runSelfImplementInner(
|
|
|
8012
8318
|
if (opts.goalFile) {
|
|
8013
8319
|
try { goalDocument = readFileSync(opts.goalFile, 'utf8'); } catch { /* no documented targets */ }
|
|
8014
8320
|
}
|
|
8015
|
-
inspectStaleReverts(revertGuardTargetPaths(
|
|
8321
|
+
inspectStaleReverts(revertGuardTargetPaths(roundGoal, goalDocument)); // E3 — refine 뒤 v2 «대상 경로»
|
|
8016
8322
|
s.commitWork(wt.path, prTitle(opts.feature, opts.goalFile));
|
|
8017
8323
|
// ⛔⭐ resume 경로와 «같은» 해석기를 쓴다 — 두 자리가 갈리면 같은 원인이 다른 얼굴로 나온다.
|
|
8018
8324
|
const resolvedTarget = resolveDefaultBranchTarget(s.defaultBranchRef ?? defaultBranchRef, wt.path);
|
|
@@ -8027,7 +8333,7 @@ async function runSelfImplementInner(
|
|
|
8027
8333
|
canAuto = false;
|
|
8028
8334
|
mergeReason = 'default-branch-unresolved';
|
|
8029
8335
|
recordMergeDecision();
|
|
8030
|
-
return { ok: false, stage: 'merge-conflict', node: 'main-sync', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), detail: 'pre-PR main sync default-branch-unresolved' };
|
|
8336
|
+
return { ok: false, stage: 'merge-conflict', node: 'main-sync', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, ...scopeExpansionResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), detail: 'pre-PR main sync default-branch-unresolved' };
|
|
8031
8337
|
}
|
|
8032
8338
|
progress('gating', `최신 ${mergeTarget} 정합 (병렬 드리프트·LLM 충돌해결)…`);
|
|
8033
8339
|
onMainSyncStarted((s.headCommit ?? ((cwd: string) => {
|
|
@@ -8045,7 +8351,7 @@ async function runSelfImplementInner(
|
|
|
8045
8351
|
mergeReason = 'main-sync-interrupted';
|
|
8046
8352
|
recordMergeDecision();
|
|
8047
8353
|
progress('merge-conflict', `⚠️ ${mergeTarget} 정합 중단 — 사람 수확 (${wt.branch})`);
|
|
8048
|
-
return { ok: false, stage: 'merge-conflict', node: 'main-sync', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), harvestable: true, detail: `pre-PR main sync interrupted: ${safeErrorDescription(error)}` };
|
|
8354
|
+
return { ok: false, stage: 'merge-conflict', node: 'main-sync', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, ...scopeExpansionResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), harvestable: true, detail: `pre-PR main sync interrupted: ${safeErrorDescription(error)}` };
|
|
8049
8355
|
}
|
|
8050
8356
|
// ⛔⭐ `OBS-T96` 🅐 — 「무엇을 봤는지」를 남긴다. 수만 남기면 정합 실패가 «재현 불가»가 된다.
|
|
8051
8357
|
observe('pre-pr-sync', mainSyncObservation(sync, mergeTarget, opts.base, wt.branch));
|
|
@@ -8056,7 +8362,7 @@ async function runSelfImplementInner(
|
|
|
8056
8362
|
recordMergeDecision();
|
|
8057
8363
|
const harvestable = (sync.reason === 'conflict-input-too-large' || sync.reason === 'conflict-resolver-interrupted')
|
|
8058
8364
|
&& await preserveMergeHarvest(sync.reason, sync.inputChars);
|
|
8059
|
-
return { ok: false, stage: 'merge-conflict', node: 'main-sync', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...(harvestable ? { harvestable: true } : {}), detail: harvestable ? sync.reason === 'conflict-input-too-large' ? `충돌 큼 — 사람 수확 (${wt.branch}, 입력 ${sync.inputChars}자)` : `충돌 해결 중단 — 사람 수확 (${wt.branch})` : `pre-PR main sync ${sync.status}` };
|
|
8365
|
+
return { ok: false, stage: 'merge-conflict', node: 'main-sync', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, ...scopeExpansionResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...(harvestable ? { harvestable: true } : {}), detail: harvestable ? sync.reason === 'conflict-input-too-large' ? `충돌 큼 — 사람 수확 (${wt.branch}, 입력 ${sync.inputChars}자)` : `충돌 해결 중단 — 사람 수확 (${wt.branch})` : `pre-PR main sync ${sync.status}` };
|
|
8060
8366
|
}
|
|
8061
8367
|
if (sync.status === 'llm-resolved' || sync.status === 'merged' || sync.status === 'deterministic-resolved') {
|
|
8062
8368
|
preservationBase = opts.base ?? mergeTarget;
|
|
@@ -8115,7 +8421,7 @@ async function runSelfImplementInner(
|
|
|
8115
8421
|
mergeReason = 'post-sync-gate-failed';
|
|
8116
8422
|
recordMergeDecision();
|
|
8117
8423
|
const pr = await preserveBlockedArtifacts({ stage: 'gate-failed', reason, gate: regate, salvageStatusExpected: false });
|
|
8118
|
-
return { ok: false, stage: 'gate-failed', node: 'regate', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate: regate, quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(), ...(review ? { review } : {}), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: reason };
|
|
8424
|
+
return { ok: false, stage: 'gate-failed', node: 'regate', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, ...scopeExpansionResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate: regate, quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(), ...(review ? { review } : {}), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: reason };
|
|
8119
8425
|
}
|
|
8120
8426
|
if (!regate.passed) {
|
|
8121
8427
|
progress('gating', timeoutOnlyPostSync
|
|
@@ -8129,7 +8435,7 @@ async function runSelfImplementInner(
|
|
|
8129
8435
|
recordMergeDecision();
|
|
8130
8436
|
if (!approved) {
|
|
8131
8437
|
observe('pr-declined', { branch: wt.branch, hadApprover: !!s.approvePr });
|
|
8132
|
-
return { ok: false, stage: 'pr-declined', node: 'open-pr', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), mergeReason, detail: s.approvePr ? 'PR not approved' : 'no approvePr seam — fail-closed(자동승인 금지)' };
|
|
8438
|
+
return { ok: false, stage: 'pr-declined', node: 'open-pr', ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, ...scopeExpansionResult, sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), mergeReason, detail: s.approvePr ? 'PR not approved' : 'no approvePr seam — fail-closed(자동승인 금지)' };
|
|
8133
8439
|
}
|
|
8134
8440
|
if (canAuto) onMergeApprovalReceived();
|
|
8135
8441
|
const extractedOriginalAsk = extractVerbatimOriginalAsk(opts.feature);
|
|
@@ -8164,7 +8470,7 @@ async function runSelfImplementInner(
|
|
|
8164
8470
|
}
|
|
8165
8471
|
const stoppedBeforePr = honorParentSoftStop('open-pr');
|
|
8166
8472
|
if (stoppedBeforePr) {
|
|
8167
|
-
return { ...stoppedBeforePr, ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, sessionId, gate, ...(review ? { review } : {}), ...(mergeSkipReason ? { mergeReason: mergeSkipReason } : {}) };
|
|
8473
|
+
return { ...stoppedBeforePr, ...resolveRunOutcome({ termination: 'abandoned' }), ...decisionSignalResult, ...scopeExpansionResult, sessionId, gate, ...(review ? { review } : {}), ...(mergeSkipReason ? { mergeReason: mergeSkipReason } : {}) };
|
|
8168
8474
|
}
|
|
8169
8475
|
progress('pr-opening', 'PR 생성…');
|
|
8170
8476
|
onNodeEntry('open-pr', round);
|
|
@@ -8204,7 +8510,8 @@ async function runSelfImplementInner(
|
|
|
8204
8510
|
addNextMdReleaseNote(wt.path, releaseNote);
|
|
8205
8511
|
const preparedPrBody = preparePrBody(
|
|
8206
8512
|
[
|
|
8207
|
-
prBody(
|
|
8513
|
+
prBody(roundGoal, impl.summary, gate.log, review, reviewIntent, declineReasons, harvestedForPr(), opts.goalFile, lastPlanRevision, releaseNote, revertGuard) + renderScopeExpansionSection(scopeExpansion),
|
|
8514
|
+
...(goalRefinement ? ['', (await import('./goal-refine.js')).renderGoalChangeSection(goalRefinement)] : []),
|
|
8208
8515
|
...(prEvidenceDecision.body ? ['', '---', '', prEvidenceDecision.body] : []),
|
|
8209
8516
|
].join('\n'),
|
|
8210
8517
|
s.persistPrBodyArtifact,
|
|
@@ -8214,6 +8521,7 @@ async function runSelfImplementInner(
|
|
|
8214
8521
|
try {
|
|
8215
8522
|
pr = await withStepTimeout(s.openPr({
|
|
8216
8523
|
title: prTitle(opts.feature, opts.goalFile),
|
|
8524
|
+
runId,
|
|
8217
8525
|
body: preparedPrBody.body,
|
|
8218
8526
|
head: wt.branch,
|
|
8219
8527
|
...(opts.base ? { base: opts.base } : {}),
|
|
@@ -8290,7 +8598,7 @@ async function runSelfImplementInner(
|
|
|
8290
8598
|
}
|
|
8291
8599
|
recordMergeDecision();
|
|
8292
8600
|
progress('pr-opened', `OP 승인 대기 (#${pr.number}): ${releaseHoldPath}`);
|
|
8293
|
-
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason, prUrl: pr.url, prNumber: pr.number, detail: `OP approval required: ${releaseHoldPath}` };
|
|
8601
|
+
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...scopeExpansionResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason, prUrl: pr.url, prNumber: pr.number, detail: `OP approval required: ${releaseHoldPath}` };
|
|
8294
8602
|
}
|
|
8295
8603
|
if (!releasePathInspectionError && labels?.includes(AUTO_REVIEW_LABEL)) {
|
|
8296
8604
|
try {
|
|
@@ -8308,7 +8616,7 @@ async function runSelfImplementInner(
|
|
|
8308
8616
|
: 'release-path-inspection-failed';
|
|
8309
8617
|
recordMergeDecision();
|
|
8310
8618
|
progress('pr-opened', `OP 승인 대기 (#${pr.number}): PR 경로 조회 실패`);
|
|
8311
|
-
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason, prUrl: pr.url, prNumber: pr.number };
|
|
8619
|
+
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...scopeExpansionResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason, prUrl: pr.url, prNumber: pr.number };
|
|
8312
8620
|
}
|
|
8313
8621
|
|
|
8314
8622
|
if (canAuto && (s.mergePr || opts.mergeByHost)) {
|
|
@@ -8358,12 +8666,12 @@ async function runSelfImplementInner(
|
|
|
8358
8666
|
// 판정(mergeReason)이 아니라 «집행 직전 가드»가 막았으므로 그 사실을 값으로 말한다.
|
|
8359
8667
|
// ⛔ 안 그러면 마지막 줄이 침묵하고, 그건 이 착지가 없애려던 상태다(리뷰 must-fix 2R).
|
|
8360
8668
|
const guardSkipReason = mergeSkipReason ?? (guardFailure ? 'merge-guard-unevaluated' : 'docs-deletion-threshold');
|
|
8361
|
-
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason: guardSkipReason, prUrl: pr.url, prNumber: pr.number, detail };
|
|
8669
|
+
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...scopeExpansionResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason: guardSkipReason, prUrl: pr.url, prNumber: pr.number, detail };
|
|
8362
8670
|
}
|
|
8363
8671
|
if (opts.mergeByHost) {
|
|
8364
8672
|
observe('merge-ready', { number: pr.number, checkedHeadCommit });
|
|
8365
8673
|
progress('pr-opened', `호스트 재게이트 대기 (#${pr.number})`);
|
|
8366
|
-
return { ok: true, stage: 'merge-ready', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, ...(reviewDeferredToHost ? { mergeReason } : {}), checkedHeadCommit: checkedHeadCommit!, prUrl: pr.url, prNumber: pr.number };
|
|
8674
|
+
return { ok: true, stage: 'merge-ready', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...scopeExpansionResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, ...(reviewDeferredToHost ? { mergeReason } : {}), checkedHeadCommit: checkedHeadCommit!, prUrl: pr.url, prNumber: pr.number };
|
|
8367
8675
|
}
|
|
8368
8676
|
// Landing freeze: the in-flight marker is written before the freeze is read, so a `freeze on` racing this merge waits.
|
|
8369
8677
|
// The resume sweep merges from the repository that owns the run worktree (the worktree itself may be cleaned up).
|
|
@@ -8375,13 +8683,13 @@ async function runSelfImplementInner(
|
|
|
8375
8683
|
};
|
|
8376
8684
|
const landing = admitLandingMerge(heldEntry, undefined, {}, { prNumber: pr.number, repoRoot: owningRepoRoot(wt.path) ?? wt.path, ...(checkedHeadCommit ? { headCommit: checkedHeadCommit } : {}) });
|
|
8377
8685
|
if (landing.kind === 'held' && !(checkedHeadCommit && /^[0-9a-f]{40}$/i.test(checkedHeadCommit))) {
|
|
8378
|
-
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason: 'merge-guard-unevaluated', prUrl: pr.url, prNumber: pr.number, detail: 'freeze: checked head SHA unavailable; PR left ready for review' };
|
|
8686
|
+
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...scopeExpansionResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason: 'merge-guard-unevaluated', prUrl: pr.url, prNumber: pr.number, detail: 'freeze: checked head SHA unavailable; PR left ready for review' };
|
|
8379
8687
|
}
|
|
8380
8688
|
if (landing.kind !== 'merge') {
|
|
8381
8689
|
const detail = landing.kind === 'held' ? landingFreezeMessage(landing.freeze) : 'freeze lifted; a resume sweep is merging this PR';
|
|
8382
8690
|
debug.log('harness.merge', 'frozen', { pr: pr.number, ...(landing.kind === 'held' ? { reason: landing.freeze.reason, until: landing.freeze.until } : { resumedElsewhere: true }) });
|
|
8383
8691
|
progress('pr-opened', `#${pr.number} ready · ${detail}`);
|
|
8384
|
-
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason: landing.kind === 'held' ? 'frozen' : 'resumed-elsewhere', prUrl: pr.url, prNumber: pr.number, detail };
|
|
8692
|
+
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...scopeExpansionResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason: landing.kind === 'held' ? 'frozen' : 'resumed-elsewhere', prUrl: pr.url, prNumber: pr.number, detail };
|
|
8385
8693
|
}
|
|
8386
8694
|
// The marker and claim live until the merge call itself settles — a step timeout does not stop a merge already
|
|
8387
8695
|
// sent — and anything that throws before the merge call is made releases them.
|
|
@@ -8464,17 +8772,17 @@ async function runSelfImplementInner(
|
|
|
8464
8772
|
...(opts.goalId ? { cellId: opts.goalId } : {}),
|
|
8465
8773
|
...(opts.goalFile ? { goalFile: opts.goalFile } : {}),
|
|
8466
8774
|
}, s.followUp);
|
|
8467
|
-
return { ok: true, stage: 'merged', node: 'merge', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), merged: true, ...(mergedBase ? { mergedBase } : {}), prUrl: pr.url, prNumber: pr.number };
|
|
8775
|
+
return { ok: true, stage: 'merged', node: 'merge', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...scopeExpansionResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), merged: true, ...(mergedBase ? { mergedBase } : {}), prUrl: pr.url, prNumber: pr.number };
|
|
8468
8776
|
}
|
|
8469
8777
|
progress('pr-opened', `병합 실패 — PR 개설됨(#${pr.number}·수동 병합). ${m.detail ?? ''}`);
|
|
8470
8778
|
// ⛔⭐ 이 경로는 `canAuto` 가 «참»이었는데 병합이 안 된 자리다 ⇒ mergeSkipReason 은 undefined 다.
|
|
8471
8779
|
// 그대로 두면 마지막 산출 줄이 «침묵»한다 — 이 착지가 없애려던 바로 그 상태다(리뷰 must-fix).
|
|
8472
8780
|
// ⇒ 판정이 아니라 «집행»에서 막힌 것이므로 그 사실을 별도 값으로 말한다.
|
|
8473
8781
|
const mergeAttemptSkipReason = mergeSkipReason ?? 'merge-attempt-failed';
|
|
8474
|
-
return { ok: true, stage: 'pr-opened', node: 'merge', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason: mergeAttemptSkipReason, merged: false, prUrl: pr.url, prNumber: pr.number, ...(m.detail ? { detail: m.detail } : {}) };
|
|
8782
|
+
return { ok: true, stage: 'pr-opened', node: 'merge', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...scopeExpansionResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, mergeReason: mergeAttemptSkipReason, merged: false, prUrl: pr.url, prNumber: pr.number, ...(m.detail ? { detail: m.detail } : {}) };
|
|
8475
8783
|
}
|
|
8476
8784
|
progress('pr-opened', `✅ PR 개설 (#${pr.number})`);
|
|
8477
|
-
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, ...(lastSupervisorReason ? { supervisorReason: lastSupervisorReason } : {}), ...(mergeSkipReason ? { mergeReason: mergeSkipReason } : {}), prUrl: pr.url, prNumber: pr.number };
|
|
8785
|
+
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...scopeExpansionResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, ...(lastSupervisorReason ? { supervisorReason: lastSupervisorReason } : {}), ...(mergeSkipReason ? { mergeReason: mergeSkipReason } : {}), prUrl: pr.url, prNumber: pr.number };
|
|
8478
8786
|
}
|
|
8479
8787
|
|
|
8480
8788
|
/** 결정적 요청 거부 — 같은 요청을 다시 보내면 «같은» 답이 온다(BACKLOG B6).
|