elanous 0.2.40 → 0.2.42
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/README.md +7 -7
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/{HjeK7zONHfR7op1hKXp4k → X1ucLw10Cds_h614NoEnh}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4769.9fd582071301f382.js → 1063.2fb8a9dc55c731f2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +36 -0
- package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{470.51a72a2348306455.js → 1262.e804feb8fd1acb8c.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7219-15bdd9a80661af8e.js → 1455-530ca16c7e71baff.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1281.d81877e35b9068f4.js → 1487.2f67b79444062da6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +32 -0
- package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +286 -0
- package/apps/pwa/out/_next/static/chunks/2160.a097e7b138ae1c55.js +23 -0
- package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +34 -0
- package/apps/pwa/out/_next/static/chunks/{1350.59f40e39e02d91b1.js → 2456.b6de0e1c05f28843.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +1 -0
- package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2690.0521c738b7749931.js +115 -0
- package/apps/pwa/out/_next/static/chunks/{5436.fdf6fa8ae3e9588d.js → 2974.595d1e29d040cb6a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5383.bdfa5d886e39a826.js → 3207.a756c95e9ec8c3c8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +93 -0
- package/apps/pwa/out/_next/static/chunks/{2177.df8547f9d7215c4e.js → 3347.f846266b5e5f3ede.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +41 -0
- package/apps/pwa/out/_next/static/chunks/{9184.45afbf44fec87574.js → 3482.a9ae9d2ad6a5bd97.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3507.97e1977bc4d5fb0a.js +2 -0
- package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{8099.1cccf31c1baa7e1c.js → 3741.9cf76acaa2ee5298.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4864a2ca.1c1c280a7772c5e5.js → 3d0154af.5331fec737ffe8c3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4043.6b91203436c9c86b.js +309 -0
- package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +77 -0
- package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3330.7443183b7e6fdbdf.js → 4276.336d76d858fcdf1b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +148 -0
- package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +74 -0
- package/apps/pwa/out/_next/static/chunks/{3b355b3d.6f73c98bf6f9c749.js → 50061469.0326382241ef3b2d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +149 -0
- package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +27 -0
- package/apps/pwa/out/_next/static/chunks/{8d173e38.18a2f7b4e1848bdb.js → 53c73f84.373b6160adfa89a4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1537-6bb97b5214928ea9.js → 5431-72a1dbde59400691.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5885.0a3e52c8faccec98.js +287 -0
- package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{261.0d471e8aded799f3.js → 6131.348b7d6bdcd267ce.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +90 -0
- package/apps/pwa/out/_next/static/chunks/{9175.2de5209a5ce6f68a.js → 6377.bc7df239edbff244.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2226.2cf61ec781827219.js → 6632.0eac1c554f8f2ef3.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +104 -0
- package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +94 -0
- package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7279-c199ea83f34338fa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b84cad00.594027ebe0531fe2.js → 73d2eb0e.4966ad55293c801a.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{6257.c0037b8949239f5e.js → 7411.9b4b8b747dc7b802.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +1 -0
- package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9189505a.980427ac048c8c60.js → 7a98bc80.fa935989e829f9c2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8138.6c10b2a356d52fca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2566.beaffc3a5e1fcd2e.js → 8262.ddc03e06b733f184.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +8 -0
- package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +79 -0
- package/apps/pwa/out/_next/static/chunks/{8272-025653884f9645d2.js → 8546-6f03f8ea34dd61d9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6051-0ae955eedb10adb9.js → 8673-bab689a55f7e13b9.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4351.0f37a6db2b34d50b.js → 9249.976f1e69a9d80754.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9353-12bfff0c130104cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9415.69e4a21c60c7d2db.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6749.0744ce6eb08d40e9.js → 9427.96aa912ddb5801e0.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7611.85f045bf232053ac.js → 9633.ce5bddc56784da72.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{3746-f80a78f220bf37b5.js → 9656-374232558fd528d0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +62 -0
- package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9a852a62-6192a6ea9346ced3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/{page-83d27757e2b8060a.js → page-0e3d7b9421b79dac.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-139d722de1dcd6c1.js → page-bf067887b3307423.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{409c787b.e48c5bec8ec10456.js → b450776b.3db34d8d965f82d3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{ca3702f8.2913182e73889fa2.js → e8543907.5b040a5f22a0b0e5.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +1 -0
- package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +22 -22
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +21 -21
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -24
- 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 +22 -22
- 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 +23 -24
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +23 -24
- 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 +6 -1
- package/catalog/models/openai/gpt-6.1-sol.yaml +16 -0
- package/catalog/models/openai/gpt-6.1-terra.yaml +16 -0
- package/docs/goal-context/04-mock-scenarios.md +13 -0
- package/graphs/catalog/catalog.yaml +1 -1
- package/graphs/demo/persona-teacher/lesson-pack.yaml +16 -0
- package/graphs/demo/persona-teacher/recipes.yaml +17 -0
- package/graphs/demo/persona-teacher/weekly-lesson.yaml +36 -0
- package/graphs/heal/heal-loop.yaml +1 -0
- package/graphs/overlays/stop-heal-ladder.yaml +136 -2
- package/graphs/release/release-loop.yaml +3 -1
- package/graphs/units/gate/gate.yaml +20 -0
- package/graphs/units/git/git.yaml +26 -0
- package/graphs/units/implement/implement.yaml +19 -0
- package/graphs/units/landing/landing.yaml +18 -0
- package/graphs/units/review/review.yaml +20 -0
- package/graphs/units/verbs/recipes.yaml +13 -10
- package/graphs/units/verbs/research.yaml +20 -0
- package/graphs/work/research-report.yaml +21 -3
- package/package.json +1 -1
- package/scripts/disk-steward.ts +46 -0
- package/scripts/fleet/node-setup.sh +50 -0
- package/scripts/graph-units/verbs/research.ts +55 -0
- package/scripts/heal/run-role.ts +99 -5
- package/scripts/land-global-checks.ts +6 -1
- package/scripts/lib/decompose-ab.ts +1 -0
- package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
- package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
- package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
- package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
- package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
- package/scripts/lib/tui-regress-checks.ts +33 -13
- package/scripts/llm-cost-ledger.ts +179 -8
- package/scripts/measure-nl-routing-corpus.ts +10 -2
- package/scripts/persona-teacher/weekly-lesson-node.ts +172 -0
- package/scripts/public-copy-lint.ts +163 -19
- package/scripts/ratchets/train-side-invariants.sh +0 -1
- package/scripts/release-loop/gate-autoheal.ts +117 -0
- package/scripts/release-loop/gate-baseline-receipt.ts +55 -10
- package/scripts/release-loop/gate-diff.ts +22 -3
- package/scripts/release-loop/gate-image-pin.ts +81 -0
- package/scripts/release-loop/gate-node-sim.ts +207 -0
- package/scripts/release-loop/gate-node.ts +489 -62
- package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
- package/scripts/release-loop/gate-radius-live.ts +97 -13
- package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
- package/scripts/release-loop/gate-shard-load-flaky.ts +256 -0
- package/scripts/release-loop/gate-train-receipts.ts +122 -0
- package/scripts/release-loop/gate-triage-node.ts +70 -10
- package/scripts/release-loop/resume-release.ts +330 -23
- package/scripts/release-loop/traffic-node.ts +6 -3
- package/scripts/release-loop/unattended-release.ts +4 -2
- package/scripts/shadow-authoring-probe.ts +20 -0
- package/scripts/ux-sim.ts +37 -3
- package/scripts/warm-pool-provider-config.ts +263 -0
- package/skills/omni-crawl/SKILL.md +5 -2
- package/skills/omni-crawl/scripts/main.ts +84 -23
- package/src/acp/core-turn-bridge.ts +99 -4
- package/src/agent/registry.ts +2 -0
- package/src/agent/task-notification.ts +25 -5
- package/src/agent/types.ts +6 -0
- package/src/agent-mission/mission-cli.ts +24 -0
- package/src/agent-mission/mission-out.ts +595 -0
- package/src/agent-mission/tool-install.ts +88 -2
- package/src/agent-substrate/context-strategy.ts +4 -4
- package/src/agent-substrate/self-review-cli.ts +267 -40
- package/src/auto-research/research-turn.ts +133 -51
- package/src/autopilot/discovery/wiki-claim-proposer.ts +22 -1
- package/src/autopilot/pr-manager.ts +38 -7
- package/src/autopilot/pty-control-loop.ts +2 -0
- package/src/boot/daemon-tools/self-implement.ts +46 -9
- package/src/budget/shadow-arms.ts +52 -0
- package/src/capture/tui-self-report.ts +22 -6
- package/src/chat/index.ts +1 -1
- package/src/chat/pickers/state.ts +7 -1
- package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
- package/src/cli/log-event-names.ts +5 -0
- package/src/cli/mcp-login.ts +8 -18
- package/src/cli/msg-cli.ts +57 -1
- package/src/cli/pr-land-heavy-remote.ts +47 -9
- package/src/cli/pr-land-overlap-evidence.ts +100 -1
- package/src/cli/pr-land-pod-shadow-job.ts +60 -0
- package/src/cli/release-checklist-read-cli.ts +20 -10
- package/src/cli/release-cli.ts +27 -1
- package/src/cli/research-cli.ts +4 -5
- package/src/cli/sim-cli.ts +7 -1
- package/src/cli/tasks-cli.ts +12 -4
- package/src/codex/models.ts +30 -15
- package/src/compact/auto.ts +8 -1
- package/src/control-plane/ledger.ts +52 -2
- package/src/control-plane/server.ts +16 -2
- package/src/core-turn/run-core-turn.ts +313 -89
- package/src/core-turn/run-goal-loop.ts +106 -2
- package/src/core-turn/types.ts +2 -0
- package/src/dashboard/acp-boot.ts +72 -3
- package/src/dashboard/classic-sidetab-mission-job.ts +58 -0
- package/src/dashboard/classic-sidetab-mission.ts +185 -0
- package/src/dashboard/index.ts +155 -15
- package/src/dashboard/input/agent-wake.ts +23 -1
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +9 -0
- package/src/dashboard/mission-cli-consumer.ts +153 -0
- package/src/dashboard/seat-boot-preamble.ts +171 -1
- package/src/dashboard/side-basic-runtime.ts +54 -1
- package/src/dashboard/sidetab-runtime.ts +90 -1
- package/src/dashboard/skill-catalog-preamble.ts +101 -0
- package/src/dashboard/skill-detection-runtime.ts +55 -15
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
- package/src/dashboard/turn-preamble.ts +65 -16
- package/src/dashboard/turn-prompt-runtime.ts +4 -2
- package/src/disk-steward/judge.ts +73 -0
- package/src/disk-steward/ledger.ts +122 -0
- package/src/disk-steward/steward.ts +373 -0
- package/src/domains/guardian-tick.ts +191 -2
- package/src/graph-runner/graph-cli.ts +44 -7
- package/src/graph-runner/graph-tick.ts +10 -2
- package/src/graph-runner/in-process-registry.ts +37 -0
- package/src/graph-runner/runner.ts +34 -4
- package/src/grok/agent-search.ts +14 -4
- package/src/grok/credential.ts +28 -11
- package/src/grounding/ref-index.ts +19 -0
- package/src/grounding/sources-cli.ts +9 -1
- package/src/harness/harness-cli-command.ts +267 -14
- package/src/harness/harness-incidents.ts +312 -7
- package/src/harness/harness-pod-dispatch.ts +81 -15
- package/src/harness/harness-space.ts +15 -1
- package/src/harness/harness-stop.ts +155 -11
- package/src/harness/progress-worker-entry.ts +59 -0
- package/src/harness/progress-worker-runtime.ts +11 -0
- package/src/index.ts +52 -7
- package/src/instance/dev-project.ts +25 -0
- package/src/instance/spawn-elanous.ts +6 -4
- package/src/intelligence-map/model-alias.ts +6 -5
- package/src/intelligence-map/model-catalog.ts +59 -2
- package/src/llm/model-defaults.ts +4 -4
- package/src/llm.ts +208 -19
- package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
- package/src/loops/orchestrator/tick.ts +61 -0
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/mcp/mcp-oauth.ts +3 -1
- package/src/model-tier/llm-tier-map.ts +9 -9
- package/src/model-tier/turn-tier.ts +1 -1
- package/src/msg/msg-mirror-github.ts +80 -0
- package/src/msg/msg-mirror-policy.ts +61 -0
- package/src/msg/msg-mirror-runner.ts +219 -0
- package/src/msg/msg-mirror-state.ts +33 -0
- package/src/msg/msg-store.ts +11 -0
- package/src/native-tool-catalog.ts +2 -2
- package/src/nexus/api/harness-traversal.ts +11 -0
- package/src/output-truncation.ts +41 -12
- package/src/pr-tool/census.ts +3 -2
- package/src/project/project-store.ts +48 -1
- package/src/pty-shell/tui-run-state.ts +188 -2
- package/src/release-loop/checklist-target-path-hint.ts +13 -0
- package/src/release-loop/checklist.ts +9 -1
- package/src/release-loop/gate-host-reservation.ts +144 -0
- package/src/release-loop/release-schedule.ts +90 -1
- package/src/repl/index.ts +43 -2
- package/src/research/axis-fanout.ts +121 -16
- package/src/research/bloom-exemplars.ts +137 -0
- package/src/research/gap-followup.ts +13 -1
- package/src/research/plugin-discovery.ts +36 -14
- package/src/research-bridge/invoke.ts +22 -5
- package/src/research-bridge/types.ts +2 -0
- package/src/self-dev/ask-launch-flow.ts +39 -25
- package/src/self-dev/decompose.ts +119 -5
- package/src/self-dev/dev-cli.ts +17 -17
- package/src/self-dev/graph-front-nodes.ts +23 -0
- package/src/self-dev/launch-preflight-text.ts +5 -6
- package/src/self-dev/launch-preflight.ts +9 -4
- package/src/self-dev/orchestrate.ts +27 -2
- package/src/self-dev/review-provider-fallback.ts +9 -2
- package/src/self-dev/run-supervisor.ts +226 -6
- package/src/self-dev/run-types.ts +7 -0
- package/src/self-implement/doctor-visit.ts +88 -0
- package/src/self-implement/gate-artifacts.ts +13 -0
- package/src/self-implement/gate-cli.ts +54 -24
- package/src/self-implement/gate-remote.ts +23 -5
- package/src/self-implement/goal-author-clarification.ts +31 -12
- package/src/self-implement/goal-author.ts +403 -8
- package/src/self-implement/graph-overlay-yaml.ts +7 -0
- package/src/self-implement/graph-stage-units.ts +172 -0
- package/src/self-implement/graph-templates.ts +162 -1
- package/src/self-implement/graph-variant.ts +37 -4
- package/src/self-implement/headless-elanous-driver.ts +31 -2
- package/src/self-implement/heal-intake.ts +112 -4
- package/src/self-implement/heal-triage.ts +20 -0
- package/src/self-implement/host-regate.ts +31 -8
- package/src/self-implement/knowhow-pack.ts +38 -0
- package/src/self-implement/merge-train.ts +5 -0
- package/src/self-implement/orchestrator.ts +359 -30
- package/src/self-implement/regate-detail.ts +38 -1
- package/src/self-implement/rework-child-provider.ts +25 -0
- package/src/self-implement/run-chart.ts +119 -0
- package/src/self-implement/run-ledger.ts +176 -17
- package/src/self-implement/run-stop.ts +208 -5
- package/src/self-implement/running-runs.ts +35 -12
- package/src/self-implement/self-implement-cli.ts +36 -4
- package/src/self-implement/stop-autoheal-operational.ts +43 -0
- package/src/self-implement/stop-autoheal.ts +28 -6
- package/src/session/chat.ts +69 -58
- package/src/session/request-size-guard.ts +123 -0
- package/src/session-runtime/index.ts +98 -4
- package/src/session-runtime/tier-flip.ts +3 -3
- package/src/sidetab-core/model.ts +150 -0
- package/src/sidetab-core/visible-agent-mission.ts +186 -0
- package/src/skills/name-match.ts +20 -0
- package/src/skills/tools/agent.ts +30 -2
- package/src/skills/tools/omni-search.ts +67 -5
- package/src/task-agent/parent-host.ts +14 -1
- package/src/task-agent/pod-distributor-entry.ts +3 -0
- package/src/task-agent/task-hand.ts +31 -1
- package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +43 -0
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +29 -4
- package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
- package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +163 -13
- package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +209 -39
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +280 -60
- package/src/task-orchestrator/surfaces/self-implement.ts +18 -0
- package/src/tokens.ts +35 -2
- package/src/tool-runtime/agent-runtime.ts +1 -0
- package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
- package/src/tool-runtime/skill-exec-runtime.ts +33 -13
- package/src/tool-runtime/types.ts +1 -0
- package/src/tui/entry.ts +24 -7
- package/src/tui/sidetab/attach.ts +47 -0
- package/src/tui/sidetab/list.ts +45 -0
- package/src/tui/sidetab/nl-tool.ts +2 -136
- package/src/tui/sidetab/peek.ts +52 -0
- package/src/tui-client/dashboard-session.ts +3 -0
- package/src/tui-client/local-chat-turn.ts +26 -13
- package/src/tui.ts +22 -0
- package/src/user-config.ts +11 -5
- package/src/ux-sim/fake-kubectl.ts +37 -3
- package/src/ux-sim/fault-needs-human-reason-repair.ts +107 -0
- package/src/ux-sim/fault-pod-child-result.ts +42 -0
- package/src/ux-sim/fault-pool-cap.ts +11 -6
- package/src/ux-sim/mock-scenario-catalog.json +41 -0
- package/src/ux-sim/mock-scenario-catalog.ts +156 -0
- package/src/ux-sim/release-sim-rig.ts +262 -0
- package/src/ux-sim/scenario.ts +116 -23
- package/src/ux-sim/seminar-rehearsal.ts +109 -0
- package/src/ux-sim/subagent-tools-device.ts +2 -2
- package/src/version/packed-revision.json +1 -1
- package/src/voice/voice-tts-singleton.ts +18 -3
- package/src/web-search/grok.ts +5 -9
- package/apps/pwa/out/_next/static/chunks/1060.014f1f01a17aec26.js +0 -115
- package/apps/pwa/out/_next/static/chunks/1415.79821ec7ae99acdb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1452.162bb2d9d699e82a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/147.f92f63bbc5e85fa5.js +0 -286
- package/apps/pwa/out/_next/static/chunks/1661.fb425a1d8a065b72.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1671-1c22b40b50b208f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1758.0204d3f48783c49d.js +0 -90
- package/apps/pwa/out/_next/static/chunks/1806.027bf78b6a94d340.js +0 -104
- package/apps/pwa/out/_next/static/chunks/2047.8f23e210995d4548.js +0 -2
- package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2066.a77257c8c350770a.js +0 -23
- package/apps/pwa/out/_next/static/chunks/2096-a938496bc996dcbd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2281-b8cede695c6c650e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2499.02fbfd18126c10c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2522.f2766b76d22c8bdf.js +0 -34
- package/apps/pwa/out/_next/static/chunks/2615.3c9738153de3ef3f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2727.e703d99ac414916d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2752.7904b8df0254d0ae.js +0 -27
- package/apps/pwa/out/_next/static/chunks/2762-5051a862dfa40e99.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2767-31784bfedf8e245d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2774-719820e3f5b2a3eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2829-734fe8bf2eee7347.js +0 -1
- package/apps/pwa/out/_next/static/chunks/311-32dcac79970985e8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3175-f93f7495cd28253c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3184.8da993f5502d2140.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3231-d7c981db0ff8bdcc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3250.151309c5176d6b4b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3517.a5aa1797a9dbf2ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3567-45f676877ed9e8a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3819.8a1de79b2e8c7298.js +0 -24
- package/apps/pwa/out/_next/static/chunks/39.9b37b0be4c128a83.js +0 -77
- package/apps/pwa/out/_next/static/chunks/4023.a19045970a9ce16a.js +0 -36
- package/apps/pwa/out/_next/static/chunks/413-24c8284bda08241d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4135.e45d6ebc29e20647.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4283.65502f5d0e6ff6c0.js +0 -287
- package/apps/pwa/out/_next/static/chunks/4305-4e28fa92a7b34a5b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4335-50efa61fd7613142.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4720.ecbd1693fa151068.js +0 -1
- package/apps/pwa/out/_next/static/chunks/483.725e4a61be922788.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4969-4b209d7307410c00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5068-c7f53862f83c0917.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5315.bc96711c24dfefe2.js +0 -74
- package/apps/pwa/out/_next/static/chunks/5542.efbf14f16baed4dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5622.94893f5aea7185d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5644.8f401a25601d05fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5658.35f70eb9871a54bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5721.7bdc0e904c76ab51.js +0 -8
- package/apps/pwa/out/_next/static/chunks/5790-eef0ca20884a6bdf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5802.ef0d8598ca68fe84.js +0 -62
- package/apps/pwa/out/_next/static/chunks/5890.fb974729788dcb71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5924.5ef25cddd36d5dbf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5979-e59c099ebf8d1f35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6020.714cfeada2315e2e.js +0 -94
- package/apps/pwa/out/_next/static/chunks/6027-dfe0349d8c50f698.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6178.bc4730c86cf74536.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6273.d808b0dcb3c2b155.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6292.6ef1df64fa6a4c8a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/647-af8dd920ba46533c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6541-170dc5c59e135c0c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6624.981ef7caeb680560.js +0 -32
- package/apps/pwa/out/_next/static/chunks/6742-a1ad4a94ba7bc37a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6836-493dc55c39187949.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6856-53ac421c06039a18.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6908.06008c67f6380ea9.js +0 -148
- package/apps/pwa/out/_next/static/chunks/6915.096931864206f522.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6925.5e181fb7dcf90193.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6cc1d1d6.9a98dd4622f1afc6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7203-800e11037adc41eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7279.6170f591105936bb.js +0 -93
- package/apps/pwa/out/_next/static/chunks/7349-373165c7fbdcc3df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7514-a533ba0ca1cae4f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7515.1ad6efe157fa4448.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7521.d919cc1fab80c1d9.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7538.90e97bbdf9178cff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7825-39203196a12579b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7869.5e1a9a12fd70d6c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8086.1ab9103c41be884f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8179-e61fffbdb70f1152.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8265.bdeb991b34db6a06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8357.1aaa713b052a78b1.js +0 -309
- package/apps/pwa/out/_next/static/chunks/8638-e42615f2166165b5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8639-92c11d069792429e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8691.54e22831d5e8ccf8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9069.657590a84afb8fac.js +0 -41
- package/apps/pwa/out/_next/static/chunks/9125-ae588d88a0293b93.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9311.f9f641a46a508611.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9371-a6fee8378ebfa3ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9421-3aa9ff4fa7f63d8a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9992.07ce73c10bd5e6a1.js +0 -79
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76394dc618d322c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-1b948637c37b3abd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-c63400f1bcf3e47c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-95d0957267819586.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ba957ff875a026a0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-bb6fd0714879cb87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8f9038520d2acbef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-d4b48397e05fce2c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-72d5744245dc0c27.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-37625dc8300fa43a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-fbef9d160272dbc1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-58424168df84928e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-72c12ba430ac57c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-d53f3e9ed806d7e0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-4d2fbd45feee0829.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-76394dc618d322c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-8783dc0ed7590a2c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-3706cb390606e930.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-9b0a86598e0111fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-4edb8df90f4537ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-47398b9ba1cc5e1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-fb86f55cfe2e681d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e22345fc8fd47b1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-fca2e59a81744d9e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-6e96bda63100b31e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-4d17ad8e0db8cea4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-121f92766c33beaa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-43f14212c545f92d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ccec2023e7a974ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-b04f33f548b89a94.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-c8792823c0917021.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-8c0e32782ceef4cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-94bd3922eb230ce8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-bca565887bafa03c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ac1dffafe649fc6c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-52374edb5e23e455.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ad4ebca120d43ca7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-76394dc618d322c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-718b89ce4b4ae4e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-204eca33eeeaddec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-e58ba9bcdb9ac0f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-98f6dd50bafd7734.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-5a4bdd72bff27057.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-6f6ab17d44f984ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-aabb7bd15fb72da9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e4322319164a4436.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-e9efc0c8f32e2371.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-ccde99f07aaf71f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +0 -1
- package/apps/pwa/out/_next/static/chunks/c696986b.5dc8bb1143af16d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/d5d3cefc-373c4eb722ed848b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/d8de0de2-dd0f4ac8e5ab1832.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-002b472a66935d31.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-49b88d47292c0476.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-fff2549cb10a133f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-32abbbba3f3b76b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-9d9cfef60c60dd7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-cc7f483fa294034a.js +0 -1
- package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
- package/scripts/ratchets/next-tui-entry-budget.ts +0 -124
- /package/apps/pwa/out/_next/static/{HjeK7zONHfR7op1hKXp4k → X1ucLw10Cds_h614NoEnh}/_ssgManifest.js +0 -0
|
@@ -4,6 +4,7 @@ import { join } from 'node:path';
|
|
|
4
4
|
import { runPodCommand, type RunPodCommandOptions, type PodCommandResult } from '../task-orchestrator/surfaces/pod-command-job.js';
|
|
5
5
|
import { redactSecretText } from '../debug/log.js';
|
|
6
6
|
import type { RootPlanSummary } from './pr-land-heavy-remote.js';
|
|
7
|
+
import type { WarmReuseEvidence, WarmReuseEvidenceByConsumer } from '../task-orchestrator/surfaces/pod-warm-switch.js';
|
|
7
8
|
|
|
8
9
|
const SHA = /^[0-9a-f]{40}$/i;
|
|
9
10
|
const MARKER = 'ELANOUS_PRLAND_SHADOW';
|
|
@@ -107,3 +108,62 @@ export async function runLandingPodShadowJob(input: LandingPodShadowInput, deps:
|
|
|
107
108
|
const gateRc = Number(match[2]);
|
|
108
109
|
return { measured: true, ok: tscRc === 0 && gateRc === 0, rootPlan, tscRc, gateRc, job: job.job };
|
|
109
110
|
}
|
|
111
|
+
|
|
112
|
+
/** WARM-REUSE-LAND-CONSUMER-WIRE — land shadow Job 결과 표본(착지쌍·lock·lease·카나리아·그림자 일치). */
|
|
113
|
+
export interface LandingShadowSample {
|
|
114
|
+
/** shadow Job 이 잰 착지쌍 — 원격 게이트가 잰 head/main 와 정확히 같아야 표본으로 센다. */
|
|
115
|
+
head: string;
|
|
116
|
+
main: string;
|
|
117
|
+
/** shadow Job 이 돈 Pod generation lock — 원값 그대로 대조한다. */
|
|
118
|
+
lock: string;
|
|
119
|
+
/** shadow Job 이 lease 를 잡고 끝까지 쟀나. */
|
|
120
|
+
leaseValid: boolean;
|
|
121
|
+
/** shadow Job 카나리아(착지 tsc+gate) 통과. */
|
|
122
|
+
canaryPassed: boolean;
|
|
123
|
+
/** 같은 착지의 fresh(원격 게이트) 판정과 그림자 비교 일치 — 불일치 표본은 최근 mismatch 로 센다. */
|
|
124
|
+
agree: boolean;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** land 소비자 판정 증거 입력 — 최근 창 표본 ⊕ 이번 착지가 기대하는 warm 워커 lock ⊕ 선행 소비자 증거. */
|
|
128
|
+
export interface LandShadowSampleWindow {
|
|
129
|
+
/** 최근 창 — 마지막 원소가 가장 최근 shadow 결과다. */
|
|
130
|
+
samples: LandingShadowSample[];
|
|
131
|
+
/** 이번 착지가 기대하는 warm 워커 lock(현재 Pod generation). */
|
|
132
|
+
lock: string;
|
|
133
|
+
/** 선행 소비자(gate-recheck)의 자기 증거 — land 는 이 칸이 live 여야 live 가 될 수 있다(비면 off). */
|
|
134
|
+
gateRecheck?: WarmReuseEvidence;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* WARM-REUSE-LAND-CONSUMER-WIRE — land shadow Job 결과에서 소비자('land') 판정 증거를 만든다.
|
|
139
|
+
* 판정 본체는 pod-warm-switch.ts `decideWarmReuse` — 이 모듈은 증거의 산지만 담당한다.
|
|
140
|
+
* 창이 없거나 비면 land 증거 칸이 비어 off 다 — 못 잰 증거는 통과가 아니다.
|
|
141
|
+
* 원값은 고쳐 읽지 않고 정확히 비교한다(신원 형식 어긋남은 pod-warm-switch 판정이 끊는다).
|
|
142
|
+
*/
|
|
143
|
+
export function buildLandWarmEvidence(
|
|
144
|
+
window: LandShadowSampleWindow | undefined,
|
|
145
|
+
expected: { head: string; main: string },
|
|
146
|
+
): WarmReuseEvidenceByConsumer {
|
|
147
|
+
const evidence: WarmReuseEvidenceByConsumer = window?.gateRecheck ? { 'gate-recheck': window.gateRecheck } : {};
|
|
148
|
+
if (!window || window.samples.length === 0) return evidence;
|
|
149
|
+
const latest = window.samples[window.samples.length - 1]!;
|
|
150
|
+
let consecutiveMatchSamples = 0;
|
|
151
|
+
for (let index = window.samples.length - 1; index >= 0; index--) {
|
|
152
|
+
const sample = window.samples[index]!;
|
|
153
|
+
if (sample.head !== expected.head || sample.main !== expected.main || sample.lock !== window.lock
|
|
154
|
+
|| sample.leaseValid !== true || sample.canaryPassed !== true || sample.agree !== true) break;
|
|
155
|
+
consecutiveMatchSamples++;
|
|
156
|
+
}
|
|
157
|
+
const recentMismatchCount = window.samples.filter((sample) => sample.agree === false).length;
|
|
158
|
+
return {
|
|
159
|
+
...evidence,
|
|
160
|
+
land: {
|
|
161
|
+
consecutiveMatchSamples,
|
|
162
|
+
recentMismatchCount,
|
|
163
|
+
leaseValid: latest.leaseValid,
|
|
164
|
+
canaryPassed: latest.canaryPassed,
|
|
165
|
+
expected: { head: expected.head, main: expected.main, lock: window.lock },
|
|
166
|
+
worker: { head: latest.head, main: latest.main, lock: latest.lock },
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
@@ -109,8 +109,11 @@ export function collectChecklistEvidenceStages(item: ReturnType<typeof listCheck
|
|
|
109
109
|
const origin = run('git', ['remote', 'get-url', 'origin']);
|
|
110
110
|
const pinObject = run('git', ['cat-file', '-e', `${pinSha}^{commit}`]);
|
|
111
111
|
const repoUrl = origin.stdout.trim().replace(/^git@github\.com:/i, 'https://github.com/').replace(/\.git$/i, '').replace(/\/$/u, '').toLowerCase();
|
|
112
|
-
const
|
|
113
|
-
|
|
112
|
+
const expectedRepos = new Set([
|
|
113
|
+
'https://github.com/elanvitalai/elanous',
|
|
114
|
+
'https://github.com/ElanvitalAI/elanous',
|
|
115
|
+
]);
|
|
116
|
+
if (repoRoot.status !== 0 || !repoRoot.stdout.trim() || origin.status !== 0 || !expectedRepos.has(repoUrl) || pinObject.status !== 0) {
|
|
114
117
|
e3.reason = '현재 git 저장소가 elanous 원본이 아니거나 설치본 pin 객체가 없어 조상 관계를 판정할 수 없다';
|
|
115
118
|
} else {
|
|
116
119
|
const ancestry = run('git', ['merge-base', '--is-ancestor', mergeSha, pinSha]);
|
|
@@ -122,11 +125,15 @@ export function collectChecklistEvidenceStages(item: ReturnType<typeof listCheck
|
|
|
122
125
|
}
|
|
123
126
|
}
|
|
124
127
|
|
|
125
|
-
const
|
|
126
|
-
|
|
128
|
+
const identityToken = '(?:run-[a-f0-9]{8}-[a-f0-9-]{27,}|[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}|[a-z0-9][a-z0-9._:-]{2,})';
|
|
129
|
+
const labelledIdentity = new RegExp(`\\b(runId|missionId|taskId)\\s*[:=]?\\s*(${identityToken})\\b`, 'i').exec(evidence);
|
|
130
|
+
const runId = labelledIdentity?.[2]
|
|
131
|
+
?? /\b(run-[a-f0-9]{8}-[a-f0-9-]{27,}|[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})\b/i.exec(evidence)?.[1];
|
|
132
|
+
const identityLabel = labelledIdentity?.[1]?.toLowerCase();
|
|
133
|
+
const identityField = identityLabel === 'missionid' ? 'missionId' : identityLabel === 'taskid' ? 'taskId' : 'runId';
|
|
127
134
|
const event = /(?:event|이벤트)\s*[:=]\s*([A-Za-z0-9_.:-]+)/iu.exec(evidence)?.[1];
|
|
128
135
|
const verificationCommand = /(?:완료 경계 증거 명령|증거 명령|verification command)\s*[:=]\s*([^\r\n]+)/iu.exec(`${item.title}\n${evidence}`)?.[1]?.trim() ?? null;
|
|
129
|
-
const e4: ChecklistEvidenceStage = { id: 'E4', state: 'missing', source: null, measuredAt, verificationCommand, reason: '근거에 runId·event·원문 검증 명령이 모두 필요하다' };
|
|
136
|
+
const e4: ChecklistEvidenceStage = { id: 'E4', state: 'missing', source: null, measuredAt, verificationCommand, reason: '근거에 runId·missionId·taskId 중 하나와 event·원문 검증 명령이 모두 필요하다' };
|
|
130
137
|
if (runId && event && verificationCommand) {
|
|
131
138
|
const logs = run('eln', ['logs', '--grep', runId, '--since', '365d', '--all', '--include-test', '--limit', '1000', '--json'], 30_000);
|
|
132
139
|
if (logs.status !== 0) { e4.state = 'unmeasurable'; e4.reason = `runId 로그 조회 실패${logs.error ? `: ${logs.error}` : ''}`; }
|
|
@@ -135,16 +142,19 @@ export function collectChecklistEvidenceStages(item: ReturnType<typeof listCheck
|
|
|
135
142
|
const truncated = rows.length >= 1000 || rows.some((row) => row._meta && typeof row._meta === 'object' && (row._meta as { limitReached?: unknown }).limitReached === true);
|
|
136
143
|
const observed = rows.some((row) => {
|
|
137
144
|
if (row.event !== event || typeof row.data !== 'string') return false;
|
|
138
|
-
try {
|
|
145
|
+
try {
|
|
146
|
+
const data = JSON.parse(row.data) as { runId?: unknown; missionId?: unknown; taskId?: unknown };
|
|
147
|
+
return data[identityField] === runId;
|
|
148
|
+
} catch { return false; }
|
|
139
149
|
});
|
|
140
|
-
e4.source = `eln logs --grep ${runId} --since 365d --all --include-test --limit 1000 --json (event=${event})`;
|
|
141
|
-
if (observed) { e4.state = 'observed'; e4.reason = `같은
|
|
150
|
+
e4.source = `eln logs --grep ${runId} --since 365d --all --include-test --limit 1000 --json (${identityField}=${runId}, event=${event})`;
|
|
151
|
+
if (observed) { e4.state = 'observed'; e4.reason = `같은 ${identityField}의 ${event} 실물 이벤트를 찾았다`; }
|
|
142
152
|
else if (truncated) { e4.state = 'unmeasurable'; e4.reason = '로그 결과가 잘려 사건 부재를 판정할 수 없다'; }
|
|
143
|
-
else { e4.reason = `같은
|
|
153
|
+
else { e4.reason = `같은 ${identityField}의 ${event} 이벤트가 없다`; }
|
|
144
154
|
}
|
|
145
155
|
}
|
|
146
156
|
|
|
147
|
-
const acceptance =
|
|
157
|
+
const acceptance = /^\s*(?:[-*]\s*)?완료 경계 실물\s*:\s*([^\r\n]+)/mu.exec(item.title)?.[1]?.trim();
|
|
148
158
|
const e5Observed = Boolean(acceptance && evidence.includes(acceptance));
|
|
149
159
|
const e5: ChecklistEvidenceStage = { id: 'E5', state: e5Observed ? 'observed' : 'missing', source: 'checklist title/evidence exact acceptance-text comparison', measuredAt,
|
|
150
160
|
reason: e5Observed ? '완료 경계 실물 문구가 기록된 근거와 일치한다' : '완료 경계 실물 문구와 일치하는 근거가 없다' };
|
package/src/cli/release-cli.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
// elanous release resume --run <runId> --from <node> [--waive <node> --reason <text>] [--accepted-regressions <json>] [--gate-executor <pod|host> [--gate-host <ssh-host>]] [--gate-pod-pool <pool>] [--json]
|
|
10
10
|
// elanous release auto-start [--window-minutes <n>] [--apply] [--json]
|
|
11
11
|
// elanous release recover --run <runId> --pick <sha...> [--from export-check] [--command-root <path>] [--repo-root <path>] [--no-partial] [--json]
|
|
12
|
+
// elanous release recover-landing --run <runId> --merge <full-sha> [--from export-check] [--repo-root <path>] [--no-partial] [--json]
|
|
12
13
|
// elanous release rehearsal tick [--apply] [--checkout <dir>] [--shards <n>] [--remote <host>] [--recovery-run <id>] [--json]
|
|
13
14
|
// elanous release preflight --version <x.y.z> [--publish-at <iso>] [--json] (컷 − 60분 main export 포함 사전 점검 · 읽기 전용 · ⛔ 있으면 exit 1)
|
|
14
15
|
// elanous release cut-branch --version <x.y.z> [--base <sha>] --pick <sha>... [--append] [--dry-run]
|
|
@@ -45,7 +46,7 @@ import { isIsolatedLedgerWriteRoot } from '../hq/ledger-write-target.js';
|
|
|
45
46
|
import { runUnattendedRelease, type UnattendedReleaseDeps } from '../../scripts/release-loop/unattended-release.js';
|
|
46
47
|
import { publishAtError } from '../../scripts/release-loop/publish-at.js';
|
|
47
48
|
import { cutReleaseBranch } from '../../scripts/release-loop/cut-branch.js';
|
|
48
|
-
import { planResumeReleaseRun, recoverReleaseRun, resumeReleaseRun, ReleaseRecoverStopped, type RecoverReleaseDeps } from '../../scripts/release-loop/resume-release.js';
|
|
49
|
+
import { planResumeReleaseRun, recoverLandingPartialOption, recoverReleaseRun, recoverReleaseRunFromLanding, resumeReleaseRun, ReleaseRecoverStopped, type RecoverReleaseDeps } from '../../scripts/release-loop/resume-release.js';
|
|
49
50
|
import type { AcceptedRegression } from '../../scripts/release-loop/resume.js';
|
|
50
51
|
import type { PrereleaseKind } from '../../scripts/release-loop/release-version.js';
|
|
51
52
|
import { releaseReadiness } from '../../scripts/release-loop/release-readiness.js';
|
|
@@ -1388,6 +1389,31 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
|
|
|
1388
1389
|
}
|
|
1389
1390
|
}, (r) => r.stages.every((stage) => stage.outcome === 'ok'));
|
|
1390
1391
|
});
|
|
1392
|
+
release.command('recover-landing')
|
|
1393
|
+
.description('착지 알림 수동 재생 입구 — merge SHA로 중복을 억제하고 append → tip 고정 → export-check 재개를 수행한다. release-loop event hook 착지 전에는 사람이 직접 호출한다')
|
|
1394
|
+
.requiredOption('--run <runId>', '실패한 release-loop 런 ID')
|
|
1395
|
+
.requiredOption('--merge <sha>', 'main에 착지한 수리 커밋의 전체 40자리 SHA')
|
|
1396
|
+
.option('--from <node>', '재개 시작 노드 — 기본 export-check')
|
|
1397
|
+
.option('--command-root <path>', '재개 명령을 실행할 checkout — 생략 시 append tip 임시 checkout')
|
|
1398
|
+
.option('--repo-root <path>', 'append를 실행할 checkout — origin remote 필요')
|
|
1399
|
+
.option('--no-partial', 'Pod image digest 등이 맞지 않으면 전체 gate를 실행하며 부분 재검을 사용하지 않음')
|
|
1400
|
+
.option('--json', '결과 한 줄 JSON(stdout) · 사람 줄은 stderr')
|
|
1401
|
+
.action(async (o: { run: string; merge: string; from?: string; commandRoot?: string; repoRoot?: string; partial?: boolean; json?: boolean }) => {
|
|
1402
|
+
await jsonAction(o.json, async (log) => {
|
|
1403
|
+
try {
|
|
1404
|
+
const partial = recoverLandingPartialOption(o.partial);
|
|
1405
|
+
return await recoverReleaseRunFromLanding({ runId: o.run, mergeSha: o.merge,
|
|
1406
|
+
...(o.from === undefined ? {} : { from: o.from }),
|
|
1407
|
+
...(o.commandRoot === undefined ? {} : { commandRoot: o.commandRoot }),
|
|
1408
|
+
...(o.repoRoot === undefined ? {} : { repoRoot: o.repoRoot }),
|
|
1409
|
+
...(partial === undefined ? {} : { partial }) },
|
|
1410
|
+
{ ...resumeDeps, onSource: log });
|
|
1411
|
+
} catch (caught) {
|
|
1412
|
+
if (!(caught instanceof ReleaseRecoverStopped)) throw caught;
|
|
1413
|
+
return { ok: false as const, error: caught.message, stages: [...caught.stages], notRun: [...caught.notRun], duplicate: false };
|
|
1414
|
+
}
|
|
1415
|
+
}, (r) => r.duplicate || r.stages.every((stage) => stage.outcome === 'ok'));
|
|
1416
|
+
});
|
|
1391
1417
|
release.command('gate-history')
|
|
1392
1418
|
.description('GATE-FAIL-HISTORY (0.2.29) — 판을 넘는 게이트 실패 표 — 모든 release-loop·light-rc 런 원장 ⊕ gate-verdict 에서 시험 파일별 introduced·preexisting·env·flaky 횟수 · 마지막 실패 판 · 원인 PR(수리 PR 본문 «원인 #N»)')
|
|
1393
1419
|
.option('--since <판|일>', '이 판(x.y.z)부터 · 또는 그 날(YYYY-MM-DD) 이후 시작된 런부터')
|
package/src/cli/research-cli.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
2
|
import { debug } from '../debug/log.js';
|
|
3
3
|
import { isLiveDetailOn } from '../live/detail-switch.js';
|
|
4
|
-
import {
|
|
5
|
-
import { getAvailableWebSearchProviders } from '../web-search/index.js';
|
|
4
|
+
import { dispatchResearchOmniSearch, getAvailableResearchSearchEngineIds } from '../skills/tools/omni-search.js';
|
|
6
5
|
|
|
7
6
|
export interface ResearchCliDeps {
|
|
8
7
|
readonly out?: { log: (line: string) => void; error: (line: string) => void };
|
|
9
|
-
readonly search?: typeof
|
|
8
|
+
readonly search?: typeof dispatchResearchOmniSearch;
|
|
10
9
|
readonly availableEngines?: () => string[];
|
|
11
10
|
readonly maxDetailOn?: (runId?: string) => boolean;
|
|
12
11
|
readonly log?: typeof debug.log;
|
|
@@ -23,7 +22,7 @@ export function registerResearchCommand(program: Command, deps: ResearchCliDeps
|
|
|
23
22
|
const query = parts.join(' ').trim();
|
|
24
23
|
const limit = Number(opts.limit);
|
|
25
24
|
const engines = opts.engines?.split(',').map(id => id.trim()).filter(Boolean);
|
|
26
|
-
const available = (deps.availableEngines ??
|
|
25
|
+
const available = (deps.availableEngines ?? getAvailableResearchSearchEngineIds)();
|
|
27
26
|
const unknown = engines?.filter(id => !available.some(p => p.toLowerCase() === id.toLowerCase())) ?? [];
|
|
28
27
|
if (!query || !Number.isInteger(limit) || limit < 1 || limit > 20 || (opts.engines !== undefined && !engines?.length) || unknown.length) {
|
|
29
28
|
out.error(unknown.length ? `research: 사용할 수 없는 엔진: ${unknown.join(', ')} (사용 가능: ${available.join(', ') || '없음'})`
|
|
@@ -41,7 +40,7 @@ export function registerResearchCommand(program: Command, deps: ResearchCliDeps
|
|
|
41
40
|
if (!wanted.length) log('research.query', 'query', { query, engines: [], limit });
|
|
42
41
|
for (const engine of wanted) log('research.query', 'query', { query, engine, limit });
|
|
43
42
|
try {
|
|
44
|
-
const result = await (deps.search ??
|
|
43
|
+
const result = await (deps.search ?? dispatchResearchOmniSearch)({ query, ...(engines?.length ? { engines } : {}), limit }, {
|
|
45
44
|
onEngine: event => {
|
|
46
45
|
if (event.phase === 'complete') log('research.result', 'result', { query, engine: event.engine, hits: event.hits, durationMs: event.durationMs, ...(event.error ? { error: event.error } : {}) });
|
|
47
46
|
},
|
package/src/cli/sim-cli.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
|
+
import { getTestStateRoot } from '../nexus/paths.js';
|
|
3
|
+
import { runReleaseSimRigIfFile } from '../ux-sim/release-sim-rig.js';
|
|
2
4
|
import { runScenarioFile } from '../ux-sim/scenario.js';
|
|
3
5
|
|
|
4
6
|
export function registerSimCommands(program: Command): void {
|
|
@@ -7,7 +9,11 @@ export function registerSimCommands(program: Command): void {
|
|
|
7
9
|
.description('등록된 UX simulation 시나리오를 test 우주에서 실행한다')
|
|
8
10
|
.action(async (scenarioFile: string) => {
|
|
9
11
|
try {
|
|
10
|
-
|
|
12
|
+
// Enforce isolation before either runner inspects the supplied path. Otherwise
|
|
13
|
+
// release-graph dispatch can leak a path-validation error outside test mode.
|
|
14
|
+
if (!getTestStateRoot()) throw new Error('scenario runner requires --test isolated mode');
|
|
15
|
+
const releaseResult = await runReleaseSimRigIfFile(scenarioFile);
|
|
16
|
+
const result = releaseResult ?? await runScenarioFile(scenarioFile);
|
|
11
17
|
console.log(JSON.stringify(result));
|
|
12
18
|
if (!result.pass) process.exitCode = 1;
|
|
13
19
|
} catch (error) {
|
package/src/cli/tasks-cli.ts
CHANGED
|
@@ -66,6 +66,10 @@ export interface TasksCliDeps {
|
|
|
66
66
|
taskStatePath?: string;
|
|
67
67
|
/** 조합 선택 시험에서만 그래프 저장소 루트를 바꾼다. */
|
|
68
68
|
taskCompositionRoot?: string;
|
|
69
|
+
/** COORD-ENTRANCE-FOLD test seam; production uses the invoking repository root. */
|
|
70
|
+
coordinatorShadowRoot?: string;
|
|
71
|
+
/** Deterministic task-hand time in isolated tests. */
|
|
72
|
+
taskNow?: () => Date;
|
|
69
73
|
/** DRAFT-CLAIM-AUTO-2-FU — `tasks hand --draft-claim <pr>` 의 관측·게시·수확 리뷰 포트(시험 주입). 기본 = `defaultDraftClaimGhPorts()`(gh CLI ⊕ 생산 리뷰 러너). */
|
|
70
74
|
draftClaimGh?: DraftClaimGhPorts;
|
|
71
75
|
/** logs.db 싱크 등록(시험 주입). 기본 = `registerStandaloneLogSink`. `hand`·`show` 가 부른다. */
|
|
@@ -473,14 +477,15 @@ async function tryRemoteParent(args: string[], cwd: string | undefined, context:
|
|
|
473
477
|
return null;
|
|
474
478
|
}
|
|
475
479
|
|
|
476
|
-
/**
|
|
477
|
-
function
|
|
480
|
+
/** Advisory lines may precede the actual fatal error. Keep the full stderr as evidence. */
|
|
481
|
+
function actionableStderrLine(path: string): string {
|
|
478
482
|
try {
|
|
479
483
|
const fd = openSync(path, 'r');
|
|
480
484
|
try {
|
|
481
485
|
const buf = Buffer.alloc(4096);
|
|
482
486
|
const n = readSync(fd, buf, 0, buf.length, 0);
|
|
483
|
-
|
|
487
|
+
const lines = buf.subarray(0, n).toString('utf8').split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
488
|
+
return lines.find((line) => /^(?:❌|error:|fatal:)/i.test(line)) ?? lines[0] ?? '';
|
|
484
489
|
} finally { closeSync(fd); }
|
|
485
490
|
} catch { return ''; }
|
|
486
491
|
}
|
|
@@ -529,7 +534,7 @@ export async function defaultTaskLauncher(args: string[], cwd?: string, context?
|
|
|
529
534
|
: undefined;
|
|
530
535
|
if (timer) clearTimeout(timer);
|
|
531
536
|
if (early && early.code !== 0) {
|
|
532
|
-
const first =
|
|
537
|
+
const first = actionableStderrLine(stderrPath);
|
|
533
538
|
const cause = `child rc=${early.code ?? early.signal ?? 'unknown'}${first ? `: ${first}` : ''}`;
|
|
534
539
|
const { boundRunStopCause, recordRunStop, runStopRecorded, RUN_STOP_EVENT } = await import('../self-implement/run-stop.js');
|
|
535
540
|
const hasStop = deps.hasStop ?? ((id: string) => {
|
|
@@ -2335,6 +2340,9 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
|
|
|
2335
2340
|
}
|
|
2336
2341
|
const handOpts = {
|
|
2337
2342
|
text: resolved.text,
|
|
2343
|
+
...(resolved.kind === 'work-order' ? { workOrder: resolved.order } : {}),
|
|
2344
|
+
...(deps.coordinatorShadowRoot ? { coordinatorShadowRoot: deps.coordinatorShadowRoot } : {}),
|
|
2345
|
+
...(deps.taskNow ? { now: deps.taskNow } : {}),
|
|
2338
2346
|
...(opts.project !== undefined && opts.target !== undefined ? { project: { id: opts.project, target: opts.target } } : {}),
|
|
2339
2347
|
...(opts.goal !== undefined ? { goal: opts.goal } : {}),
|
|
2340
2348
|
...(opts.milestone !== undefined ? { milestone: opts.milestone } : {}),
|
package/src/codex/models.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
// ── OpenAI Codex model catalog ──
|
|
2
2
|
//
|
|
3
|
-
// Curated subset of the full OpenAI Codex CLI model roster
|
|
4
|
-
//
|
|
5
|
-
// the onboarding picker. Source: omni-crawl sweep on 2026-04-14 across
|
|
3
|
+
// Curated subset of the full OpenAI Codex CLI model roster, covering
|
|
4
|
+
// common use cases without overwhelming the onboarding picker. Source: omni-crawl sweep on 2026-04-14 across
|
|
6
5
|
// - developers.openai.com/api/docs/models/{all,codex-mini-latest,gpt-5-codex}
|
|
7
6
|
// - developers.openai.com/codex/models
|
|
8
7
|
// - platform.openai.com/docs/models
|
|
@@ -20,10 +19,9 @@
|
|
|
20
19
|
// 2026-09-09 refresh (live 1차 대조 — developers.openai.com/api/내부 문서 `gpt-6-astra`
|
|
21
20
|
// ⊕ openai.com/api/pricing/ ⊕ `codex exec --model gpt-6-astra` 실호출):
|
|
22
21
|
// + gpt-6-astra (2026-09-03 출시 · 현 최상단)
|
|
23
|
-
// + gpt-5.6-terra (
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
// astra 는 recommended 가 «아니다» — terra 대비 input 4배·output 3.3배라 기본값이 될 수 없다.
|
|
22
|
+
// + gpt-5.6-terra (at the time, the configured `llm.model` default)
|
|
23
|
+
// GPT-6.1 refresh (2026-10-28): recommended is GPT-6.1 Terra; Sol is available for higher-cost deep work.
|
|
24
|
+
// `recommended` means a safe default, not the strongest model; Astra remains opt-in due to its higher cost.
|
|
27
25
|
|
|
28
26
|
export type CodexModelTier = 'flagship' | 'balanced' | 'cheap' | 'specialist' | 'legacy';
|
|
29
27
|
|
|
@@ -44,11 +42,21 @@ export interface CodexModel {
|
|
|
44
42
|
recommended?: boolean;
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
45
|
+
/** Curated models for the 1-point setup picker. Ordering reflects the UI:
|
|
46
|
+
* recommended first, then by descending tier. */
|
|
49
47
|
export const CODEX_MODELS: CodexModel[] = [
|
|
50
48
|
{
|
|
51
|
-
|
|
49
|
+
id: 'gpt-6.1-terra',
|
|
50
|
+
label: 'GPT-6.1 Terra',
|
|
51
|
+
tier: 'balanced',
|
|
52
|
+
description: 'Recommended everyday Codex model. 500K context; $1/$5 per million tokens, cached input $0.05.',
|
|
53
|
+
contextWindow: 500_000,
|
|
54
|
+
pricingUsd: { inputPerM: 1.0, outputPerM: 5.0, cacheReadPerM: 0.05 },
|
|
55
|
+
recommended: true,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
// Cache-read rates: Astra $1.00/M, GPT-6.1 Sol $0.10/M, Terra $0.05/M, Luna $0.01/M.
|
|
59
|
+
// Per OP 2026-10-28 price direction, legacy GPT-6 Sol also uses $0.10/M for cost estimates.
|
|
52
60
|
id: 'gpt-6-astra',
|
|
53
61
|
label: 'GPT-6 Astra (frontier)',
|
|
54
62
|
tier: 'flagship',
|
|
@@ -56,14 +64,21 @@ export const CODEX_MODELS: CodexModel[] = [
|
|
|
56
64
|
contextWindow: 1_050_000,
|
|
57
65
|
pricingUsd: { inputPerM: 10.0, outputPerM: 50.0, cacheReadPerM: 1.0 },
|
|
58
66
|
},
|
|
67
|
+
{
|
|
68
|
+
id: 'gpt-6.1-sol',
|
|
69
|
+
label: 'GPT-6.1 Sol',
|
|
70
|
+
tier: 'flagship',
|
|
71
|
+
description: 'Higher-capability reasoning and coding model. 500K context; $2/$10 per million tokens, cached input $0.10.',
|
|
72
|
+
contextWindow: 500_000,
|
|
73
|
+
pricingUsd: { inputPerM: 2.0, outputPerM: 10.0, cacheReadPerM: 0.1 },
|
|
74
|
+
},
|
|
59
75
|
{
|
|
60
76
|
id: 'gpt-6-sol',
|
|
61
|
-
label: 'GPT-6 Sol',
|
|
62
|
-
tier: '
|
|
63
|
-
description: '
|
|
77
|
+
label: 'GPT-6 Sol',
|
|
78
|
+
tier: 'legacy',
|
|
79
|
+
description: 'Legacy GPT-6 Sol retained for compatibility; GPT-6.1 Sol is its higher-performing successor at the same price, while Terra is a lower-cost default.',
|
|
64
80
|
contextWindow: 1_050_000,
|
|
65
|
-
pricingUsd: { inputPerM: 2.0, outputPerM: 10.0, cacheReadPerM: 0.
|
|
66
|
-
recommended: true,
|
|
81
|
+
pricingUsd: { inputPerM: 2.0, outputPerM: 10.0, cacheReadPerM: 0.1 },
|
|
67
82
|
},
|
|
68
83
|
{
|
|
69
84
|
id: 'gpt-6-luna',
|
package/src/compact/auto.ts
CHANGED
|
@@ -31,8 +31,15 @@ export function shouldAutoCompact(
|
|
|
31
31
|
messages: MessageLike[],
|
|
32
32
|
modelId: string | undefined,
|
|
33
33
|
config: ChatAutoCompactConfig,
|
|
34
|
+
observedInputTokens?: number,
|
|
34
35
|
): AutoCompactDecision {
|
|
35
|
-
const
|
|
36
|
+
const hasObservedInputTokens = typeof observedInputTokens === 'number'
|
|
37
|
+
&& Number.isFinite(observedInputTokens)
|
|
38
|
+
&& observedInputTokens >= 0;
|
|
39
|
+
const estimatedTokens = estimateMessagesTokens(messages);
|
|
40
|
+
// Provider usage captures model/tokenizer overhead; current history also
|
|
41
|
+
// includes tool output appended since that provider response.
|
|
42
|
+
const usedTokens = hasObservedInputTokens ? Math.max(observedInputTokens, estimatedTokens) : estimatedTokens;
|
|
36
43
|
const windowTokens = resolveModelContextWindow(modelId) ?? inferContextWindow(modelId);
|
|
37
44
|
const configuredBudget = config.workingBudgetTokens;
|
|
38
45
|
const budgetTokens = typeof configuredBudget === 'number'
|
|
@@ -20,7 +20,7 @@ export interface ResourceRecord {
|
|
|
20
20
|
export type ResourceView = ResourceRecord & { ageMs: number; expired: boolean };
|
|
21
21
|
|
|
22
22
|
export interface PodWorkerKey { context: string; imageDigest: string; lockHash: string; architecture: string }
|
|
23
|
-
type PodWorkerState = 'idle' | 'leased' | 'sanitizing' | 'quarantined';
|
|
23
|
+
type PodWorkerState = 'idle' | 'leased' | 'sanitizing' | 'timeout-fenced' | 'quarantined';
|
|
24
24
|
interface PodWorkerLeaseAttrs {
|
|
25
25
|
key: PodWorkerKey;
|
|
26
26
|
podUid: string;
|
|
@@ -32,6 +32,9 @@ interface PodWorkerLeaseAttrs {
|
|
|
32
32
|
/** The just-sanitized generation remains fenceable until the next acquisition. */
|
|
33
33
|
lastLeaseId?: string;
|
|
34
34
|
lastLeaseOwner?: string;
|
|
35
|
+
timeoutFenceUntil?: number;
|
|
36
|
+
timeoutRunId?: string;
|
|
37
|
+
timeoutAttemptId?: string;
|
|
35
38
|
runId?: string;
|
|
36
39
|
attemptId?: string;
|
|
37
40
|
reason?: string;
|
|
@@ -231,17 +234,35 @@ export class ResourceLedger {
|
|
|
231
234
|
return this.mutate(() => {
|
|
232
235
|
const at = now ?? Date.now();
|
|
233
236
|
const rows = this.read();
|
|
237
|
+
let expiredFenceChanged = false;
|
|
238
|
+
for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
|
|
239
|
+
const candidate = rows[rowIndex]!;
|
|
240
|
+
if (candidate.kind !== 'pod-worker-lease') continue;
|
|
241
|
+
const candidateAttrs = workerAttrs(candidate);
|
|
242
|
+
if (candidateAttrs.state !== 'timeout-fenced' || candidateAttrs.timeoutFenceUntil === undefined
|
|
243
|
+
|| candidateAttrs.timeoutFenceUntil > at || candidateAttrs.leaseId) continue;
|
|
244
|
+
const idleAttrs: PodWorkerLeaseAttrs = { ...candidateAttrs, state: 'idle' };
|
|
245
|
+
delete idleAttrs.leaseId; delete idleAttrs.leaseOwner; delete idleAttrs.runId; delete idleAttrs.attemptId;
|
|
246
|
+
delete idleAttrs.timeoutFenceUntil; delete idleAttrs.timeoutRunId; delete idleAttrs.timeoutAttemptId;
|
|
247
|
+
rows[rowIndex] = { ...candidate, attrs: idleAttrs as unknown as Record<string, unknown>, observedAt: at,
|
|
248
|
+
ttlMs: candidateAttrs.idleTtlMs };
|
|
249
|
+
expiredFenceChanged = true;
|
|
250
|
+
}
|
|
234
251
|
const index = rows.findIndex(row => row.kind === 'pod-worker-lease' && (!request.machine || row.machine === request.machine)
|
|
235
252
|
&& Math.max(0, at - row.observedAt) < row.ttlMs && workerAttrs(row).state === 'idle'
|
|
236
253
|
&& typeof workerAttrs(row).podUid === 'string' && workerAttrs(row).podUid.trim().length > 0
|
|
237
254
|
&& sameWorkerKey(workerAttrs(row).key, request.key));
|
|
238
|
-
if (index < 0)
|
|
255
|
+
if (index < 0) {
|
|
256
|
+
if (expiredFenceChanged) this.write(rows);
|
|
257
|
+
throw new ResourceLedgerError(409, 'no-warm-worker');
|
|
258
|
+
}
|
|
239
259
|
const row = rows[index]!;
|
|
240
260
|
const attrs = workerAttrs(row);
|
|
241
261
|
const nextAttrs: PodWorkerLeaseAttrs = { ...attrs, state: 'leased', generation: attrs.generation + 1,
|
|
242
262
|
leaseId: randomUUID(), leaseOwner: request.owner, runId: request.runId, attemptId: request.attemptId };
|
|
243
263
|
delete nextAttrs.lastLeaseId;
|
|
244
264
|
delete nextAttrs.lastLeaseOwner;
|
|
265
|
+
delete nextAttrs.timeoutFenceUntil; delete nextAttrs.timeoutRunId; delete nextAttrs.timeoutAttemptId;
|
|
245
266
|
const next: ResourceRecord = { ...row, attrs: nextAttrs as unknown as Record<string, unknown>,
|
|
246
267
|
observedAt: at, ttlMs: request.ttlMs };
|
|
247
268
|
rows[index] = next;
|
|
@@ -250,6 +271,31 @@ export class ResourceLedger {
|
|
|
250
271
|
});
|
|
251
272
|
}
|
|
252
273
|
|
|
274
|
+
fenceTimedOutPodWorker(id: string, request: { owner: string; runId: string; attemptId: string; fenceMs: number }, now?: number): ResourceRecord {
|
|
275
|
+
return this.mutate(() => {
|
|
276
|
+
const at = now ?? Date.now();
|
|
277
|
+
const rows = this.read();
|
|
278
|
+
const index = rows.findIndex(row => row.id === id && row.kind === 'pod-worker-lease');
|
|
279
|
+
if (index < 0) throw new ResourceLedgerError(404, 'not-found');
|
|
280
|
+
const row = rows[index]!;
|
|
281
|
+
const attrs = workerAttrs(row);
|
|
282
|
+
const sameFence = attrs.state === 'timeout-fenced' && attrs.timeoutRunId === request.runId
|
|
283
|
+
&& attrs.timeoutAttemptId === request.attemptId;
|
|
284
|
+
const sameLease = attrs.state === 'leased' && attrs.leaseOwner === request.owner
|
|
285
|
+
&& attrs.runId === request.runId && attrs.attemptId === request.attemptId;
|
|
286
|
+
const available = attrs.state === 'idle';
|
|
287
|
+
if (!request.owner || !request.runId || !request.attemptId || !Number.isSafeInteger(request.fenceMs)
|
|
288
|
+
|| request.fenceMs < 1 || !(sameFence || sameLease || available))
|
|
289
|
+
throw new ResourceLedgerError(409, 'stale-timeout-fence');
|
|
290
|
+
const nextAttrs: PodWorkerLeaseAttrs = { ...attrs, state: 'timeout-fenced',
|
|
291
|
+
timeoutFenceUntil: at + request.fenceMs, timeoutRunId: request.runId, timeoutAttemptId: request.attemptId };
|
|
292
|
+
const next: ResourceRecord = { ...row, attrs: nextAttrs as unknown as Record<string, unknown>, observedAt: at };
|
|
293
|
+
rows[index] = next;
|
|
294
|
+
this.write(rows);
|
|
295
|
+
return next;
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
|
|
253
299
|
transitionPodWorker(id: string, request: { owner: string; leaseId: string; generation: number; action: 'renew' | 'release' | 'sanitize' | 'quarantine'; ttlMs?: number; reason?: string }, now?: number): ResourceRecord {
|
|
254
300
|
return this.mutate(() => {
|
|
255
301
|
now ??= Date.now();
|
|
@@ -260,11 +306,14 @@ export class ResourceLedger {
|
|
|
260
306
|
const attrs = workerAttrs(row);
|
|
261
307
|
const lateIdleQuarantine = request.action === 'quarantine' && attrs.state === 'idle'
|
|
262
308
|
&& attrs.lastLeaseId === request.leaseId && attrs.generation === request.generation;
|
|
309
|
+
const timeoutFencedQuarantine = request.action === 'quarantine' && attrs.state === 'timeout-fenced'
|
|
310
|
+
&& attrs.leaseId === request.leaseId && attrs.generation === request.generation;
|
|
263
311
|
if (!request.leaseId || (attrs.leaseId !== request.leaseId && !lateIdleQuarantine)
|
|
264
312
|
|| attrs.generation !== request.generation) throw new ResourceLedgerError(409, 'stale-worker-lease');
|
|
265
313
|
const permitted = request.action === 'sanitize' ? row.owner === request.owner
|
|
266
314
|
: request.action === 'quarantine' ? row.owner === request.owner || attrs.leaseOwner === request.owner
|
|
267
315
|
|| (lateIdleQuarantine && attrs.lastLeaseOwner === request.owner)
|
|
316
|
+
|| (timeoutFencedQuarantine && attrs.leaseOwner === request.owner)
|
|
268
317
|
: attrs.leaseOwner === request.owner;
|
|
269
318
|
if (!permitted) {
|
|
270
319
|
throw new ResourceLedgerError(403, 'not-owner');
|
|
@@ -283,6 +332,7 @@ export class ResourceLedger {
|
|
|
283
332
|
} else if (state === 'quarantined') {
|
|
284
333
|
delete nextAttrs.lastLeaseId;
|
|
285
334
|
delete nextAttrs.lastLeaseOwner;
|
|
335
|
+
delete nextAttrs.timeoutFenceUntil; delete nextAttrs.timeoutRunId; delete nextAttrs.timeoutAttemptId;
|
|
286
336
|
}
|
|
287
337
|
const ttlMs = state === 'idle' ? attrs.idleTtlMs : request.ttlMs ?? row.ttlMs;
|
|
288
338
|
const next: ResourceRecord = { ...row, attrs: nextAttrs as unknown as Record<string, unknown>, observedAt: now, ttlMs };
|
|
@@ -10,6 +10,7 @@ import type { LeaseHolderView } from './lease-holder.js';
|
|
|
10
10
|
export const DEFAULT_CONTROL_PORT = PORT_BANDS.reserved[0];
|
|
11
11
|
export const CONTROL_HOSTNAME = '127.0.0.1';
|
|
12
12
|
const MAX_POD_WORKER_TTL_MS = 24 * 60 * 60 * 1000;
|
|
13
|
+
const POD_WORKER_TIMEOUT_FENCE_MS = 150_000;
|
|
13
14
|
|
|
14
15
|
export function allowedControlHostname(hostname: string): boolean {
|
|
15
16
|
if (hostname === '127.0.0.1' || hostname === '::1') return true;
|
|
@@ -126,7 +127,7 @@ export function startControlServer(opts: ControlServerOptions = {}): {
|
|
|
126
127
|
const leaseRenewal = /^\/v1\/leases\/port\/([^/]+)\/heartbeat$/.exec(path);
|
|
127
128
|
const workerRegister = path === '/v1/workers/pod' && method === 'POST';
|
|
128
129
|
const workerAcquire = path === '/v1/leases/pod-worker' && method === 'POST';
|
|
129
|
-
const workerTransition = /^\/v1\/leases\/pod-worker\/([^/]+)\/(renew|release|sanitize|quarantine)$/.exec(path);
|
|
130
|
+
const workerTransition = /^\/v1\/leases\/pod-worker\/([^/]+)\/(renew|release|sanitize|quarantine|timeout)$/.exec(path);
|
|
130
131
|
if (!resourcePath && !registerPath && !leaseRequest && !workerRegister && !workerAcquire && !(workerTransition && method === 'POST') && !(leaseDeletion && method === 'DELETE') && !(leaseRenewal && method === 'POST') && !(heartbeat && method === 'POST') && !(deletion && method === 'DELETE')) {
|
|
131
132
|
return json({ error: 'not-found' }, 404);
|
|
132
133
|
}
|
|
@@ -191,7 +192,20 @@ export function startControlServer(opts: ControlServerOptions = {}): {
|
|
|
191
192
|
if (workerTransition) {
|
|
192
193
|
const workerId = decodeURIComponent(workerTransition[1]!);
|
|
193
194
|
if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,95}$/.test(workerId)) throw new ResourceLedgerError(400, 'invalid-worker-id');
|
|
194
|
-
const action = workerTransition[2] as 'renew' | 'release' | 'sanitize' | 'quarantine';
|
|
195
|
+
const action = workerTransition[2] as 'renew' | 'release' | 'sanitize' | 'quarantine' | 'timeout';
|
|
196
|
+
if (action === 'timeout') {
|
|
197
|
+
if (scope !== 'member') throw new ResourceLedgerError(403, 'worker-timeout-scope');
|
|
198
|
+
const body = podWorkerBody(await req.json());
|
|
199
|
+
const { runId, attemptId } = body;
|
|
200
|
+
if (typeof runId !== 'string' || !runId.trim() || typeof attemptId !== 'string' || !attemptId.trim())
|
|
201
|
+
throw new ResourceLedgerError(400, 'invalid-pod-worker-timeout');
|
|
202
|
+
const id = `pod-worker-lease:${workerId}`;
|
|
203
|
+
requireTarget(id);
|
|
204
|
+
const stale = await currentWorkerPrimary();
|
|
205
|
+
if (stale) return stale;
|
|
206
|
+
return json(await ledger.withGuardedWorkerMutation(async () => !(await currentWorkerPrimary()),
|
|
207
|
+
() => ledger.fenceTimedOutPodWorker(id, { owner, runId, attemptId, fenceMs: POD_WORKER_TIMEOUT_FENCE_MS })));
|
|
208
|
+
}
|
|
195
209
|
if (action === 'sanitize' ? !machine : (action === 'renew' || action === 'release') && scope !== 'member') {
|
|
196
210
|
throw new ResourceLedgerError(403, 'worker-scope');
|
|
197
211
|
}
|