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
|
@@ -17,6 +17,7 @@ import { validateUnitCalls } from '../graph-runner/runner.js';
|
|
|
17
17
|
import { parseGraphTemplateYaml } from '../self-implement/graph-yaml.js';
|
|
18
18
|
import { resolveDaemonHarnessTarget } from '../intake-plane/harness-target.js';
|
|
19
19
|
import { HARNESS_RUN_ID_ENV, mintRunId, normalizeRunId } from '../harness/harness-space.js';
|
|
20
|
+
import { newLaunchUtteranceId, recordLaunchUtterance } from '../harness/launch-utterance-ledger.js';
|
|
20
21
|
import { debug } from '../debug/log.js';
|
|
21
22
|
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
22
23
|
import { withFileLockSync } from '../storage/file-lock.js';
|
|
@@ -51,38 +52,35 @@ function missingOrReadFailure(error: unknown): '없다' | '읽기 실패' {
|
|
|
51
52
|
return code === 'ENOENT' || code === 'ENOTDIR' ? '없다' : '읽기 실패';
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
/**
|
|
55
|
-
* TA-WORK-ORDER — `.work-order.json` 골 파일의 내용을 지시서로 검증한다.
|
|
56
|
-
* 통과하면 골 문면으로 펼쳐 `work-order` 로, 깨진 JSON·칸 id 없음은 `rejected`(사유) 로 돌린다.
|
|
57
|
-
* 관측: `debug.log('task-agent.work-order', 'parsed' | 'rejected', { cellId, unknownFields })`.
|
|
58
|
-
*/
|
|
59
|
-
function resolveWorkOrderFile(content: string, path: string): ResolvedHandText {
|
|
60
|
-
const parsed = parseWorkOrder(content);
|
|
61
|
-
if (!parsed.ok) {
|
|
62
|
-
try { debug.log('task-agent.work-order', 'rejected', { cellId: null, unknownFields: [] }); } catch { /* fail-soft */ }
|
|
63
|
-
return { kind: 'rejected', path, reason: parsed.reason };
|
|
64
|
-
}
|
|
65
|
-
try { debug.log('task-agent.work-order', 'parsed', { cellId: parsed.order.cellId, unknownFields: parsed.order.unknownFields }); } catch { /* fail-soft */ }
|
|
66
|
-
return { kind: 'work-order', text: renderWorkOrderGoal(parsed.order), path, order: parsed.order };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** 파일 판정만 한다. 관측과 카드 작성은 호출자가 결과에 따라 수행한다. */
|
|
55
|
+
/** 파일 판정만 한다. 카드 작성은 호출자가 결과에 따라 수행한다. */
|
|
70
56
|
export function resolveHandText(text: string, deps: ResolveHandTextDeps = { cwd: process.cwd(), stat: statSync, readFile: readFileSync }): ResolvedHandText {
|
|
71
|
-
|
|
57
|
+
const workOrder = WORK_ORDER_FILE_PATTERN.test(text);
|
|
58
|
+
if (!text || (/\s/.test(text) && !workOrder)) return { kind: 'unchanged', text };
|
|
72
59
|
const path = resolve(deps.cwd, text);
|
|
73
60
|
const extension = /\.(?:md|markdown|txt)$/i.test(text);
|
|
61
|
+
const reject = (reason: string): ResolvedHandText => {
|
|
62
|
+
if (workOrder) {
|
|
63
|
+
try { debug.log('task-agent.work-order', 'rejected', { cellId: null, unknownFields: [] }); } catch { /* fail-soft */ }
|
|
64
|
+
}
|
|
65
|
+
return { kind: 'rejected', path, reason };
|
|
66
|
+
};
|
|
74
67
|
let file: Pick<Stats, 'isFile' | 'isDirectory'>;
|
|
75
68
|
try { file = deps.stat(path); } catch (error) {
|
|
76
|
-
if (!extension) return { kind: 'unchanged', text };
|
|
77
|
-
return
|
|
69
|
+
if (!extension && !workOrder) return { kind: 'unchanged', text };
|
|
70
|
+
return reject(missingOrReadFailure(error));
|
|
78
71
|
}
|
|
79
|
-
if (!file.isFile() && !extension && !file.isDirectory()) return { kind: 'unchanged', text };
|
|
80
|
-
if (!file.isFile()) return
|
|
72
|
+
if (!file.isFile() && !extension && !workOrder && !file.isDirectory()) return { kind: 'unchanged', text };
|
|
73
|
+
if (!file.isFile()) return reject(file.isDirectory() ? '디렉터리' : '읽기 실패');
|
|
81
74
|
let content: string;
|
|
82
75
|
// stat 과 read 사이에 지워지거나 경로가 바뀌어도 사유는 같은 규칙(없다/읽기 실패)으로 가른다.
|
|
83
|
-
try { content = deps.readFile(path, 'utf8'); } catch (error) { return
|
|
76
|
+
try { content = deps.readFile(path, 'utf8'); } catch (error) { return reject(missingOrReadFailure(error)); }
|
|
84
77
|
// TA-WORK-ORDER — 지시서 골 파일은 인라인하지 않고 지시서로 검증해 골 문면으로 펼친다.
|
|
85
|
-
if (
|
|
78
|
+
if (workOrder) {
|
|
79
|
+
const parsed = parseWorkOrder(content);
|
|
80
|
+
if (!parsed.ok) return reject(parsed.reason);
|
|
81
|
+
try { debug.log('task-agent.work-order', 'parsed', { cellId: parsed.order.cellId, unknownFields: parsed.order.unknownFields }); } catch { /* fail-soft */ }
|
|
82
|
+
return { kind: 'work-order', text: renderWorkOrderGoal(parsed.order), path, order: parsed.order };
|
|
83
|
+
}
|
|
86
84
|
const carried = content.trim();
|
|
87
85
|
if (!carried) return { kind: 'rejected', path, reason: '비었다' };
|
|
88
86
|
return { kind: 'inlined', text: content, path, chars: carried.length, sha256: createHash('sha256').update(carried).digest('hex') };
|
|
@@ -305,6 +303,11 @@ export interface TaskCard {
|
|
|
305
303
|
childLlm?: TaskChildLlm;
|
|
306
304
|
/** Dispatch difficulty, fixed at handoff so repair uses the same judgement. */
|
|
307
305
|
tier?: '하' | '중' | '상' | '특';
|
|
306
|
+
/**
|
|
307
|
+
* TIER-SPLIT-BEFORE-LAUNCH — 상·특 hand 를 분해해 나온 조각 카드(`tier-split.ts`). group = 같은 hand 에서 나온 조각들의 묶음 id
|
|
308
|
+
* (칸 연결은 `checklistId` 가 그대로 잇는다) · fromTier = 원래 난이도 · unavoidable = 상으로 남은 조각의 불가피 이유.
|
|
309
|
+
*/
|
|
310
|
+
tierSplit?: { group: string; fromTier: '상' | '특'; index: number; total: number; unavoidable?: string };
|
|
308
311
|
/** RUN-IDENTITY-TAGS — 출생 신분 묶음(`run-identity.js` 정본): 칸 우선순위·대표 표시에서 태어나고 `--tag k=v` 가 덮는다. 카드 상태 파일이 원장 정본이다. */
|
|
309
312
|
identity?: RunIdentity;
|
|
310
313
|
/** Same-PR repair launches; exact source head and worker result are retained for CAS and retry limits. */
|
|
@@ -577,7 +580,7 @@ export function shellQuote(arg: string): string {
|
|
|
577
580
|
}
|
|
578
581
|
|
|
579
582
|
/** 발사기에 넘기는 연결 — env(`ELANOUS_RUN_ID`)를 자식 환경에 얹으면 하니스 런이 `runId` 로 돈다(`resolveRunIdentity` 상속). launchId 는 카드에만 남는 발사 토큰이다. */
|
|
580
|
-
export interface TaskLaunchContext { runId: string; launchId: string; env: Record<string, string>; cardLabelContext?: TaskCardLabelContext; substrate?: 'pod'; podGoal?: string; effectiveChildProvider?: string }
|
|
583
|
+
export interface TaskLaunchContext { runId: string; launchId: string; env: Record<string, string>; /** exact untrimmed hand text (launch-utterance ledger pair) */ launchUtterance?: string; cardLabelContext?: TaskCardLabelContext; substrate?: 'pod'; podGoal?: string; effectiveChildProvider?: string }
|
|
581
584
|
/** 발사기가 «이 런 id 로 띄웠다»고 돌려주는 영수증 — 없으면 카드에 런 id 를 적지 않는다(추측하지 않는다). */
|
|
582
585
|
export interface TaskLaunchReceipt {
|
|
583
586
|
runId?: string;
|
|
@@ -597,12 +600,18 @@ export interface HandTaskOptions {
|
|
|
597
600
|
goal?: string;
|
|
598
601
|
milestone?: string;
|
|
599
602
|
live?: boolean;
|
|
603
|
+
/** Production `tasks hand --live` guard; test launchers opt in explicitly. */
|
|
604
|
+
preflightGoalDoneBoundary?: boolean;
|
|
600
605
|
/** TA-LIVE-LAND-2 — `--ta-land`: card field `taLand` ⊕ launch env `ELANOUS_TA_LAND=1`. */
|
|
601
606
|
taLand?: boolean;
|
|
602
607
|
/** TASKS-HAND-CHILD-LLM — `<provider>/<model>`(`parseChildLlm`) ⊕ 선택 추론 노력. effort 만 주면 거부. */
|
|
603
608
|
childLlm?: string;
|
|
604
609
|
childLlmEffort?: string;
|
|
605
610
|
tier?: TaskCard['tier'];
|
|
611
|
+
/** TIER-SPLIT-BEFORE-LAUNCH — 조각 카드에 싣는 분해 연결(`tier-split.ts` 만 준다). */
|
|
612
|
+
tierSplit?: TaskCard['tierSplit'];
|
|
613
|
+
/** TIER-SPLIT-BEFORE-LAUNCH — 분해 실패 사유. 주면 카드를 발사 없이 failed(history `tier-split-failed`)로 남기고 launched:false 로 돌아온다. */
|
|
614
|
+
tierSplitBlocked?: string;
|
|
606
615
|
/** RUN-IDENTITY-TAGS — `tasks hand --tag k=v`(반복): 출생 신분을 덮는다. 목록 밖 값은 거부한다(`run-identity.js`). */
|
|
607
616
|
tags?: string[];
|
|
608
617
|
/** RUN-IDENTITY-TAGS — 칸 읽기 seam(우선순위·대표 표시). 주면 그 답이 최종이다(«칸 없음» 포함). */
|
|
@@ -682,6 +691,7 @@ export function dispatchDeliverableCompletion(id: string, input: { ref: string;
|
|
|
682
691
|
export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
683
692
|
const text = opts.text.trim();
|
|
684
693
|
if (!text) throw new Error('과제 한 줄이 비어 있다');
|
|
694
|
+
const path = opts.statePath ?? taskAgentStatePath();
|
|
685
695
|
const targetPathHints = parseAskTargetPathHintsResult(text);
|
|
686
696
|
const targetPaths = canonicalTargetPaths(targetPathHints.paths);
|
|
687
697
|
if (opts.seat !== undefined && !TASK_SEATS.includes(opts.seat)) throw new Error(`자리는 ${TASK_SEATS.join('|')} 중 하나다: ${opts.seat}`);
|
|
@@ -691,6 +701,7 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
|
691
701
|
}
|
|
692
702
|
if (opts.childLlmEffort !== undefined && opts.childLlm === undefined) throw new Error('--child-llm-effort 는 --child-llm <provider>/<model> 과 함께 준다');
|
|
693
703
|
if (opts.tier !== undefined && !['하', '중', '상', '특'].includes(opts.tier)) throw new Error(`--tier 는 하|중|상|특 중 하나다: ${opts.tier}`);
|
|
704
|
+
const tierSplitBlocked = opts.tierSplitBlocked;
|
|
694
705
|
// RUN-IDENTITY-TAGS — 출생 신분: 칸 우선순위(P0 = critical·special·protect · P1 = normal · 그 외 normal)·대표 표시에서 단다.
|
|
695
706
|
// `--tag k=v`(반복) 이 덮는다 — 칸·태그 없는 손은 오늘 모양 그대로다(신분 없음). 목록 밖 값은 카드를 적기 전에 거부한다(`run-identity.js` 정본).
|
|
696
707
|
const birthCell = opts.checklistId === undefined ? undefined
|
|
@@ -732,7 +743,6 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
|
732
743
|
const now = (opts.now ?? (() => new Date()))();
|
|
733
744
|
const id = opts.id ?? `${TASK_CARD_PREFIX}${now.toISOString().slice(0, 10).replaceAll('-', '')}-${randomBytes(3).toString('hex')}`;
|
|
734
745
|
const mode = opts.live ? 'live' : 'shadow';
|
|
735
|
-
const path = opts.statePath ?? taskAgentStatePath();
|
|
736
746
|
const card: TaskCard = {
|
|
737
747
|
id, text,
|
|
738
748
|
...(!targetPathHints.labelMissing ? { targetPaths } : {}),
|
|
@@ -749,18 +759,21 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
|
749
759
|
...(opts.taLand === true ? { taLand: true as const } : {}),
|
|
750
760
|
...(childLlm ? { childLlm } : {}),
|
|
751
761
|
...(opts.tier ? { tier: opts.tier } : {}),
|
|
762
|
+
...(opts.tierSplit ? { tierSplit: opts.tierSplit } : {}),
|
|
752
763
|
...(identity ? { identity } : {}),
|
|
753
764
|
createdAt: now.toISOString(),
|
|
754
|
-
status: selectionFailure ? 'failed' : 'handed',
|
|
765
|
+
status: selectionFailure || tierSplitBlocked !== undefined ? 'failed' : 'handed',
|
|
755
766
|
history: selectionFailure ? [{ at: now.toISOString(), event: !selected.composition ? 'composition-missing'
|
|
756
|
-
: selected.error ? 'composition-invalid' : 'composition-launcher-unavailable', detail: selectionFailure }]
|
|
767
|
+
: selected.error ? 'composition-invalid' : 'composition-launcher-unavailable', detail: selectionFailure }]
|
|
768
|
+
: tierSplitBlocked !== undefined ? [{ at: now.toISOString(), event: 'tier-split-failed', detail: `tier-split-failed: ${tierSplitBlocked}` }] : [],
|
|
757
769
|
...(opts.mission ? { mission: opts.mission, after: [...(opts.after ?? [])] } : {}),
|
|
758
770
|
...(opts.cardFields?.pr !== undefined ? { pr: opts.cardFields.pr } : {}),
|
|
759
771
|
...(opts.cardFields?.goalId !== undefined ? { goalId: opts.cardFields.goalId } : {}),
|
|
760
772
|
...(opts.cardFields?.handed !== undefined ? { handed: opts.cardFields.handed } : {}),
|
|
761
773
|
};
|
|
762
774
|
const move = selectionFailure ? undefined : nextMoveFor(card, opts.landed);
|
|
763
|
-
|
|
775
|
+
// 분해 실패로 막은 카드는 wait(failed 사유)가 정답이다 — 던지지 않고 카드를 적은 뒤 발사 0 으로 돌아간다.
|
|
776
|
+
if (move && move.kind !== 'launch' && tierSplitBlocked === undefined) throw new Error(`발사할 수 없는 과제다 — ${move.reason}`);
|
|
764
777
|
const guard = opts.writeGuard;
|
|
765
778
|
const writeCard = (target: string, next: TaskCard): void => {
|
|
766
779
|
if (!guard) { writeTaskCards(target, [next]); return; }
|
|
@@ -775,6 +788,15 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
|
775
788
|
});
|
|
776
789
|
if (!owned.ok) throw new TaskCardSupersededError(next.id);
|
|
777
790
|
};
|
|
791
|
+
// Production Pod launches use the remote-parent lint's shared boundary judge.
|
|
792
|
+
// Injected launchers are test seams and opt in explicitly at the contract test.
|
|
793
|
+
if (opts.live && opts.preflightGoalDoneBoundary && !selectionFailure && move?.kind === 'launch') {
|
|
794
|
+
readTaskAgentState(path);
|
|
795
|
+
const { missing } = inspectGoalDoneBoundary(text);
|
|
796
|
+
if (missing.length > 0) {
|
|
797
|
+
throw new Error(`goal-revision-required: 완료 경계 누락 ${missing.join(' · ')} — 골 문면에 완료 경계 코드·완료 경계 실물·완료 경계 증거 명령을 적은 뒤 다시 넘기세요`);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
778
800
|
writeCard(path, card);
|
|
779
801
|
try { debug.log('task-agent.hand', 'target-paths', { card: id, count: targetPaths.length, labelMissing: targetPathHints.labelMissing }); } catch { /* fail-soft */ }
|
|
780
802
|
try { debug.log('task-agent.graph-select', !selected.composition ? 'composition-missing' : selected.error ? 'composition-invalid' : 'composition-selected', {
|
|
@@ -783,6 +805,7 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
|
783
805
|
...(selected.error ? { error: selected.error } : {}),
|
|
784
806
|
}); } catch { /* fail-soft */ }
|
|
785
807
|
if (selectionFailure) throw new Error(`${selectionFailure} (카드 ${id})`);
|
|
808
|
+
if (tierSplitBlocked !== undefined && move) return { card, move, mode, launched: false, ...(project ? { cwd: project.target } : {}) };
|
|
786
809
|
if (!move || move.kind !== 'launch') throw new Error('조합 선택 뒤 발사 수가 없다');
|
|
787
810
|
try { debug.log('task-agent', 'handed', { taskId: id, seat: card.seat ?? null, checklistId: card.checklistId ?? null, mode, projectId: project?.id ?? null, targetIsGit, taLand: card.taLand === true, runPriority: card.identity ? runPriorityClass(card.identity) : null }); } catch { /* fail-soft */ }
|
|
788
811
|
if (childLlm) {
|
|
@@ -790,17 +813,6 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
|
790
813
|
}
|
|
791
814
|
if (mode === 'shadow') return { card, move, mode, launched: false, ...(project ? { cwd: project.target } : {}) };
|
|
792
815
|
if (!opts.launcher) throw new Error('--live 인데 launcher 가 없다');
|
|
793
|
-
if (completion === 'code-pr' && card.checklistId) {
|
|
794
|
-
const { missing } = inspectGoalDoneBoundary(text);
|
|
795
|
-
if (missing.length > 0) {
|
|
796
|
-
const reason = `goal-revision-required: 완료 경계 누락 ${missing.join(' · ')} — 골 문면을 고친 뒤 다시 넘기세요`;
|
|
797
|
-
const failed: TaskCard = { ...card, status: 'failed', history: [...card.history,
|
|
798
|
-
{ at: (opts.now ?? (() => new Date()))().toISOString(), event: 'goal-revision-required', detail: reason }] };
|
|
799
|
-
writeCard(path, failed);
|
|
800
|
-
try { debug.log('task-agent.hand', 'done-boundary-missing', { taskId: id, checklistId: card.checklistId ?? null, missing, reason }); } catch { /* fail-soft */ }
|
|
801
|
-
throw new Error(`${reason} (카드 ${id})`);
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
816
|
let prelaunch: AlreadyDoneDecision;
|
|
805
817
|
try { prelaunch = completion === 'code-pr'
|
|
806
818
|
? (opts.prelaunchInspector ?? ((input, target) => inspectPrelaunchAlreadyDone(input, target,
|
|
@@ -817,8 +829,9 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
|
|
|
817
829
|
return { card: candidate, move: nextMoveFor(candidate), mode, launched: false, ...(project ? { cwd: project.target } : {}) };
|
|
818
830
|
}
|
|
819
831
|
const runId = mintRunId();
|
|
820
|
-
const launchId =
|
|
821
|
-
|
|
832
|
+
const launchId = newLaunchUtteranceId();
|
|
833
|
+
recordLaunchUtterance({ source: 'hand', utterance: opts.text, launchId });
|
|
834
|
+
const context: TaskLaunchContext = { runId, launchId, launchUtterance: opts.text, env: { [HARNESS_RUN_ID_ENV]: runId, ELANOUS_TASK_CARD_ID: card.id,
|
|
822
835
|
...(cardPrNumber(card) ? { ELANOUS_TASK_BOUND_PR: String(cardPrNumber(card)) } : {}),
|
|
823
836
|
...(card.checklistId ? { ELANOUS_POD_SLOT_ID: card.checklistId } : {}),
|
|
824
837
|
...(card.seat ? { ELANOUS_POD_OWNER_KIND: 'seat', ELANOUS_POD_OWNER_ID: card.seat } : {}),
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TIER-SPLIT-BEFORE-LAUNCH (0.2.35 P0) — `tasks hand --tier 상|특 --live` 를 한 덩어리로 쏘지 않고, 저작 분해
|
|
3
|
+
* (TC TIER-SIZED-DECOMPOSE `decomposeToTierSizedSlices`)가 만든 «중 이하 조각»으로 나눠 조각마다 hand 발사한다.
|
|
4
|
+
* 대표: «최우선으로 중·하 난이도로 쪼개기를 정착 · 구독 sol 은 웬만해선 소진 안 함».
|
|
5
|
+
*
|
|
6
|
+
* - 분해 규칙은 TC 몫 — 여기는 그 함수를 «주입 seam» 으로 받는다. 기본 seam 은 이 파일 한 곳(`DEFAULT_TIER_SIZED_DECOMPOSE`)에서만 정한다.
|
|
7
|
+
* - 분해기 «미배선»(seam 에 undefined 명시) = `decomposer-unavailable` → 종전처럼 한 덩어리 발사 ⊕ 기록. 기본 seam 은 TC 함수다.
|
|
8
|
+
* - 분해 «실패»(ok:false · throw · 불가피 이유 없는 상 조각 · 빈/잘못된 조각) → 발사 0 · 카드 failed(history `tier-split-failed`).
|
|
9
|
+
* - 관측: `debug.log('task-agent.hand', 'tier-split', {cid, fromTier, outcome, reason?, slices, unavoidable})`.
|
|
10
|
+
*/
|
|
11
|
+
import { randomBytes } from 'node:crypto';
|
|
12
|
+
import { debug } from '../debug/log.js';
|
|
13
|
+
import { handTask, TASK_CARD_PREFIX, type HandTaskOptions, type HandTaskResult } from './task-hand.js';
|
|
14
|
+
|
|
15
|
+
// 분해 규칙·타입 정본 = TC `src/self-implement/goal-author-decompose.ts`(TIER-SIZED-DECOMPOSE · #29987).
|
|
16
|
+
import { decomposeToTierSizedSlices, type SizedSlice, type TierSizedDecomposeResult } from '../self-implement/goal-author-decompose.js';
|
|
17
|
+
export type { SizedSlice, TierSizedDecomposeResult };
|
|
18
|
+
export type TierSizedDecompose = (goal: string, opts?: { signal?: AbortSignal }) => Promise<TierSizedDecomposeResult>;
|
|
19
|
+
|
|
20
|
+
/** 기본 분해기 — TC `decomposeToTierSizedSlices`. seam 에 undefined 를 명시하면 «미배선»(decomposer-unavailable). */
|
|
21
|
+
export const DEFAULT_TIER_SIZED_DECOMPOSE: TierSizedDecompose | undefined = decomposeToTierSizedSlices;
|
|
22
|
+
|
|
23
|
+
export const TIER_SPLIT_UNAVAILABLE = 'decomposer-unavailable';
|
|
24
|
+
|
|
25
|
+
/** 분해 시간 상한 — LLM 이 매달려도 디스패처의 손 넘김 한 번을 끝없이 붙잡지 않는다. 넘으면 막힘(decompose-timeout). */
|
|
26
|
+
export const TIER_SPLIT_DECOMPOSE_TIMEOUT_MS = 300_000;
|
|
27
|
+
|
|
28
|
+
/** 조각이 부모 칸에서 물려받는 줄 머리 — hand 의 골 검사(완료 경계 셋)와 계약·경계 문맥. */
|
|
29
|
+
const INHERITED_PARENT_LABELS = /^\s*(?:[-*]\s*)?(현재 계약|완료 경계 코드|완료 경계 실물|완료 경계 증거 명령|경계|증거 보충)\s*:/;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 조각 hand 문면 = 조각 골(대상 경로·동작 — 첫 줄 유지) ⊕ 조각 표지 ⊕ 부모 칸의 계약·완료 경계·경계 줄.
|
|
33
|
+
* 분해기의 조각 골은 짧은 제목뿐이라 그대로 넘기면 hand 의 골 검사(완료 경계 누락)가 막는다(10-21 DEVICE-FIRST-AUTHORING 발사 0).
|
|
34
|
+
* 부모에 그 줄이 없으면 아무것도 더하지 않는다 — 검사가 지금처럼 거부한다(보수 쪽).
|
|
35
|
+
*/
|
|
36
|
+
export function composeSliceHandText(sliceGoal: string, parentText: string, marker: { index: number; total: number; fromTier: '상' | '특'; cid: string | null }): string {
|
|
37
|
+
const sliceLines = sliceGoal.trim().split('\n');
|
|
38
|
+
const sliceHas = new Set(sliceLines.map((line) => INHERITED_PARENT_LABELS.exec(line)?.[1]).filter(Boolean));
|
|
39
|
+
const inherited = parentText.split('\n').filter((line) => {
|
|
40
|
+
const label = INHERITED_PARENT_LABELS.exec(line)?.[1];
|
|
41
|
+
return label !== undefined && !sliceHas.has(label);
|
|
42
|
+
});
|
|
43
|
+
if (inherited.length === 0) return sliceGoal;
|
|
44
|
+
const tag = `조각 ${marker.index}/${marker.total} — 부모 ${marker.cid ?? '(칸 없음)'}(${marker.fromTier}) 를 중 이하로 나눈 몫. 아래 계약·완료 경계는 부모 칸에서 물려받았다 — 이 조각 범위만 채운다.`;
|
|
45
|
+
return [...sliceLines, tag, ...inherited].join('\n');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type TierSplitPlan =
|
|
49
|
+
| { kind: 'split'; slices: SizedSlice[] }
|
|
50
|
+
| { kind: 'blocked'; reason: string };
|
|
51
|
+
|
|
52
|
+
/** 순수 판정 — 분해 결과 → 발사 계획. 이유 없는 상 조각이 하나라도 있으면 결과 전체를 실패로 본다(이유 없는 상 0). */
|
|
53
|
+
export function planTierSplit(result: TierSizedDecomposeResult): TierSplitPlan {
|
|
54
|
+
if (!result.ok) return { kind: 'blocked', reason: `decompose-failed: ${result.reason}` };
|
|
55
|
+
if (result.slices.length === 0) return { kind: 'blocked', reason: 'no-slices' };
|
|
56
|
+
for (const [index, slice] of result.slices.entries()) {
|
|
57
|
+
if (!['하', '중', '상'].includes(slice.tier)) return { kind: 'blocked', reason: `invalid-slice-tier: #${index + 1} ${String(slice.tier)}` };
|
|
58
|
+
if (!slice.goal?.trim()) return { kind: 'blocked', reason: `empty-slice-goal: #${index + 1}` };
|
|
59
|
+
if (slice.tier === '상' && !slice.unavoidable?.trim()) return { kind: 'blocked', reason: `unjustified-상-slice: #${index + 1}` };
|
|
60
|
+
}
|
|
61
|
+
return { kind: 'split', slices: result.slices };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface TierSplitSliceOutcome { slice: SizedSlice; result?: HandTaskResult; error?: string }
|
|
65
|
+
export type TierSplitHandResult =
|
|
66
|
+
| { kind: 'whole'; result: HandTaskResult; reason?: string }
|
|
67
|
+
| { kind: 'blocked'; result: HandTaskResult; reason: string }
|
|
68
|
+
| { kind: 'split'; group: string; fromTier: '상' | '특'; slices: TierSplitSliceOutcome[] };
|
|
69
|
+
|
|
70
|
+
export interface TierSplitHandOptions extends HandTaskOptions {
|
|
71
|
+
/** 분해기 seam — 키를 안 주면 기본(`DEFAULT_TIER_SIZED_DECOMPOSE`) · undefined 를 명시하면 «미배선». */
|
|
72
|
+
decompose?: TierSizedDecompose;
|
|
73
|
+
/** 분해 시간 상한(시험 주입) — 기본 `TIER_SPLIT_DECOMPOSE_TIMEOUT_MS`. */
|
|
74
|
+
decomposeTimeoutMs?: number;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function record(data: Record<string, unknown>): void {
|
|
78
|
+
try { debug.log('task-agent.hand', 'tier-split', data); } catch { /* fail-soft */ }
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* `tasks hand` 의 발사 앞단. 분해는 `--live` ⊕ tier 상|특 일 때만 — 중·하·tier 없음·shadow 는 `handTask` 그대로(분해 호출 0).
|
|
83
|
+
*/
|
|
84
|
+
export async function handTaskWithTierSplit(opts: TierSplitHandOptions): Promise<TierSplitHandResult> {
|
|
85
|
+
const { decompose: injected, decomposeTimeoutMs = TIER_SPLIT_DECOMPOSE_TIMEOUT_MS, ...hand } = opts;
|
|
86
|
+
const fromTier = hand.tier;
|
|
87
|
+
if (!hand.live || (fromTier !== '상' && fromTier !== '특')) return { kind: 'whole', result: await handTask(hand) };
|
|
88
|
+
const decompose = 'decompose' in opts ? injected : DEFAULT_TIER_SIZED_DECOMPOSE;
|
|
89
|
+
const cid = hand.checklistId ?? null;
|
|
90
|
+
if (!decompose) {
|
|
91
|
+
record({ cid, fromTier, outcome: 'whole', reason: TIER_SPLIT_UNAVAILABLE, slices: [], unavoidable: [] });
|
|
92
|
+
return { kind: 'whole', result: await handTask(hand), reason: TIER_SPLIT_UNAVAILABLE };
|
|
93
|
+
}
|
|
94
|
+
let plan: TierSplitPlan;
|
|
95
|
+
const controller = new AbortController();
|
|
96
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
97
|
+
const timedOut = new Promise<'timeout'>((resolve) => { timer = setTimeout(() => { controller.abort(); resolve('timeout'); }, decomposeTimeoutMs); });
|
|
98
|
+
try {
|
|
99
|
+
const raced = await Promise.race([decompose(hand.text.trim(), { signal: controller.signal }), timedOut]);
|
|
100
|
+
plan = raced === 'timeout' ? { kind: 'blocked', reason: `decompose-timeout: ${decomposeTimeoutMs}ms` } : planTierSplit(raced);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
plan = { kind: 'blocked', reason: `decompose-threw: ${String((error as Error)?.message ?? error).slice(0, 200)}` };
|
|
103
|
+
} finally { clearTimeout(timer); }
|
|
104
|
+
if (plan.kind === 'blocked') {
|
|
105
|
+
record({ cid, fromTier, outcome: 'blocked', reason: plan.reason, slices: [], unavoidable: [] });
|
|
106
|
+
return { kind: 'blocked', result: await handTask({ ...hand, tierSplitBlocked: plan.reason }), reason: plan.reason };
|
|
107
|
+
}
|
|
108
|
+
const group = `${TASK_CARD_PREFIX}split-${randomBytes(4).toString('hex')}`;
|
|
109
|
+
const total = plan.slices.length;
|
|
110
|
+
const unavoidable = plan.slices.filter((slice) => slice.tier === '상').map((slice) => slice.unavoidable!.trim());
|
|
111
|
+
// 조각은 새 카드다 — 호출자 id·pr·goalId 를 조각마다 복제하면 «PR: #N» 조회·수확이 엇갈린다. 버린 것은 기록에 남긴다.
|
|
112
|
+
const dropped = { ...(hand.id ? { id: hand.id } : {}), ...(hand.cardFields?.pr !== undefined ? { pr: hand.cardFields.pr } : {}), ...(hand.cardFields?.goalId !== undefined ? { goalId: hand.cardFields.goalId } : {}) };
|
|
113
|
+
record({ cid, fromTier, outcome: 'split', group, ...(Object.keys(dropped).length ? { dropped } : {}), slices: plan.slices.map((s) => ({ tier: s.tier, files: s.files, behaviours: s.behaviours })), unavoidable });
|
|
114
|
+
const { id: _wholeId, cardFields, ...rest } = hand;
|
|
115
|
+
const base = { ...rest, ...(cardFields?.handed !== undefined ? { cardFields: { handed: cardFields.handed } } : {}) };
|
|
116
|
+
const slices: TierSplitSliceOutcome[] = [];
|
|
117
|
+
for (const [index, slice] of plan.slices.entries()) {
|
|
118
|
+
try {
|
|
119
|
+
const result = await handTask({ ...base, text: composeSliceHandText(slice.goal, hand.text, { index: index + 1, total, fromTier, cid }), tier: slice.tier,
|
|
120
|
+
tierSplit: { group, fromTier, index: index + 1, total, ...(slice.tier === '상' ? { unavoidable: slice.unavoidable!.trim() } : {}) } });
|
|
121
|
+
slices.push({ slice, result });
|
|
122
|
+
} catch (error) {
|
|
123
|
+
slices.push({ slice, error: error instanceof Error ? error.message : String(error) });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return { kind: 'split', group, fromTier, slices };
|
|
127
|
+
}
|
|
@@ -6,6 +6,7 @@ export interface BuildWorkOrderInput {
|
|
|
6
6
|
lifeId?: string;
|
|
7
7
|
priority?: string;
|
|
8
8
|
peers?: string;
|
|
9
|
+
boundary?: string;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
/** Build the normalized nine-field core from already-grounded inputs; no CLI, filesystem, or launch side effects. */
|
|
@@ -16,6 +17,7 @@ export function buildWorkOrder(input: BuildWorkOrderInput): WorkOrder {
|
|
|
16
17
|
version: input.version,
|
|
17
18
|
priority: input.priority,
|
|
18
19
|
peers: input.peers,
|
|
20
|
+
boundary: input.boundary,
|
|
19
21
|
}));
|
|
20
22
|
if (!parsed.ok) throw new Error(parsed.reason);
|
|
21
23
|
return parsed.order;
|
|
@@ -79,8 +79,9 @@ export function parseWorkOrder(source: string): ParseWorkOrderResult {
|
|
|
79
79
|
const unknownFields: string[] = [];
|
|
80
80
|
const cells = {} as Record<WorkOrderField, string>;
|
|
81
81
|
for (const field of WORK_ORDER_FIELDS) {
|
|
82
|
-
const
|
|
83
|
-
|
|
82
|
+
const value = record[field];
|
|
83
|
+
const text = cellText(value);
|
|
84
|
+
if (value == null || (typeof value === 'string' && !value.trim())) unknownFields.push(field);
|
|
84
85
|
cells[field] = text;
|
|
85
86
|
}
|
|
86
87
|
return { ok: true, order: { cellId: rawCellId.trim(), ...cells, unknownFields } };
|
|
@@ -10,10 +10,13 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { DecomposeInput } from './generator.js';
|
|
12
12
|
import type { ProposalValidationError } from './generator-schema.js';
|
|
13
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
14
|
+
import { resolve } from 'node:path';
|
|
13
15
|
|
|
14
16
|
export type DecomposePromptProfile = 'goal-author-coarse';
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
/** TaskGenerator's safety ceiling, not an authoring target; goal-author splits by slice size. */
|
|
19
|
+
export const GOAL_AUTHOR_SIZE_SAFETY_MAX_SLICES = 15;
|
|
17
20
|
|
|
18
21
|
export interface BuildPromptOptions {
|
|
19
22
|
maxTasks: number;
|
|
@@ -39,6 +42,35 @@ const CODING_GOAL_KINDS: ReadonlySet<string> = new Set([
|
|
|
39
42
|
'agentic',
|
|
40
43
|
]);
|
|
41
44
|
|
|
45
|
+
/** Read the existing device sources at authoring time; the LLM has no file tools in this phase. */
|
|
46
|
+
let deviceInventoryCache: string[] | undefined;
|
|
47
|
+
function deviceInventory(): string[] {
|
|
48
|
+
if (deviceInventoryCache) return deviceInventoryCache;
|
|
49
|
+
const root = resolve(import.meta.dir, '../..');
|
|
50
|
+
const fallback = ['- Device inventory unavailable in this installation; verify a named device before claiming it exists.'];
|
|
51
|
+
if (!existsSync(resolve(root, 'src/ux-sim'))) return deviceInventoryCache = fallback;
|
|
52
|
+
try {
|
|
53
|
+
const files = readdirSync(resolve(root, 'src/ux-sim'))
|
|
54
|
+
.filter((name) => name.endsWith('.ts') && !name.endsWith('.test.ts')).sort();
|
|
55
|
+
const monkey = readFileSync(resolve(root, 'src/ux-sim/event-monkey.ts'), 'utf8');
|
|
56
|
+
const kinds = monkey.match(/export const EVENT_MONKEY_KINDS = \[([\s\S]*?)\] as const;/)?.[1]
|
|
57
|
+
?.match(/'[^']+'/g)?.map((kind) => kind.slice(1, -1)) ?? [];
|
|
58
|
+
let rows: string[] = [];
|
|
59
|
+
try {
|
|
60
|
+
const manual = readFileSync(resolve(root, 'docs/manual/MANUAL-ux-simulation-devices-2026-08-23.md'), 'utf8');
|
|
61
|
+
rows = manual.split('\n').filter((line) => line.startsWith('|') && line.includes('`src/ux-sim/'));
|
|
62
|
+
} catch { /* Published packages omit docs/manual; source catalog still applies. */ }
|
|
63
|
+
return deviceInventoryCache = [
|
|
64
|
+
`- src/ux-sim files: ${files.join(', ')}`,
|
|
65
|
+
`- event-monkey kinds: ${kinds.join(', ')}`,
|
|
66
|
+
...(rows.length ? [] : ['- manual §1 table unavailable in this installation; use the source files and event kinds above.']),
|
|
67
|
+
...rows.map((row) => `- manual §1: ${row.replace(/\s*\|\s*/g, ' · ').slice(0, 500)}`),
|
|
68
|
+
];
|
|
69
|
+
} catch {
|
|
70
|
+
return deviceInventoryCache = fallback;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
42
74
|
export function buildDecomposePrompt(
|
|
43
75
|
input: DecomposeInput,
|
|
44
76
|
opts: BuildPromptOptions
|
|
@@ -53,7 +85,7 @@ export function buildDecomposePrompt(
|
|
|
53
85
|
lines.push(
|
|
54
86
|
'You are the monad-agent Task Orchestrator decomposition planner.',
|
|
55
87
|
isGoalAuthorCoarse
|
|
56
|
-
?
|
|
88
|
+
? 'Break the objective into implementation slices that a low or medium tier model can finish. Split by slice size, not a target number of slices; the task count limit is only a safety ceiling.'
|
|
57
89
|
: 'Break the objective into 3-7 concrete, single-responsibility tasks.',
|
|
58
90
|
'',
|
|
59
91
|
'## Output (STRICT JSON)',
|
|
@@ -119,9 +151,10 @@ export function buildDecomposePrompt(
|
|
|
119
151
|
'- ★ Complete dependsOn contracts: if a phase CONSUMES another phase\'s output, that producing phase MUST be in this phase\'s `dependsOn` (by index). A consumer with no dependsOn on its producer looks like an ungrounded/orphan dependency to the critique. Trace every consumed symbol to either grounding (exists) or a dependsOn phase (produced this mission).',
|
|
120
152
|
...(isGoalAuthorCoarse
|
|
121
153
|
? [
|
|
122
|
-
'-
|
|
123
|
-
'-
|
|
124
|
-
'- Keep
|
|
154
|
+
'- Goal-author size: each slice should touch at most 4 target files, change at most 2 behaviors, and create at most 2 files. Count tests and runtime wiring among target files.',
|
|
155
|
+
'- Prefer low tier (at most 2 files, 1 behavior, 1 new file), then medium tier (at most 4 files, 2 behaviors, 2 new files). Do not make a high tier slice merely to reduce the number of slices.',
|
|
156
|
+
'- Keep the executable dependency path through dependsOn; split oversized work into dependent slices rather than hiding multiple behaviors in one title.',
|
|
157
|
+
'- A high tier slice is allowed only when it cannot be split further without breaking an inseparable operation. State its unavoidable reason in the rationale.',
|
|
125
158
|
]
|
|
126
159
|
: [
|
|
127
160
|
'- Small scope: keep each task ≈≤250 LOC of change. If a step is bigger, split it into sibling tasks or defer to a recursive decompose (depth) rather than one giant task.',
|
|
@@ -155,13 +188,29 @@ export function buildDecomposePrompt(
|
|
|
155
188
|
if (isGoalAuthorCoarse) {
|
|
156
189
|
lines.push(
|
|
157
190
|
'',
|
|
158
|
-
'## Goal-author
|
|
159
|
-
'-
|
|
160
|
-
'-
|
|
161
|
-
'-
|
|
162
|
-
'- Every
|
|
191
|
+
'## Goal-author size-bounded slicing (follow strictly)',
|
|
192
|
+
'- Use the task budget as a safety ceiling, not a target. Add dependent slices whenever one slice would exceed medium size.',
|
|
193
|
+
'- Give each slice an executable outcome with tests or runtime wiring inside its size limit; place further wiring in a dependent slice.',
|
|
194
|
+
'- Every slice title MUST name at least one actual file path or function name because only the title is passed to the next stage; slices must remain grounded and verifiable.',
|
|
195
|
+
'- Every task JSON must include files, behaviours, newFiles and tier. Example: {"index":0,"title":"대상 경로: src/a.ts · 동작: 연결","files":1,"behaviours":1,"newFiles":0,"tier":"low","surface":{"kind":"llm-direct","prompt":"wire src/a.ts"}}.',
|
|
196
|
+
'- Only the title reaches the sizing fallback: start it with "대상 경로:" and name all touched paths; add one "동작:" clause per changed behavior and "신규 경로:" for each new file. Keep the title within 80 characters by splitting oversized work.',
|
|
163
197
|
'- Fold non-code investigation or design into the implementation slice that needs it; do not emit it as a standalone slice.',
|
|
164
|
-
'- Use dependsOn
|
|
198
|
+
'- Use dependsOn for genuine ordering between independently completable slices, including definition before dependent runtime wiring.',
|
|
199
|
+
);
|
|
200
|
+
// ── 장치 우선 분해 (DEVICE-FIRST-AUTHORING · 대표 10-21 18:1x 골 저작 지침) ──
|
|
201
|
+
// 골 저작의 검증 계획(TDD) 절이 무대·층을 고를 때 그 시험에 필요한 mock 장치·주입 사건 정의의
|
|
202
|
+
// 존재를 먼저 확인하게 한다. 장치가 없으면 «실물 없음»으로 초록이 막히므로 첫 조각이 장치 조각이 된다.
|
|
203
|
+
lines.push(
|
|
204
|
+
'',
|
|
205
|
+
'## Device-first decomposition (DEVICE-FIRST-AUTHORING — follow strictly)',
|
|
206
|
+
'### Existing device inventory (read from this checkout; use these names before proposing a new device)',
|
|
207
|
+
...deviceInventory(),
|
|
208
|
+
'- The objective\'s verification plan (검증 계획/TDD) section picks a stage and ladder tier (무대·층) — e.g. a `src/ux-sim/*` stage at L2 (fake-llm·fake-bin·fake-clock). BEFORE writing slices, CHECK whether the mock device or injected event definition that this verification plan needs ALREADY EXISTS: look in `src/ux-sim/*`, the §1 device table of `docs/manual/MANUAL-ux-simulation-devices-2026-08-23.md`, and the event-monkey event kinds.',
|
|
209
|
+
'- Two branches — exactly one applies per needed device:',
|
|
210
|
+
' - Device EXISTS: its name MUST go into the verification plan wording — the slice that tests the feature carries the device\'s exact name (device file / §1 table row / event kind) in its acceptance criteria and reuses the device; never re-create it.',
|
|
211
|
+
' - Device MISSING: the FIRST slice MUST be a device slice that develops that device feature first — the mock device or injected event definition under `src/ux-sim/*` — and every slice that tests the feature depends on it (구현할 때 해당 시험 mock 장치나 이벤트 정의가 있나 확인하고, 없으면 그 장치 피처를 먼저 개발).',
|
|
212
|
+
'- Do NOT create the device itself here beyond emitting that device slice (장치 자체는 만들지 않는다 — 조각으로 내보낼 뿐); consumer slices reference it only via dependsOn.',
|
|
213
|
+
'- Device slices obey the same size bounds and acceptance bar as every other slice — the size rules (TIER-SIZED-DECOMPOSE) and the green-judgment rules are UNCHANGED.',
|
|
165
214
|
);
|
|
166
215
|
}
|
|
167
216
|
|
|
@@ -149,6 +149,39 @@ export function ownerCodexMirrorCandidate(candidates: readonly RotationCandidate
|
|
|
149
149
|
});
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
export interface OwnerCodexMirrorAccount { account: string; usedPercent: number | null; thresholdPercent: number; expiresAt: number }
|
|
153
|
+
|
|
154
|
+
/** The remote may rotate only across the accounts HQ actually installed in this launch snapshot. */
|
|
155
|
+
export function parseOwnerCodexMirrorAccounts(raw: string): OwnerCodexMirrorAccount[] {
|
|
156
|
+
let parsed: unknown;
|
|
157
|
+
try { parsed = JSON.parse(raw); } catch { throw new Error('HQ Codex 미러 계정 목록이 잘못됐다'); }
|
|
158
|
+
if (!Array.isArray(parsed) || parsed.length === 0 || parsed.length > 16) throw new Error('HQ Codex 미러 계정 목록이 잘못됐다');
|
|
159
|
+
const seen = new Set<string>();
|
|
160
|
+
return parsed.map((item: unknown) => {
|
|
161
|
+
if (!item || typeof item !== 'object') throw new Error('HQ Codex 미러 계정 항목이 잘못됐다');
|
|
162
|
+
const value = item as Record<string, unknown>;
|
|
163
|
+
const { account, usedPercent, thresholdPercent, expiresAt } = value;
|
|
164
|
+
if (typeof account !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(account) || seen.has(account)
|
|
165
|
+
|| (usedPercent !== null && (typeof usedPercent !== 'number' || !Number.isFinite(usedPercent) || usedPercent < 0 || usedPercent > 100))
|
|
166
|
+
|| typeof thresholdPercent !== 'number' || !Number.isFinite(thresholdPercent) || thresholdPercent <= 0 || thresholdPercent > 100
|
|
167
|
+
|| typeof expiresAt !== 'number' || !Number.isFinite(expiresAt) || expiresAt <= 0)
|
|
168
|
+
throw new Error('HQ Codex 미러 계정 항목이 잘못됐다');
|
|
169
|
+
seen.add(account);
|
|
170
|
+
return { account, usedPercent: usedPercent as number | null, thresholdPercent, expiresAt };
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Do not plan a Pod against an access token that might expire while it starts and runs. */
|
|
175
|
+
export function freshOwnerCodexMirrorAccounts(accounts: readonly OwnerCodexMirrorAccount[], now = Date.now()): OwnerCodexMirrorAccount[] {
|
|
176
|
+
return accounts.filter(({ expiresAt }) => expiresAt > now + 3 * 60 * 60 * 1000);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export function selectOwnerCodexMirrorCandidates(candidates: readonly RotationCandidate[], accounts: readonly OwnerCodexMirrorAccount[]): RotationCandidate[] {
|
|
180
|
+
const selected = accounts.flatMap(({ account, usedPercent }) => ownerCodexMirrorCandidate(candidates, account, usedPercent ?? undefined));
|
|
181
|
+
if (selected.length !== accounts.length) throw new Error('HQ Codex 미러 계정 일부가 원격 auth-store 후보에 없다');
|
|
182
|
+
return selected;
|
|
183
|
+
}
|
|
184
|
+
|
|
152
185
|
/** Job 마다 다음 계정 — 잔량 순으로 돌려 가며. 쓸 계정이 없으면 만들 때 이유를 대고 던진다. */
|
|
153
186
|
export function makePodAccountBroker(plan: PodAccountPlan): () => string {
|
|
154
187
|
if (plan.usable.length === 0) {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
// BEDROCK-PROVIDER ② (0.2.24) — bedrock 은 «이름 있는 AWS Secret» 이 클러스터에 있을 때만 뜬다(pod-bedrock-child.ts · 발사 전 거부).
|
|
11
11
|
// ZAI-POD-CHILD (0.2.24) — glm 은 Z.ai GLM Coding Plan(정액 구독) · «이름 있는 ZAI Secret» 이 클러스터에 있을 때만 뜬다(pod-zai-child.ts · 발사 전 거부 · 동시 상한 넘치면 정책대로).
|
|
12
|
-
export const POD_CHILD_PROVIDERS = ['openai-codex', 'grok', 'openrouter', 'anthropic', 'bedrock', 'glm'] as const;
|
|
12
|
+
export const POD_CHILD_PROVIDERS = ['openai-codex', 'grok', 'openrouter', 'opengateway', 'anthropic', 'bedrock', 'glm'] as const;
|
|
13
13
|
export type PodChildProvider = typeof POD_CHILD_PROVIDERS[number];
|
|
14
14
|
|
|
15
15
|
/** 사람이 쓰는 별칭 → 정식 이름. */
|