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
|
@@ -5,7 +5,7 @@ import { opSeatStatePath, readTrafficSignal } from '../seat-loop/traffic-signal.
|
|
|
5
5
|
|
|
6
6
|
const SEATS = ['OP', 'MK', 'TC', 'UX'] as const;
|
|
7
7
|
type Seat = typeof SEATS[number];
|
|
8
|
-
export type HygieneCell = { id: string; owner?: string | null; status: string };
|
|
8
|
+
export type HygieneCell = { id: string; owner?: string | null; status: string; title?: string };
|
|
9
9
|
export type HygieneNotice = { to: Seat; key: string; body: string };
|
|
10
10
|
export type HygieneDeps = {
|
|
11
11
|
root: string;
|
|
@@ -45,7 +45,7 @@ export function starvingCycles(log: string): { reasons: Record<string, number> }
|
|
|
45
45
|
return { reasons };
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
type HoldMeta = { id?: unknown; op?: unknown; reason?: unknown; until?: unknown };
|
|
48
|
+
type HoldMeta = { id?: unknown; op?: unknown; reason?: unknown; until?: unknown; kind?: unknown; confirmedAt?: unknown; at?: unknown; title?: unknown };
|
|
49
49
|
function holdMetadata(path: string): Map<string, HoldMeta> {
|
|
50
50
|
const latest = new Map<string, HoldMeta>();
|
|
51
51
|
for (const line of (readOptional(path) ?? '').split(/\r?\n/)) {
|
|
@@ -65,6 +65,10 @@ function untilTime(value: unknown): number | null {
|
|
|
65
65
|
return Number.isFinite(time) ? time : null;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
function confirmedTime(value: unknown): number | null {
|
|
69
|
+
return typeof value === 'string' && /^\d{12}$/.test(value) ? untilTime(value) : null;
|
|
70
|
+
}
|
|
71
|
+
|
|
68
72
|
export function inspectHoldHygiene(deps: HygieneDeps): HygieneNotice[] {
|
|
69
73
|
const notices: HygieneNotice[] = [];
|
|
70
74
|
const dir = deps.dispatcherDir ?? opSeatStatePath('feeder');
|
|
@@ -88,11 +92,25 @@ export function inspectHoldHygiene(deps: HygieneDeps): HygieneNotice[] {
|
|
|
88
92
|
if (!SEATS.some(seat => seat === owner)) continue;
|
|
89
93
|
const meta = metadata.get(cell.id);
|
|
90
94
|
const reason = meta?.op === 'add' && typeof meta.reason === 'string' ? meta.reason.trim() : '';
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
let attention = '';
|
|
96
|
+
if (meta?.kind === '손작업') {
|
|
97
|
+
const confirmed = confirmedTime(meta.confirmedAt ?? meta.at);
|
|
98
|
+
if (confirmed === null) attention = '재확인 시각 없음';
|
|
99
|
+
else if (deps.now.getTime() - confirmed >= 24 * 60 * 60_000) attention = '24h 재확인 지연';
|
|
100
|
+
} else if (meta?.kind === '재발사금지') {
|
|
101
|
+
if (typeof meta.title !== 'string' || !meta.title || typeof cell.title !== 'string' || !cell.title) attention = '제목 기준 확인 불가';
|
|
102
|
+
else if (cell.title !== meta.title) attention = '칸 제목 변경';
|
|
103
|
+
} else if (meta?.kind === '선행대기' || meta?.kind === undefined || meta?.kind === '') {
|
|
104
|
+
const expiry = untilTime(meta?.until);
|
|
105
|
+
if (expiry === null) attention = 'until 확인 불가';
|
|
106
|
+
else if (expiry <= deps.now.getTime()) attention = `until ${String(meta?.until)} 지남`;
|
|
107
|
+
} else attention = 'hold 종류 확인 불가';
|
|
108
|
+
if (reason && !attention) continue;
|
|
109
|
+
const guidance = meta?.kind === '손작업' ? '재확인 시각·사유를 판단해 OP에 알려 주세요.'
|
|
110
|
+
: meta?.kind === '재발사금지' ? '칸 제목과 기준 제목·사유를 대조해 OP에 알려 주세요.'
|
|
111
|
+
: '풀기/유지(사유·until)를 판단해 OP에 알려 주세요.';
|
|
94
112
|
notices.push({ to: owner as Seat, key: `hold:${cell.id}:${owner}`,
|
|
95
|
-
body: `노랑 칸 ${cell.id} traffic hold: ${!reason ? '사유 없음' : `사유 ${reason}`} ${
|
|
113
|
+
body: `노랑 칸 ${cell.id} traffic hold: ${!reason ? '사유 없음' : `사유 ${reason}`} ${attention ? `· ${attention}` : ''}. ${guidance} 자동 해제하지 않습니다.` });
|
|
96
114
|
}
|
|
97
115
|
return notices;
|
|
98
116
|
}
|
|
@@ -63,8 +63,16 @@ function defaultStampPath(): string {
|
|
|
63
63
|
function readStamp(path: string): string | null {
|
|
64
64
|
try {
|
|
65
65
|
const value = (JSON.parse(readFileSync(path, 'utf8')) as { startedAt?: unknown }).startedAt;
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
if (typeof value !== 'string' || !Number.isFinite(Date.parse(value))) {
|
|
67
|
+
throw new Error(`invalid steward stamp startedAt: ${path}`);
|
|
68
|
+
}
|
|
69
|
+
return value;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
// A missing stamp is the first tick. A corrupt or unreadable existing stamp is not:
|
|
72
|
+
// claiming it would overwrite the evidence and could launch an overlapping rejudge.
|
|
73
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return null;
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
68
76
|
}
|
|
69
77
|
|
|
70
78
|
/** Same universe as this process (env inherited) · same installed version (entry next to this module). */
|
|
@@ -7,6 +7,7 @@ import { acquireLockSync } from '../storage/file-lock.js';
|
|
|
7
7
|
import { subscribeInsideEvent, type InsideLiveEvent } from '../nexus/api/inside-events.js';
|
|
8
8
|
import type { NexusEventBus } from '../nexus/api/event-bus.js';
|
|
9
9
|
import { parseRepairWorkerResult } from '../task-agent/repair-worker.js';
|
|
10
|
+
import { pairMoveId } from '../task-agent/repair-next-move.js';
|
|
10
11
|
import { readTaskCard, taskAgentStatePath } from '../task-agent/task-hand.js';
|
|
11
12
|
|
|
12
13
|
const SHA40 = /^[0-9a-f]{40}$/i;
|
|
@@ -17,6 +18,8 @@ const OUTPUT_LIMIT = 1024 * 1024;
|
|
|
17
18
|
export interface TaRepairCompleted {
|
|
18
19
|
kind: 'ta.repair.completed'; schema: 1; card: string; pr: number; head: string;
|
|
19
20
|
runId: string; resultPath: string; completedAt: string;
|
|
21
|
+
/** HARNESS-FULL-GRAPH-NEXTMOVE — worker 가 받은 수 id(옛 worker 는 없다 · 꼴이 틀려도 사건을 버리지 않고 짝짓기에서 «못 짝지음»으로 남긴다). */
|
|
22
|
+
moveId?: string;
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
export function parseTaRepairCompleted(value: unknown): TaRepairCompleted | null {
|
|
@@ -102,14 +105,22 @@ export async function collectTaRepairCompleted(input: unknown, deps: TaRepairCol
|
|
|
102
105
|
let card;
|
|
103
106
|
try { card = readTaskCard(event.card, statePath); } catch { emit('deferred', { reason: 'card unreadable' }); return 'deferred'; }
|
|
104
107
|
const repair = Array.isArray(card?.repairs) ? card.repairs.find(entry => entry && typeof entry === 'object' && entry.runId === event.runId) : undefined;
|
|
108
|
+
// NEXTMOVE-GENERAL-RELAUNCH-MOVEID — 사건의 수 id 를 카드(발사 순간 적은 값)와 짝짓는다. 결과는 관측 칸에만 싣는다(fail-soft · 수거 판단은 그대로).
|
|
109
|
+
const observedMoveId: unknown = (event as { moveId?: unknown }).moveId;
|
|
110
|
+
const pairing = pairMoveId(repair?.moveId, observedMoveId);
|
|
111
|
+
const moveFields: Record<string, unknown> = pairing.kind === 'legacy' ? {}
|
|
112
|
+
: { moveId: pairing.kind === 'paired' ? pairing.moveId : typeof observedMoveId === 'string' ? observedMoveId : null,
|
|
113
|
+
moveIdPaired: pairing.kind === 'paired', ...(pairing.kind === 'unpaired' ? { expectedMoveId: pairing.expected } : {}) };
|
|
114
|
+
const emitPaired = (outcome: string, extra: Record<string, unknown> = {}) => emit(outcome, { ...moveFields, ...extra });
|
|
105
115
|
if (!repair || repair.pr !== event.pr || typeof repair.head !== 'string' || repair.head.toLowerCase() !== event.head.toLowerCase()
|
|
106
116
|
|| typeof repair.resultPath !== 'string' || !repair.resultPath.startsWith('/')
|
|
117
|
+
// 카드 귀속이 안 맞는 사건엔 짝짓기 칸을 싣지 않는다 — 남의 수리와 대조한 값이 관측에 섞이지 않게(r1 should-fix).
|
|
107
118
|
|| resolve(repair.resultPath) !== resolve(event.resultPath)) { emit('invalid', { reason: 'event differs from card binding' }); return 'invalid'; }
|
|
108
|
-
if (repair.status !== 'requested') {
|
|
119
|
+
if (repair.status !== 'requested') { emitPaired('duplicate', { reason: `repair ${repair.status}` }); return 'duplicate'; }
|
|
109
120
|
let result;
|
|
110
121
|
try { result = parseRepairWorkerResult((deps.read ?? ((path) => readFileSync(path, 'utf8')))(repair.resultPath), event.pr, event.head, event.runId); }
|
|
111
122
|
catch { /* periodic tick can recover a missing result */ }
|
|
112
|
-
if (!result) {
|
|
123
|
+
if (!result) { emitPaired('deferred', { reason: 'worker result missing or invalid' }); return 'deferred'; }
|
|
113
124
|
|
|
114
125
|
// Existing PID-aware lock recovers a dead daemon without making later events wait forever.
|
|
115
126
|
// A live holder keeps the lock through the child process; the card CAS covers periodic-tick races.
|
|
@@ -119,25 +130,25 @@ export async function collectTaRepairCompleted(input: unknown, deps: TaRepairCol
|
|
|
119
130
|
mkdirSync(dirname(lock), { recursive: true });
|
|
120
131
|
release = acquireLockSync(lock, { breakDeadHolder: true, staleMs: TIMEOUT_MS + 60_000, maxTries: 2 });
|
|
121
132
|
}
|
|
122
|
-
catch {
|
|
133
|
+
catch { emitPaired('deferred', { reason: 'collector busy; periodic fallback remains' }); return 'deferred'; }
|
|
123
134
|
try {
|
|
124
135
|
// Recheck after claiming: another collector or the periodic tick may have consumed the file.
|
|
125
136
|
const current = readTaskCard(event.card, statePath);
|
|
126
137
|
const latest = Array.isArray(current?.repairs) ? current.repairs.find(entry => entry && typeof entry === 'object' && entry.runId === event.runId) : undefined;
|
|
127
138
|
if (!latest || latest.status !== 'requested' || latest.pr !== event.pr || typeof latest.head !== 'string'
|
|
128
139
|
|| latest.head.toLowerCase() !== event.head.toLowerCase() || typeof latest.resultPath !== 'string'
|
|
129
|
-
|| !latest.resultPath.startsWith('/') || resolve(latest.resultPath) !== resolve(event.resultPath)) {
|
|
140
|
+
|| !latest.resultPath.startsWith('/') || resolve(latest.resultPath) !== resolve(event.resultPath)) { emitPaired('duplicate'); return 'duplicate'; }
|
|
130
141
|
const child = await (deps.run ?? ((card) => defaultRun(card, statePath, deps.cliBin)))(event.card);
|
|
131
142
|
const after = readTaskCard(event.card, statePath)?.repairs?.find(entry => entry.runId === event.runId);
|
|
132
143
|
const consumed = child.code === 0 && !child.truncated && after?.status !== 'requested' && after !== undefined
|
|
133
144
|
&& childConsumedRepair(child.output, event);
|
|
134
145
|
const outcome = consumed ? 'collected' : child.truncated ? 'deferred' : after && after.status !== 'requested' ? 'duplicate' : 'deferred';
|
|
135
|
-
|
|
146
|
+
emitPaired(outcome, { rc: child.code, repairStatus: after?.status,
|
|
136
147
|
...(child.truncated ? { reason: 'rejudge output exceeded 1 MiB; event attribution unmeasured' } : {}),
|
|
137
148
|
detail: child.output.slice(-300) });
|
|
138
149
|
return consumed ? 'collected' : outcome === 'duplicate' ? 'duplicate' : 'deferred';
|
|
139
150
|
} catch (error) {
|
|
140
|
-
|
|
151
|
+
emitPaired('deferred', { reason: String(error).slice(-300) });
|
|
141
152
|
return 'deferred';
|
|
142
153
|
} finally { release(); }
|
|
143
154
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
|
+
import { appendFileSync, mkdirSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
2
4
|
import { debug } from '../debug/log.js';
|
|
3
5
|
import type { TriageDecision, TriageIssue } from './triage.js';
|
|
4
6
|
import { InvalidWorkingBackwardsDraft } from './working-backwards.js';
|
|
@@ -187,3 +189,195 @@ export async function draftWithinBudget<T>({ wishes, draft, concurrency = 4, per
|
|
|
187
189
|
debug.log('steward.triage', 'draft-budget', stats);
|
|
188
190
|
return { ...result, stats };
|
|
189
191
|
}
|
|
192
|
+
|
|
193
|
+
/** Consecutive healthy shadow ticks before a live move is safe to record. */
|
|
194
|
+
export const LIVE_AFTER_TICKS = 3;
|
|
195
|
+
|
|
196
|
+
/** Reasons a decision is a placeholder, not a judgment — they must never be reused as if they were fresh. */
|
|
197
|
+
const TEMPORARY_WHYS = ['triage deferred — deadline', 'triage judgment timed out — human review',
|
|
198
|
+
'triage judgment unavailable — human review'];
|
|
199
|
+
|
|
200
|
+
export function isTemporaryDecision(decision: TriageDecision): boolean {
|
|
201
|
+
return decision.rung === 'hitl' && decision.hitlReason === 'other' && TEMPORARY_WHYS.includes(decision.why);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export interface TriageTickCycle {
|
|
205
|
+
/** sha256 of this tick's sorted issue identifiers — the batch fingerprint. */
|
|
206
|
+
key: string;
|
|
207
|
+
/** Consecutive ticks (this one included) that carried the same fingerprint. */
|
|
208
|
+
ticks: number;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export interface TriageTickBudget {
|
|
212
|
+
cycle: TriageTickCycle;
|
|
213
|
+
deadlineMs: number;
|
|
214
|
+
perIssueMs: number;
|
|
215
|
+
concurrency: number;
|
|
216
|
+
/** `repeat-tick` when the same batch already arrived in the previous tick. */
|
|
217
|
+
basis: 'first-tick' | 'repeat-tick';
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export type TriageItemOutcome = 'reused' | 'judged' | 'timed-out' | 'unavailable' | 'deferred';
|
|
221
|
+
|
|
222
|
+
export interface TriageItemEvent {
|
|
223
|
+
/** 1-based position of the issue in this tick's batch. */
|
|
224
|
+
index: number;
|
|
225
|
+
/** Which tick cycle the item was judged in. */
|
|
226
|
+
cycle: number;
|
|
227
|
+
issue: string;
|
|
228
|
+
outcome: TriageItemOutcome;
|
|
229
|
+
/** No fresh judgment backs this item — the next tick (or a human) must pick it up. */
|
|
230
|
+
degraded: boolean;
|
|
231
|
+
why: string;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export interface TriageItemMetrics {
|
|
235
|
+
items: number;
|
|
236
|
+
fresh: number;
|
|
237
|
+
reused: number;
|
|
238
|
+
degraded: number;
|
|
239
|
+
byOutcome: Record<TriageItemOutcome, number>;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export interface TriageTickHealth {
|
|
243
|
+
degraded: string[];
|
|
244
|
+
/** Degraded last tick, freshly judged this tick. */
|
|
245
|
+
healed: string[];
|
|
246
|
+
health: 'healthy' | 'healing' | 'degraded';
|
|
247
|
+
/** Consecutive non-degraded shadow ticks. */
|
|
248
|
+
liveStreak: number;
|
|
249
|
+
/** Shadow has stayed healthy long enough that a live move is safe; the mode itself is not flipped here. */
|
|
250
|
+
liveEligible: boolean;
|
|
251
|
+
transition?: 'shadow→live' | 'live→shadow';
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export interface TriageTickRecord extends TriageTickHealth {
|
|
255
|
+
at: string;
|
|
256
|
+
mode: string;
|
|
257
|
+
key: string;
|
|
258
|
+
ticks: number;
|
|
259
|
+
issues: number;
|
|
260
|
+
deadlineMs: number;
|
|
261
|
+
perIssueMs: number;
|
|
262
|
+
concurrency: number;
|
|
263
|
+
reused: number;
|
|
264
|
+
judged: number;
|
|
265
|
+
timedOut: number;
|
|
266
|
+
deferred: number;
|
|
267
|
+
events: TriageItemEvent[];
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export function triageTickKey(issues: TriageIssue[]): string {
|
|
271
|
+
return createHash('sha256').update(JSON.stringify(issues.map(issue => issue.identifier).sort())).digest('hex').slice(0, 16);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** The tick cycle: a batch that keeps re-arriving is the same cycle, counted up; a changed batch starts at 1. */
|
|
275
|
+
export function triageTickCycle(previous: Pick<TriageTickRecord, 'key' | 'ticks'> | undefined, key: string): TriageTickCycle {
|
|
276
|
+
const ticks = previous && previous.key === key && Number.isFinite(previous.ticks) ? Math.max(1, previous.ticks) + 1 : 1;
|
|
277
|
+
return { key, ticks };
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Budget derived from the tick cycle: the stage deadline is fixed per tick, but a repeat cycle widens each issue's
|
|
282
|
+
* slice (up to 3×) instead of re-running the same timeout on the batch that already ran out of window last tick.
|
|
283
|
+
*/
|
|
284
|
+
export function triageTickBudget({ cycle, issueCount, deadlineMs = 240_000, basePerIssueMs = 90_000, maxConcurrency = 8 }: {
|
|
285
|
+
cycle: TriageTickCycle;
|
|
286
|
+
issueCount: number;
|
|
287
|
+
deadlineMs?: number;
|
|
288
|
+
basePerIssueMs?: number;
|
|
289
|
+
maxConcurrency?: number;
|
|
290
|
+
}): TriageTickBudget {
|
|
291
|
+
const count = Math.max(1, Math.floor(issueCount));
|
|
292
|
+
const concurrency = Math.max(1, Math.min(Math.max(1, Math.floor(maxConcurrency)), count));
|
|
293
|
+
const stretch = Math.min(Math.max(1, Math.floor(cycle.ticks)), 3);
|
|
294
|
+
return { cycle, deadlineMs, perIssueMs: Math.min(deadlineMs, basePerIssueMs * stretch), concurrency,
|
|
295
|
+
basis: cycle.ticks > 1 ? 'repeat-tick' : 'first-tick' };
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/** One event per item: what actually happened to it this tick and whether that leaves it degraded. */
|
|
299
|
+
export function triageItemEvents({ cycle, issues, decisions, previous = [] }: {
|
|
300
|
+
cycle: TriageTickCycle;
|
|
301
|
+
issues: TriageIssue[];
|
|
302
|
+
decisions: Array<TriageDecision & { inputHash?: string; deferred?: true }>;
|
|
303
|
+
previous?: Array<TriageDecision & { inputHash?: string }>;
|
|
304
|
+
}): TriageItemEvent[] {
|
|
305
|
+
const judged = new Map(decisions.map(decision => [decision.issue, decision]));
|
|
306
|
+
const earlier = new Map(previous.map(decision => [decision.issue, decision]));
|
|
307
|
+
const events: TriageItemEvent[] = [];
|
|
308
|
+
for (const [index, issue] of issues.entries()) {
|
|
309
|
+
const decision = judged.get(issue.identifier);
|
|
310
|
+
const before = earlier.get(issue.identifier);
|
|
311
|
+
let outcome: TriageItemOutcome;
|
|
312
|
+
if (!decision) outcome = 'unavailable';
|
|
313
|
+
else if (decision.deferred === true) outcome = 'deferred';
|
|
314
|
+
else if (decision.why === 'triage judgment timed out — human review') outcome = 'timed-out';
|
|
315
|
+
else if (decision.why === 'triage judgment unavailable — human review') outcome = 'unavailable';
|
|
316
|
+
else if (before && before.inputHash !== undefined && before.inputHash === decision.inputHash &&
|
|
317
|
+
!before.deferred && !isTemporaryDecision(before)) outcome = 'reused';
|
|
318
|
+
else outcome = 'judged';
|
|
319
|
+
events.push({ index: index + 1, cycle: cycle.ticks, issue: issue.identifier, outcome,
|
|
320
|
+
degraded: outcome !== 'judged' && outcome !== 'reused',
|
|
321
|
+
why: decision?.why ?? 'triage decision missing' });
|
|
322
|
+
}
|
|
323
|
+
return events;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export function triageItemMetrics(events: TriageItemEvent[]): TriageItemMetrics {
|
|
327
|
+
const byOutcome: Record<TriageItemOutcome, number> = { reused: 0, judged: 0, 'timed-out': 0, unavailable: 0, deferred: 0 };
|
|
328
|
+
for (const event of events) byOutcome[event.outcome]++;
|
|
329
|
+
const reused = byOutcome.reused;
|
|
330
|
+
return { items: events.length, fresh: byOutcome.judged, reused,
|
|
331
|
+
degraded: events.filter(event => event.degraded).length, byOutcome };
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/** Healing and the shadow→live transition, read off the previous real tick — never off an assumed one. */
|
|
335
|
+
export function triageTickHealth({ previous, mode, events }: {
|
|
336
|
+
previous?: Pick<TriageTickRecord, 'mode' | 'degraded' | 'liveStreak'>;
|
|
337
|
+
mode: string;
|
|
338
|
+
events: TriageItemEvent[];
|
|
339
|
+
}): TriageTickHealth {
|
|
340
|
+
const degraded = events.filter(event => event.degraded).map(event => event.issue);
|
|
341
|
+
const healed = (previous?.degraded ?? []).filter(issue => !degraded.includes(issue)).sort();
|
|
342
|
+
const health = healed.length ? 'healing' : degraded.length ? 'degraded' : 'healthy';
|
|
343
|
+
// Any degradation still present this tick resets the streak — a healed item next to a degraded one is not a healthy tick.
|
|
344
|
+
const liveStreak = mode === 'shadow' ? (degraded.length ? 0 : (previous?.mode === 'shadow' ? previous.liveStreak + 1 : 1)) : 0;
|
|
345
|
+
const transition = previous && previous.mode !== mode
|
|
346
|
+
? (mode === 'live' && previous.mode === 'shadow' ? 'shadow→live'
|
|
347
|
+
: mode === 'shadow' && previous.mode === 'live' ? 'live→shadow' : undefined)
|
|
348
|
+
: undefined;
|
|
349
|
+
return { degraded, healed, health, liveStreak, liveEligible: mode === 'shadow' && liveStreak >= LIVE_AFTER_TICKS,
|
|
350
|
+
...(transition ? { transition } : {}) };
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export function triageTickLedgerPath(root: string): string {
|
|
354
|
+
return join(root, 'steward', 'triage-ticks.jsonl');
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/** The real ticks that already ran, oldest first. A torn line is not a tick. */
|
|
358
|
+
export function readTriageTicks(root: string, limit = 24): TriageTickRecord[] {
|
|
359
|
+
let text: string;
|
|
360
|
+
try { text = readFileSync(triageTickLedgerPath(root), 'utf8'); } catch { return []; }
|
|
361
|
+
const records: TriageTickRecord[] = [];
|
|
362
|
+
for (const line of text.split('\n')) {
|
|
363
|
+
if (!line.trim()) continue;
|
|
364
|
+
try {
|
|
365
|
+
const parsed: unknown = JSON.parse(line);
|
|
366
|
+
if (parsed && typeof parsed === 'object' && typeof (parsed as { mode?: unknown }).mode === 'string' &&
|
|
367
|
+
typeof (parsed as { key?: unknown }).key === 'string' && typeof (parsed as { ticks?: unknown }).ticks === 'number' &&
|
|
368
|
+
Array.isArray((parsed as { degraded?: unknown }).degraded) && Array.isArray((parsed as { events?: unknown }).events)) {
|
|
369
|
+
records.push(parsed as TriageTickRecord);
|
|
370
|
+
}
|
|
371
|
+
} catch { /* torn line */ }
|
|
372
|
+
}
|
|
373
|
+
return records.slice(-Math.max(1, limit));
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export function appendTriageTick(root: string, record: TriageTickRecord): void {
|
|
377
|
+
try {
|
|
378
|
+
mkdirSync(join(root, 'steward'), { recursive: true });
|
|
379
|
+
appendFileSync(triageTickLedgerPath(root), `${JSON.stringify(record)}\n`);
|
|
380
|
+
} catch (error) {
|
|
381
|
+
debug.log('steward.triage', 'tick-ledger-failed', { reason: String(error) }, { level: 'warn' });
|
|
382
|
+
}
|
|
383
|
+
}
|
package/src/steward/triage.ts
CHANGED
|
@@ -130,7 +130,7 @@ export function trackTablePrompt(tracks?: Record<string, string>): string {
|
|
|
130
130
|
return `\n담당 트랙(owner) — 아래 중 하나(${keys.map(k => JSON.stringify(k)).join('|')}) · 이슈가 어느 트랙 일인지:\n${keys.map(k => `- ${k}: ${tracks[k]}`).join('\n')}`;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
export async function triageIssues(issues: TriageIssue[], judge?: NonNullable<StewardDeps['judge']>, decide: typeof emitDecision = emitDecision, tracks?: Record<string, string>, previous: Array<TriageDecision & { inputHash?: string }> = [], ask: StewardAsk = askSteward): Promise<TriageDecision[]> {
|
|
133
|
+
export async function triageIssues(issues: TriageIssue[], judge?: NonNullable<StewardDeps['judge']>, decide: typeof emitDecision = emitDecision, tracks?: Record<string, string>, previous: Array<TriageDecision & { inputHash?: string }> = [], ask: StewardAsk = askSteward, budget?: { deadlineMs: number; perIssueMs: number; concurrency: number }): Promise<TriageDecision[]> {
|
|
134
134
|
const started = judge ? 0 : Date.now();
|
|
135
135
|
const classified: ClassifiedIssue[] = [];
|
|
136
136
|
const classifiedIds = new Set<string>();
|
|
@@ -144,7 +144,7 @@ export async function triageIssues(issues: TriageIssue[], judge?: NonNullable<St
|
|
|
144
144
|
decide({ kind: result.rung === 'hitl' ? 'ESCALATE' : 'ROUTE', what: result.issue, reason: result.why,
|
|
145
145
|
purpose: 'steward triage', target: result.owner ? `${result.rung} · ${result.owner}` : String(result.rung), refs: { issue: result.issue } });
|
|
146
146
|
};
|
|
147
|
-
const { decisions } = await triageWithinBudget({ issues, previous, tracks, judge: async (issue, observedIssues) => {
|
|
147
|
+
const { decisions } = await triageWithinBudget({ issues, previous, tracks, ...(budget ?? {}), judge: async (issue, observedIssues) => {
|
|
148
148
|
try {
|
|
149
149
|
if (judge) return parseJudgment(issue, await judge(issue, observedIssues ?? issues, tracks), tracks);
|
|
150
150
|
const byRule = ruleJudgment(issue, observedIssues ?? issues);
|
|
@@ -487,7 +487,24 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
|
|
|
487
487
|
Array.isArray(item.dependsOn) && item.dependsOn.every((dep: unknown) => typeof dep === 'string') &&
|
|
488
488
|
typeof item.priority === 'number' && Number.isFinite(item.priority) && typeof item.why === 'string')) previous = parsed;
|
|
489
489
|
} catch { /* Missing or corrupt previous judgments are an empty cache. */ }
|
|
490
|
-
|
|
490
|
+
const { appendTriageTick, readTriageTicks, triageItemEvents, triageItemMetrics, triageTickBudget, triageTickCycle,
|
|
491
|
+
triageTickHealth, triageTickKey } = await import('./triage-budget.js');
|
|
492
|
+
const ticks = readTriageTicks(root);
|
|
493
|
+
const cycle = triageTickCycle(ticks.at(-1), triageTickKey(issues));
|
|
494
|
+
const budget = triageTickBudget({ cycle, issueCount: issues.length });
|
|
495
|
+
const decisions = await triageIssues(issues, judge, deps.decide, settings.tracks, previous, deps.ask, budget);
|
|
496
|
+
writeFileSync(judgments, JSON.stringify(decisions));
|
|
497
|
+
const events = triageItemEvents({ cycle, issues, decisions, previous });
|
|
498
|
+
const metrics = triageItemMetrics(events);
|
|
499
|
+
const mode = settings.mode ?? 'shadow';
|
|
500
|
+
const health = triageTickHealth({ previous: ticks.at(-1), mode, events });
|
|
501
|
+
for (const event of events) debug.log('steward.triage', 'item-event', { ...event, health: health.health });
|
|
502
|
+
debug.log('steward.triage', 'tick', { cycle, basis: budget.basis, perIssueMs: budget.perIssueMs,
|
|
503
|
+
concurrency: budget.concurrency, ...metrics, ...health });
|
|
504
|
+
appendTriageTick(root, { at: new Date().toISOString(), mode, key: cycle.key, ticks: cycle.ticks, issues: issues.length,
|
|
505
|
+
deadlineMs: budget.deadlineMs, perIssueMs: budget.perIssueMs, concurrency: budget.concurrency,
|
|
506
|
+
reused: metrics.byOutcome.reused, judged: metrics.byOutcome.judged, timedOut: metrics.byOutcome['timed-out'],
|
|
507
|
+
deferred: metrics.byOutcome.deferred, ...health, events });
|
|
491
508
|
} else if (stage === 'schedule') {
|
|
492
509
|
const decisions = JSON.parse(readFileSync(judgments, 'utf8')) as TriageDecision[];
|
|
493
510
|
const pending = new Set(decisions.flatMap(decision => decision.dependsOn));
|
|
@@ -48,6 +48,8 @@ export interface NextAction {
|
|
|
48
48
|
cwd?: string;
|
|
49
49
|
risk?: 'money' | 'security' | 'irreversible-publication';
|
|
50
50
|
delivery?: { kind: DeliveryKind; worktreePath: string; projectTarget: string; files: string[] };
|
|
51
|
+
/** NEXTMOVE-GENERAL-RELAUNCH-MOVEID — 이 재발사를 고른 next-move 결정의 수 id(결정 순간 한 번 · 다시 만들지 않는다). 있으면 `harness say --move-id` 로 싣는다. */
|
|
52
|
+
moveId?: string;
|
|
51
53
|
}
|
|
52
54
|
export interface ActionDeps {
|
|
53
55
|
command(args: string[]): Promise<{ status: number; stdout: string; stderr?: string }>;
|
|
@@ -64,7 +66,7 @@ export interface ActionDeps {
|
|
|
64
66
|
releaseLanding?(day: string): void;
|
|
65
67
|
/** 실패 한 번을 잠금 안에서 디스크에 더한다(다른 프로세스의 실패를 덮지 않게) · 더한 뒤의 값을 돌려준다. */
|
|
66
68
|
incrementFailure?(key: string): number;
|
|
67
|
-
observe(event: 'task-agent.action', data:
|
|
69
|
+
observe(event: 'task-agent.action' | 'task-agent.entrance-denominator', data: ActionObservation): void;
|
|
68
70
|
/** 사다리 R4 — 실제로 할 재발사 수의 허용 목록(`taskAgent.liveMoves` 어휘). 없으면 종전 그대로(재발사에 목록 검사 없음) · 목록에 없는 수는 shadow. */
|
|
69
71
|
liveMoves?: ReadonlySet<string>;
|
|
70
72
|
/** 한 판단 회차의 발사 칸 — 호출부가 회차마다 새로 준다. 없으면 회당 상한 없음(종전). 발사를 시도할 때마다 `count` 가 오른다. */
|
|
@@ -76,6 +78,49 @@ export interface ActionDeps {
|
|
|
76
78
|
/** 재발사는 한 판단 회차에 한 건만 발사한다. */
|
|
77
79
|
export const RETRY_LAUNCHES_PER_CYCLE = 1;
|
|
78
80
|
|
|
81
|
+
export interface ActionObservation {
|
|
82
|
+
taskId: string;
|
|
83
|
+
kind: NextActionKind | 'entrance-tick';
|
|
84
|
+
result: string;
|
|
85
|
+
reason: string;
|
|
86
|
+
reviewed?: number;
|
|
87
|
+
allowed?: number;
|
|
88
|
+
refused?: number;
|
|
89
|
+
reasons?: Record<string, number>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface EntranceCandidateReview {
|
|
93
|
+
taskId: string;
|
|
94
|
+
kind: NextActionKind;
|
|
95
|
+
refusal?: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface EntranceTickCandidate {
|
|
99
|
+
action: NextAction;
|
|
100
|
+
refusal?: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface EntranceRefusalDenominator {
|
|
104
|
+
reviewed: number;
|
|
105
|
+
allowed: number;
|
|
106
|
+
refused: number;
|
|
107
|
+
reasons: Record<string, number>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Count a tick's candidate refusals without confusing special object keys with prototypes. */
|
|
111
|
+
export function buildEntranceRefusalDenominator(reviews: readonly EntranceCandidateReview[]): EntranceRefusalDenominator {
|
|
112
|
+
const reasonCounts = new Map<string, number>();
|
|
113
|
+
let refused = 0;
|
|
114
|
+
for (const review of reviews) {
|
|
115
|
+
const reason = typeof review.refusal === 'string' ? review.refusal.trim() : '';
|
|
116
|
+
if (!reason) continue;
|
|
117
|
+
refused += 1;
|
|
118
|
+
reasonCounts.set(reason, (reasonCounts.get(reason) ?? 0) + 1);
|
|
119
|
+
}
|
|
120
|
+
const reasons = Object.fromEntries(reasonCounts) as Record<string, number>;
|
|
121
|
+
return { reviewed: reviews.length, allowed: reviews.length - refused, refused, reasons };
|
|
122
|
+
}
|
|
123
|
+
|
|
79
124
|
/** live 인데도 shadow 로 내릴 사유 — 없으면 발사해도 된다(재발사 아닌 수는 늘 없다). 기다림(wait)은 발사가 아니라 부하·회당 상한을 보지 않는다. */
|
|
80
125
|
function retryShadowReason(action: NextAction, deps: ActionDeps): string | undefined {
|
|
81
126
|
if (action.kind !== 'retry') return undefined;
|
|
@@ -230,7 +275,7 @@ export async function executeNextAction(action: NextAction, deps: ActionDeps): P
|
|
|
230
275
|
return card('review verdict or must-fix unavailable');
|
|
231
276
|
}
|
|
232
277
|
// 여기 닿는 종류는 land · retry 둘뿐이다(green·decision·review 는 위에서 끝난다).
|
|
233
|
-
const args = action.kind === 'land' ? ['pr', 'land', '--cwd', action.cwd!] : ['harness', 'say', retryText(action)];
|
|
278
|
+
const args = action.kind === 'land' ? ['pr', 'land', '--cwd', action.cwd!] : ['harness', 'say', retryText(action), ...(action.moveId ? ['--move-id', action.moveId] : [])];
|
|
234
279
|
const day = deps.landingDay ?? new Date().toLocaleDateString('en-CA', { timeZone: 'Asia/Seoul' });
|
|
235
280
|
if (action.kind === 'retry' && deps.retryLaunches) deps.retryLaunches.count++;
|
|
236
281
|
const outcome = await deps.command(args);
|
|
@@ -264,6 +309,31 @@ export async function executeNextAction(action: NextAction, deps: ActionDeps): P
|
|
|
264
309
|
return record('done', action.rationale);
|
|
265
310
|
}
|
|
266
311
|
|
|
312
|
+
/** Execute the allowed candidates in a caller-supplied tick and emit one isolated denominator event. */
|
|
313
|
+
export async function executeEntranceTick(candidates: readonly EntranceTickCandidate[], deps: ActionDeps): Promise<string[]> {
|
|
314
|
+
const denominator = buildEntranceRefusalDenominator(candidates.map(({ action, refusal }) => ({
|
|
315
|
+
taskId: action.taskId,
|
|
316
|
+
kind: action.kind,
|
|
317
|
+
...(typeof refusal === 'string' ? { refusal } : {}),
|
|
318
|
+
})));
|
|
319
|
+
const observeDenominator = (result: string) => {
|
|
320
|
+
try {
|
|
321
|
+
deps.observe('task-agent.entrance-denominator', {
|
|
322
|
+
taskId: candidates[0]?.action.taskId ?? 'entrance-tick',
|
|
323
|
+
kind: 'entrance-tick', result, reason: 'entrance refusal denominator', ...denominator,
|
|
324
|
+
});
|
|
325
|
+
} catch { /* Logging must not change the actions selected for this tick. */ }
|
|
326
|
+
};
|
|
327
|
+
const results: string[] = [];
|
|
328
|
+
for (const { action, refusal } of candidates) {
|
|
329
|
+
if (typeof refusal === 'string' && refusal.trim()) continue;
|
|
330
|
+
try { results.push(await executeNextAction(action, deps)); }
|
|
331
|
+
catch (error) { observeDenominator('failed'); throw error; }
|
|
332
|
+
}
|
|
333
|
+
observeDenominator(results.at(-1) ?? 'refused-all');
|
|
334
|
+
return results;
|
|
335
|
+
}
|
|
336
|
+
|
|
267
337
|
/** 재발사 문면 — 원문은 고치지 않고 앞에 둔다 · 갈래 문면 · must-fix · 직전 런 순서. */
|
|
268
338
|
export function retryText(action: NextAction): string {
|
|
269
339
|
const sections = [action.original];
|
|
@@ -28,6 +28,8 @@ export interface GreenSweepDecision {
|
|
|
28
28
|
source: GreenSweepCandidate['source'];
|
|
29
29
|
verdict: GreenSweepVerdict;
|
|
30
30
|
reason: string;
|
|
31
|
+
/** Present when traffic hold state could not be read; preserves the decision reason while exposing its cause. */
|
|
32
|
+
holdDiagnostic?: string;
|
|
31
33
|
evidence: string;
|
|
32
34
|
existingEvidence: string;
|
|
33
35
|
/** Preview only; a later live operation may persist this complete value. */
|
|
@@ -107,6 +109,7 @@ export function decideGreenSweep(input: {
|
|
|
107
109
|
pr: GreenSweepPr | null;
|
|
108
110
|
ancestor: boolean | null;
|
|
109
111
|
hold: boolean | null;
|
|
112
|
+
holdDiagnostic?: string;
|
|
110
113
|
repositoryMatches?: boolean | null;
|
|
111
114
|
ambiguousAcrossCells?: boolean;
|
|
112
115
|
}): GreenSweepDecision {
|
|
@@ -116,6 +119,7 @@ export function decideGreenSweep(input: {
|
|
|
116
119
|
const landing = pr?.viaTrain ? ` via train #${pr.viaTrain.integrationPr}` : '';
|
|
117
120
|
const evidence = `GREEN-FROM-LEDGER: PR #${candidate.pr}${landing}${mergeSha ? ` merged ${mergeSha}` : ''} · ${verdict} · ${reason}`;
|
|
118
121
|
return { cell: item.id, pr: candidate.pr, mergeSha, source: candidate.source, verdict, reason,
|
|
122
|
+
...(reason === 'hold-state-unreadable' && input.holdDiagnostic ? { holdDiagnostic: input.holdDiagnostic } : {}),
|
|
119
123
|
evidence, existingEvidence: item.evidence ?? '', plannedEvidence: appendGreenSweepEvidence(item.evidence, evidence) };
|
|
120
124
|
};
|
|
121
125
|
if (item.status !== 'yellow' && item.status !== 'red') return result('skip', 'cell-not-yellow');
|
|
@@ -4,6 +4,7 @@ import { mkdirSync, readFileSync } from 'node:fs';
|
|
|
4
4
|
import { dirname, isAbsolute, join } from 'node:path';
|
|
5
5
|
import { randomUUID } from 'node:crypto';
|
|
6
6
|
import { parseReviewResultOutput } from './review-result-capture.js';
|
|
7
|
+
import { executeBoundPrLandRecover, PR_LAND_CARD_ID_ENV } from '../cli/pr-land-recovery.js';
|
|
7
8
|
|
|
8
9
|
type CommandResult = { status: number; stdout: string; stderr: string };
|
|
9
10
|
export interface QueueLandingInput {
|
|
@@ -13,6 +14,8 @@ export interface QueueLandingInput {
|
|
|
13
14
|
export interface QueueLandingDeps {
|
|
14
15
|
run?: (command: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv) => Promise<CommandResult>;
|
|
15
16
|
read?: (path: string) => string;
|
|
17
|
+
/** LAND-REFUSAL-EXEC — observe a refusal on the recover@1 edge and run that unit once (never an effect). */
|
|
18
|
+
recover?: typeof executeBoundPrLandRecover;
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
async function run(command: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv): Promise<CommandResult> {
|
|
@@ -31,14 +34,24 @@ export async function runQueuedLanding(input: QueueLandingInput, deps: QueueLand
|
|
|
31
34
|
const invoke = deps.run ?? run;
|
|
32
35
|
const read = deps.read ?? ((path: string) => readFileSync(path, 'utf8'));
|
|
33
36
|
const fail = (stage: string, reason: string): CommandResult => ({ status: 1, stdout: '', stderr: `${stage}: ${reason.slice(-500)}` });
|
|
37
|
+
// LAND-REFUSAL-EXEC — a judged refusal (not an unmeasured prerequisite) is bound to recover@1 with this card
|
|
38
|
+
// and that unit runs once. The returned refusal is unchanged; recovery observation never replaces it.
|
|
39
|
+
const refuse = async (stage: string, reason: string): Promise<CommandResult> => {
|
|
40
|
+
const refused = fail(stage, reason);
|
|
41
|
+
try { await (deps.recover ?? executeBoundPrLandRecover)({ refusal: refused.stderr, pr: input.pr, head: input.head, cardId: input.card }, { root: dirname(input.statePath) }); }
|
|
42
|
+
catch { /* fail-soft */ }
|
|
43
|
+
return refused;
|
|
44
|
+
};
|
|
45
|
+
// The card rides along to every child that may land or record this PR (same env as TA defaultLand).
|
|
46
|
+
const cardEnv = (extra: Record<string, string> = {}): NodeJS.ProcessEnv => ({ ...process.env, ...extra, [PR_LAND_CARD_ID_ENV]: input.card });
|
|
34
47
|
if (!/^[a-f0-9]{40}$/i.test(input.head) || !Number.isSafeInteger(input.pr) || input.pr < 1) return fail('input', 'invalid PR/head');
|
|
35
48
|
if (!isAbsolute(input.command) || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(input.remote)) return fail('config', 'land queue command/remote invalid');
|
|
36
49
|
let review: ReturnType<typeof parseReviewResultOutput>;
|
|
37
50
|
try { review = parseReviewResultOutput(read(input.reviewResult)); }
|
|
38
|
-
catch (error) { return
|
|
51
|
+
catch (error) { return refuse('review', String(error)); }
|
|
39
52
|
if (!review || review.pr !== input.pr || review.head?.toLowerCase() !== input.head.toLowerCase()
|
|
40
53
|
|| review.reviewed !== true || !['pass', 'warn'].includes(review.verdict ?? '') || review.mustFix !== 0 || review.error) {
|
|
41
|
-
return
|
|
54
|
+
return refuse('review', `exact head #${input.pr} ${input.head.slice(0, 12)} PASS/WARN mf0 not proven`);
|
|
42
55
|
}
|
|
43
56
|
const git = async (args: string[]) => invoke(process.execPath, [input.entry, '--config-dir', input.configDir, 'git', ...args], input.cwd);
|
|
44
57
|
const fetched = await git(['fetch', '--quiet', 'origin', 'main']);
|
|
@@ -52,15 +65,15 @@ export async function runQueuedLanding(input: QueueLandingInput, deps: QueueLand
|
|
|
52
65
|
const artifact = join(dirname(input.statePath), 'land-queue-gates', `${safeCard}-${input.pr}-${input.head.slice(0, 12)}-${randomUUID()}`);
|
|
53
66
|
mkdirSync(artifact, { recursive: true });
|
|
54
67
|
const gate = await invoke(process.execPath, [input.entry, '--config-dir', input.configDir,
|
|
55
|
-
'self', 'gate', '--changed', '--base', baseHead!, '--remote', input.remote, '--shards', '4', '--artifact-dir', artifact], input.cwd);
|
|
56
|
-
if (gate.status !== 0) return
|
|
68
|
+
'self', 'gate', '--changed', '--base', baseHead!, '--remote', input.remote, '--shards', '4', '--artifact-dir', artifact], input.cwd, cardEnv());
|
|
69
|
+
if (gate.status !== 0) return refuse('remote-changed-gate', gate.stderr || gate.stdout || `exit ${gate.status}`);
|
|
57
70
|
let summary: Record<string, unknown>;
|
|
58
71
|
try { summary = JSON.parse(read(join(artifact, 'summary.json'))) as Record<string, unknown>; }
|
|
59
72
|
catch (error) { return fail('remote-changed-gate', `summary unreadable: ${String(error)}`); }
|
|
60
73
|
if (summary.head40 !== input.head || summary.base40 !== baseHead || summary.remoteHost !== input.remote
|
|
61
74
|
|| summary.verdict !== 'passed' || summary.exitCode !== 0 || summary.introduced !== 0
|
|
62
75
|
|| summary.unknown !== 0 || summary.preconditionUnmet !== 0) {
|
|
63
|
-
return
|
|
76
|
+
return refuse('remote-changed-gate', 'summary does not prove this head/base/remote passed with zero unknown');
|
|
64
77
|
}
|
|
65
78
|
const fresh = await invoke('gh', ['pr', 'view', String(input.pr), '--json', 'headRefOid,state,isDraft'], input.cwd);
|
|
66
79
|
let latest: { headRefOid?: unknown; state?: unknown; isDraft?: unknown };
|
|
@@ -68,12 +81,12 @@ export async function runQueuedLanding(input: QueueLandingInput, deps: QueueLand
|
|
|
68
81
|
catch { return fail('pr-head', `current PR state unreadable: ${fresh.stderr || fresh.stdout || fresh.status}`); }
|
|
69
82
|
if (fresh.status !== 0 || latest.state !== 'OPEN' || latest.isDraft !== false
|
|
70
83
|
|| typeof latest.headRefOid !== 'string' || latest.headRefOid.toLowerCase() !== input.head.toLowerCase()) {
|
|
71
|
-
return
|
|
84
|
+
return refuse('pr-head', `PR #${input.pr} changed after gate or is not ready`);
|
|
72
85
|
}
|
|
73
86
|
const enrolled = await invoke(input.command, [String(input.pr), input.cwd, '--review', input.reviewResult, '--expected-head', input.head], input.cwd,
|
|
74
|
-
{
|
|
87
|
+
cardEnv({ LAND_RR_DIR: dirname(input.reviewResult) }));
|
|
75
88
|
if (enrolled.status !== 0 || !new RegExp(`^OK #${input.pr} head=${input.head.slice(0, 12)}(?:\\s|$)`, 'm').test(enrolled.stdout)) {
|
|
76
|
-
return
|
|
89
|
+
return refuse('land-enqueue-refused', enrolled.stdout || enrolled.stderr || `exit ${enrolled.status}`);
|
|
77
90
|
}
|
|
78
91
|
return { status: 0, stdout: `queued #${input.pr} head ${input.head.slice(0, 12)} gate ${artifact} · ${enrolled.stdout.slice(-250)}`, stderr: '' };
|
|
79
92
|
}
|