elanous 0.2.35 → 0.2.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/{d06f9160.a3d9062f95de8ad7.js → 053a429e.9a63436527cc751c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +287 -0
- package/apps/pwa/out/_next/static/chunks/{4346.8601952e73bf5803.js → 1201.afbfc5b1c5e5cbe4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/190.285c832bd9626f8c.js +64 -0
- package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +36 -0
- package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +149 -0
- package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3103.0df8da390948bb84.js → 2500.cbc1257b774aae52.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7644.17e37ba6f1d4226e.js → 2683.c9773a0c589b031b.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{4718-17d2af636796a330.js → 275-02ea4c2a33980422.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/2812ca6a.3b9f4a7a08885744.js +1 -0
- package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8714.ff0b7ce3ec3e3ae2.js → 2941.3c3546f96bc6efa7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{9214.63a510d39178e997.js → 2986.45d7652e4f13557e.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3136.30aaaa5fa03662a3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3677-4215f826f6aa68e5.js → 3148-98efd4869d660a87.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +226 -0
- package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3324.a09703033abcbd2f.js +34 -0
- package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +8 -0
- package/apps/pwa/out/_next/static/chunks/3410.7f9af5ab77cbe65f.js +115 -0
- package/apps/pwa/out/_next/static/chunks/3538.a445e50bb359d068.js +32 -0
- package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +286 -0
- package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9512.5a76207a730e0491.js → 3727.7949ccaacaa71242.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8557-e7898769499cd56f.js → 3757-180308bc61021b05.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +74 -0
- package/apps/pwa/out/_next/static/chunks/{359-2250789a2d3499e7.js → 3840-5825d56d46976a92.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{da5176c6.6773b6c5994e1d99.js → 3a3d9966.cc4d4585a2708e7c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +104 -0
- package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9952.5daf5f94063a2b3e.js → 4286.b70c4520306817e8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4304.e9b2512834a9e23e.js +23 -0
- package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{938.66ad1ef0e5abae1c.js → 4615.8525eb0add35eba6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +148 -0
- package/apps/pwa/out/_next/static/chunks/5085-bce4904931767ca6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +93 -0
- package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6236.e18cced2d5ba6afb.js → 528.38ce20ef8aa251ff.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +122 -0
- package/apps/pwa/out/_next/static/chunks/{3408.21d1570602f4b6c0.js → 552.b7d061ad91eeac51.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5711.957b095705c12560.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1530.0e612369b6fd7ea0.js → 575.d929793a53f27c4b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/599.c39c571b6733f2a2.js +41 -0
- package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +79 -0
- package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6466-92e65a48490b68a9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +1 -0
- package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +27 -0
- package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6925.562d532110879886.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7385.50a308a477bdfc21.js → 6943.c6b24124853a47b2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{630.fe5a46428d63b013.js → 727.7deb87749b0a343a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2018.a741297bce759490.js → 7481.39f7a4654907bf6e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8444.4c26b379ca2b9596.js → 771.c3cdb6c1f7f47c02.js} +17 -17
- package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3589.5444a06bcf6e775c.js → 7891.03f910124a737985.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +1 -0
- package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +62 -0
- package/apps/pwa/out/_next/static/chunks/{b2f6ba4d.fb56fdbbf798df33.js → 873d6c12.09bd499f57171543.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5101.e32282718f99ed6f.js → 8904.7d51af2dc033965c.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +90 -0
- package/apps/pwa/out/_next/static/chunks/{5637.281e5dec4ea6ecf1.js → 914.8abefd48d579547b.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4705-194e64e47ca0fbdb.js → 9250-072df22eaadaa6b5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +77 -0
- package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8637.47f5b35afcae5e6b.js → 9514.131c52cc75fe6439.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1674.2a65fd5668e1cc5f.js → 9789.60f723d18097ec30.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9f31e478.fefcbcd3c388ebc5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-083747f1d4518f61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-e2de2e59111c9aad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-f2b2e4bf6e981450.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2af16e62c12f22df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{0368f25d-ad84af92fefee68f.js → ccae1c4b-0cf414f5eff1b10d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{cbe38a15.5a032598e39970c6.js → ceba0382.650712b56b85b582.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{b6705a4f-b9a9047de9eecfd0.js → da5ecc5c-b005ad8cac737d57.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{56d372f2.681ab4ec4c998fae.js → f9a61e4d.1fc2c1dbdd49fe46.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +1 -0
- package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → uC-N0emedeNOFuaBQFv-I}/_buildManifest.js +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +22 -22
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +21 -21
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +22 -22
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +22 -22
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +22 -22
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +21 -21
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +21 -21
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +21 -21
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +21 -21
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +21 -21
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
- package/docs/goal-context/README.md +3 -0
- package/graphs/default-loop.yaml +6 -1
- package/graphs/implement-loop.yaml +24 -0
- package/graphs/release/recipes.yaml +6 -0
- package/graphs/release/release-loop.yaml +17 -4
- package/graphs/wizard/recipes.yaml +44 -0
- package/graphs/wizard/wizard-loop.yaml +44 -0
- package/graphs/work/research-report.yaml +2 -0
- package/package.json +1 -1
- package/scripts/ci-typecheck-changed.ts +139 -5
- package/scripts/coord-role-pack.ts +1 -1
- package/scripts/first10-gate.ts +416 -0
- package/scripts/fleet/wsl-node-setup.sh +432 -0
- package/scripts/release-loop/docs-node.ts +204 -8
- package/scripts/release-loop/gate-node.ts +249 -53
- package/scripts/release-loop/node-verdict.ts +2 -0
- package/scripts/release-loop/resume-cap.ts +14 -34
- package/scripts/release-loop/resume-release.ts +37 -11
- package/scripts/release-loop/traffic-node.ts +59 -0
- package/scripts/release-loop/traffic-transition.ts +159 -0
- package/scripts/rhythm/daily.ts +137 -3
- package/scripts/ux-sim.ts +53 -0
- package/skills/README.md +1 -0
- package/src/acp/core-turn-bridge.ts +48 -6
- package/src/agent/delegate-hint.ts +16 -0
- package/src/agent/runner.ts +82 -2
- package/src/agent/task-notification.ts +56 -10
- package/src/agent/types.ts +4 -0
- package/src/agent-substrate/pr-reviewer.ts +55 -3
- package/src/agent-substrate/review-intent.ts +29 -2
- package/src/agent-substrate/review-observation.ts +3 -0
- package/src/agent-substrate/self-review-cli.ts +168 -16
- package/src/autopilot/mission-codebase-gate.ts +141 -12
- package/src/autopilot/pr-manager.ts +25 -5
- package/src/boot/daemon-tools/self-implement.ts +1 -0
- package/src/budget/usage-outcomes.ts +8 -4
- package/src/capture/tui-self-report.ts +102 -0
- package/src/chat/goal-continue-verdict.ts +41 -0
- package/src/chat/index.ts +30 -4
- package/src/chat/internal-turn-origin.ts +1 -0
- package/src/chat/paste-fold.ts +86 -0
- package/src/chat/tool-render/block.ts +32 -0
- package/src/chat/tool-render/dispatch.ts +2 -20
- package/src/chat/tool-render/result-text.ts +98 -0
- package/src/chat/turn-typeahead.ts +70 -7
- package/src/cli/config-audit.ts +119 -0
- package/src/cli/doctor-cli.ts +22 -0
- package/src/cli/guardian-cli.ts +10 -0
- package/src/cli/herdr-cli.ts +34 -0
- package/src/cli/light-entry-route.ts +6 -3
- package/src/cli/log-event-names.ts +2 -0
- package/src/cli/make-cli.ts +247 -11
- package/src/cli/msg-cli.ts +117 -3
- package/src/cli/pr-cli.ts +29 -16
- package/src/cli/pr-land-base-read.ts +11 -2
- package/src/cli/pr-land-heavy-remote.ts +6 -3
- package/src/cli/pr-land-overlap-evidence.ts +23 -4
- package/src/cli/pr-land-recovery.ts +117 -1
- package/src/cli/pty-takeover-cli.ts +8 -7
- package/src/cli/release-cli.ts +21 -5
- package/src/cli/release-single-flight.ts +1 -1
- package/src/cli/tasks-card-show.ts +162 -0
- package/src/cli/tasks-cli.ts +574 -356
- package/src/cli/tasks-read-cli.ts +197 -0
- package/src/core-turn/run-core-turn.ts +4 -2
- package/src/core-turn/run-goal-loop.ts +73 -16
- package/src/core-turn/types.ts +6 -1
- package/src/dashboard/context/keys.ts +8 -31
- package/src/dashboard/index.ts +202 -49
- package/src/dashboard/input/agent-wake.ts +7 -1
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
- package/src/dashboard/input/chat-main-slash-command.ts +4 -2
- package/src/dashboard/input/goal-continue.ts +210 -0
- package/src/dashboard/input/goal-interim.ts +2 -0
- package/src/dashboard/input/internal-turn.ts +2 -8
- package/src/dashboard/input/seat-autowake.ts +9 -7
- package/src/dashboard/input/turn-autoheal.ts +52 -0
- package/src/dashboard/seat-boot-preamble.ts +132 -5
- package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +3 -2
- package/src/dashboard/slash-runtime/model-choices.ts +15 -0
- package/src/dashboard/stale-install-check.ts +3 -99
- package/src/debug/batch-queue.ts +119 -0
- package/src/debug/tui-log-tag.ts +67 -0
- package/src/display/agent-surface.ts +7 -0
- package/src/domains/standalone-log-sink.ts +15 -2
- package/src/esc-abort-gate.ts +69 -0
- package/src/git-fs/worktree.ts +95 -1
- package/src/graph-runner/graph-cli.ts +18 -0
- package/src/graph-runner/runner.ts +20 -11
- package/src/graph-wizard/generate.ts +108 -4
- package/src/graph-wizard/steps.ts +15 -0
- package/src/grounding/proactive-ground.ts +86 -0
- package/src/harness/control-inbox.ts +49 -1
- package/src/harness/harness-cli-command.ts +51 -7
- package/src/harness/harness-incidents.ts +52 -1
- package/src/harness/pod-control-send.ts +33 -5
- package/src/harness/self-send-remote.ts +69 -0
- package/src/harness/self-send-routing-guard.ts +6 -0
- package/src/harness/self-send-target.ts +4 -3
- package/src/index.ts +327 -12
- package/src/input-core/context-key-runtime.ts +21 -0
- package/src/light-cli.ts +6 -1
- package/src/llm-wellformed.ts +70 -0
- package/src/llm.ts +35 -4
- package/src/loops/msg-wake.ts +35 -39
- package/src/loops/orchestrator/inbox.ts +59 -11
- package/src/loops/orchestrator/knowhow-pack.ts +364 -0
- package/src/loops/orchestrator/tick.ts +5 -1
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/models/prompts.ts +17 -2
- package/src/msg/msg-post-office.ts +116 -0
- package/src/mss/logging/log-store.ts +79 -22
- package/src/nexus/api/decisions-route.ts +38 -18
- package/src/nexus/api/graph-wizard-api.ts +20 -2
- package/src/nexus/boot/register-mcp-clients.ts +263 -38
- package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
- package/src/onboarding/first-run.ts +37 -6
- package/src/onboarding/web-first.ts +43 -11
- package/src/ops/overview-collect.ts +12 -6
- package/src/ops/overview.ts +3 -3
- package/src/persona/loader.ts +11 -0
- package/src/persona/types.ts +8 -0
- package/src/prompt-library/session-guidance.ts +14 -0
- package/src/provider-summary.ts +8 -0
- package/src/pty-shell/herdr-agent-report.ts +118 -9
- package/src/pty-shell/herdr-prompt.ts +266 -0
- package/src/pty-shell/pty-control-ipc.ts +151 -8
- package/src/pty-shell/pty-special-keys.ts +42 -2
- package/src/pty-shell/stale-install-check.ts +99 -0
- package/src/pty-shell/tui-run-state.ts +14 -2
- package/src/release-loop/auto-start.ts +20 -2
- package/src/release-loop/checklist.ts +76 -4
- package/src/release-loop/rehearsal.ts +36 -20
- package/src/repl/index.ts +19 -1
- package/src/seat-loop/knowhow-lint.ts +1 -1
- package/src/self-dev/decompose-proposal.ts +172 -20
- package/src/self-dev/decompose.ts +61 -0
- package/src/self-dev/dev-cli.ts +37 -3
- package/src/self-dev/dev-pipeline.ts +8 -2
- package/src/self-dev/draft-triage-rules.ts +31 -0
- package/src/self-dev/glm-credential-guard.ts +77 -0
- package/src/self-dev/graph-journey-nodes.ts +1 -0
- package/src/self-dev/graph-journey-route.ts +12 -2
- package/src/self-dev/orchestrate-cli.ts +68 -3
- package/src/self-dev/orchestrate.ts +116 -17
- package/src/self-dev/run-supervisor.ts +55 -2
- package/src/self-dev/run-types.ts +1 -1
- package/src/self-health/autoheal.ts +153 -0
- package/src/self-health/signatures.ts +6 -0
- package/src/self-implement/device-first.ts +116 -0
- package/src/self-implement/doctor-visit.ts +239 -1
- package/src/self-implement/evidence-command-budget.ts +80 -0
- package/src/self-implement/goal-author-cli.ts +1 -0
- package/src/self-implement/goal-author-decompose.ts +265 -4
- package/src/self-implement/goal-author.ts +33 -8
- package/src/self-implement/goal-elaborate.ts +176 -22
- package/src/self-implement/goal-refine.ts +3 -0
- package/src/self-implement/graph-variant.ts +40 -6
- package/src/self-implement/headless-elanous-driver.ts +19 -3
- package/src/self-implement/off-diff-evidence.ts +58 -6
- package/src/self-implement/orchestrator.ts +222 -21
- package/src/self-implement/pod-warm-pool-profile.ts +1 -0
- package/src/self-implement/pwa-import-graph.ts +1 -1
- package/src/self-implement/rework-policy.ts +30 -0
- package/src/self-implement/run-ledger.ts +108 -0
- package/src/self-implement/run-ttl.ts +38 -24
- package/src/self-implement/scope-adjacency.ts +3 -1
- package/src/self-implement/seams.ts +60 -4
- package/src/self-implement/wiring-check.ts +358 -0
- package/src/shell-env-bootstrap.ts +11 -4
- package/src/skills/runner.ts +4 -2
- package/src/skills/tools/agent.ts +290 -48
- package/src/skills/tools/schedule-wakeup.ts +23 -4
- package/src/skills/tools/shell.ts +61 -6
- package/src/skills/tools/terminal-modal-inject.ts +1 -2
- package/src/skills/tools/terminal-modal.ts +10 -8
- package/src/skills/url-router.ts +41 -1
- package/src/smart-wizard/run.ts +66 -0
- package/src/status/bar.ts +34 -6
- package/src/status/status-provider-info.ts +37 -6
- package/src/steward/rejudge-tick.ts +10 -2
- package/src/steward/ta-repair-event-collect.ts +17 -6
- package/src/task-agent/actions.ts +3 -1
- package/src/task-agent/land-queue.ts +21 -8
- package/src/task-agent/live-moves.ts +22 -6
- package/src/task-agent/mission.ts +30 -0
- package/src/task-agent/rejudge-on-head.ts +15 -0
- package/src/task-agent/repair-cycle.ts +138 -32
- package/src/task-agent/repair-next-move.ts +31 -3
- package/src/task-agent/repair-outcomes.ts +29 -0
- package/src/task-agent/repair-worker.ts +14 -4
- package/src/task-agent/shadow.ts +41 -3
- package/src/task-agent/task-card-prefix.ts +2 -0
- package/src/task-agent/task-hand.ts +477 -22
- package/src/task-agent/task-parent-role-llm.ts +36 -0
- package/src/task-agent/tier-split.ts +78 -9
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +9 -0
- package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +86 -5
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
- package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
- package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +11 -0
- package/src/task-orchestrator/surfaces/pod-pool.ts +76 -4
- package/src/task-orchestrator/surfaces/pod-provenance.ts +8 -2
- package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
- package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +4 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +485 -36
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +396 -19
- package/src/task-orchestrator/surfaces/self-implement.ts +42 -2
- package/src/tool-runtime/index.ts +15 -2
- package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
- package/src/tty-foreground.ts +155 -0
- package/src/tui/chat/goal-interim.ts +173 -0
- package/src/tui/chat/log-view.ts +205 -18
- package/src/tui/chat/self-health-status.ts +232 -0
- package/src/tui/entry.ts +370 -81
- package/src/tui/input/composer.ts +8 -1
- package/src/tui/slash/compact-command.ts +7 -0
- package/src/tui/slash/compact.ts +1 -7
- package/src/tui/slash/resume.ts +75 -0
- package/src/tui-client/local-chat-turn.ts +45 -2
- package/src/tui-client/next-dashboard-runtime.ts +8 -0
- package/src/tui-client/next-loop-command.ts +70 -0
- package/src/tui-client/next-wakeup.ts +191 -0
- package/src/tui.ts +37 -0
- package/src/ui/modal-adapter.ts +2 -2
- package/src/ux-sim/classic-tui-seat-scenarios.ts +516 -0
- package/src/ux-sim/cli-config-audit-device.ts +121 -0
- package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
- package/src/ux-sim/event-monkey.ts +3 -2
- package/src/ux-sim/fake-bin.ts +45 -0
- package/src/ux-sim/fake-herdr.ts +238 -0
- package/src/ux-sim/fake-llm.ts +111 -6
- package/src/ux-sim/fault-glm-no-credential.ts +116 -0
- package/src/ux-sim/fault-nextmove-dispatch.ts +102 -1
- package/src/ux-sim/fault-scope-escape-lift.ts +33 -6
- package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
- package/src/ux-sim/goal-device.ts +619 -0
- package/src/ux-sim/in-process-cli.ts +22 -5
- package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
- package/src/ux-sim/mock-authoring-first-run.ts +97 -0
- package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
- package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
- package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
- package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
- package/src/ux-sim/next-tui-seat-scenarios.ts +631 -0
- package/src/ux-sim/onboarding-first-run-device.ts +269 -0
- package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
- package/src/ux-sim/subagent-tools-device.ts +81 -0
- package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
- package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +0 -1
- package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +0 -32
- package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +0 -41
- package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +0 -24
- package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +0 -74
- package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +0 -148
- package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +0 -34
- package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +0 -77
- package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +0 -62
- package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +0 -90
- package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +0 -36
- package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +0 -79
- package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +0 -122
- package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +0 -286
- package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +0 -24
- package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +0 -23
- package/apps/pwa/out/_next/static/chunks/5483-dd5d7697f6bdb106.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +0 -287
- package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +0 -1
- package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +0 -8
- package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +0 -27
- package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +0 -93
- package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +0 -149
- package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +0 -104
- package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +0 -226
- package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +0 -64
- package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +0 -115
- package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-47c5d4db587266bd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-dc0a532f5b9196ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +0 -1
- /package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → uC-N0emedeNOFuaBQFv-I}/_ssgManifest.js +0 -0
package/src/ux-sim/fake-llm.ts
CHANGED
|
@@ -2,17 +2,114 @@
|
|
|
2
2
|
* Deterministic, network-free LLM for gate tests without provider credentials.
|
|
3
3
|
* The opt-in is deliberately explicit; production never selects this provider.
|
|
4
4
|
*/
|
|
5
|
+
import { appendFileSync } from 'node:fs';
|
|
5
6
|
import type { LLMMessage, LLMOpts, LLMProvider, LLMStreamEvent } from '../llm.js';
|
|
6
7
|
|
|
7
8
|
export const TEST_FAKE_LLM_ENV = 'ELANOUS_TEST_FAKE_LLM';
|
|
8
9
|
export const TEST_FAKE_LLM_RESPONSE_ENV = 'ELANOUS_TEST_FAKE_LLM_RESPONSE';
|
|
10
|
+
/** TUI-400-AUTOHEAL-FALLBACK — 호출별 결함 스크립트(쉼표 목록 · `400` | `400codex` | `ok`). 예: `400,ok,ok`.
|
|
11
|
+
* `400` 칸은 실측 «대화 기록 어긋남» 꼴(`LLM API 400: … No tool call found for function call output …`)을 던진다.
|
|
12
|
+
* 스크립트가 끝나면 `ok`. 칸 소비는 이 프로세스 안 호출 순서다(라이브 TUI 격리 무대용 — 생산은 이 env 를 안 본다). */
|
|
13
|
+
export const TEST_FAKE_LLM_SCRIPT_ENV = 'ELANOUS_TEST_FAKE_LLM_SCRIPT';
|
|
14
|
+
export const TEST_FAKE_LLM_400_MESSAGE = 'LLM API 400: {"error":{"message":"No tool call found for function call output with call_id call_fake_llm.","type":"invalid_request_error"}}';
|
|
15
|
+
/** TUI-ORPHAN-AUTO-RESUME-STOP — `400codex` 칸: 같은 «고아 도구 출력» 400 을 Codex 공급자 머리(`Codex API 400`)로 던진다.
|
|
16
|
+
* seat-autowake 의 종결 판정은 생산 Codex 문면을 문다 — `400` 칸(`LLM API 400`)으로는 그 길이 안 열린다. */
|
|
17
|
+
export const TEST_FAKE_LLM_CODEX_400_MESSAGE = 'Codex API 400: {"error":{"message":"No tool call found for function call output with call_id call_fake_llm.","type":"invalid_request_error"}}';
|
|
9
18
|
|
|
10
19
|
export function testFakeLlmEnabled(): boolean {
|
|
11
20
|
return process.env[TEST_FAKE_LLM_ENV] === '1';
|
|
12
21
|
}
|
|
13
22
|
|
|
14
|
-
|
|
15
|
-
|
|
23
|
+
/** `{step}` in the response becomes the number of user messages (tool results excluded) the model received — a different reply per
|
|
24
|
+
* turn of one conversation (TUI-GOAL-INTERIM-QUIET: «every step ends with 아직 못 했다» without same-reply stops). */
|
|
25
|
+
const TEST_FAKE_LLM_STEP_TOKEN = '{step}';
|
|
26
|
+
|
|
27
|
+
export function testFakeLlmResponse(messages?: readonly LLMMessage[]): string {
|
|
28
|
+
const text = process.env[TEST_FAKE_LLM_RESPONSE_ENV] ?? '[test-fake-llm] OK';
|
|
29
|
+
if (!text.includes(TEST_FAKE_LLM_STEP_TOKEN)) return text;
|
|
30
|
+
// Person/internal-turn text only — a tool result travels as a user-role message and must not count as a step.
|
|
31
|
+
const step = (messages ?? []).filter((m) => m.role === 'user'
|
|
32
|
+
&& !(Array.isArray(m.content) && m.content.some((block) => block.type === 'tool_result'))).length;
|
|
33
|
+
return text.split(TEST_FAKE_LLM_STEP_TOKEN).join(String(step));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let scriptCursor = 0;
|
|
37
|
+
/** 커서가 센 스크립트 문자열 — env 가 바뀌면 처음부터 다시 센다(앞 시험의 진행이 뒤 시험으로 새지 않게). */
|
|
38
|
+
let scriptCursorFor: string | undefined;
|
|
39
|
+
|
|
40
|
+
/** 시험 seam — 스크립트 칸 위치를 처음으로. */
|
|
41
|
+
export function resetTestFakeLlmScript(): void {
|
|
42
|
+
scriptCursor = 0;
|
|
43
|
+
scriptCursorFor = undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** TUI-ORPHAN-AUTO-RESUME-STOP — 마지막 사람 발화가 이 표지를 담으면 스크립트 칸을 안 쓰고 답한다
|
|
47
|
+
* («결함이 계속되는 세션에서도 사람 턴은 답을 받는다» 무대 · 칸 수를 호출 수에 맞춰 세지 않게). */
|
|
48
|
+
export const TEST_FAKE_LLM_SCRIPT_SKIP_WHEN_ENV = 'ELANOUS_TEST_FAKE_LLM_SCRIPT_SKIP_WHEN';
|
|
49
|
+
|
|
50
|
+
/** 다음 호출의 스크립트 칸을 소비한다. 400 칸이면 던진다. */
|
|
51
|
+
function consumeScriptStep(messages: LLMMessage[]): void {
|
|
52
|
+
const raw = process.env[TEST_FAKE_LLM_SCRIPT_ENV];
|
|
53
|
+
if (!raw) return;
|
|
54
|
+
const skipWhen = process.env[TEST_FAKE_LLM_SCRIPT_SKIP_WHEN_ENV];
|
|
55
|
+
if (skipWhen && (lastHumanText(messages) ?? '').includes(skipWhen)) return;
|
|
56
|
+
if (raw !== scriptCursorFor) { scriptCursorFor = raw; scriptCursor = 0; }
|
|
57
|
+
const steps = raw.split(',').map((step) => step.trim()).filter(Boolean);
|
|
58
|
+
const step = steps[scriptCursor];
|
|
59
|
+
scriptCursor += 1;
|
|
60
|
+
if (step === '400') throw new Error(TEST_FAKE_LLM_400_MESSAGE);
|
|
61
|
+
if (step === '400codex') throw new Error(TEST_FAKE_LLM_CODEX_400_MESSAGE);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** TUI-SEAT-MEMORY-RECALL — 요청 기록(격리 무대 전용). 경로를 주면 호출마다 받은 메시지(role·문자열 content)를
|
|
65
|
+
* JSONL 한 줄로 덧붙인다 — «모델이 실제로 받은 preamble» 을 무대 밖에서 단언하기 위함. 생산은 이 env 를 안 본다. */
|
|
66
|
+
export const TEST_FAKE_LLM_CAPTURE_ENV = 'ELANOUS_TEST_FAKE_LLM_CAPTURE';
|
|
67
|
+
|
|
68
|
+
function captureRequest(messages: LLMMessage[]): void {
|
|
69
|
+
const path = process.env[TEST_FAKE_LLM_CAPTURE_ENV];
|
|
70
|
+
if (!path) return;
|
|
71
|
+
const rows = messages.map((message) => ({ role: message.role, content: typeof message.content === 'string' ? message.content : null }));
|
|
72
|
+
appendFileSync(path, `${JSON.stringify({ messages: rows })}\n`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** TUI-NEXT-QUEUE-AND-WAKE — `{"when":"<표지>","name":"<도구>","args":{…}}`. 마지막 메시지가 표지를 담은 사람 발화
|
|
76
|
+
* (도구 결과 아님)면 텍스트 대신 그 도구 호출 하나를 낸다 — 도구가 실제 턴 루프에서 «불리는» 무대(예: ScheduleWakeup).
|
|
77
|
+
* 도구 결과 뒤 호출·표지 없는 발화는 고정 응답. JSON 이 틀리면 없는 것과 같다. */
|
|
78
|
+
export const TEST_FAKE_LLM_TOOL_CALL_ENV = 'ELANOUS_TEST_FAKE_LLM_TOOL_CALL';
|
|
79
|
+
/** 응답 전 지연(ms) — «도는 턴»을 사람 손으로 잡을 만큼 길게 만든다(busy 중 입력 무대). */
|
|
80
|
+
export const TEST_FAKE_LLM_DELAY_MS_ENV = 'ELANOUS_TEST_FAKE_LLM_DELAY_MS';
|
|
81
|
+
/** 주면 마지막 사람 발화가 이 표지를 담을 때만 지연한다. */
|
|
82
|
+
export const TEST_FAKE_LLM_DELAY_WHEN_ENV = 'ELANOUS_TEST_FAKE_LLM_DELAY_WHEN';
|
|
83
|
+
|
|
84
|
+
let toolCallSeq = 0;
|
|
85
|
+
|
|
86
|
+
/** 마지막 메시지가 사람 발화면 그 글, 도구 결과(또는 사람 아님)면 null. */
|
|
87
|
+
function lastHumanText(messages: LLMMessage[]): string | null {
|
|
88
|
+
const last = messages.at(-1);
|
|
89
|
+
if (!last || last.role !== 'user') return null;
|
|
90
|
+
if (typeof last.content === 'string') return last.content;
|
|
91
|
+
if (last.content.some((block) => block.type === 'tool_result')) return null;
|
|
92
|
+
return last.content.map((block) => (block.type === 'text' ? block.text : '')).join('');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function scriptedToolCall(messages: LLMMessage[]): LLMStreamEvent | null {
|
|
96
|
+
const raw = process.env[TEST_FAKE_LLM_TOOL_CALL_ENV];
|
|
97
|
+
if (!raw) return null;
|
|
98
|
+
let spec: { when?: unknown; name?: unknown; args?: unknown };
|
|
99
|
+
try { spec = JSON.parse(raw) as typeof spec; } catch { return null; }
|
|
100
|
+
if (typeof spec.when !== 'string' || typeof spec.name !== 'string') return null;
|
|
101
|
+
const text = lastHumanText(messages);
|
|
102
|
+
if (text === null || !text.includes(spec.when)) return null;
|
|
103
|
+
const args = spec.args && typeof spec.args === 'object' ? spec.args as Record<string, unknown> : {};
|
|
104
|
+
return { type: 'tool_call', id: `call_fake_llm_tool_${++toolCallSeq}`, name: spec.name, args };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function scriptedDelay(messages: LLMMessage[]): Promise<void> {
|
|
108
|
+
const ms = Number(process.env[TEST_FAKE_LLM_DELAY_MS_ENV] ?? 0);
|
|
109
|
+
if (!Number.isFinite(ms) || ms <= 0) return;
|
|
110
|
+
const when = process.env[TEST_FAKE_LLM_DELAY_WHEN_ENV];
|
|
111
|
+
if (when && !(lastHumanText(messages) ?? '').includes(when)) return;
|
|
112
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
16
113
|
}
|
|
17
114
|
|
|
18
115
|
/** Shares the real LLMProvider contract; only the external model call is replaced. */
|
|
@@ -20,10 +117,18 @@ export const testFakeLlmProvider: LLMProvider = {
|
|
|
20
117
|
name: 'test-fake-llm',
|
|
21
118
|
defaultModel: 'test-fake-llm',
|
|
22
119
|
available: testFakeLlmEnabled,
|
|
23
|
-
async *chat(
|
|
24
|
-
|
|
120
|
+
async *chat(messages: LLMMessage[], _opts?: LLMOpts): AsyncGenerator<string, void, unknown> {
|
|
121
|
+
captureRequest(messages);
|
|
122
|
+
consumeScriptStep(messages);
|
|
123
|
+
await scriptedDelay(messages);
|
|
124
|
+
yield testFakeLlmResponse(messages);
|
|
25
125
|
},
|
|
26
|
-
async *streamChat(
|
|
27
|
-
|
|
126
|
+
async *streamChat(messages: LLMMessage[], _opts?: LLMOpts): AsyncGenerator<LLMStreamEvent, void, unknown> {
|
|
127
|
+
captureRequest(messages);
|
|
128
|
+
consumeScriptStep(messages);
|
|
129
|
+
await scriptedDelay(messages);
|
|
130
|
+
const call = scriptedToolCall(messages);
|
|
131
|
+
if (call) { yield call; return; }
|
|
132
|
+
yield { type: 'text', delta: testFakeLlmResponse(messages) };
|
|
28
133
|
},
|
|
29
134
|
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// 결함 주입 심 «glm 자식 자격 없음» ── 하니스 자식 공급자를 glm(Z.ai GLM Coding Plan)으로 쐈는데 이 프로세스에
|
|
2
|
+
// Z.ai 자격이 없을 때, 발사 직전 해석(생산 `toSelfImplementOptions`)이 무엇을 내는지 프로세스 안(S1)에서 잰다.
|
|
3
|
+
//
|
|
4
|
+
// 🚨 왜 이것이 있나 (GLM-NO-CREDENTIAL-FALLBACK · OP #28375 · 2026-10-22)
|
|
5
|
+
// run-6c85c69f 부검이 «provider: glm / glm-5.3 · no provider configured» 한 줄로 «자격 결손 → 구현 0» 을 추정했다.
|
|
6
|
+
// 실측(Pod 로그)은 자격이 살아 있었고(Z.ai 200 OK) 그 줄은 배너가 glm 칸을 몰라 찍은 «거짓 표시»였다.
|
|
7
|
+
// 이 심은 두 축을 상주 시험으로 만든다 —
|
|
8
|
+
// ① 자격이 정말 없을 때: OpenRouter 키 있음 → openrouter/z-ai/glm-5.3 로 바꿔 발사 · 둘 다 없음 → 발사 전 거부
|
|
9
|
+
// ② 자격이 있을 때: 배너가 «no provider configured» 라고 거짓말하지 않는다
|
|
10
|
+
//
|
|
11
|
+
// ⛔ 흉내 내지 않는다 — 진짜 `toSelfImplementOptions`(dev-pipeline 이 runSelfImplement 직전에 부르는 그 함수) ⊕
|
|
12
|
+
// 진짜 `zaiCodingPlanAvailable`·`getOpenRouterApiKey`(키 캐시 → env) ⊕ 진짜 `oneLineProvider` 를 부른다.
|
|
13
|
+
// 주입은 «자격 env» 하나뿐이다(키 캐시 파일은 ELANOUS_KEEP_ENV_KEYS 로 끄고 기억된 값도 비운다 — 호스트의 진짜 키가 섞이지 않게).
|
|
14
|
+
// 관측 = 결과 선택 · 거부 문면 · self-dev.child-llm 관측 원본 · 배너 한 줄 · 영수증(명령 ⊕ injectionId ⊕ 결과) · 층 L1.
|
|
15
|
+
|
|
16
|
+
import { randomUUID } from 'node:crypto';
|
|
17
|
+
import { _resetKeyCacheForTests } from '../config.js';
|
|
18
|
+
import { debug } from '../debug/log.js';
|
|
19
|
+
import type { ChildLlmSelection } from '../agent/run-context.js';
|
|
20
|
+
import { planDevPipeline, toSelfImplementOptions } from '../self-dev/dev-pipeline.js';
|
|
21
|
+
import type { SelfImplementSeams } from '../self-implement/orchestrator.js';
|
|
22
|
+
import { inspectActiveProvider, oneLineProvider } from '../provider-summary.js';
|
|
23
|
+
import { getUserConfig, setUserConfigOverlay } from '../user-config.js';
|
|
24
|
+
|
|
25
|
+
export const GLM_NO_CREDENTIAL_LEVEL = 'L1' as const;
|
|
26
|
+
export const GLM_NO_CREDENTIAL_EVIDENCE_COMMAND = 'bun test src/ux-sim/fault-glm-no-credential.test.ts';
|
|
27
|
+
|
|
28
|
+
const ISOLATED_KEYS = ['ZAI_API_KEY', 'OPENROUTER_API_KEY'] as const;
|
|
29
|
+
|
|
30
|
+
export interface GlmNoCredentialScenario {
|
|
31
|
+
/** Z.ai 자격(env ZAI_API_KEY)을 둔다. */
|
|
32
|
+
readonly zaiKey: boolean;
|
|
33
|
+
/** OpenRouter 자격(env OPENROUTER_API_KEY)을 둔다. */
|
|
34
|
+
readonly openrouterKey: boolean;
|
|
35
|
+
/** 발사 인자 모델(기본 glm-5.3). */
|
|
36
|
+
readonly model?: string;
|
|
37
|
+
readonly injectionId?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface GlmNoCredentialObservedRow {
|
|
41
|
+
readonly category: string;
|
|
42
|
+
readonly event: string;
|
|
43
|
+
readonly data: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface GlmNoCredentialObservation {
|
|
47
|
+
readonly level: typeof GLM_NO_CREDENTIAL_LEVEL;
|
|
48
|
+
readonly injectionId: string;
|
|
49
|
+
readonly scenario: { zaiKey: boolean; openrouterKey: boolean; model: string };
|
|
50
|
+
/** keep = glm 그대로 · fallback = openrouter 로 바꿈 · refused = 발사 전 거부. */
|
|
51
|
+
readonly result: 'keep' | 'fallback' | 'refused';
|
|
52
|
+
readonly childLlm: ChildLlmSelection | null;
|
|
53
|
+
readonly error: string | null;
|
|
54
|
+
readonly rows: readonly GlmNoCredentialObservedRow[];
|
|
55
|
+
/** 같은 자격 상태에서 llm.provider=glm 일 때 배너가 찍는 한 줄(자식 PTY 첫 줄과 같은 함수). */
|
|
56
|
+
readonly banner: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function glmNoCredentialReceipt(observation: Pick<GlmNoCredentialObservation, 'injectionId' | 'result'>): string {
|
|
60
|
+
return `영수증: ${GLM_NO_CREDENTIAL_EVIDENCE_COMMAND} ⊕ ${observation.injectionId} ⊕ ${observation.result}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function renderGlmNoCredential(observation: GlmNoCredentialObservation): string[] {
|
|
64
|
+
const { scenario } = observation;
|
|
65
|
+
return [
|
|
66
|
+
`glm-no-credential · 층 ${observation.level} · 주입 ${observation.injectionId} · zai=${scenario.zaiKey ? '있음' : '없음'} · openrouter=${scenario.openrouterKey ? '있음' : '없음'} · 결과 ${observation.result}`,
|
|
67
|
+
observation.childLlm ? ` 자식 선택: ${observation.childLlm.provider}/${observation.childLlm.model}` : ` 거부: ${observation.error ?? '-'}`,
|
|
68
|
+
...observation.rows.map((row) => ` ${row.category} ${row.event} ${JSON.stringify(row.data)}`),
|
|
69
|
+
` 배너: ${observation.banner}`,
|
|
70
|
+
glmNoCredentialReceipt(observation),
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** 결함 주입 본체 — 생산 `toSelfImplementOptions` 를 그대로 부른다(runSelfImplement 는 부르지 않는다 · 발사 0). */
|
|
75
|
+
export function simGlmNoCredential(scenario: GlmNoCredentialScenario): GlmNoCredentialObservation {
|
|
76
|
+
const injectionId = scenario.injectionId ?? `inj-${randomUUID()}`;
|
|
77
|
+
const model = scenario.model ?? 'glm-5.3';
|
|
78
|
+
const savedEnv: Record<string, string | undefined> = {};
|
|
79
|
+
for (const key of [...ISOLATED_KEYS, 'ELANOUS_KEEP_ENV_KEYS']) savedEnv[key] = process.env[key];
|
|
80
|
+
const savedLog = debug.log;
|
|
81
|
+
const rows: GlmNoCredentialObservedRow[] = [];
|
|
82
|
+
try {
|
|
83
|
+
for (const key of ISOLATED_KEYS) delete process.env[key];
|
|
84
|
+
process.env.ELANOUS_KEEP_ENV_KEYS = '1';
|
|
85
|
+
_resetKeyCacheForTests();
|
|
86
|
+
if (scenario.zaiKey) process.env.ZAI_API_KEY = 'fake-zai-test-only';
|
|
87
|
+
if (scenario.openrouterKey) process.env.OPENROUTER_API_KEY = 'fake-openrouter-test-only';
|
|
88
|
+
debug.log = ((category: string, event: string, data: Record<string, unknown>): void => {
|
|
89
|
+
if (category === 'self-dev.child-llm') rows.push({ category, event, data });
|
|
90
|
+
}) as typeof debug.log;
|
|
91
|
+
const requested: ChildLlmSelection = { provider: 'glm', model, source: 'flag' };
|
|
92
|
+
const plan = planDevPipeline({ input: { text: `glm-no-credential ${injectionId}` }, executor: { kind: 'self' }, completion: 'worktree-only', self: { childLlm: requested } });
|
|
93
|
+
let childLlm: ChildLlmSelection | null = null;
|
|
94
|
+
let error: string | null = null;
|
|
95
|
+
try {
|
|
96
|
+
childLlm = toSelfImplementOptions(plan.input && 'text' in plan.input ? plan.input.text : '', plan, {} as SelfImplementSeams).childLlm ?? null;
|
|
97
|
+
} catch (caught) {
|
|
98
|
+
error = caught instanceof Error ? caught.message : String(caught);
|
|
99
|
+
}
|
|
100
|
+
setUserConfigOverlay((config) => ({ ...config, llm: { ...config.llm, provider: 'glm', model } }));
|
|
101
|
+
let banner: string;
|
|
102
|
+
// 자격이 없으면 생산 해석기가 glm 을 «배선 안 됨» 오류로 던진다 — 그 문면을 그대로 배너 칸에 싣는다(삼키지 않는다).
|
|
103
|
+
try { banner = oneLineProvider(inspectActiveProvider(getUserConfig())); }
|
|
104
|
+
catch (caught) { banner = `throw: ${caught instanceof Error ? caught.message : String(caught)}`; }
|
|
105
|
+
finally { setUserConfigOverlay(null); }
|
|
106
|
+
const result = error !== null ? 'refused' as const : childLlm?.provider === 'glm' ? 'keep' as const : 'fallback' as const;
|
|
107
|
+
return { level: GLM_NO_CREDENTIAL_LEVEL, injectionId, scenario: { zaiKey: scenario.zaiKey, openrouterKey: scenario.openrouterKey, model }, result, childLlm, error, rows, banner };
|
|
108
|
+
} finally {
|
|
109
|
+
debug.log = savedLog;
|
|
110
|
+
for (const [key, value] of Object.entries(savedEnv)) {
|
|
111
|
+
if (value === undefined) delete process.env[key];
|
|
112
|
+
else process.env[key] = value;
|
|
113
|
+
}
|
|
114
|
+
_resetKeyCacheForTests();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -29,6 +29,10 @@ import { createTempGitRemote, type TempGitRemote } from './temp-git-remote.js';
|
|
|
29
29
|
import { runRepairCycle, type RepairCycleInput, type RepairLaunchRequest } from '../task-agent/repair-cycle.js';
|
|
30
30
|
import { applyRepairBundle, REPAIR_BUNDLE_REF, type RepairCasDeps } from '../task-agent/repair-branch-cas.js';
|
|
31
31
|
import { readTaskCard, writeTaskCards, type TaskCard } from '../task-agent/task-hand.js';
|
|
32
|
+
import { recordTaskAgentShadowMove, RELAUNCH_LAUNCHED_EVENT } from '../task-agent/shadow.js';
|
|
33
|
+
import { installHarnessCliCommand } from '../harness/harness-cli-command.js';
|
|
34
|
+
import type { SupervisorJobResult } from '../self-dev/run-supervisor.js';
|
|
35
|
+
import { Command } from 'commander';
|
|
32
36
|
|
|
33
37
|
/** 이 심을 재는 증거 명령 — 매뉴얼 §3 과 영수증의 «명령» 칸이 같은 문자열이다. */
|
|
34
38
|
export const FAULT_NEXTMOVE_DISPATCH_COMMAND = 'bun test src/ux-sim/fault-nextmove-dispatch.test.ts';
|
|
@@ -166,6 +170,10 @@ export interface FaultNextmoveDispatchObservation {
|
|
|
166
170
|
readonly ghCalls: number;
|
|
167
171
|
/** 생산 확인 루프가 요청한 지연(ms) — 확인 지연이 «생산 루프를 다 돈 뒤» unconfirmed 가 됐다는 증거. */
|
|
168
172
|
readonly confirmSleeps: readonly number[];
|
|
173
|
+
/** HARNESS-FULL-GRAPH-NEXTMOVE — 한 수의 id 를 세 원문에서 읽은 값(결정 = next-move 노드 출구 · 간선 · 실제 발사 요청). */
|
|
174
|
+
readonly moveId: { readonly decision: string | undefined; readonly edge: string | undefined; readonly dispatch: string | undefined;
|
|
175
|
+
/** NEXTMOVE-GENERAL-RELAUNCH-MOVEID — 회수 틱이 결과 파일과 짝지어 카드 `repair-result` 줄에 실은 값. */
|
|
176
|
+
readonly consumed: string | undefined };
|
|
169
177
|
/** 두 틱이 낸 알림(심이 받아 적음 · 운영 우편함 0). */
|
|
170
178
|
readonly notified: readonly { seat: string; body: string }[];
|
|
171
179
|
/** 영수증 = 명령 ⊕ injectionId ⊕ 결과. */
|
|
@@ -179,10 +187,13 @@ export async function simFaultNextmoveDispatch(): Promise<FaultNextmoveDispatchO
|
|
|
179
187
|
const firstTick = new Date('2026-10-21T08:00:00.000Z');
|
|
180
188
|
const secondTick = new Date('2026-10-21T08:01:00.000Z');
|
|
181
189
|
const edges: Record<string, unknown>[] = [];
|
|
190
|
+
const decisions: Record<string, unknown>[] = [];
|
|
182
191
|
const off = debug.registerSink({
|
|
183
192
|
name: `ux-sim-fault-nextmove-dispatch-${injectionId}`,
|
|
184
193
|
emit: (record) => {
|
|
185
194
|
if (record.category === 'self-implement' && record.event === 'graph-edge-taken') edges.push(record.data as Record<string, unknown>);
|
|
195
|
+
if (record.category === 'self-implement' && record.event === 'pipeline-node-exit'
|
|
196
|
+
&& (record.data as Record<string, unknown> | undefined)?.node === 'next-move') decisions.push(record.data as Record<string, unknown>);
|
|
186
197
|
},
|
|
187
198
|
});
|
|
188
199
|
// ⛔ 생산 기본 notify(`msg post`)·request(detached elanous spawn)에 «절대» 닿지 않게 두 틱 모두 기록용 심을 준다.
|
|
@@ -208,9 +219,10 @@ export async function simFaultNextmoveDispatch(): Promise<FaultNextmoveDispatchO
|
|
|
208
219
|
// 수리 worker 가 끝 JSON ⊕ artifact 를 남겼다(생산 회수 경로가 읽는 꼴 그대로).
|
|
209
220
|
const result = { pr: PR, baseHead: fixture.head, runId: launch.runId, commit: fixture.commit, bundleSha256: fixture.bundleSha256 };
|
|
210
221
|
writeFileSync(join(fixture.artifactDir, 'result.json'), JSON.stringify(result));
|
|
222
|
+
// 생산 runRepairWorker 는 받은 --move-id 를 결과 파일에 그대로 싣는다(RepairWorkerResult.moveId).
|
|
211
223
|
writeFileSync(launch.resultPath, JSON.stringify({
|
|
212
224
|
pr: PR, head: fixture.head, runId: launch.runId, ok: true, job: JOB,
|
|
213
|
-
artifactDir: fixture.artifactDir, result,
|
|
225
|
+
artifactDir: fixture.artifactDir, result, moveId: launch.moveId,
|
|
214
226
|
}));
|
|
215
227
|
// 틱 ② — 결과 회수. 생산 applyRepairBundle 이 exact-head CAS push 에 성공하고
|
|
216
228
|
// PR 머리 확인이 늙은 가짜 gh 머리를 못 따라잡아 unconfirmed 로 돌아온다.
|
|
@@ -228,6 +240,14 @@ export async function simFaultNextmoveDispatch(): Promise<FaultNextmoveDispatchO
|
|
|
228
240
|
reason: second.reason,
|
|
229
241
|
};
|
|
230
242
|
const edgeCount = edges.filter((edge) => edge.from === 'next-move' && edge.to === 'dispatch').length;
|
|
243
|
+
const asId = (value: unknown): string | undefined => (typeof value === 'string' ? value : undefined);
|
|
244
|
+
const moveId = {
|
|
245
|
+
// 발사 요청과 같은 runId 의 결정만 짝짓는다(결정이 여럿이어도 남의 결정과 대조하지 않게).
|
|
246
|
+
decision: asId(decisions.find((row) => row.runId === launch.runId)?.moveId),
|
|
247
|
+
edge: asId(edges.find((edge) => edge.from === 'next-move' && edge.to === 'dispatch')?.moveId),
|
|
248
|
+
dispatch: launch.moveId,
|
|
249
|
+
consumed: asId(stored?.history.find((entry) => entry.event === 'repair-result' && entry.runId === launch.runId)?.moveId),
|
|
250
|
+
};
|
|
231
251
|
const remoteHead = fixture.remote.git(fixture.remote.checkout, ['ls-remote', 'origin', `refs/heads/${BRANCH}`]).split('\t')[0] ?? '';
|
|
232
252
|
const ghCalls = fixture.fakeBins.calls().filter((call) => call.name === 'gh').length;
|
|
233
253
|
const receipt = {
|
|
@@ -240,6 +260,7 @@ export async function simFaultNextmoveDispatch(): Promise<FaultNextmoveDispatchO
|
|
|
240
260
|
edge: { count: edgeCount, record: edges.find((edge) => edge.from === 'next-move' && edge.to === 'dispatch'), decision: first.decision },
|
|
241
261
|
unconfirmed,
|
|
242
262
|
remoteHead,
|
|
263
|
+
moveId,
|
|
243
264
|
repairCommit: fixture.commit,
|
|
244
265
|
ghCalls,
|
|
245
266
|
confirmSleeps: [...fixture.confirmSleeps],
|
|
@@ -258,9 +279,89 @@ export function renderFaultNextmoveDispatch(observation: FaultNextmoveDispatchOb
|
|
|
258
279
|
'fault-nextmove-dispatch · 층 L2 · 생산 runRepairCycle/repairNextMove/applyRepairBundle 직접 호출(GitHub API·네트워크 0)',
|
|
259
280
|
` receipt: command=${observation.receipt.command} ⊕ injectionId=${observation.receipt.injectionId} ⊕ result=${observation.receipt.result}`,
|
|
260
281
|
` ① graph-edge-taken: ${JSON.stringify(observation.edge.record ?? {})}`,
|
|
282
|
+
` ⓜ moveId: ${renderMoveIds(observation.moveId)}`,
|
|
261
283
|
` ② unconfirmed: decision=${observation.unconfirmed.decision} · status=${observation.unconfirmed.status ?? '-'} · reason=${observation.unconfirmed.reason}`,
|
|
262
284
|
` 원격 PR 가지 머리: ${observation.remoteHead.slice(0, 12)} · 수리 commit ${observation.repairCommit.slice(0, 12)} · push ${observation.remoteHead === observation.repairCommit ? '됨' : '안 됨'}`,
|
|
263
285
|
` 확인 지연 루프 요청(ms): ${observation.confirmSleeps.join(',') || '-'} · 알림 ${observation.notified.length}건(심이 받음)`,
|
|
264
286
|
` 가짜 gh 심 호출: ${observation.ghCalls}회 · 발사 틱 판정: ${observation.edge.decision}`,
|
|
265
287
|
];
|
|
266
288
|
}
|
|
289
|
+
|
|
290
|
+
/** 수 id 네 원문 한 줄 — 넷이 다 같아야 «일치». */
|
|
291
|
+
function renderMoveIds(ids: { decision: string | undefined; edge: string | undefined; dispatch: string | undefined; consumed: string | undefined }): string {
|
|
292
|
+
const same = ids.decision !== undefined && [ids.edge, ids.dispatch, ids.consumed].every((id) => id === ids.decision);
|
|
293
|
+
return `decision=${ids.decision ?? '-'} · graph-edge-taken=${ids.edge ?? '-'} · dispatch=${ids.dispatch ?? '-'} · consumed=${ids.consumed ?? '-'} · ${same ? '일치' : '불일치'}`;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ── NEXTMOVE-GENERAL-RELAUNCH-MOVEID — 일반 재발사(TA terminal → `harness say` 문자열 경로) 한 건 ─────────
|
|
297
|
+
// 생산 recordTaskAgentShadowMove(shadow.ts) → executeNextAction(actions.ts) 를 그대로 돌리고, 실행부가 낸 argv 를
|
|
298
|
+
// 생산 `harness say` CLI 파서(installHarnessCliCommand)에 그대로 먹인다. ⛔ 실제 발사·spawn 0 — command 는 argv 를 적기만 하고,
|
|
299
|
+
// say 처리기는 문장만 받아 적는다. 카드 상태는 임시 디렉터리 하나에만 쓰고 끝에 지운다.
|
|
300
|
+
|
|
301
|
+
export const FAULT_NEXTMOVE_GENERAL_COMMAND = 'bun test src/self-dev/graph-nextmove-moveid.test.ts -t "general relaunch device"';
|
|
302
|
+
|
|
303
|
+
export interface FaultNextmoveGeneralObservation {
|
|
304
|
+
readonly injectionId: string;
|
|
305
|
+
readonly executorResult: string | null;
|
|
306
|
+
/** 실행부가 낸 발사 argv(하나). */
|
|
307
|
+
readonly argv: readonly string[];
|
|
308
|
+
/** 결정(next-move 노드 출구) · graph-edge-taken · 발사(harness say 가 받은 값) · 카드 history(relaunch-launched). */
|
|
309
|
+
readonly moveId: { readonly decision: string | undefined; readonly edge: string | undefined; readonly dispatch: string | undefined; readonly consumed: string | undefined };
|
|
310
|
+
readonly receipt: { readonly command: string; readonly injectionId: string; readonly result: string };
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export async function simFaultNextmoveGeneralRelaunch(): Promise<FaultNextmoveGeneralObservation> {
|
|
314
|
+
const injectionId = `fng-${randomBytes(6).toString('hex')}`;
|
|
315
|
+
const root = mkdtempSync(join(tmpdir(), 'ux-sim-nextmove-general-'));
|
|
316
|
+
const runId = `run-sim-general-${injectionId.slice(4)}`;
|
|
317
|
+
const statePath = join(root, 'task-agent-actions.json');
|
|
318
|
+
const card: TaskCard = { id: 'ta-sim-general', text: 'feature ask', seat: 'TC', createdAt: '2026-10-22T08:00:00.000Z',
|
|
319
|
+
status: 'launched', history: [], runId };
|
|
320
|
+
writeTaskCards(statePath, [card]);
|
|
321
|
+
const rows: { category: string; event: string; data: Record<string, unknown> }[] = [];
|
|
322
|
+
const off = debug.registerSink({ name: `ux-sim-fault-nextmove-general-${injectionId}`, emit: (record) => {
|
|
323
|
+
if (record.category === 'self-implement' || record.category === 'harness') rows.push({ category: record.category, event: record.event, data: record.data as Record<string, unknown> });
|
|
324
|
+
} });
|
|
325
|
+
try {
|
|
326
|
+
const argvs: string[][] = [];
|
|
327
|
+
const job = { taskId: 't', feature: 'feature ask', status: 'done' } as SupervisorJobResult;
|
|
328
|
+
const move = await recordTaskAgentShadowMove({ runId, stopReason: 'no-progress', results: [job] }, {
|
|
329
|
+
// 빈 env — Pod·카드 힌트 없이 HQ 로컬 런으로 판단한다(운영 env 를 읽지 않는다).
|
|
330
|
+
env: {} as NodeJS.ProcessEnv, statePath, log: () => {}, liveMoves: new Set(['narrow-relaunch']),
|
|
331
|
+
loadGate: { loadMax: 2, load1: () => 0.5 },
|
|
332
|
+
command: async (args) => { argvs.push(args); return { status: 0, stdout: '' }; },
|
|
333
|
+
});
|
|
334
|
+
if (argvs.length !== 1) throw new Error(`fault-nextmove-general: 발사 argv ${argvs.length}건(기대 1) · executorResult=${move.executorResult}`);
|
|
335
|
+
// 발사 받는 쪽 — 생산 harness say 파서에 그 argv 를 그대로(처리기는 문장만 적는다 · 발사 0).
|
|
336
|
+
const program = new Command().exitOverride();
|
|
337
|
+
const said: string[][] = [];
|
|
338
|
+
installHarnessCliCommand(program, { registerSink: async () => {}, resolveSurface: async () => 'harness',
|
|
339
|
+
say: async (words: string[]) => { said.push(words); } } as never);
|
|
340
|
+
await program.parseAsync(['node', 'elanous', ...argvs[0]!]);
|
|
341
|
+
if (said.length !== 1) throw new Error(`fault-nextmove-general: harness say 처리기 호출 ${said.length}건(기대 1)`);
|
|
342
|
+
const asId = (value: unknown): string | undefined => (typeof value === 'string' ? value : undefined);
|
|
343
|
+
const stored = readTaskCard(card.id, statePath);
|
|
344
|
+
const moveId = {
|
|
345
|
+
decision: asId(rows.find((row) => row.event === 'pipeline-node-exit' && row.data.node === 'next-move' && row.data.runId === runId)?.data.moveId),
|
|
346
|
+
edge: asId(rows.find((row) => row.event === 'graph-edge-taken' && row.data.from === 'next-move' && row.data.to === 'dispatch')?.data.moveId),
|
|
347
|
+
dispatch: asId(rows.find((row) => row.category === 'harness' && row.event === 'move-id-received')?.data.moveId),
|
|
348
|
+
consumed: asId(stored?.history.find((entry) => entry.event === RELAUNCH_LAUNCHED_EVENT && entry.runId === runId)?.moveId),
|
|
349
|
+
};
|
|
350
|
+
return {
|
|
351
|
+
injectionId, executorResult: move.executorResult, argv: argvs[0]!, moveId,
|
|
352
|
+
receipt: { command: FAULT_NEXTMOVE_GENERAL_COMMAND, injectionId, result: renderMoveIds(moveId) },
|
|
353
|
+
};
|
|
354
|
+
} finally {
|
|
355
|
+
off();
|
|
356
|
+
rmSync(root, { recursive: true, force: true });
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export function renderFaultNextmoveGeneralRelaunch(observation: FaultNextmoveGeneralObservation): string[] {
|
|
361
|
+
return [
|
|
362
|
+
'fault-nextmove-dispatch · 일반 재발사 · 층 L2 · 생산 recordTaskAgentShadowMove/executeNextAction/harness say 파서 직접 호출(발사·spawn 0)',
|
|
363
|
+
` receipt: command=${observation.receipt.command} ⊕ injectionId=${observation.receipt.injectionId} ⊕ result=${observation.receipt.result}`,
|
|
364
|
+
` 실행부 결과: ${observation.executorResult ?? '-'} · argv 꼬리: ${JSON.stringify(observation.argv.slice(-2))}`,
|
|
365
|
+
` ⓜ moveId: ${renderMoveIds(observation.moveId)}`,
|
|
366
|
+
];
|
|
367
|
+
}
|
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
// ② 원장 줄 pod-child-run ⊕ pod-child-evidence — self-implement-pod.ts 가 쓰는 꼴 그대로 appendRunLedgerEntry
|
|
11
11
|
// ③ classifyHarnessPodExit → recordHarnessPodStop(부모 stop) → recordClassifiedHarnessPodExit(incident) · harness-cli-command.ts
|
|
12
12
|
// 부모 출력 줄은 formatOrchestrateResultLine(운영 요약 줄) ⊕ extractPodFailureReason(운영 Pod 사유)로 만든다.
|
|
13
|
+
// ④ 처방 = AUTOHEAL_ACTION_BY_CLASS[stop.class](stop-autoheal.ts 표) — «런 계속(resume-from-salvage)» vs «정지(needs-owner)».
|
|
14
|
+
//
|
|
15
|
+
// 🔀 SCOPE-ESCAPE-AS-REFINE (2026-10-22 · 대표 «범위 밖 허용도 로직으로») — 정지 사유(삭제·보호 경로·상한) 없는 held 편집은
|
|
16
|
+
// scope-escape 가 아니라 newScope(«구현이 알려준 새 범위»)로 기록된다. 사례 셋:
|
|
17
|
+
// 'scope-escape' = 사유 없는 held(옛 정지 → 이제 계속) · 'scope-stop' = 삭제 사유 held(여전히 정지) · 'implementation-deficit' = held 없음.
|
|
13
18
|
// kubectl·Pod·네트워크는 없다. 쓰기는 임시 ELANOUS_STATE_DIR 하나에만 가고 끝에 지운다.
|
|
14
19
|
|
|
15
20
|
import { mkdtempSync, rmSync } from 'node:fs';
|
|
@@ -23,8 +28,9 @@ import { classifyHarnessPodExit, recordClassifiedHarnessPodExit, recordHarnessPo
|
|
|
23
28
|
import { readRunExits } from '../harness/harness-incidents.js';
|
|
24
29
|
import { appendRunLedgerEntry, loadRunLedger, runLedgerDir } from '../self-implement/run-ledger.js';
|
|
25
30
|
import { readRunStopRecord, type RunStopRecord } from '../self-implement/run-stop.js';
|
|
31
|
+
import { AUTOHEAL_ACTION_BY_CLASS, type AutohealAction } from '../self-implement/stop-autoheal.js';
|
|
26
32
|
|
|
27
|
-
export type ScopeEscapeLiftCase = 'scope-escape' | 'implementation-deficit';
|
|
33
|
+
export type ScopeEscapeLiftCase = 'scope-escape' | 'scope-stop' | 'implementation-deficit';
|
|
28
34
|
|
|
29
35
|
/** 두 입력이 공유하는 자식 끝 JSON 몸통 — `attachAbandonedClassification` 이 붙이는 분류 꼴 그대로. */
|
|
30
36
|
function childBase(): Record<string, unknown> {
|
|
@@ -55,6 +61,11 @@ export function scopeEscapeChildResult(): Record<string, unknown> {
|
|
|
55
61
|
return { ...childBase(), ...held };
|
|
56
62
|
}
|
|
57
63
|
|
|
64
|
+
/** 정지 사유가 있는 범위 이탈 — orchestrator decideScopeExpansion 이 삭제를 보고 held 한 끝 JSON(scopeStopReasons 한 칸 더). */
|
|
65
|
+
export function scopeStopChildResult(): Record<string, unknown> {
|
|
66
|
+
return { ...scopeEscapeChildResult(), scopeStopReasons: ['deletion'] };
|
|
67
|
+
}
|
|
68
|
+
|
|
58
69
|
/** 구현 결손 — held 편집 없이 같은 분류(implementation-deficit)로 멈춘 끝 JSON. */
|
|
59
70
|
export function implementationDeficitChildResult(): Record<string, unknown> {
|
|
60
71
|
return childBase();
|
|
@@ -74,6 +85,10 @@ export interface ScopeEscapeLiftObservation {
|
|
|
74
85
|
readonly stop: RunStopRecord | undefined;
|
|
75
86
|
/** recordClassifiedHarnessPodExit 가 incidents 에 쓴 한 줄. */
|
|
76
87
|
readonly incident: { reason: string; childEvidence?: PodChildEvidence } | undefined;
|
|
88
|
+
/** stop class 의 기본 처방(AUTOHEAL_ACTION_BY_CLASS) — needs-owner 면 정지, 아니면 런이 이어진다. */
|
|
89
|
+
readonly autohealAction: AutohealAction | undefined;
|
|
90
|
+
/** childEvidence.newScope — «구현이 알려준 새 범위»(정지 사유 없는 범위 밖 편집). */
|
|
91
|
+
readonly newScope: readonly string[] | undefined;
|
|
77
92
|
}
|
|
78
93
|
|
|
79
94
|
function withTempState<T>(fn: (root: string) => T): T {
|
|
@@ -91,7 +106,8 @@ function withTempState<T>(fn: (root: string) => T): T {
|
|
|
91
106
|
/** 한 자식 실패를 부모 기록 경로 전체에 흘리고 각 층의 필드를 돌려준다. */
|
|
92
107
|
export function simScopeEscapeLift(
|
|
93
108
|
which: ScopeEscapeLiftCase,
|
|
94
|
-
childResult: Record<string, unknown> = which === 'scope-escape' ? scopeEscapeChildResult()
|
|
109
|
+
childResult: Record<string, unknown> = which === 'scope-escape' ? scopeEscapeChildResult()
|
|
110
|
+
: which === 'scope-stop' ? scopeStopChildResult() : implementationDeficitChildResult(),
|
|
95
111
|
): ScopeEscapeLiftObservation {
|
|
96
112
|
const suffix = randomBytes(4).toString('hex');
|
|
97
113
|
const runId = `run-sim-scope-lift-${suffix}`;
|
|
@@ -121,6 +137,7 @@ export function simScopeEscapeLift(
|
|
|
121
137
|
const ledger = loadRunLedger(runId, dir) ?? [];
|
|
122
138
|
const stopEntry = ledger.find((entry) => entry.event === 'stop');
|
|
123
139
|
const incidentRow = readRunExits(root).find((row) => row.runId === runId);
|
|
140
|
+
const stop = stopEntry ? readRunStopRecord(stopEntry) : undefined;
|
|
124
141
|
return {
|
|
125
142
|
case: which,
|
|
126
143
|
disposition: {
|
|
@@ -130,9 +147,11 @@ export function simScopeEscapeLift(
|
|
|
130
147
|
childEvidence,
|
|
131
148
|
ledgerChildEvidence: ledger.find((entry) => entry.event === 'pod-child-evidence')?.data.childEvidence,
|
|
132
149
|
parentExitReason: classified.reason,
|
|
133
|
-
stop
|
|
150
|
+
stop,
|
|
134
151
|
incident: incidentRow ? { reason: incidentRow.reason,
|
|
135
152
|
...(incidentRow.childEvidence ? { childEvidence: incidentRow.childEvidence } : {}) } : undefined,
|
|
153
|
+
autohealAction: stop ? AUTOHEAL_ACTION_BY_CLASS[stop.class] : undefined,
|
|
154
|
+
newScope: childEvidence?.newScope,
|
|
136
155
|
};
|
|
137
156
|
});
|
|
138
157
|
}
|
|
@@ -140,6 +159,8 @@ export function simScopeEscapeLift(
|
|
|
140
159
|
export interface ScopeEscapeLiftPair {
|
|
141
160
|
readonly scopeEscape: ScopeEscapeLiftObservation;
|
|
142
161
|
readonly implementationDeficit: ScopeEscapeLiftObservation;
|
|
162
|
+
/** 정지 사유(삭제) 있는 범위 이탈 — 비교 밖 · 정지가 남아 있음을 같은 화면에 보인다. */
|
|
163
|
+
readonly scopeStop: ScopeEscapeLiftObservation;
|
|
143
164
|
/** 두 결과가 갈린 칸(고정 순서). */
|
|
144
165
|
readonly differingFields: readonly string[];
|
|
145
166
|
/** 두 결과가 같은 칸(고정 순서). */
|
|
@@ -152,23 +173,27 @@ const COMPARED: ReadonlyArray<readonly [string, (o: ScopeEscapeLiftObservation)
|
|
|
152
173
|
['childEvidence.classification', (o) => o.childEvidence?.classification],
|
|
153
174
|
['childEvidence.scopeEscape', (o) => o.childEvidence?.scopeEscape],
|
|
154
175
|
['childEvidence.outOfScopeEdits', (o) => o.childEvidence?.outOfScopeEdits],
|
|
176
|
+
['childEvidence.newScope', (o) => o.childEvidence?.newScope],
|
|
155
177
|
['childEvidence.detail', (o) => o.childEvidence?.detail],
|
|
156
178
|
['parentExitReason', (o) => o.parentExitReason],
|
|
157
179
|
['stop.class', (o) => o.stop?.class],
|
|
158
|
-
|
|
180
|
+
// 무작위 Job 이름 접미는 비교에서 뺀다 — 같은 사유가 Job 이름 때문에 «갈렸다» 고 읽히지 않게.
|
|
181
|
+
['stop.cause', (o) => o.stop?.cause.replace(/si-sim-scope-lift-[0-9a-f]+/g, 'si-sim-scope-lift-*')],
|
|
159
182
|
['incident.reason', (o) => o.incident?.reason],
|
|
183
|
+
['autohealAction', (o) => o.autohealAction],
|
|
160
184
|
];
|
|
161
185
|
|
|
162
186
|
/** 두 입력을 나란히 흘리고 갈린 칸을 센다. */
|
|
163
187
|
export function simScopeEscapeLiftPair(): ScopeEscapeLiftPair {
|
|
164
188
|
const scopeEscape = simScopeEscapeLift('scope-escape');
|
|
165
189
|
const implementationDeficit = simScopeEscapeLift('implementation-deficit');
|
|
190
|
+
const scopeStop = simScopeEscapeLift('scope-stop');
|
|
166
191
|
const differingFields: string[] = [];
|
|
167
192
|
const sameFields: string[] = [];
|
|
168
193
|
for (const [name, read] of COMPARED) {
|
|
169
194
|
(JSON.stringify(read(scopeEscape)) === JSON.stringify(read(implementationDeficit)) ? sameFields : differingFields).push(name);
|
|
170
195
|
}
|
|
171
|
-
return { scopeEscape, implementationDeficit, differingFields, sameFields };
|
|
196
|
+
return { scopeEscape, implementationDeficit, scopeStop, differingFields, sameFields };
|
|
172
197
|
}
|
|
173
198
|
|
|
174
199
|
/** CLI·시험 출력 한 화면 — 두 분류 원문을 나란히. */
|
|
@@ -176,10 +201,12 @@ export function renderScopeEscapeLift(pair: ScopeEscapeLiftPair): string[] {
|
|
|
176
201
|
const row = (o: ScopeEscapeLiftObservation): string =>
|
|
177
202
|
` ${o.case} · classification=${o.childEvidence?.classification ?? '-'} · scopeEscape=${String(o.childEvidence?.scopeEscape ?? '-')}`
|
|
178
203
|
+ ` · exit=${o.parentExitReason} · stop=${o.stop?.class ?? '-'} · incident=${o.incident?.reason ?? '-'}`
|
|
179
|
-
+ ` · failureClassification=${o.disposition.failureClassification ?? '-'}
|
|
204
|
+
+ ` · failureClassification=${o.disposition.failureClassification ?? '-'}`
|
|
205
|
+
+ ` · newScope=${o.newScope ? JSON.stringify(o.newScope) : '-'} · autoheal=${o.autohealAction ?? '-'}`;
|
|
180
206
|
return [
|
|
181
207
|
'scope-escape-lift · 층 L1 · 운영 함수 직접 호출(kubectl·네트워크 0)',
|
|
182
208
|
row(pair.scopeEscape),
|
|
209
|
+
row(pair.scopeStop),
|
|
183
210
|
row(pair.implementationDeficit),
|
|
184
211
|
` 다른 칸: ${pair.differingFields.join(', ') || '없음'}`,
|
|
185
212
|
` 같은 칸: ${pair.sameFields.join(', ') || '없음'}`,
|