elanous 0.2.34 → 0.2.35
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/{L04y73dlwKeTW-GetaTF3 → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{5014f970-22bef0b5210f7d60.js → 0368f25d-ad84af92fefee68f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +1 -0
- package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +32 -0
- package/apps/pwa/out/_next/static/chunks/{2124.ed5bf480cea7f85b.js → 1530.0e612369b6fd7ea0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +41 -0
- package/apps/pwa/out/_next/static/chunks/1674.2a65fd5668e1cc5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +24 -0
- package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +74 -0
- package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8368.014caa8de2f5af34.js → 2018.a741297bce759490.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +148 -0
- package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +34 -0
- package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +77 -0
- package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +62 -0
- package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +90 -0
- package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1644.35dd25240ae24e4b.js → 3408.21d1570602f4b6c0.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3121.779fafe3e44612c5.js → 3589.5444a06bcf6e775c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/359-2250789a2d3499e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +36 -0
- package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9131-fce7256c4180c4a5.js → 3677-4215f826f6aa68e5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +79 -0
- package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +122 -0
- package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4346.8601952e73bf5803.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6053-d893974de92e6198.js → 4441-875b97f5821ed58a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +286 -0
- package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{1895-60ed0e341c658bd4.js → 4705-194e64e47ca0fbdb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5576-82d3703636d5c4b9.js → 4718-17d2af636796a330.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7431.3051e9b8a4372d2d.js → 5101.e32282718f99ed6f.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +23 -0
- package/apps/pwa/out/_next/static/chunks/{2987-30cf9c2eb7b8bdd5.js → 5483-dd5d7697f6bdb106.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +94 -0
- package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +1 -0
- package/apps/pwa/out/_next/static/chunks/56d372f2.681ab4ec4c998fae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7386.5d8e7e42e818dfb6.js → 5852.db1f7449f4f74612.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +1 -0
- package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3110.0a7065f25c841818.js → 6236.e18cced2d5ba6afb.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +8 -0
- package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +27 -0
- package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +93 -0
- package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +149 -0
- package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{7005.1623d2aea78eb85f.js → 7385.50a308a477bdfc21.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6086.913a69e6fa3e4a8b.js → 7644.17e37ba6f1d4226e.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7193-cf355cca5ba6c5d5.js → 8437-8d5492094b166cfa.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2554.3b5e200f5f5cfcd6.js → 8444.4c26b379ca2b9596.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +226 -0
- package/apps/pwa/out/_next/static/chunks/8557-e7898769499cd56f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +64 -0
- package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2547.dd27303624cb4da8.js → 8637.47f5b35afcae5e6b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9550.d5f76828f972058c.js → 9214.63a510d39178e997.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +115 -0
- package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8548.036c344973968847.js → 938.66ad1ef0e5abae1c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3414.172ad4ca2d9b08e8.js → 9512.5a76207a730e0491.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6740.43de73fc427c9fe2.js → 9952.5daf5f94063a2b3e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/{page-d7bff0f0905a662c.js → page-26e6c18a1a750cf6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-47c5d4db587266bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-df3445b207ceceab.js → page-dc0a532f5b9196ec.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9a8cb466.cc9fc9e6e46038aa.js → b2f6ba4d.fb56fdbbf798df33.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/b6705a4f-b9a9047de9eecfd0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4fa33ebd.21c1bd5b294496e6.js → cbe38a15.5a032598e39970c6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{abb4b98b.163e0f56e84ae35d.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9b48c871.204d5d13e7809bd0.js → da5176c6.6773b6c5994e1d99.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +1 -0
- 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/README.md +4 -0
- package/graphs/catalog/catalog.yaml +1 -1
- package/graphs/default-loop.yaml +57 -3
- package/graphs/document-loop.yaml +51 -3
- package/graphs/implement-loop.yaml +53 -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/research-loop.yaml +137 -3
- package/graphs/test-diet/test-diet.yaml +3 -0
- package/package.json +1 -1
- package/scripts/coord-role-pack.ts +19 -6
- package/scripts/hq/standby-snapshot.ts +17 -12
- package/scripts/release-loop/docs-land-node.ts +21 -5
- package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
- package/scripts/release-loop/gate-node.ts +181 -22
- 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 +12 -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-release.ts +41 -4
- package/scripts/release-loop/unattended-release.ts +2 -0
- package/scripts/test-diet/lib.ts +6 -1
- package/scripts/test-diet/node.ts +194 -13
- package/scripts/ux-sim.ts +39 -0
- package/src/agent/self-ambient-cache.ts +8 -0
- package/src/agent-substrate/acp-reviewer.ts +39 -4
- package/src/agent-substrate/pr-reviewer.ts +17 -0
- package/src/agent-substrate/self-review-cli.ts +62 -13
- package/src/autopilot/pr-manager.ts +215 -36
- package/src/budget/run-usage-rollup.ts +1 -0
- package/src/chat/index.ts +0 -2
- package/src/chat/pickers/modal-runtime.ts +10 -27
- package/src/cli/agent-cli.ts +13 -2
- package/src/cli/doctor-cli.ts +4 -1
- package/src/cli/light-entry-route.ts +46 -6
- package/src/cli/pod-cli.ts +77 -3
- package/src/cli/pr-cli.ts +5 -2
- package/src/cli/pr-land-pod-shadow-job.ts +3 -0
- package/src/cli/release-checklist-read-cli.ts +79 -0
- package/src/cli/release-cli.ts +72 -102
- 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-cli.ts +540 -31
- package/src/cli/usage-cli.ts +13 -11
- package/src/clipboard/history.ts +179 -13
- package/src/config.ts +8 -1
- package/src/dashboard/chat/acp-chat.ts +8 -0
- package/src/dashboard/index.ts +78 -10
- package/src/dashboard/render/theme-resolver.ts +33 -4
- package/src/domains/schedule-registry.ts +16 -2
- package/src/git-fs/idle-refresh.ts +76 -0
- package/src/git-fs/index.ts +18 -7
- package/src/git-fs/worktree.ts +42 -4
- package/src/graph-kinds/registry.ts +2 -2
- package/src/graph-runner/runner.ts +153 -10
- package/src/grok/credential.ts +10 -3
- package/src/harness/harness-cli-command.ts +112 -28
- package/src/harness/harness-incidents.ts +33 -0
- package/src/harness/launch-utterance-ledger.ts +208 -0
- 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 +496 -143
- package/src/intake-plane/already-built-hint.ts +4 -2
- package/src/intake-plane/requirement-funnel.ts +29 -1
- package/src/light-cli.ts +27 -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.ts +213 -56
- package/src/model-tier/llm-tier-map.ts +15 -1
- package/src/native-tool-catalog.ts +15 -1
- package/src/nexus/api/loop-resources.ts +13 -1
- package/src/oauth/codex.ts +7 -0
- package/src/ops/overview-collect.ts +18 -3
- package/src/ops/overview.ts +20 -7
- package/src/pr-tool/census.ts +261 -27
- package/src/pty-shell/pty-manifest.ts +7 -0
- package/src/release-loop/checklist.ts +24 -0
- 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 +2 -2
- package/src/repl/index.ts +174 -17
- package/src/repl/ops-msg-bridge.ts +32 -0
- package/src/self-dev/ask-launch-flow.ts +44 -5
- package/src/self-dev/cli-help-text.ts +17 -0
- package/src/self-dev/dev-cli.ts +11 -9
- 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 +107 -0
- package/src/self-dev/fleet-reduce.ts +3 -2
- package/src/self-dev/graph-front-nodes.ts +112 -0
- package/src/self-dev/graph-journey-nodes.ts +1 -0
- package/src/self-dev/harness-run-cli.ts +3 -15
- package/src/self-dev/orchestrate-cli-text.ts +10 -0
- package/src/self-dev/review-provider-fallback.ts +35 -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-implement/blocked-draft-policy.ts +20 -0
- package/src/self-implement/classify-shadow.ts +3 -7
- package/src/self-implement/doctor-visit.ts +18 -1
- 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-decompose.ts +275 -47
- package/src/self-implement/goal-author.ts +250 -0
- package/src/self-implement/goal-elaborate.ts +295 -0
- package/src/self-implement/goal-refine.ts +270 -0
- package/src/self-implement/graph-overlay-yaml.ts +14 -3
- package/src/self-implement/orchestrator.ts +152 -45
- package/src/self-implement/rework-budget-judgment.ts +5 -8
- package/src/self-implement/run-stop.ts +10 -1
- package/src/self-implement/running-runs.ts +29 -1
- package/src/self-implement/scope-adjacency.ts +113 -0
- package/src/self-implement/seams.ts +127 -24
- package/src/self-implement/stop-autoheal.ts +87 -1
- package/src/session-runtime/index.ts +1 -1
- package/src/setup/llm-env-detect.ts +5 -0
- package/src/skills/tools/agent.ts +140 -14
- package/src/skills/tools/msg-ask.ts +100 -0
- package/src/skills/tools/ops-ledger.ts +2 -1
- package/src/steward/hold-hygiene.ts +24 -6
- package/src/steward/triage-budget.ts +194 -0
- package/src/steward/triage.ts +20 -3
- package/src/task-agent/actions.ts +69 -1
- package/src/task-agent/green-sweep.ts +4 -0
- package/src/task-agent/live-moves.ts +160 -4
- package/src/task-agent/parent-host.ts +123 -3
- package/src/task-agent/shadow.ts +7 -1
- package/src/task-agent/task-hand.ts +54 -41
- package/src/task-agent/tier-split.ts +127 -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 +33 -0
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-command-job.ts +45 -7
- package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
- package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
- package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +8 -2
- package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -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 +3 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +37 -5
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +368 -36
- package/src/task-orchestrator/surfaces/self-implement.ts +23 -0
- package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
- package/src/tui/README.md +2 -0
- package/src/tui/chat/background-job-status.ts +54 -0
- package/src/tui/chat/log-view.ts +80 -0
- package/src/tui/entry.ts +406 -0
- package/src/tui/input/composer.ts +144 -0
- package/src/tui/seat-mail-boot.ts +59 -0
- package/src/tui/slash/compact.ts +100 -0
- package/src/tui/slash/new-session.ts +35 -0
- package/src/tui-client/local-chat-turn.ts +239 -0
- package/src/tui-client/local-harness-command.ts +63 -0
- package/src/tui-client/local-provider-command.ts +184 -0
- package/src/user-config.ts +4 -2
- package/src/ux-sim/event-monkey.ts +378 -0
- package/src/ux-sim/fake-bin.ts +42 -7
- package/src/ux-sim/fault-nextmove-dispatch.ts +266 -0
- package/src/ux-sim/fault-pod-codex-503.ts +211 -0
- package/src/ux-sim/fault-scope-escape-lift.ts +189 -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/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/3103.84470c8445962f04.js +0 -34
- 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/3411-f87314c6c66ebc73.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3498.cf2a15a8a9e5b926.js +0 -226
- package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3819.163d4777f0a597f6.js +0 -32
- package/apps/pwa/out/_next/static/chunks/3837.722e053fb9f321ad.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/5446.edf141cff9ef647d.js +0 -1
- 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/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/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/7448.478958ffbbba0ac0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7562.948255cbc3e79d33.js +0 -41
- 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/8817.61bb7ffbba502ecb.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/field/page-4fb31eb476dcbad3.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/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/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/ffdc3a04.b9c23c1b28dd4a96.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 → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
|
@@ -60,8 +60,8 @@ export const AGENT_TOOL_DEFAULT_MAX_TURNS = 20;
|
|
|
60
60
|
export const AGENT_TOOL_TURNS_CEILING = 50;
|
|
61
61
|
|
|
62
62
|
/** Numeric ceiling on concurrent `run_in_background` Agent-tool fan-out.
|
|
63
|
-
*
|
|
64
|
-
*
|
|
63
|
+
* Enforced at exactly one point in `dispatchAgent` (see the
|
|
64
|
+
* `background-fanout-limit` block: after dedup, before `noteSeen`). */
|
|
65
65
|
export const AGENT_TOOL_BACKGROUND_FANOUT_CEILING = 8;
|
|
66
66
|
|
|
67
67
|
/** Clamp a caller-supplied `max_turns` onto `[1, AGENT_TOOL_TURNS_CEILING]`.
|
|
@@ -82,7 +82,9 @@ export function stripAgentToolForOneLevelNesting<T extends { name: string }>(
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
/** Live `run_in_background` tasks occupy fan-out slots until they terminal.
|
|
85
|
-
*
|
|
85
|
+
* Counts a task list (e.g. `globalAgentRegistry.list()`). `dispatchAgent`
|
|
86
|
+
* enforces the per-session ceiling over its own reservation ledger
|
|
87
|
+
* (`backgroundFanoutSlots`) instead — see that field's doc. */
|
|
86
88
|
export function countLiveBackgroundFanout(
|
|
87
89
|
tasks: ReadonlyArray<{ background?: boolean; state?: string }>,
|
|
88
90
|
): number {
|
|
@@ -95,6 +97,35 @@ export function countLiveBackgroundFanout(
|
|
|
95
97
|
return n;
|
|
96
98
|
}
|
|
97
99
|
|
|
100
|
+
/** Fallback fan-out session key for dispatches that carry no
|
|
101
|
+
* `sessionCache` (agent-cli, one-off callers). All of their slots share
|
|
102
|
+
* one process-wide bucket so the ceiling still binds for them. */
|
|
103
|
+
const UNSCOPED_BACKGROUND_FANOUT_SESSION: object = Object.freeze({});
|
|
104
|
+
|
|
105
|
+
/** Fan-out slots by session (the dispatching session's `SessionCache`
|
|
106
|
+
* identity; WeakMap so a dropped session releases its key together with
|
|
107
|
+
* the cache instance). A slot is RESERVED in the same synchronous block
|
|
108
|
+
* as the ceiling check inside `dispatchAgent` — concurrent dispatches
|
|
109
|
+
* that interleave at the async definition-resolution awaits cannot all
|
|
110
|
+
* pass the check before any of them registers — and RELEASED when the
|
|
111
|
+
* registered task reaches a terminal state (done/error/aborted) via
|
|
112
|
+
* `globalAgentRegistry.onTaskDone`. A dispatch that throws before it
|
|
113
|
+
* registers releases its own reservation (see
|
|
114
|
+
* `releaseReservedFanoutSlot` inside `dispatchAgent`). */
|
|
115
|
+
const backgroundFanoutSlots = new WeakMap<object, number>();
|
|
116
|
+
|
|
117
|
+
/** Count this session's live fan-out slots (reserved or running). */
|
|
118
|
+
export function countSessionBackgroundFanout(session: object): number {
|
|
119
|
+
return backgroundFanoutSlots.get(session) ?? 0;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Release one of this session's fan-out slots (floors at zero). */
|
|
123
|
+
function releaseBackgroundFanoutSlot(session: object): void {
|
|
124
|
+
const live = backgroundFanoutSlots.get(session);
|
|
125
|
+
if (live === undefined || live <= 1) backgroundFanoutSlots.delete(session);
|
|
126
|
+
else backgroundFanoutSlots.set(session, live - 1);
|
|
127
|
+
}
|
|
128
|
+
|
|
98
129
|
/** Fallback agent when subagent_type is missing or unresolvable. The
|
|
99
130
|
* loader picks this up from src/agents/general-purpose.md — built
|
|
100
131
|
* inline below as a defensive default in case that file is removed. */
|
|
@@ -374,19 +405,22 @@ export async function dispatchAgent(
|
|
|
374
405
|
// burn another turn on the same work. Return a stub that points
|
|
375
406
|
// the parent back to its existing history. Parents stuck in a
|
|
376
407
|
// "keep re-spawning Data Collector" loop escape via this gate.
|
|
377
|
-
|
|
378
|
-
|
|
408
|
+
const sessionCache = opts.sessionCache;
|
|
409
|
+
const cacheKey = sessionCache
|
|
410
|
+
? agentCacheKey(requestedType, requestedType, prompt)
|
|
411
|
+
: undefined;
|
|
412
|
+
if (sessionCache && cacheKey) {
|
|
379
413
|
// Key strategy: description is noisy (parents sometimes vary the
|
|
380
414
|
// label between calls); we hash the FUNCTIONAL signature only
|
|
381
415
|
// — subagent_type + prompt. Same prompt to same agent = same
|
|
382
416
|
// expected work, regardless of how the call was labelled.
|
|
383
|
-
const hit =
|
|
417
|
+
const hit = sessionCache.check(cacheKey);
|
|
384
418
|
if (hit) {
|
|
385
419
|
const label = `Agent[${requestedType}] "${description.slice(0, 60)}"`;
|
|
386
420
|
logDedupHit('agent.dedup', label, hit, {
|
|
387
421
|
requestedType,
|
|
388
422
|
description: description.slice(0, 80),
|
|
389
|
-
consecutive:
|
|
423
|
+
consecutive: sessionCache.consecutiveHits,
|
|
390
424
|
});
|
|
391
425
|
|
|
392
426
|
// Runtime-level block: same treatment as Read. When the parent
|
|
@@ -395,16 +429,16 @@ export async function dispatchAgent(
|
|
|
395
429
|
// tool_result carries is_error=true. Soft stubs have been
|
|
396
430
|
// observed to produce 6+ retries in the wild; an error break
|
|
397
431
|
// the reflex loop more reliably.
|
|
398
|
-
if (
|
|
432
|
+
if (sessionCache.consecutiveHits >= CONSECUTIVE_DEDUP_BLOCK_THRESHOLD) {
|
|
399
433
|
debug.log('agent.dedup', 'consecutive-block', {
|
|
400
434
|
requestedType,
|
|
401
435
|
description: description.slice(0, 80),
|
|
402
|
-
consecutive:
|
|
436
|
+
consecutive: sessionCache.consecutiveHits,
|
|
403
437
|
threshold: CONSECUTIVE_DEDUP_BLOCK_THRESHOLD,
|
|
404
438
|
});
|
|
405
439
|
throw new Error(
|
|
406
440
|
`RUNTIME BLOCKED — Agent[${requestedType}] "${description.slice(0, 60)}" ` +
|
|
407
|
-
`has been spawned ${
|
|
441
|
+
`has been spawned ${sessionCache.consecutiveHits} times in a row with ` +
|
|
408
442
|
`no intervening progress. The previous sub-agent's final message is in ` +
|
|
409
443
|
`your conversation history above — use that. Spawn an Agent with a ` +
|
|
410
444
|
`DIFFERENT persona (different subagent_type or a substantively different ` +
|
|
@@ -420,9 +454,9 @@ export async function dispatchAgent(
|
|
|
420
454
|
// ~500 chars of history noise per hit. We now emit the debug
|
|
421
455
|
// event past threshold for traceability but return the normal
|
|
422
456
|
// "spawn a different persona" stub — same message every hit.
|
|
423
|
-
if (
|
|
457
|
+
if (sessionCache.totalHits >= DEDUP_CASCADE_HALT_THRESHOLD) {
|
|
424
458
|
debug.log('agent.dedup', 'cascade-threshold', {
|
|
425
|
-
totalHits:
|
|
459
|
+
totalHits: sessionCache.totalHits,
|
|
426
460
|
threshold: DEDUP_CASCADE_HALT_THRESHOLD,
|
|
427
461
|
requestedType,
|
|
428
462
|
description: description.slice(0, 80),
|
|
@@ -444,7 +478,79 @@ export async function dispatchAgent(
|
|
|
444
478
|
taskId: 'dedup',
|
|
445
479
|
};
|
|
446
480
|
}
|
|
447
|
-
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// ── TUI-AGENT-CAPS-FU: background fan-out ceiling ──
|
|
484
|
+
//
|
|
485
|
+
// The ONE enforcement point for AGENT_TOOL_BACKGROUND_FANOUT_CEILING, and
|
|
486
|
+
// it sits exactly between the dedup short-circuit above and `noteSeen`
|
|
487
|
+
// below on purpose:
|
|
488
|
+
// • after dedup — a repeat of an already-answered prompt still gets the
|
|
489
|
+
// dedup stub instead of a fan-out refusal (it never reaches here);
|
|
490
|
+
// • before `noteSeen` — a refused launch must NOT register its cache
|
|
491
|
+
// key. Otherwise the caller's retry (same prompt, once a slot opens)
|
|
492
|
+
// would be answered with "you already got this result" even though no
|
|
493
|
+
// child ever ran, permanently poisoning the cache with a spawn that
|
|
494
|
+
// never happened.
|
|
495
|
+
//
|
|
496
|
+
// Live slots are counted over the shared task ledger: `background` tasks
|
|
497
|
+
// that have not reached a terminal state (done / error / aborted). So a
|
|
498
|
+
// slot re-opens the moment any background agent finishes, which is what
|
|
499
|
+
// lets the next launch through again.
|
|
500
|
+
let fanoutSession: object | undefined;
|
|
501
|
+
if (runInBackground) {
|
|
502
|
+
// Per-session scope: slots count against THIS session's cache
|
|
503
|
+
// identity (shared fallback bucket for cache-less callers), so a
|
|
504
|
+
// busy OTHER session cannot starve this one's first launch.
|
|
505
|
+
fanoutSession = opts.sessionCache ?? UNSCOPED_BACKGROUND_FANOUT_SESSION;
|
|
506
|
+
const liveBackground = countSessionBackgroundFanout(fanoutSession);
|
|
507
|
+
if (liveBackground >= AGENT_TOOL_BACKGROUND_FANOUT_CEILING) {
|
|
508
|
+
debug.log('agent.spawn', 'background-fanout-limit', {
|
|
509
|
+
cid: debugCorrelationId,
|
|
510
|
+
requestedType,
|
|
511
|
+
description: description.slice(0, 80),
|
|
512
|
+
liveBackground,
|
|
513
|
+
ceiling: AGENT_TOOL_BACKGROUND_FANOUT_CEILING,
|
|
514
|
+
}, { level: 'warn' });
|
|
515
|
+
// Not spawned: no registry task, no provider call, no cache entry.
|
|
516
|
+
// taskId is a sentinel (like 'dedup' above) so a caller can tell a
|
|
517
|
+
// refusal from a real spawn without parsing the prose.
|
|
518
|
+
return {
|
|
519
|
+
output:
|
|
520
|
+
`NOT SPAWNED — ${liveBackground} background agents are already live and the ` +
|
|
521
|
+
`fan-out ceiling is ${AGENT_TOOL_BACKGROUND_FANOUT_CEILING}. A slot reopens as ` +
|
|
522
|
+
`soon as one of them reaches a terminal state (done/error/aborted); its result ` +
|
|
523
|
+
`then arrives as a task-notification. Either wait for one to finish, fold this ` +
|
|
524
|
+
`work into an existing background spawn, or re-issue it without ` +
|
|
525
|
+
`run_in_background so it runs in the foreground.`,
|
|
526
|
+
agent: requestedType,
|
|
527
|
+
cid: debugCorrelationId,
|
|
528
|
+
durationMs: 0,
|
|
529
|
+
maxTurns: requestedMaxTurns,
|
|
530
|
+
taskId: 'background-fanout-limit',
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
if (fanoutSession !== undefined) {
|
|
536
|
+
// Atomic reservation: taken in the SAME synchronous block as the
|
|
537
|
+
// ceiling check above, before any await — concurrent dispatches
|
|
538
|
+
// cannot all pass the check and push this session past the ceiling
|
|
539
|
+
// while their definitions resolve. Released when the registered
|
|
540
|
+
// task terminals (see the onTaskDone subscription at spawn); a
|
|
541
|
+
// dispatch that throws before registering releases it in the finally
|
|
542
|
+
// below, including failures from definition resolution and lazy imports.
|
|
543
|
+
backgroundFanoutSlots.set(fanoutSession, countSessionBackgroundFanout(fanoutSession) + 1);
|
|
544
|
+
}
|
|
545
|
+
const releaseReservedFanoutSlot = (): void => {
|
|
546
|
+
if (fanoutSession === undefined) return;
|
|
547
|
+
releaseBackgroundFanoutSlot(fanoutSession);
|
|
548
|
+
fanoutSession = undefined;
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
try {
|
|
552
|
+
if (sessionCache && cacheKey) {
|
|
553
|
+
sessionCache.noteSeen(cacheKey, `Agent[${requestedType}] ${description.slice(0, 60)}`);
|
|
448
554
|
}
|
|
449
555
|
|
|
450
556
|
// Resolve the agent definition. Try the 4-layer resolver first;
|
|
@@ -536,7 +642,9 @@ export async function dispatchAgent(
|
|
|
536
642
|
});
|
|
537
643
|
} catch (error) {
|
|
538
644
|
const message = error instanceof Error ? error.message : String(error);
|
|
539
|
-
if (!message.includes('is not inside a git repo'))
|
|
645
|
+
if (!message.includes('is not inside a git repo')) {
|
|
646
|
+
throw error;
|
|
647
|
+
}
|
|
540
648
|
childCwd = opts.cwd ?? getSessionCwd();
|
|
541
649
|
appliedIsolation = 'cwd';
|
|
542
650
|
debug.log('agent.spawn', 'worktree-fallback-cwd', {
|
|
@@ -679,6 +787,19 @@ export async function dispatchAgent(
|
|
|
679
787
|
...(runInBackground ? { background: true } : {}),
|
|
680
788
|
});
|
|
681
789
|
|
|
790
|
+
// Terminal release for this dispatch's reserved fan-out slot: the
|
|
791
|
+
// registry fires this exactly once per task when it reaches a
|
|
792
|
+
// terminal state (done/error/aborted); until then the slot counts as
|
|
793
|
+
// occupied against this session's ceiling above.
|
|
794
|
+
if (fanoutSession !== undefined) {
|
|
795
|
+
const fanoutSlotSession = fanoutSession;
|
|
796
|
+
const fanoutSlotSubscription = globalAgentRegistry.onTaskDone((task) => {
|
|
797
|
+
if (!task || task.id !== handle.task.id) return;
|
|
798
|
+
fanoutSlotSubscription.dispose();
|
|
799
|
+
releaseBackgroundFanoutSlot(fanoutSlotSession);
|
|
800
|
+
});
|
|
801
|
+
fanoutSession = undefined; // the terminal subscription owns the release now
|
|
802
|
+
}
|
|
682
803
|
// Forward parent abort to the spawned task. The registry owns the
|
|
683
804
|
// child's controller; we just chain ours into it.
|
|
684
805
|
if (opts.signal) {
|
|
@@ -907,4 +1028,9 @@ export async function dispatchAgent(
|
|
|
907
1028
|
...(childCwd ? { cwd: childCwd } : {}),
|
|
908
1029
|
...(appliedIsolation ? { isolation: appliedIsolation } : {}),
|
|
909
1030
|
};
|
|
1031
|
+
} finally {
|
|
1032
|
+
// The registered task owns its slot after the handoff above. Every
|
|
1033
|
+
// pre-registration throw leaves fanoutSession set and releases it here.
|
|
1034
|
+
releaseReservedFanoutSlot();
|
|
1035
|
+
}
|
|
910
1036
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { LLMToolSpec } from '../../llm.js';
|
|
2
|
+
import { openMsgStore, validateMessageEnvelope, type Message, type MsgStore } from '../../msg/msg-store.js';
|
|
3
|
+
|
|
4
|
+
export interface MsgAskDeps {
|
|
5
|
+
openStore?: () => MsgStore;
|
|
6
|
+
sleep?: (ms: number) => Promise<void>;
|
|
7
|
+
monotonicNow?: () => number;
|
|
8
|
+
wallNow?: () => number;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface MsgAskResult extends Record<string, unknown> {
|
|
13
|
+
output: string;
|
|
14
|
+
ok: boolean;
|
|
15
|
+
question: Message;
|
|
16
|
+
reply: Message | null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function buildMsgAskTool(): LLMToolSpec {
|
|
20
|
+
return {
|
|
21
|
+
name: 'MsgAsk',
|
|
22
|
+
description: 'Post a durable seat question, then wait for the first message whose replyTo points to it. A timeout or cancellation keeps the posted question and returns its ID for later follow-up.',
|
|
23
|
+
parameters: {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
from: { type: 'string', description: 'Asking seat (ALL cannot send).' },
|
|
27
|
+
to: { type: 'string', description: 'Recipient seat.' },
|
|
28
|
+
question: { type: 'string', description: 'Nonempty question body.' },
|
|
29
|
+
waitSeconds: { type: 'integer', description: 'Wait 0–300 seconds; default 60.' },
|
|
30
|
+
},
|
|
31
|
+
required: ['from', 'to', 'question'],
|
|
32
|
+
additionalProperties: false,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function dispatchMsgAsk(rawArgs: Record<string, unknown>, deps: MsgAskDeps = {}): Promise<MsgAskResult> {
|
|
38
|
+
const waitRaw = rawArgs.waitSeconds ?? 60;
|
|
39
|
+
if (typeof waitRaw !== 'number' || !Number.isSafeInteger(waitRaw) || waitRaw < 0 || waitRaw > 300) {
|
|
40
|
+
throw new Error("'waitSeconds' must be an integer between 0 and 300");
|
|
41
|
+
}
|
|
42
|
+
const envelope = validateMessageEnvelope({
|
|
43
|
+
from: rawArgs.from,
|
|
44
|
+
to: rawArgs.to,
|
|
45
|
+
body: rawArgs.question,
|
|
46
|
+
});
|
|
47
|
+
if (envelope.to === 'ALL') throw new Error("'to' must name one recipient seat for MsgAsk");
|
|
48
|
+
const monotonicNow = deps.monotonicNow ?? (() => performance.now());
|
|
49
|
+
const wallNow = deps.wallNow ?? Date.now;
|
|
50
|
+
const sleep = deps.sleep ?? ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)));
|
|
51
|
+
const store = deps.openStore?.() ?? openMsgStore();
|
|
52
|
+
try {
|
|
53
|
+
if (deps.signal?.aborted) throw new Error('ask cancelled before posting');
|
|
54
|
+
const question = store.post(envelope);
|
|
55
|
+
const startedAt = monotonicNow();
|
|
56
|
+
const wallStartedAt = wallNow();
|
|
57
|
+
const deadline = startedAt + waitRaw * 1000;
|
|
58
|
+
const wallDeadline = Date.parse(question.createdAt) + waitRaw * 1000;
|
|
59
|
+
// Ledger timestamps are wall time while the wait budget is monotonic.
|
|
60
|
+
// If the two clocks diverge materially, preserve the question ID and
|
|
61
|
+
// make the uncertain result explicit instead of accepting a late reply.
|
|
62
|
+
const clockAdjusted = () => Math.abs((wallNow() - wallStartedAt) - (monotonicNow() - startedAt)) > 250;
|
|
63
|
+
let afterId = 0;
|
|
64
|
+
do {
|
|
65
|
+
if (deps.signal?.aborted) {
|
|
66
|
+
return { output: `MsgAsk #${question.id} posted; wait cancelled`, ok: false, question, reply: null };
|
|
67
|
+
}
|
|
68
|
+
if (clockAdjusted()) {
|
|
69
|
+
return { output: `MsgAsk #${question.id} posted; clock adjusted during wait, inspect linked replies`, ok: false, question, reply: null };
|
|
70
|
+
}
|
|
71
|
+
const replies = store.listReplies(question.id, 1000, afterId);
|
|
72
|
+
if (clockAdjusted()) {
|
|
73
|
+
return { output: `MsgAsk #${question.id} posted; clock adjusted during wait, inspect linked replies`, ok: false, question, reply: null };
|
|
74
|
+
}
|
|
75
|
+
for (const reply of replies) {
|
|
76
|
+
afterId = reply.id;
|
|
77
|
+
// A replyTo link alone does not prove the intended seat answered.
|
|
78
|
+
// A wall-clock timestamp can move backwards by less than the clock
|
|
79
|
+
// adjustment guard. Never accept a reply once monotonic time expired.
|
|
80
|
+
// This conservatively leaves replies observed late for follow-up.
|
|
81
|
+
if (reply.from === question.to && reply.to === question.from
|
|
82
|
+
&& monotonicNow() <= deadline && Date.parse(reply.createdAt) <= wallDeadline) {
|
|
83
|
+
return { output: `MsgAsk #${question.id} → reply #${reply.id}: ${reply.body}`, ok: true, question, reply };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const remaining = deadline - monotonicNow();
|
|
87
|
+
if (deps.signal?.aborted) {
|
|
88
|
+
return { output: `MsgAsk #${question.id} posted; wait cancelled`, ok: false, question, reply: null };
|
|
89
|
+
}
|
|
90
|
+
if (remaining <= 0) {
|
|
91
|
+
return { output: `MsgAsk #${question.id} posted; no linked reply within ${waitRaw}s`, ok: false, question, reply: null };
|
|
92
|
+
}
|
|
93
|
+
// A full page may repeat forever. Yield so timers and AbortSignal
|
|
94
|
+
// callbacks can run before asking SQLite for the next page.
|
|
95
|
+
await sleep(replies.length === 1000 ? 0 : Math.min(100, remaining));
|
|
96
|
+
} while (true);
|
|
97
|
+
} finally {
|
|
98
|
+
store.close();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// OP TUI turns previously drove `elanous msg list/post/ack` and
|
|
4
4
|
// `elanous release checklist list/move/set/add` through RunShell:
|
|
5
5
|
// 1.3–2s of CLI startup per call, 30+ spawns per turn, and the CLI's
|
|
6
|
-
// human-oriented stdout amplifying TUI screen defects. These
|
|
6
|
+
// human-oriented stdout amplifying TUI screen defects. These
|
|
7
7
|
// tools reuse the SAME durable services in-process —
|
|
8
8
|
//
|
|
9
9
|
// • msg tools → src/msg/msg-store.ts (the SQLite ledger `elanous msg`
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// • checklist tools → src/release-loop/checklist.ts + feature-store.ts
|
|
12
12
|
// (the same per-version ledger, claim history, seat/OP move rules)
|
|
13
13
|
//
|
|
14
|
+
// MsgAsk joins this family through msg-ask.ts; the other dispatchers live here.
|
|
14
15
|
// The permission and audit contract is preserved 1:1:
|
|
15
16
|
// • writes record the actor from ELANOUS_TRACK (seat identity),
|
|
16
17
|
// • ChecklistMove keeps the CLI routing — anonymous (no ELANOUS_TRACK)
|
|
@@ -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
|
}
|
|
@@ -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));
|